Click here to Skip to main content
Click here to Skip to main content

Code Project Forums In Perl

By , 2 Sep 2001
Rate this:
Please Sign up or sign in to vote.
<!-- Download Links -->

Sample Image - screenshot.gif

<!-- Add the rest of your HTML here -->

Introduction

I have created a perl version of the Code Project Discussion Forums. The perl version of the forum is very basic and lacks a lot of features. This project is an open-source project meaning that I am urging perl programmers to help make this forum better. Feel free to add features but don't forget to report them so I can update the source code file. Currently the forums don't use some sort of a database but future releases will use the mySQL database. This is only BETA 1 of version 1.0. The forums are tested under Apache for Win32. Currently there is no admin feature but future releases will definitely include an admin section.

Lets get our hands dirty...

Instructions on how to install the script are included in the zip file. Installing the script is very easy. The project is made up of 7 files and 2 directories.

Directories

img/ 

 Where the emoticon icons are stored.

messages/ 

 Where the reply forms are stored

Files

Install.txt: Contains instruction on how to install the script.
global.css: The CSS file used for the HTML pages.
forum.pl: This does the hard work.
forum.html: This file contains the messages posted.
data.txt: A simple text file that keeps a count of how many messages are posted.
mouse.js: Contains JavaScript functions.
new.html: The form for posting a new message.

That's all there is to it.

To do...

There is lots of work to be done with the Perl Discussion Forums. The new versions will be releases right here at Code Project. Please give some feed back!

Enjoy!

Revision History

17 Jun 2002 - Initial Revision
17 Jun 2002 - Reformatted Text and Resized Image

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

No Biography provided

Comments and Discussions

 
QuestionHow to redirect output to variable instead of file in perl PinmemberAmarjeetSinghMatharu25-Nov-08 1:51 
QuestionRegular Expression [modified] PinmemberVenkataramuc4-Oct-07 20:52 
QuestionPerl on pop-up menus or sliding menus Pinmembersharpcloak14-Feb-07 21:38 
Questionusing parameters in select statement PinmemberMember #326181613-Feb-07 0:36 
NewsASP.NET Version available PinmemberQuartz...15-Dec-06 12:39 
Generalplzz help me...perl checking Flash must support clickTAG Pinmembertanmoy panja30-Mar-06 18:03 
GeneralProblem with RegXp Pinmembervodevil5-Jul-05 15:16 
Generaloraperl mod for oracle 9i Pinmemberrapace16-Mar-05 14:12 
GeneralError 500 on Web Page when executing perl script.. Pinmemberjcs200421-Nov-04 18:39 
GeneralProblem in loading self defined modules Pinmembersarah_xue10-Nov-04 14:05 
GeneralChecking for new messages. PinmemberWouter Dhondt14-May-03 0:05 
Hi all.
 
I wrote some code that will check if a message has been posted in the forum. It will check the data.txt file every 30 minutes to see if the number has changed. The code is based on this cp article [^]
 
Note that this code is a very quick hack so expect bugs! It works for me though...
 

// FCheck.cpp : Defines the entry point for the application.
//
 
#include
#include
#include
#include
 
typedef BOOL (__stdcall * LPFN_INETAUTODIAL)(DWORD, HWND);
typedef BOOL (__stdcall * LPFN_INETREADFILE)(LPVOID, LPVOID, DWORD, LPDWORD);
typedef BOOL (__stdcall * LPFN_INETAUTOHANGUP)(DWORD);
typedef BOOL (__stdcall * LPFN_INETCLOSEHANDLE)(LPVOID);
typedef BOOL (__stdcall * LPFN_INETGETCONNSTATE)(LPDWORD, DWORD);
typedef LPVOID (__stdcall * LPFN_INETOPEN)(LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD);
typedef LPVOID (__stdcall * LPFN_INETOPENURL)(LPVOID, LPCSTR, LPCSTR, DWORD, DWORD, DWORD);
 
HINSTANCE hWinInet;
bool bDLLFailure;
HINTERNET hInternetSession;
HINTERNET hURL;
char szTempName[MAX_PATH];
DWORD m_LastKnownAmount;
 
// APIs.
LPFN_INETGETCONNSTATE Inet_GetConnectedState;
LPFN_INETAUTODIAL Inet_AutoDial;
LPFN_INETOPEN Inet_Open;
LPFN_INETCLOSEHANDLE Inet_CloseHandle;
LPFN_INETOPENURL Inet_OpenUrl;
LPFN_INETREADFILE Inet_ReadFile;
LPFN_INETAUTOHANGUP Inet_AutoHangup;
 
