#include "/Mailbox.h"

struct	ExecBase			*SysBase;
struct	DosLibrary		*DOSBase;
struct	List				BrettDataList;
struct	List				FreeList;
struct	DateStamp		date;
struct	Node				*e;

struct DelBrett
{
	struct Node node;

	char name[81];
	char flags[81];
}	*entry;

#define ARGTEMPLATE "P=PATH/K/A,N=NUMBER/N,D=DAYS/N,B=BYTES/N"

enum { ARG_PATH, ARG_NUMBER, ARG_DAYS, ARG_BYTES, ARGS };

VOID error(STRPTR);
struct Node *GetLine(VOID);
VOID FreeLine(struct Line *);
VOID RemList(struct List *);
UBYTE *GetFile(STRPTR, LONG *);
BOOL Compare(STRPTR, STRPTR);
VOID GetBrettData(STRPTR, struct List *);

LONG __saveds main()
{
	UBYTE **ArgArray;
	LONG number, days, bytes, size, value;
	char file[256], path[256];
	STRPTR buf, buffer, ptr;
	BOOL err;
	BPTR FH;

	SysBase = *(struct ExecBase **)4;

	if(!(DOSBase = OpenLibrary("dos.library", 36)))
		error("dos.library");

	number = days = bytes = 0;
	NewList(&FreeList);
	DateStamp(&date);

	if(ArgArray = (UBYTE **)AllocVec(sizeof(UBYTE *) * ARGS, MEMF_ANY | MEMF_CLEAR))
	{
		struct RDArgs *ArgsPtr;

		if(ArgsPtr = (struct RDArgs *)AllocVec(sizeof(struct RDArgs), MEMF_ANY | MEMF_CLEAR))
		{
			ArgsPtr -> RDA_ExtHelp = "\nUsage: \33[1mDelMail\33[0m <P=path> [N=number] [D=days] [B=Bytes]\n\n";

			if(ReadArgs(ARGTEMPLATE, (LONG *)ArgArray, ArgsPtr))
			{
				if(ArgArray[ARG_PATH]) 		strcpy(path, ArgArray[ARG_PATH]);
				if(ArgArray[ARG_NUMBER])	number	= *((LONG *)ArgArray[ARG_NUMBER]);
				if(ArgArray[ARG_DAYS])		days		= *((LONG *)ArgArray[ARG_DAYS]);
				if(ArgArray[ARG_BYTES])		bytes		= *((LONG *)ArgArray[ARG_BYTES]);
			}
			else
			{
				PrintFault(IoErr(), "DelMail");

				FreeArgs(ArgsPtr);
				FreeVec(ArgsPtr);
				FreeVec(ArgArray);
				CloseLibrary(DOSBase);

				return(RETURN_ERROR);
			}
			FreeArgs(ArgsPtr);
			FreeVec(ArgsPtr);
		}
		FreeVec(ArgArray);
	}

	if(path[strlen(path) - 1] != '/' || path[strlen(path) - 1] != ':')
		strcpy(&path[strlen(path)], "/");

	NewList(&BrettDataList);
	SPrintf(file, "%lsBrettData", path);
	GetBrettData(file, &BrettDataList);

	entry = GetHead(&BrettDataList);
	while(entry)
	{
		Printf("brett: %ls\n", entry->name);

		if(strchr(entry->flags, 'N') || strchr(entry->flags, 'D') ||
			strchr(entry->flags, 'B') || number || days || bytes)
		{
			SPrintf(file, "%ls%ls/Index", path, entry->name);
			if(buffer = GetFile(file, &size))
			{
				buf = buffer;

				if(number || (ptr = strchr(entry->flags, 'N')))
				{
					value = (number ? number : atol(ptr + 1));
					while(buf < buffer + size)
					{
						if(ptr = strchr(buf, '\n'))
						{
							*ptr = 0;
							buf = ptr + 1;
						}
					}
				}

				if(days || (ptr = strchr(entry->flags, 'D')))
				{
					struct List DelList;
					struct FileInfoBlock *finfo;
					BPTR lock;

					if(days)	value = days;
					else
					{
						value = 0;
						ptr++;
						while(isdigit(*ptr))
						{
							value *= 10;
							value += *ptr - 48;
							ptr++;
						}
					}
					NewList(&DelList);

					SPrintf(file, "%ls%ls", path, entry->name);
					if(lock = Lock(file, ACCESS_READ))
					{
						if(finfo = AllocVec(sizeof(struct FileInfoBlock), MEMF_ANY | MEMF_CLEAR))
						{
							if(Examine(lock, finfo) != DOSFALSE)
							{
								do
								{
									ExNext(lock, finfo);
									err = IoErr();
									if(!err && !Compare(finfo->fib_FileName, "Index") &&
										!Compare(finfo->fib_FileName, "UserRead"))
									{
										if(finfo->fib_Date.ds_Days + value - 1 < date.ds_Days)
										{
											if(e = GetLine())
											{
												strcpy(e->text, finfo->fib_FileName);
												AddTail(&DelList, e);
											}
										}
									}
								}	while(!err);
							}
							FreeVec(finfo);
						}
						UnLock(lock);
					}
					e = GetHead(&DelList);
					while(e)
					{
						Printf("delete mail #%ls\n", e->text);
						SPrintf(file, "%ls%ls/%ls", path, entry->name, e->text);
						e = GetSucc(e);
						if(!(DeleteFile(file)))
						{
							struct Line *e2;

							e2 = GetPred(e);
							Remove(e2);
							FreeVec(e2);
							Printf("mail was protected !\n");
						}
					}
					SPrintf(file, "%ls%ls/Index", path, entry->name);
					if(FH = Open(file, MODE_NEWFILE))
					{
						STRPTR temp_ptr;

						while(buf < buffer + size)
						{
							temp_ptr = buf;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
							if(ptr = strchr(buf, '\n'))
							{
								*ptr = 0;
								if(!FindName(&DelList, buf))
								{
									*ptr = '\n';
									Write(FH, temp_ptr, ptr - temp_ptr + 1);
								}
								buf = ptr + 1;
							}
						}
						Close(FH);
					}

					FreeLineList(&DelList);
				}
				FreeVec(buffer);
			}
		}
		entry = GetSucc(entry);
	}

	error(NULL);
}



