Click here to Skip to main content
15,885,106 members
Articles / Programming Languages / Perl
Article

Code Project Forums In Perl

Rate me:
Please Sign up or sign in to vote.
3.00/5 (6 votes)
2 Sep 20011 min read 144.6K   662   13   36
The Code Project discussion board in Perl. This is an open source project for the Code Project community.

Sample Image - screenshot.gif

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow to redirect output to variable instead of file in perl Pin
AmarjeetSinghMatharu25-Nov-08 1:51
AmarjeetSinghMatharu25-Nov-08 1:51 
QuestionRegular Expression [modified] Pin
Venkataramuc4-Oct-07 20:52
Venkataramuc4-Oct-07 20:52 
QuestionPerl on pop-up menus or sliding menus Pin
sharpcloak14-Feb-07 21:38
sharpcloak14-Feb-07 21:38 
Questionusing parameters in select statement Pin
Sarathy8013-Feb-07 0:36
Sarathy8013-Feb-07 0:36 
NewsASP.NET Version available Pin
Raj Lal15-Dec-06 12:39
professionalRaj Lal15-Dec-06 12:39 
Generalplzz help me...perl checking Flash must support clickTAG Pin
tanmoy panja30-Mar-06 18:03
tanmoy panja30-Mar-06 18:03 
GeneralProblem with RegXp Pin
vodevil5-Jul-05 15:16
vodevil5-Jul-05 15:16 
Generaloraperl mod for oracle 9i Pin
rapace16-Mar-05 14:12
rapace16-Mar-05 14:12 
GeneralError 500 on Web Page when executing perl script.. Pin
jcs200421-Nov-04 18:39
jcs200421-Nov-04 18:39 
GeneralProblem in loading self defined modules Pin
sarah_xue10-Nov-04 14:05
sarah_xue10-Nov-04 14:05 
GeneralChecking for new messages. Pin
Wouter Dhondt14-May-03 0:05
Wouter 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...