int RegReadDWord( HKEY hkey, LPTSTR name, DWORD *pval);
DWORD RegReadDWord(LPCTSTR key, LPCTSTR name, DWORD defaultVal, HKEY hParent = HKEY_LOCAL_MACHINE);
int RegWriteDWord(HKEY hkey, LPTSTR name, DWORD val);
BOOL RegWriteDWord(LPCTSTR hKey, LPCTSTR name, DWORD value, HKEY hKeyParent = HKEY_LOCAL_MACHINE);
 
void ErrorHandler (char * szMessage)
{
// Display a message box to alert the user to the failure.
::MessageBox (NULL, szMessage, "Checking Forum", MB_OK | MB_ICONINFORMATION);
}
 
bool ConnectToWeb (char * szAgent)
{
DWORD dwFlags;

// First we see if the user is already connected...
if (!Inet_GetConnectedState (&dwFlags, 0)) {
// Prompt the user to connect to the internet.
if (!Inet_AutoDial (0, NULL)) {
ErrorHandler ("This application must connect to the Internet to check the forum.");
return false;
}
}

// Ok first connect to the internet.
hInternetSession = Inet_Open (szAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternetSession == NULL) {
ErrorHandler ("Cannot connect to the Internet.");
return false;
}

return true;
}
 
bool DisconnectFromWeb ()
{
// Close down connections.
Inet_CloseHandle (hInternetSession);

// Disconnect from the Internet.
Inet_AutoHangup (0);

return true;
}
 
bool RetrieveFileFromWeb (char * szUrl, char * szFileName)
{
DWORD dwBytesRead, dwBytesWritten;
char szFileBuffer[4096];
HANDLE hTempFile;
char * szBuffer;

// Make the complete URL from the filename and URL given.
szBuffer = new char [strlen (szUrl) + strlen (szFileName) + 2];
if (szBuffer == NULL) {
ErrorHandler ("Cannot allocate memory to buffer!");
return false;
}

// Concatinate the URL and filename
sprintf (szBuffer, "%s/%s", szUrl, szFileName);

// Open the URL.
hURL = Inet_OpenUrl (hInternetSession, szBuffer, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0, 0);
if (hURL == NULL) {
ErrorHandler ("Cannot connect to forum URL.");
delete[] szBuffer;
return false;
}

// Create a temporary file.
char* pBuf = new char[MAX_PATH];
GetTempPath(MAX_PATH, pBuf);
GetTempFileName (pBuf, "WU_", 0, szTempName);
delete[] pBuf;
hTempFile = CreateFile ((LPTSTR) szTempName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);

// Check to see if the file was created successfully.
if (hTempFile == INVALID_HANDLE_VALUE) {
ErrorHandler ("Cannot create a temporary forum check file.");
delete[] szBuffer;
return false;
}

// TODO: show progress bar!
do {
// Keep reading until we have the entire file.
Inet_ReadFile (hURL, (LPSTR) szFileBuffer, (DWORD) 1024, &dwBytesRead);

// If we retrieved some data - write it to the output file.
if (dwBytesRead > 0) WriteFile (hTempFile, (PVOID) szFileBuffer, dwBytesRead, &dwBytesWritten, NULL);
} while (dwBytesRead > 0);
 
// Close the handle to the file.
CloseHandle (hTempFile);

// Close the handle to the URL.
Inet_CloseHandle (hURL);

return true;
}
 
bool ParseVersionFile (char * szVersionFile)
{
DWORD dwBytesRead, dwSize;
int nCounter = 0;
char * szBuffer;
HANDLE hVersionFile;

// Open the file for reading.
hVersionFile = CreateFile (szVersionFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hVersionFile == INVALID_HANDLE_VALUE) {
ErrorHandler ("Cannot open downloaded version file.");
return false;
}

// Try to obtain the version file size.
dwSize = GetFileSize (hVersionFile, NULL);

// Read the file into a buffer.
szBuffer = new char [dwSize];
if (szBuffer == NULL) {
ErrorHandler ("Cannot allocate memory for buffer.");
return false;
}

memset(szBuffer, 0, dwSize);
// Actually read from the file.
if (!ReadFile (hVersionFile, szBuffer, dwSize, &dwBytesRead, NULL)) {
ErrorHandler ("Cannot read from downloaded version file.");
return false;
}

// Close the handle to the file.
CloseHandle (hVersionFile);

// Parse the file
if (atol(szBuffer) != m_LastKnownAmount)
{
// A new message!
m_LastKnownAmount = atol(szBuffer);
char msg[MAX_PATH];
memset(&msg, 0, MAX_PATH);
sprintf((char *)&msg, "New message! Total messages: %d.", m_LastKnownAmount);
ErrorHandler(msg);
HKEY hKey;
DWORD disp = REG_OPENED_EXISTING_KEY;
if ( RegCreateKeyEx( HKEY_LOCAL_MACHINE,
"SOFTWARE\\YOURKEY\\FCheck",
0,
"",
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&disp) != ERROR_SUCCESS)
{
return FALSE;
}
::RegWriteDWord(hKey, "Forum Check", m_LastKnownAmount);
}

// Clean up the memory allocations.
delete [] szBuffer;

return true;
}
 
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
HKEY hKey;
RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\YOURKEY\\FCheck", &hKey);
if (RegReadDWord(hKey, "Forum Check", &m_LastKnownAmount)<0)
{
m_LastKnownAmount = 60000;
}
RegCloseKey(hKey);

