/*
ForumCheck
For use with a simple Network54 forum
Version 1.0 - Build 122
20th April 2005 - 25th April 2005

Coded by JT
*/
//#define JDEBUG
#define REAL

#include <Windows.h>
#include <Windowsx.h>
#include <winuser.h>
#include <commctrl.h>
#ifdef REAL
#include <winsock.h>
#endif
#include <stdio.h>
#include "rsrc.h"
#include <math.h>


char buf1[1048576], buf2[1310720], dwnlMessage[524288];
HTREEITEM screen[20];
int first=1;
long mpos;
HWND hWnd,status;

typedef struct {
	unsigned long	MessageId;     //as used in URL
	int				ParentId;
	unsigned char	Title[160];
	unsigned char	Owner[64];
	unsigned char 	Email[160];
	unsigned long	Date;
	unsigned long	MessageSize;
	long 			StartMessage;
	} MessagePrep;

typedef struct {
	unsigned long	MessageId;     //as used in URL
	int				ParentId;
	int				LocalId;       //database specific id
	int				LocalParentId;
	unsigned char	Title[160];
	unsigned char	Owner[64];
	unsigned char 	Email[160];
	int				OwnerId;
	int				Replies;
	unsigned long	Date;
	unsigned long	MessageSizeU;
	unsigned long	MessageSizeC;
	unsigned long 	CRC32;
	int 			Extra;
	long 			StartMessage;
	} MessageStruct;   //size 432

typedef struct {
	unsigned long	Signature;	// QBDB (0x42444251)
	unsigned short	Version;	// 1L
	int				Threads;
	int				Messages;
	unsigned long	FirstMessage; //Pointer to First Message (NULL if none)
	long			FileSizeC;
	long			FileSizeU;
	} FileHeader;

// *That would generate larger numbers than sum = sum + (x * 2), certainly, but nothing huge.

HTREEITEM treeitems[1024];
int poststack[128], poststackl;
TV_ITEM newItem;
HMENU menu;

//#ifdef REAL
#define MAX_SIZE	524288

char buffer[MAX_SIZE];
long bsize;
void *transbuffer;

/*void bzero(long *dest, int len)
{
 int i;
 void *out;
 for(i=0;i<len;i++)
 {
 	out=dest+i;
 	*(char *)out=0;
 }
}*/



//__declspec(dllexport)
int GetAddress(const char* HostName, int Port, struct sockaddr* Result)
    {
    struct hostent*     Host;
    SOCKADDR_IN         Address;

    memset(Result, 0, sizeof(*Result));
    memset(&Address, 0, sizeof(Address));

    Host                = gethostbyname(HostName);
    if(Host != NULL)
        {
        Address.sin_family  = AF_INET;
        Address.sin_port    = htons((short)Port);
        memcpy(&Address.sin_addr, Host->h_addr_list[0], Host->h_length);
        memcpy(Result, &Address, sizeof(Address));
        }
    return Host != NULL;
    }


int ReadPage(const char *Host, const char *Page)
{
 struct sockaddr SockAddr;
 SOCKET Socket;
 int Port=80;
 bsize=0;

 SetWindowText(GetDlgItem(hWnd,IDC_HEADING),"Connecting to Server...");

 if(GetAddress(Host,Port,&SockAddr))
 {
 	int Status;
 	Socket=socket(AF_INET,SOCK_STREAM,0);
 	Status=connect(Socket,&SockAddr,sizeof(SockAddr));
 	if(Status>=0)
 	{
 		DWORD StartTime,EndTime;
 		char Request[512];
 		char *Rover=&dwnlMessage[0];
 		int Read;
 		SetWindowText(GetDlgItem(hWnd,IDC_HEADING),"Dowloading Index...");
 		sprintf(Request,"GET %s HTTP/1.0\n\n",Page);
 		send(Socket,Request,strlen(Request),0);
 		StartTime=GetTickCount();

 		for(Read=0;Read<MAX_SIZE;)
 		{
 			int ThisRead;
 			ThisRead=recv(Socket,Rover,MAX_SIZE-Read,0);
 			if(ThisRead==SOCKET_ERROR || ThisRead==0)
 				break;
 			else
 			{
 				Read+=ThisRead;
 				Rover+=ThisRead;
 				bsize+=ThisRead;
 			}
 		}

 		EndTime=GetTickCount();
 		closesocket(Socket);
 	}
 	else
 	{
 		MessageBox(NULL,"Can't connect to Server!","ILib Error",0);
 		return(0);
 	}

 }
 else
 {
 	MessageBox(NULL,"Can't connect to Server!","ILib Error",0);
 	return(0);
 }
 return 1;
}