VOID error(STRPTR meldung)
{
	if(meldung)
	{
		Printf("\nerror: couldn't open %ls\n\n", meldung);
	}

	RemList(&FreeList);
	RemList(&BrettDataList);
	if(DOSBase)			CloseLibrary((struct DosLibrary *)DOSBase);

	Exit(NULL);
}



UBYTE *GetFile(STRPTR file, LONG *size)
{
	BPTR FH;
	UBYTE *buf;
	struct FileInfoBlock fib;

	buf = NULL;
	*size = 0;

	if(FH = Open(file, MODE_OLDFILE))
	{
		ExamineFH(FH, &fib);

		*size = fib.fib_Size;
		if(buf = (UBYTE *)AllocVec(*size + 8, MEMF_ANY | MEMF_CLEAR))
			Read(FH, buf, *size);

		Close(FH);
	}

	return(buf);
}



struct Line *GetLine()
{
	struct Line *e;

	if(e = GetHead(&FreeList))
	{
		LONG i;

		i = 80;
		do
		{
			e->text[i] = 0;
		}	while(i--);

		Remove(e);
		return(e);
	}
	else
	{
		if(e = AllocVec(sizeof(struct Line), MEMF_ANY | MEMF_CLEAR))
		{
			e->node.ln_Name = e->text;
			return(e);
		}
		return(NULL);
	}
}



VOID FreeLine(struct Line *e)
{
	if(e)	AddTail(&FreeList, e);
}



VOID RemList(struct List *list)
{
	APTR e1, e2;

	e2 = GetHead(list);
	while (e1 = e2)
	{
		e2 = GetSucc(e1);
		Remove(e1);
		FreeVec(e1);
	}
}



BOOL Compare(STRPTR s1, STRPTR s2)
{
	STRPTR b1, b2;
	BOOL ret;

	ret = FALSE;

	if(b1 = (STRPTR)AllocVec(strlen(s1) + 8, MEMF_ANY))
	{
		if(b2 = (STRPTR)AllocVec(strlen(s2) + 8, MEMF_ANY))
		{
			CopyMem(s1, b1, strlen(s1) + 1);
			CopyMem(s2, b2, strlen(s2) + 1);

			strupr(b1);
			strupr(b2);

			ret = !strcmp(b1, b2);

			FreeVec(b2);
		}
		FreeVec(b1);
	}

	return(ret);
}



VOID GetBrettData(STRPTR file, struct List *list)
{
	STRPTR ptr, buffer, buf;
	LONG size;

	if(!(buffer = GetFile(file, &size)))
		error(file);

	buf = buffer;
	entry = (struct DelBrett *)AllocVec(sizeof(struct DelBrett), MEMF_ANY | MEMF_CLEAR);
	while(buf < buffer + size && entry)
	{
		if(ptr = strchr(buf, '\n'))
		{
			*ptr = 0;
			strcpy(entry->name, buf);
			buf = ptr + 1;
		}
		if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
		if(ptr = strchr(buf, '\n'))
		{
			*ptr = 0;
			strcpy(entry->flags, buf);
			buf = ptr + 1;
		}
		if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
		if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
		if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
		while(*buf != '#' && buf < buffer + size)
		{
			if(ptr = strchr(buf, '\n'))	buf = ptr + 1;
		}
		if(ptr = strchr(buf, '\n'))
		{
			buf = ptr + 1;

			entry->node.ln_Name = entry->name;
			entry->node.ln_Type = NT_MEMORY;

			AddTail(list, entry);
			entry = AllocVec(sizeof(struct DelBrett), MEMF_ANY | MEMF_CLEAR);
		}
	}
	if(entry)	FreeVec(entry);

	FreeVec(buffer);
}