bDLLFailure = false;

// Dynamically load the WinInet.Dll file.
hWinInet = LoadLibrary ("WinInet.Dll");
if (hWinInet == NULL) {
ErrorHandler ("Cannot load WinInet.Dll. Please make sure IE 4.0 or greater is installed!");
return TRUE;
}

// Attempt to dynamically load the APIs
Inet_GetConnectedState = (LPFN_INETGETCONNSTATE) GetProcAddress (hWinInet, "InternetGetConnectedState");
Inet_AutoDial = (LPFN_INETAUTODIAL) GetProcAddress (hWinInet, "InternetAutodial");
Inet_Open = (LPFN_INETOPEN) GetProcAddress (hWinInet, "InternetOpenA");
Inet_CloseHandle = (LPFN_INETCLOSEHANDLE) GetProcAddress (hWinInet, "InternetCloseHandle");
Inet_OpenUrl = (LPFN_INETOPENURL) GetProcAddress (hWinInet, "InternetOpenUrlA");
Inet_ReadFile = (LPFN_INETREADFILE) GetProcAddress (hWinInet, "InternetReadFile");
Inet_AutoHangup = (LPFN_INETAUTOHANGUP) GetProcAddress (hWinInet, "InternetAutodialHangup");

// Check to see if all the APIs have been successful and we have a v4.0 WinInet.Dll...
if (Inet_GetConnectedState == NULL) bDLLFailure = true;
if (Inet_AutoDial == NULL) bDLLFailure = true;
if (Inet_Open == NULL) bDLLFailure = true;
if (Inet_CloseHandle == NULL) bDLLFailure = true;
if (Inet_OpenUrl == NULL) bDLLFailure = true;
if (Inet_ReadFile == NULL) bDLLFailure = true;
if (Inet_AutoHangup == NULL) bDLLFailure = true;

// If we have a failure report it to the user and force the upgrade to stop.
if (bDLLFailure == true) {
ErrorHandler ("Cannot load WinInet.Dll. Please make sure IE 4.0 or greater is installed!");
return TRUE;
}

// If we have a failure report it to the user and force the upgrade to stop.
if (bDLLFailure == true) {
ErrorHandler ("IE 4.0 or greater has to be installed to use forum check!");
return -1;
}