//__declspec(dllexport)

//#endif

void AddPost(char *text)
{
 //SendMessage(GetDlgItem(hWnd,IDC_POSTS),LB_ADDSTRING,0,text);
}

BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	//SetMenu(hDlg,menu);
	hWnd=hDlg;
	if(first)
	 {
	 	SetMenu(hDlg,menu);
	 	first=0;
	 	//status=CreateStatusWindow(WS_CHILD | WS_VISIBLE,"Idle",hDlg,IDC_STATUS);
	 	//DrawStatusText(GetDlgItem(hDlg,IDC_STATUS),&r,"Everything is Ok",SBT_NOBORDERS);
	 	//SendMessage(GetDlgItem(hDlg,IDC_STATUS),SB_SETTEXT,255,"Idle");
	 }

	switch (uMsg) {
	//case WM_CREATE:
		//if(SetMenu(hDlg,menu)!=0)
		//	MessageBox(NULL,"Unable To Create","Error",0);
		//break;
	case WM_CLOSE:
		EndDialog(hDlg,TRUE);
		ExitProcess(1);
		return 0;
		break;
		case WM_COMMAND:
		switch (GET_WM_COMMAND_ID(wParam, lParam)) {
		case IDM_EXIT:
			EndDialog(hDlg,TRUE);
			ExitProcess(1);
			break;
		case IDM_ABOUT:
//			About();
			break;
		case IDC_POSTS:
		case IDC_LOOK:
		case IDC_LOGIN:
			//SendMessage(GetDlgItem(hWnd,IDC_POSTS),LB_SETCOLUMNWIDTH ,280,0);
//			MessageBox(NULL,"Button","button",0);
			DFile();
			return 0;
			break;
		}
	default:
		return 0;
	}
}

BOOL CALLBACK AboutProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch (uMsg) {
	case WM_CLOSE:
		EndDialog(hDlg,TRUE);
		break;
	default:
		return 0;
	}
}

// void About()
//{
  //DialogBox(hInstance,MAKEINTRESOURCE(IDD_MAIN),NULL,AboutProc);
//}

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 LPVOID lpMsgBuf;
 InitCommonControls();
 menu=LoadMenu(hInstance,MAKEINTRESOURCE(IDM_MENU));
 if(DialogBox(hInstance,MAKEINTRESOURCE(IDD_MAIN),NULL,DlgProc)==-1)
 	{
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL);
	MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
	LocalFree( lpMsgBuf );
	exit(0);
 	}
}

int DFile()   //used for testing and debugging
{
 FILE *inFil;
 long fsize;
 char buf[20];
 //SetMenu(hWnd,menu);
 WSADATA         WsaData;
 WSAStartup(0x0001, &WsaData);
 //fsize=ReadPage("www.network54.com","http://www.network54.com/Forum/13959");
 fsize=ReadPage("127.0.0.1","/Forum/13959");
 //inFil=fopen("forum.htm","r");
 //fsize=filesize(inFil);
 //fread(&dwnlMessage[0],fsize,1,inFil);
 //fwrite(&dwnlMessage[0],strlen(dwnlMessage),1,inFil);
 //fclose(inFil);
 SetWindowText(GetDlgItem(hWnd,IDC_HEADING),"Analyzing Data...");
 AnalyzeMessages(&dwnlMessage[0],bsize);
 WSACleanup();
 SetWindowText(GetDlgItem(hWnd,IDC_HEADING),"ForumCheck");
 return 0;
 /*FILE *inFil,*outFil;
 char buf3[20];
 unsigned long u,crc,filesz;
 crc = crc32(0L, Z_NULL, 0);
 inFil=fopen("ffx2.txt","r");
 outFil=fopen("ffx2.dat","w+b");
 filesz=filesize(inFil);
 fread(&buf1[0],filesz,1,inFil);
 compress2(&buf2[0],&u,&buf1[0],filesz,9);
 crc=crc32(crc,buf1,filesz);
 fwrite(&buf2[0],u,1,outFil);
 fclose(inFil);
 fclose(outFil);
 MessageBox(NULL,itoa(crc,buf3,16),"DFile",0);
 return 0;*/
}

int filesize( FILE *fil )
{
    long int savepos, sizeoffile;
    savepos=ftell(fil);
    fseek(fil,0,SEEK_END);
    sizeoffile=ftell(fil);
    fseek(fil,savepos,SEEK_SET);
    return(sizeoffile);
}

void seek(long pos)
{
	mpos=0;
}

void *GetData(int where)
{
 	return(&dwnlMessage[0]+where);
}

int iseq(char *string, int where)
{
 return(strncmp(string,&dwnlMessage[where],strlen(string)));
}

int isneq(char *string, int where, int len)
{
 return(strncmp(string,&dwnlMessage[where],len));
}

void PushPostStack(HTREEITEM val)
{
 poststackl++;
 poststack[poststackl]=val;
}

HTREEITEM PopPostStack()
{
 return(poststack[poststackl]);
 poststackl--;
}
//int poststack[128], poststackl=0;


int ExtractPostTitleLength(int loc)
{
 int i,j,k;
 unsigned long start, cmp, retv;
 char buf[20];
 start=&dwnlMessage[loc];
 for(i=0;i<256;i++)
 {
 	memcpy(&cmp,&dwnlMessage[i+loc], 4);
 	//MessageBox(NULL,itoa(cmp,buf,16),"Reference",0);

 	if(cmp==0x3E612f3C)  //0x3E412f3C
 	{
 		retv=i;
 		return retv;
 	}
 }
 return 0;
}

//void FormatString(char *dest, char *src)

int lastindent, indent;
// Analyzes raw html code (index.htm) and extracts all the posts

int AnalyzeMessages(char * data, long length)
{
 char buf3[20],s,t,url[20],furl[80], text[256], ftext[256], itext[256],poster[64], gtext[64];
 long messagesn=0,i,j,k,l,m,n, lastitem=0;
 MessagePrep messages[512];
 HTREEITEM parent=0, cindex=0;
 TV_INSERTSTRUCT msg;
 TV_ITEM item;
#ifdef JDEBUG
 char debugbuffer[80];
 FILE *fil;
 fil=fopen("debug.dbg","w+b");
#endif
 //AllocConsole();
 seek(0);
 if(iseq("HTTP/1.1 200 OK",0))
 	{
	MessageBox(NULL,"Error in Downloaded Data!","DFile",0);
    return 0;
	}

 lastindent=0;
 indent=0;



 for(i=0;i<length;i++)
 	{
 	//if(((iseq("aaaacc><FONT size=-1>",i)==0))||((iseq("aaaacc><FONT",i)==0)))
 	if(((iseq("bgcolor=AAAACC width=70%><font  size=",i)==0))||((iseq("aaaacc><FONT",i)==0)))
 	 { //an indentation spot is found (to search for replies)
 		 int startp,endp,count=0; //i didn't know you could do this...

 		 for(j=0;j<64;j++)
 	 	  {
 		  	if(iseq("&nbsp;",i+j)==0)
 		  	 {
 		  		count++;
 		  	 }
 		  }
 		 indent=count;
         //MessageBox(NULL,itoa(iseq("HTTP",0),buf3,10),"ForumCheck Diagnostic",0);
 //        MessageBox(NULL,"Indentation FOund","ForumCheck Diagnostic",0);
 	 }
    //fprintf(fil,"Indent: %d  LastIndent: %d\n",indent,lastindent);

    if((iseq("<font  size=\"-1\" ><b>",i)==0))
     {
     	int a,b,c;
     	a=0;
     	for(j=0;j<64;j++)
     	 {
     	  	if(iseq("</b>",i+j)==0)
     	  	 {
     	  	  a=j;
     	  	  //break;
     	  	  //goto gototest;

     	  	 }
     	 }
     	gototest:
     	memset(&poster[0],0,64);
     	m=0;
     	if((a-21)>0)
     	 {
     		memcpy(&poster[0],&dwnlMessage[i+21],a-21);
     		m=1;
     		//MessageBox(NULL,poster,"Poster ForumCheck",0);
     	 }

     	 /*else
     	 {
     	 	for(k=0;k<256;k++)
     	 	 {
     	 	 	if(iseq("<noscript>",i+a+k)==0)
     	 	 	 {
     	 	 	 m=i+a+k+15;
     	 			for(l=0;l<64;l++)
     	 			 {
     	  				if(iseq("</noscript>",i+a+k+l)==0)
     	  	 			 {
     	  	  				n=i+a+k+l;
     	  	  				memcpy(&poster[0],&dwnlMessage[m],n);
     						MessageBox(NULL,poster,"Poster ForumCheck",0);
     	  	  				//break;
     	  	  				//goto gototest;

                         }
                     }
                  }

     	  	 }
     	 }*/

     }

    if((iseq("message?forumid=13959&messageid=",i)==0))
 	//if((iseq("http://www.network54.com/Forum/message?forumid=13959&amp;messageid=",i)==0))
 	 {
 		                                                  //67

		memset(&text[0],0,256);
		memset(&ftext[0],0,256);
 	    //k=ExtractPostTitleLength(i+49); //79
 	    k=ExtractPostTitleLength(i+44); //79
 	    //MessageBox(NULL,itoa(k,buf3,10),"Lower",0);
 	    memcpy(&text[0],&dwnlMessage[i+44],k);
 		messagesn++;
 		memset(&furl[0],0,80);
 		memcpy(&furl[0],GetData(i),42);
 		//SetDlgItemText(hWnd,IDC_POSTTEXT,furl);                           //    W   L
 		l=0;
 		for(j=0;j<k;j++)
 		 {
 			 if(!((*(char *)(&text[j])==0xD)||(*(char *)(&text[j])==0xA)))
 				memcpy(&ftext[l++],&text[j],1);
 			 else
 			 	j+=5;
 		 }
        //MessageBox(NULL,text,"wwe",0);
		if(indent>lastindent)
		 {
		 	PushPostStack(parent);
		 	parent=cindex;
		 }
        //MessageBox(NULL,itoa(indent+(lastindent*1000),buf3,10),"Lower",0);
        //cputs(itoa(indent,buf3,10));
        //cputs("            ");
        //cputs(itoa(lastindent,buf3,10));
        //cputs("\n");
		if((indent<lastindent)&&(indent))
		 {
		    int c;
		    HTREEITEM n=cindex;

		    for(c=indent;c<(lastindent+2);c++)
		     {
		    	cindex=parent;
 				parent=PopPostStack();
				if(c==indent)
				 {
		    		newItem.mask=TVIF_CHILDREN	| TVIF_HANDLE;// | TVIF_STATE;
	 				newItem.cChildren=0;
 					newItem.hItem=n;
		    		SendMessage(GetDlgItem(hWnd,IDC_POSTS),TVM_SETITEM,0,&newItem);
		    	 }

		 	}
		 }

		if(indent==lastindent)
		 {
		    	newItem.mask=TVIF_CHILDREN	| TVIF_HANDLE;// | TVIF_STATE;
 			newItem.cChildren=0;
 			newItem.hItem=cindex;
		    SendMessage(GetDlgItem(hWnd,IDC_POSTS),TVM_SETITEM,0,&newItem);
		 }

		if((indent==0)&&(!(lastindent==0)))
		 {
		    	newItem.mask=TVIF_CHILDREN	| TVIF_HANDLE;// | TVIF_STATE;
 				newItem.cChildren=0;
 				newItem.hItem=cindex;
		    SendMessage(GetDlgItem(hWnd,IDC_POSTS),TVM_SETITEM,0,&newItem);
		    parent=0;
		    poststackl=0;
		 }
         strcpy(gtext,ftext);
         strcat(gtext," - ");
         strcat(gtext,poster);
		 //if(m==1)
     	  //{
     	 	//strcat(ftext, " - ");
     	 	//strcat(ftext, poster);
     	 	//memcpy(&ftext[strlen(ftext)-1]," - ",3);
     	  //}

#ifdef JDEBUG
 //sprintf(debugbuffer,"Title: %s text\n",ftext);
 //cputs(debugbuffer);
 fprintf(fil,"Indent: %d  LastIndent: %d  Title: %s\n",indent,lastindent,gtext);

#endif
 	lastindent=indent;
 		//if(messagesn<10)
 			//SendMessage(GetDlgItem(hWnd,IDC_POSTS),LB_ADDSTRING,0,ftext);
 			item.mask=TVIF_TEXT | TVIF_CHILDREN;
 			item.pszText=ftext;
 			item.cchTextMax=5;
 			item.cChildren=1;
 			//item.hItem=treeitems[lastitem];
 			//if((indent>0)&&(lastitem))
 			//	msg.hParent=treeitems[lastitem];//lastitem;
 			//else
 			//	msg.hParent=TVI_ROOT;
 			msg.hParent=parent;
 			msg.hInsertAfter=TVI_LAST;
 			msg.item=item;
 			treeitems[lastitem]=SendMessage(GetDlgItem(hWnd,IDC_POSTS),TVM_INSERTITEM,0,&msg);
 			cindex=treeitems[lastitem];
 			screen[indent]=cindex;
 			//SendMessage(GetDlgItem(hWnd,IDC_POSTS), TVM_EXPAND, TVE_EXPAND,treeitems[lastitem]);
            lastitem++;
        /*if(GetDlgItem(hWnd,IDC_POSTS)==NULL)
        	{
        	MessageBox(NULL,"Error in ListBox Data!","DFile",0);
        	return 0;
        	}
 		ListView_InsertItem(GetDlgItem(hWnd,IDC_POSTS),&item);*/
 		}

 	}
 //MessageBox(NULL,itoa(messagesn,buf3,10),"DFile",0); //Messages found
}