<br />
// FCheck.cpp : Defines the entry point for the application.<br />
//<br />
<br />
#include <windows.h><br />
#include <wininet.h><br />
#include <stdio.h><br />
#include <stdlib.h><br />
<br />
typedef BOOL (__stdcall * LPFN_INETAUTODIAL)(DWORD, HWND);<br />
typedef BOOL (__stdcall * LPFN_INETREADFILE)(LPVOID, LPVOID, DWORD, LPDWORD);<br />
typedef BOOL (__stdcall * LPFN_INETAUTOHANGUP)(DWORD);<br />
typedef BOOL (__stdcall * LPFN_INETCLOSEHANDLE)(LPVOID);<br />
typedef BOOL (__stdcall * LPFN_INETGETCONNSTATE)(LPDWORD, DWORD);<br />
typedef LPVOID (__stdcall * LPFN_INETOPEN)(LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD);<br />
typedef LPVOID (__stdcall * LPFN_INETOPENURL)(LPVOID, LPCSTR, LPCSTR, DWORD, DWORD, DWORD);<br />
<br />
HINSTANCE hWinInet;<br />
bool bDLLFailure;<br />
HINTERNET hInternetSession;<br />
HINTERNET hURL;<br />
char szTempName[MAX_PATH];<br />
DWORD m_LastKnownAmount;<br />
<br />
// APIs.<br />
LPFN_INETGETCONNSTATE Inet_GetConnectedState;<br />
LPFN_INETAUTODIAL Inet_AutoDial;<br />
LPFN_INETOPEN Inet_Open;<br />
LPFN_INETCLOSEHANDLE Inet_CloseHandle;<br />
LPFN_INETOPENURL Inet_OpenUrl;<br />
LPFN_INETREADFILE Inet_ReadFile;<br />
LPFN_INETAUTOHANGUP Inet_AutoHangup;<br />
<br />
int RegReadDWord( HKEY hkey, LPTSTR name, DWORD *pval);<br />
DWORD RegReadDWord(LPCTSTR key, LPCTSTR name, DWORD defaultVal, HKEY hParent = HKEY_LOCAL_MACHINE);<br />
int RegWriteDWord(HKEY hkey, LPTSTR name, DWORD val);<br />
BOOL RegWriteDWord(LPCTSTR hKey, LPCTSTR name, DWORD value, HKEY hKeyParent = HKEY_LOCAL_MACHINE);<br />
<br />
void ErrorHandler (char * szMessage)<br />
{<br />
	// Display a message box to alert the user to the failure.<br />
	::MessageBox (NULL, szMessage, "Checking Forum", MB_OK | MB_ICONINFORMATION);<br />
}<br />
<br />
bool ConnectToWeb (char * szAgent)<br />
{<br />
	DWORD dwFlags;<br />
	<br />
	// First we see if the user is already connected...<br />
	if (!Inet_GetConnectedState (&dwFlags, 0)) {<br />
		// Prompt the user to connect to the internet.<br />
		if (!Inet_AutoDial (0, NULL)) {<br />
			ErrorHandler ("This application must connect to the Internet to check the forum.");<br />
			return false;<br />
		}<br />
	}<br />
	<br />
	// Ok first connect to the internet.<br />
	hInternetSession = Inet_Open (szAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);<br />
	if (hInternetSession == NULL) {<br />
		ErrorHandler ("Cannot connect to the Internet.");	<br />
		return false;<br />
	}<br />
	<br />
	return true;<br />
}<br />
<br />
bool DisconnectFromWeb ()<br />
{<br />
	// Close down connections.<br />
	Inet_CloseHandle (hInternetSession);<br />
	<br />
	// Disconnect from the Internet.<br />
	Inet_AutoHangup (0);<br />
	<br />
	return true;<br />
}<br />
<br />
bool RetrieveFileFromWeb (char * szUrl, char * szFileName)<br />
{<br />
	DWORD dwBytesRead, dwBytesWritten;<br />
	char szFileBuffer[4096];<br />
	HANDLE hTempFile;<br />
	char * szBuffer;<br />
	<br />
	// Make the complete URL from the filename and URL given.<br />
	szBuffer = new char [strlen (szUrl) + strlen (szFileName) + 2];<br />
	if (szBuffer == NULL) {<br />
		ErrorHandler ("Cannot allocate memory to buffer!");	<br />
		return false;<br />
	}<br />
	<br />
	// Concatinate the URL and filename<br />
	sprintf (szBuffer, "%s/%s", szUrl, szFileName);<br />
	<br />
	// Open the URL.<br />
	hURL = Inet_OpenUrl (hInternetSession, szBuffer, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0, 0);<br />
	if (hURL == NULL) {<br />
	ErrorHandler ("Cannot connect to forum URL.");<br />
	delete[] szBuffer;<br />
	return false;<br />
	}<br />
	<br />
	// Create a temporary file.<br />
	char* pBuf = new char[MAX_PATH];<br />
	GetTempPath(MAX_PATH, pBuf);<br />
	GetTempFileName (pBuf,  "WU_", 0, szTempName);<br />
	delete[] pBuf;<br />
	hTempFile = CreateFile ((LPTSTR) szTempName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);<br />
    <br />
	// Check to see if the file was created successfully.<br />
	if (hTempFile == INVALID_HANDLE_VALUE) {<br />
		ErrorHandler ("Cannot create a temporary forum check file.");<br />
		delete[] szBuffer;<br />
		return false;<br />
	}<br />
	<br />
    // TODO: show progress bar!<br />
	do {<br />
	// Keep reading until we have the entire file.<br />
	Inet_ReadFile (hURL, (LPSTR) szFileBuffer, (DWORD) 1024, &dwBytesRead);<br />
	<br />
	  // If we retrieved some data - write it to the output file.<br />
	  if (dwBytesRead > 0) WriteFile (hTempFile, (PVOID) szFileBuffer, dwBytesRead, &dwBytesWritten, NULL);<br />
	} while (dwBytesRead > 0);<br />
<br />
	// Close the handle to the file.<br />
	CloseHandle (hTempFile);<br />
	<br />
	// Close the handle to the URL.<br />
	Inet_CloseHandle (hURL);<br />
	<br />
	return true;<br />
}<br />
<br />
bool ParseVersionFile (char * szVersionFile)<br />
{<br />
	DWORD dwBytesRead, dwSize;<br />
	int nCounter = 0;<br />
	char * szBuffer;<br />
	HANDLE hVersionFile;<br />
	<br />
	// Open the file for reading.<br />
	hVersionFile = CreateFile (szVersionFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);<br />
	if (hVersionFile == INVALID_HANDLE_VALUE) {<br />
		ErrorHandler ("Cannot open downloaded version file.");	<br />
		return false;<br />
	}<br />
	<br />
	// Try to obtain the version file size.<br />
	dwSize = GetFileSize (hVersionFile, NULL);<br />
	<br />
	// Read the file into a buffer.<br />
	szBuffer = new char [dwSize];<br />
	if (szBuffer == NULL) {<br />
		ErrorHandler ("Cannot allocate memory for buffer.");<br />
		return false;<br />
	}<br />
	<br />
	memset(szBuffer, 0, dwSize);<br />
	// Actually read from the file.<br />
	if (!ReadFile (hVersionFile, szBuffer, dwSize, &dwBytesRead, NULL)) {<br />
		ErrorHandler ("Cannot read from downloaded version file.");	<br />
		return false;<br />
	}<br />
	<br />
	// Close the handle to the file.<br />
	CloseHandle (hVersionFile);<br />
	<br />
	// Parse the file<br />
	if (atol(szBuffer) != m_LastKnownAmount)<br />
	{<br />
		// A new message!<br />
		m_LastKnownAmount = atol(szBuffer);<br />
		char msg[MAX_PATH];<br />
		memset(&msg, 0, MAX_PATH);<br />
		sprintf((char *)&msg, "New message! Total messages: %d.", m_LastKnownAmount);<br />
		ErrorHandler(msg);<br />
		HKEY hKey;<br />
		DWORD disp = REG_OPENED_EXISTING_KEY;<br />
		if ( RegCreateKeyEx( HKEY_LOCAL_MACHINE,<br />
			"SOFTWARE\\YOURKEY\\FCheck",<br />
			0,<br />
			"",<br />
			REG_OPTION_NON_VOLATILE,<br />
			KEY_ALL_ACCESS,<br />
			NULL,<br />
			&hKey,<br />
			&disp) != ERROR_SUCCESS)<br />
		{<br />
			return FALSE;<br />
		}<br />
		::RegWriteDWord(hKey, "Forum Check", m_LastKnownAmount);<br />
	}<br />
	<br />
	// Clean up the memory allocations.<br />
	delete [] szBuffer;<br />
	<br />
	return true;<br />
}<br />
<br />
int APIENTRY WinMain(HINSTANCE hInstance,<br />
                     HINSTANCE hPrevInstance,<br />
                     LPSTR     lpCmdLine,<br />
                     int       nCmdShow)<br />
{<br />
 	// TODO: Place code here.<br />
	HKEY hKey;<br />
	RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\YOURKEY\\FCheck", &hKey);<br />
	if (RegReadDWord(hKey, "Forum Check", &m_LastKnownAmount)<0)<br />
	{<br />
		m_LastKnownAmount = 60000;<br />
	}<br />
	RegCloseKey(hKey);<br />
	<br />
	bDLLFailure = false;<br />
	<br />
	// Dynamically load the WinInet.Dll file.<br />
	hWinInet = LoadLibrary ("WinInet.Dll");<br />
	if (hWinInet == NULL) {<br />
		ErrorHandler ("Cannot load WinInet.Dll. Please make sure IE 4.0 or greater is installed!");<br />
		return TRUE;<br />
	}<br />
	<br />
	// Attempt to dynamically load the APIs<br />
	Inet_GetConnectedState = (LPFN_INETGETCONNSTATE) GetProcAddress (hWinInet, "InternetGetConnectedState");<br />
	Inet_AutoDial = (LPFN_INETAUTODIAL) GetProcAddress (hWinInet, "InternetAutodial");<br />
	Inet_Open = (LPFN_INETOPEN) GetProcAddress (hWinInet, "InternetOpenA");<br />
	Inet_CloseHandle = (LPFN_INETCLOSEHANDLE) GetProcAddress (hWinInet, "InternetCloseHandle");<br />
	Inet_OpenUrl = (LPFN_INETOPENURL) GetProcAddress (hWinInet, "InternetOpenUrlA");<br />
	Inet_ReadFile = (LPFN_INETREADFILE) GetProcAddress (hWinInet, "InternetReadFile");<br />
	Inet_AutoHangup = (LPFN_INETAUTOHANGUP) GetProcAddress (hWinInet, "InternetAutodialHangup");<br />
	<br />
	// Check to see if all the APIs have been successful and we have a v4.0 WinInet.Dll...<br />
	if (Inet_GetConnectedState == NULL) bDLLFailure = true;<br />
	if (Inet_AutoDial == NULL) bDLLFailure = true;<br />
	if (Inet_Open == NULL) bDLLFailure = true;<br />
	if (Inet_CloseHandle == NULL) bDLLFailure = true;<br />
	if (Inet_OpenUrl == NULL) bDLLFailure = true;<br />
	if (Inet_ReadFile == NULL) bDLLFailure = true;<br />
	if (Inet_AutoHangup == NULL) bDLLFailure = true;<br />
	<br />
	// If we have a failure report it to the user and force the upgrade to stop.<br />
	if (bDLLFailure == true) {<br />
		ErrorHandler ("Cannot load WinInet.Dll. Please make sure IE 4.0 or greater is installed!");<br />
		return TRUE;<br />
	}<br />
	<br />
	// If we have a failure report it to the user and force the upgrade to stop.<br />
	if (bDLLFailure == true) {<br />
		ErrorHandler ("IE 4.0 or greater has to be installed to use forum check!");<br />
		return -1;<br />
	}<br />
	<br />
	while (1)<br />
	{<br />
		// Connect to the Internet.<br />
		if (!ConnectToWeb (forum checker"))<br />
		{<br />
			Sleep(5 * 60 * 1000);<br />
			continue;<br />
		}<br />
		if (!RetrieveFileFromWeb ("http://www.YOURSITE.com", "data.txt"))<br />
		{<br />
			DisconnectFromWeb();<br />
			Sleep(5 * 60 * 1000);<br />
			continue;<br />
		}<br />
		<br />
		if (!ParseVersionFile (szTempName))<br />
		{<br />
			DisconnectFromWeb();<br />
			Sleep(5 * 60 * 1000);<br />
			continue;<br />
		}<br />
		<br />
		if (!DisconnectFromWeb ())<br />
		{<br />
			Sleep(5 * 60 * 1000);<br />
			continue;<br />
		}<br />
		<br />
		DeleteFile(szTempName);<br />
		Sleep(30 * 60 * 1000);<br />
	}<br />
<br />
	return 0;<br />
}<br />
<br />
<br />
<br />
/***************************************************************************<br />
* RegReadDWord()<br />
*<br />
* Function reads a DWORD entry from the registry<br />
*<br />
* hkey: handle of key to query <br />
* name: address of name of value to query <br />
* pval: address of the variable to fill in upon return<br />
*<br />
* Returns: -1 when the entry does not exist or is not a DWORD<br />
*         >=0 when the entry is read<br />
* <br />
*/<br />
int RegReadDWord( HKEY hkey, LPTSTR name, DWORD *pval)<br />
{<br />
    DWORD var = 0;<br />
	DWORD type = REG_DWORD;<br />
	DWORD size = sizeof( DWORD);<br />
<br />
    // Query the value, check if it exists and really is a DWORD<br />
    LONG retv = RegQueryValueEx( hkey,<br />
					             name,<br />
					             NULL,<br />
					             &type,<br />
					             (BYTE*)&var,<br />
					             &size);<br />
    if ( retv == ERROR_SUCCESS && type == REG_DWORD)<br />
    {<br />
        *pval = var;<br />
        return 0;<br />
    }<br />
<br />
    return -1;<br />
}<br />
<br />
<br />
/***************************************************************************<br />
* RegReadDWord()<br />
*<br />
* Description : Reads a value from the registry<br />
*<br />
* Return value : the value if succeeded, or the default value otherwise<br />
*<br />
* Parameters :<br />
*   - key : the key in which to read (e.g. SOFTWARE\\dZine\\SomeKey)<br />
*   - name : the name of the value to read<br />
*   - defaultVal : the value to return if the read fails<br />
*   - hKeyParent : the key from which to start<br />
*				   (default : HKEY_LOCAL_MACHINE)<br />
*<br />
*/<br />
DWORD RegReadDWord(LPCTSTR key, LPCTSTR name, DWORD defaultVal, HKEY hKeyParent)<br />
{<br />
	HKEY hKey = NULL;<br />
	DWORD result = defaultVal;<br />
	if (RegOpenKeyEx(hKeyParent,<br />
					 (LPCTSTR)key,<br />
					 0,<br />
					 KEY_QUERY_VALUE,<br />
					 &hKey) == ERROR_SUCCESS) <br />
	{<br />
<br />
		DWORD type = REG_SZ;<br />
		DWORD size = sizeof(DWORD);<br />
		DWORD valueRead;<br />
		// Query the value, check if it exists and really is a DWORD<br />
		if (RegQueryValueEx(hKey,<br />
			name,<br />
			NULL,<br />
			&type,<br />
			(BYTE *)&valueRead,<br />
			&size) == ERROR_SUCCESS)<br />
		{<br />
			result = valueRead;<br />
		}<br />
		RegCloseKey(hKey);<br />
	}<br />
	return result;<br />
}<br />
<br />
/***************************************************************************<br />
* RegWriteDWord()<br />
*<br />
* Function writes a DWORD entry to the registry<br />
*<br />
* hkey: handle of key to query <br />
* name: address of name of value to write <br />
* val:  value to write<br />
*<br />
* Returns: -1 failed to write the entry (invalid key, no rights ???)<br />
*         >=0 when the entry is written<br />
* <br />
*/<br />
int RegWriteDWord( HKEY hkey, LPTSTR name, DWORD val)<br />
{<br />
    if ( RegSetValueEx( hkey, name, 0, REG_DWORD,<br />
                        (BYTE*)&val, sizeof( DWORD)) != ERROR_SUCCESS)<br />
        return -1;<br />
<br />
    return 0;<br />
}<br />
<br />
<br />
/***************************************************************************<br />
* RegWriteDWord()<br />
*<br />
* Description : Writes a DWORD value to the registry<br />
*<br />
* Return value : TRUE == success, FALSE == error<br />
*<br />
* Parameters :<br />
*   - key : the name of the key (e.g. SOFTWARE\\dZine\\SomeKey)<br />
*   - name : the name of  the registry value<br />
*   - value : the value to write<br />
*   - hKeyParent : the key from which to start<br />
*				   (default : HKEY_LOCAL_MACHINE)<br />
*<br />
*/<br />
BOOL RegWriteDWord(LPCTSTR key, LPCTSTR name, DWORD value, HKEY hKeyParent)<br />
{<br />
	HKEY hKey;<br />
	DWORD disposition;<br />
	if ( RegCreateKeyEx(hKeyParent,<br />
					    key,<br />
					    0,<br />
						"",<br />
						REG_OPTION_NON_VOLATILE,<br />
					    KEY_SET_VALUE,<br />
						NULL,<br />
					    &hKey,<br />
						&disposition) != ERROR_SUCCESS) <br />
	{<br />
        return FALSE;<br />
	}<br />
	if (RegSetValueEx(hKey,<br />
					  name, <br />
					  0,<br />
					  REG_DWORD,<br />
					  (const BYTE *)&value,<br />
					  sizeof(DWORD)) != ERROR_SUCCESS)<br />
	{<br />
		RegCloseKey(hKey);<br />
		return FALSE;<br />
	}<br />
<br />
	RegCloseKey(hKey);<br />
	return TRUE;<br />
}<br />


-----------------------
New and improved: kwakkelflap.com
My second CP article: MAP files[^]

while (!:bob:.IsDrunk())<br />
{<br />
:bob:.Drink( :beer: );<br />
}

QuestionGreat! But some problem? Pin
Wouter Dhondt8-May-03 23:39
Wouter Dhondt8-May-03 23:39 
GeneralCygwin perl... Ftp... Windows line end.. Pin
Anonymous7-May-03 10:20
Anonymous7-May-03 10:20 
GeneralRe: Cygwin perl... Ftp... Windows line end.. Pin
FooOfTheBar4-Aug-03 1:31
FooOfTheBar4-Aug-03 1:31 
GeneralProblem Pin
dali9-Dec-02 5:14
dali9-Dec-02 5:14 
General.NET Pin
Anonymous23-Aug-02 15:45
Anonymous23-Aug-02 15:45 
AnswerRe: .NET Pin
Raj Lal15-Dec-06 12:38
professionalRaj Lal15-Dec-06 12:38 
Generalplease help me Pin
19-Nov-01 21:31
suss19-Nov-01 21:31 
GeneralRe: please help me Pin
2-Dec-01 9:20
suss2-Dec-01 9:20 
GeneralRe: please help me Pin
Jon Sagara2-Dec-01 10:38
Jon Sagara2-Dec-01 10:38 
GeneralRe: please help me Pin
Jon Sagara3-Jan-02 13:53
Jon Sagara3-Jan-02 13:53 
GeneralRe: please help me Pin
Member 20584072-Jul-05 0:59
Member 20584072-Jul-05 0:59 
GeneralRe: please help me Pin
17-Jun-02 19:21
suss17-Jun-02 19:21 
GeneralPerl Excel and Ole Pin
14-Sep-01 10:23
suss14-Sep-01 10:23 
GeneralRe: Perl Excel and Ole Pin
Mandalay18-Jul-02 12:35
Mandalay18-Jul-02 12:35 

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

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