while (1)
{
// Connect to the Internet.
if (!ConnectToWeb (forum checker"))
{
Sleep(5 * 60 * 1000);
continue;
}
if (!RetrieveFileFromWeb ("http://www.YOURSITE.com", "data.txt"))
{
DisconnectFromWeb();
Sleep(5 * 60 * 1000);
continue;
}

if (!ParseVersionFile (szTempName))
{
DisconnectFromWeb();
Sleep(5 * 60 * 1000);
continue;
}

if (!DisconnectFromWeb ())
{
Sleep(5 * 60 * 1000);
continue;
}

DeleteFile(szTempName);
Sleep(30 * 60 * 1000);
}
 
return 0;
}
 

 
/***************************************************************************
* RegReadDWord()
*
* Function reads a DWORD entry from the registry
*
* hkey: handle of key to query
* name: address of name of value to query
* pval: address of the variable to fill in upon return
*
* Returns: -1 when the entry does not exist or is not a DWORD
* >=0 when the entry is read
*
*/
int RegReadDWord( HKEY hkey, LPTSTR name, DWORD *pval)
{
DWORD var = 0;
DWORD type = REG_DWORD;
DWORD size = sizeof( DWORD);
 
// Query the value, check if it exists and really is a DWORD
LONG retv = RegQueryValueEx( hkey,
name,
NULL,
&type,
(BYTE*)&var,
&size);
if ( retv == ERROR_SUCCESS && type == REG_DWORD)
{
*pval = var;
return 0;
}
 
return -1;
}
 

/***************************************************************************
* RegReadDWord()
*
* Description : Reads a value from the registry
*
* Return value : the value if succeeded, or the default value otherwise
*
* Parameters :
* - key : the key in which to read (e.g. SOFTWARE\\dZine\\SomeKey)
* - name : the name of the value to read
* - defaultVal : the value to return if the read fails
* - hKeyParent : the key from which to start
* (default : HKEY_LOCAL_MACHINE)
*
*/
DWORD RegReadDWord(LPCTSTR key, LPCTSTR name, DWORD defaultVal, HKEY hKeyParent)
{
HKEY hKey = NULL;
DWORD result = defaultVal;
if (RegOpenKeyEx(hKeyParent,
(LPCTSTR)key,
0,
KEY_QUERY_VALUE,
&hKey) == ERROR_SUCCESS)
{
 
DWORD type = REG_SZ;
DWORD size = sizeof(DWORD);
DWORD valueRead;
// Query the value, check if it exists and really is a DWORD
if (RegQueryValueEx(hKey,
name,
NULL,
&type,
(BYTE *)&valueRead,
&size) == ERROR_SUCCESS)
{
result = valueRead;
}
RegCloseKey(hKey);
}
return result;
}
 
/***************************************************************************
* RegWriteDWord()
*
* Function writes a DWORD entry to the registry
*
* hkey: handle of key to query
* name: address of name of value to write
* val: value to write
*
* Returns: -1 failed to write the entry (invalid key, no rights ???)
* >=0 when the entry is written
*
*/
int RegWriteDWord( HKEY hkey, LPTSTR name, DWORD val)
{
if ( RegSetValueEx( hkey, name, 0, REG_DWORD,
(BYTE*)&val, sizeof( DWORD)) != ERROR_SUCCESS)
return -1;
 
return 0;
}
 

/***************************************************************************
* RegWriteDWord()
*
* Description : Writes a DWORD value to the registry
*
* Return value : TRUE == success, FALSE == error
*
* Parameters :
* - key : the name of the key (e.g. SOFTWARE\\dZine\\SomeKey)
* - name : the name of the registry value
* - value : the value to write
* - hKeyParent : the key from which to start
* (default : HKEY_LOCAL_MACHINE)
*
*/
BOOL RegWriteDWord(LPCTSTR key, LPCTSTR name, DWORD value, HKEY hKeyParent)
{
HKEY hKey;
DWORD disposition;
if ( RegCreateKeyEx(hKeyParent,
key,
0,
"",
REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE,
NULL,
&hKey,
&disposition) != ERROR_SUCCESS)
{
return FALSE;
}
if (RegSetValueEx(hKey,
name,
0,
REG_DWORD,
(const BYTE *)&value,
sizeof(DWORD)) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return FALSE;
}
 
RegCloseKey(hKey);
return TRUE;
}

 
-----------------------
New and improved: kwakkelflap.com
My second CP article: MAP files[^]
 
while (!:bob:.IsDrunk())
{
:bob:.Drink( :beer: );
}

QuestionGreat! But some problem? PinmemberWouter Dhondt8-May-03 23:39 
GeneralCygwin perl... Ftp... Windows line end.. PinsussAnonymous7-May-03 10:20 
GeneralRe: Cygwin perl... Ftp... Windows line end.. PinmemberFooOfTheBar4-Aug-03 1:31 
GeneralProblem Pinmemberdali9-Dec-02 5:14 
General.NET PinsussAnonymous23-Aug-02 15:45 
AnswerRe: .NET PinmemberQuartz...15-Dec-06 12:38 
Generalplease help me Pinmemberamir_khan19-Nov-01 21:31 
GeneralRe: please help me PinmemberJohn Ribar2-Dec-01 9:20 
GeneralRe: please help me PinmemberJon Sagara2-Dec-01 10:38 
GeneralRe: please help me PinmemberJon Sagara3-Jan-02 13:53 
GeneralRe: please help me Pinmemberjaygiri212-Jul-05 0:59 
GeneralRe: please help me PinmemberAmin shayan17-Jun-02 19:21 
GeneralPerl Excel and Ole PinmemberArno Teunisse14-Sep-01 10:23 
GeneralRe: Perl Excel and Ole PinmemberMandalay18-Jul-02 12:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 3 Sep 2001
Article Copyright 2001 by John Simmon / outlaw programmer
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid