/* PopDir v1.4 © Copyright 1989 Jonathan Potter */

#include "PopDir.h"

main()
{
	struct Gadget *Gadget;
	int GadgetID,whichwin,file,x,y,a;
	int IRQCheck=FALSE;
	IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0);
	GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0);
	finfo=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),MEMF_CHIP|MEMF_CLEAR);
	Window=(struct Window *) OpenWindow(&small);
	whichwin=1;
	(void) SetTaskPri(FindTask((char *) 0), 20);
	for (;;) {
		Wait(1<<Window->UserPort->mp_SigBit);
		while (Msg=GetMsg(Window->UserPort)) {
			ReplyMsg(Msg);
			switch (Msg->Class) {
				case INACTIVEWINDOW:	
					med.LeftEdge=Window->LeftEdge;
					med.TopEdge=Window->TopEdge;
					small.LeftEdge=Window->LeftEdge;
					small.TopEdge=Window->TopEdge;
					CloseWindow(Window);
					Window=(struct Window *) OpenWindow(&small);
					whichwin=1;
					break;

				case CLOSEWINDOW:
					CloseWindow(Window);
					if (whichwin==2) {
						FreeMem(finfo,sizeof(struct FileInfoBlock));
						CloseLibrary(IntuitionBase);
						CloseLibrary(GfxBase);
						OpenWorkBench();
						exit(0);
					}
					Window=(struct Window *) OpenWindow(&med);
					SetWindowTitles(Window,-1,"PopDir v1.4 © Copyright 1988 Jonathan Potter");
					whichwin=2;
					break;

				case GADGETUP:
					if (whichwin==1) {
						CloseWindow(Window);
						Window=(struct Window *) OpenWindow(&med);
						SetWindowTitles(Window,-1,"PopDir v1.4 © Copyright 1988 Jonathan Potter");
						whichwin=2;
						break;
					}
					Gadget=(struct Gadget *) Msg->IAddress;
					GadgetID=Gadget->GadgetID;
					if (GadgetID>1 && GadgetID<14) {
						sprintf(dobuffer,Gadget->GadgetText->IText);
						RefreshGadgets(&StrGad,Window,NULL);
						break;
					}
					else if (GadgetID==14) {
						if (IRQCheck==FALSE) IRQCheck=TRUE; else IRQCheck=FALSE;
						break;
					}
					whichwin=3;
					med.LeftEdge=Window->LeftEdge;
					med.TopEdge=Window->TopEdge;
					CloseWindow(Window);
					Window=(struct Window *) OpenWindow(&big);
					SetWindowTitles(Window,dobuffer,"PopDir v1.4 © Copyright 1988 Jonathan Potter");
 					if ((lock=Lock(dobuffer,ACCESS_READ))==0) {
						sprintf(ToPrint,"Can't lock requested directory!");
						PrintIText(Window->RPort,&Files,10,12);
						sprintf(ToPrint,"Click on Close Gadget to continue");
						WriteStatus();
						goto finalquit;
					}
					NonExTotal=VirTotal=CleanTotal=KilledTotal=0;
					Examine(lock,finfo);
					file=0; y=12; x=10; a=0;
					if (finfo->fib_DirEntryType<0) {
						sprintf(ToPrint,"%-30s",finfo->fib_FileName);
						PrintIText(Window->RPort,&Files,x,y);
						sprintf(ToPrint,"%-7ld",finfo->fib_Size);
						PrintIText(Window->RPort,&Files,x+242,y);
						if (IRQCheck)
							CheckIRQ(dobuffer,finfo->fib_FileName);
						sprintf(ToPrint,"Click on Close Gadget to continue");
						WriteStatus();
						goto finalquit;;
					}
					if (IRQCheck) {
						if (dobuffer[0]!=0 && dobuffer[1]!=0 &&
							dobuffer[strlen(dobuffer)-1]!=':' &&
							dobuffer[strlen(dobuffer)-1]!='/')
							strcat(dobuffer,"/");
					}
					oldlock=CurrentDir(lock);
					Forbid(); 
					while ((ExNext(lock,finfo))!=0) {
						a=1;
						if (file==0) {
							sprintf(ToPrint,"Reading directory.. Close gadget to cancel");
							WriteStatus();
						}
						if (Msg=GetMsg(Window->UserPort)) {
							ReplyMsg(Msg);	
							if (Msg->Class==CLOSEWINDOW) {
								CloseWindow(Window);
								Window=(struct Window *) OpenWindow(&med);
								SetWindowTitles(Window,-1,"PopDir v1.4 © Copyright 1988 Jonathan Potter");
								whichwin=2;
								goto quit;
							}
						}
						if (finfo->fib_DirEntryType>0)
							Files.FrontPen=3;
						sprintf(ToPrint,"%-30s",finfo->fib_FileName);
						PrintIText(Window->RPort,&Files,x,y);
						if (finfo->fib_DirEntryType<0) {
							sprintf(ToPrint,"%-7ld",finfo->fib_Size);
							PrintIText(Window->RPort,&Files,x+242,y);
							if (IRQCheck)
								CheckIRQ(dobuffer,finfo->fib_FileName);
						}
						Files.FrontPen=1; 
						if (x==10) x=330;
						else {
							x=10;
							y=y+8;
						}
						++file;
						if (file>43) {
							sprintf(ToPrint,"Press any key to continue, or click on Close Gadget to cancel");
							WriteStatus();
							Wait(1<<Window->UserPort->mp_SigBit);
							while (Msg=GetMsg(Window->UserPort)) {	
								ReplyMsg(Msg);	
								if (Msg->Class==CLOSEWINDOW) {
									CloseWindow(Window);
									Window=(struct Window *) OpenWindow(&med);
									SetWindowTitles(Window,-1,"PopDir v1.4 © Copyright 1988 Jonathan Potter");
									whichwin=2;
									goto quit;
								}
							}
							SetAPen(Window->RPort,0);
							RectFill(Window->RPort,9,10,637,198);
							file=0; y=12; x=10;
						}
					}
					if (a==0) {
						sprintf(ToPrint,"Requested directory is empty");
						PrintIText(Window->RPort,&Files,10,12);
					}
					if (IRQCheck)
						sprintf(ToPrint,"Checked:%d Clean:%d Viruses:%d Killed:%d",
							NonExTotal+VirTotal+CleanTotal,CleanTotal+NonExTotal,
							VirTotal,KilledTotal);
					else sprintf(ToPrint,"Click on close gadget to continue");
					WriteStatus();
					quit:
					Permit();
					CurrentDir(oldlock);
					UnLock(lock);
					finalquit:
					break;

				default:
					break;
			}
		}
	}
}

CheckIRQ(directory,name)
char *directory;
char *name;
{
	int i=0;
	long hunka,hunkb,hunkc;
	long filebuff[122];
	long inp, *buff, size;
	inp=0; buff=0;
	sprintf(ToPrint,"Checking file \"%s%s\" for IRQ virus...",directory,name);
	WriteStatus();
	if ((inp=Open(name,MODE_OLDFILE))==0) {
		sprintf(ToPrint,"Error! Can't find file \"%s%s\"!",directory,name);
		WriteStatus();
		goto CleanUp;
	}
	Read (inp,(char *)&filebuff[0],487);
	if (filebuff[0]!=0x000003f3) {
		sprintf(ToPrint,"File \"%s%s\" is not executable.",directory,name);
		WriteStatus();
		++NonExTotal;
		goto CleanUp;
	}
	if (filebuff[5]!=0x00000109) {
		sprintf(ToPrint,"File \"%s%s\" is clean!",directory,name);
		WriteStatus();
		++CleanTotal;
		goto CleanUp;
	}
	Seek (inp,0,OFFSET_END);
	size=Seek (inp,0,OFFSET_BEGINNING);
	if (size<=0) {
		sprintf(ToPrint,"Error! Seek error on file \"%s%s\"!",directory,name);
		WriteStatus();
		goto CleanUp;
	}
	if ((buff=AllocMem(size,0))==0) {
		sprintf(ToPrint,"Error! Can't allocate memory!");
		WriteStatus();
		goto CleanUp;
	}
	if (Read(inp,(char *)&buff[0],size)!=size) {
		sprintf(ToPrint,"Error reading file \"%s%s\"!",directory,name);
		WriteStatus();
		goto CleanUp;
	}
	hunkc=buff[2]; hunka=buff[3]; hunkb=buff[4];
	while (buff[i++]!=0x000003e9);
	if (((buff[i+1]&0x0000ffff)!=0x0000fffe) ||
		((buff[i+2]&0xffff0000)!=0x61000000)) {
		sprintf(ToPrint,"File \"%s%s\" is clean!",directory,name);
		WriteStatus();
		++CleanTotal;
		goto CleanUp;
	}
	Close(inp);
	sprintf(ToPrint,"IRQ virus found in file \"%s%s\"!",directory,name);
	WriteStatus();
	++VirTotal;
	if ((inp=Open(name,MODE_NEWFILE))==0) {
		sprintf(ToPrint,"Error opening file for write!");
		WriteStatus();
		goto CleanUp;
	}
	buff[2]-=1; buff[4]-=1;
	if (Write(inp,(char *)&buff[0],5*((long)sizeof(long)))!=
		5*((long)sizeof(long))) {
		sprintf(ToPrint,"Write error!");
		WriteStatus();
		goto CleanUp;
	}
	if (Write(inp,(char *)&buff[6],hunkc*((long)sizeof(long)))!=
		hunkc*((long)sizeof(long))) {
		sprintf(ToPrint,"Write error!");
		WriteStatus();
		goto CleanUp;
	}
	i=i+273;
	size=(size/((long)sizeof(long))-i)*((long)sizeof(long));
	if (Write(inp,(char *)&buff[i],size)!=size) {
		sprintf(ToPrint,"Write error!");
		WriteStatus();
		goto CleanUp;
	}
	sprintf(ToPrint,"IRQ virus killed in file \"%s%s\"!",directory,name);
	WriteStatus();
	++KilledTotal;
	CleanUp:
	if (inp) Close(inp);
	if (buff) FreeMem(buff,size);
	return(0);
}

WriteStatus()
{
	SetAPen(Window->RPort,0);
	RectFill(Window->RPort,2,189,637,198);
	Files.FrontPen=3;
	PrintIText(Window->RPort,&Files,10,189);
	Files.FrontPen=1;
	return(0);
}
