#include <exec/types.h>
#include <proto/exec.h>
#include <clib/dos_protos.h>
#include <dos/var.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "AXsh.h"

extern BOOL sw_remote,logged_in,sw_nullmodem;
extern int commandcount,commandshift,autologout;
extern char tty[],mailhome[],thismachine[];
extern struct User user;
extern int Rows,Columns;
extern struct Library *ArpBase;

#define DUMB	0
#define VT100	1
#define ANSI	2

#define MODE_NORMAL	0
#define MODE_ESC	1
#define MODE_CSI	2

int getstring(char *pr,UBYTE *a,int lenght,BOOL echo)	/* getline routine with echo and history */
{														/* additionally log-keeping and carrier checking */
	static int func=-1,histc=0;	/* history count */
	static UBYTE history[HISTORY][ARGLEN]={"A"}; /* table for history */
	static UBYTE funcstr[ARGLEN+1],killbuf[ARGLEN+1];
	BOOL ignoreeof;
	int autologout=4;
	UBYTE c=0,temp[ARGLEN+2];	/* temporary for expansions etc. */
	int done=0,term=DUMB,hist=histc,oldhist=histc,altc=0,mode=MODE_NORMAL;
	long Signals,file,count=0;
	register int i,j,k;

	who(COM_GET,NULL,"term",temp);
	lowercase(temp,temp);
	if(!strncmp(temp,"vt100",5) || !strncmp(temp,"vt102",5))	term=VT100;
	if(!strncmp(temp,"ansi",5))	term=ANSI;
	ignoreeof = who(COM_GET,NULL,"ignoreeof",temp);	/* if set ignore.. */
	if(!who(COM_GET,NULL,"autologout",temp))
	{
		autologout=atoi(temp);
		if(autologout<1 || autologout>15)
			autologout=15;
	}

	if(history[0][0]=='A')		/* init will be executed once only */
	{
		for(i=0;i<HISTORY;i++)
			history[i][0]=0;
		killbuf[0]='\0';
	}
	a[i=0]=0;

	if(!sw_remote)
	{
		printf("%c11{",0x9b);	/* Report - Window closed */
		printf("%c12{",0x9b);	/* Report - Window size changed */
		fflush(stdout);
	}

	while(!done)
	{
		c='\0';
		j=1;
		if(sw_remote && !sw_nullmodem)
		{
			if(carrier_lost())
			{
				SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
				return 1;	/* carrier lost in axaux: */
			}
		}

		if(func!=-1)
		{
			if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
			{
				printf("^C");
				mode=0;
				func=-1;
				continue;
			}
			switch(c=funcstr[func++])
			{
			case '\\':
				if(funcstr[func])
				{
					switch(c=funcstr[func++])
					{
					case 'n':
						c=0x0a;
						break;
					case 't':
						c=0x09;
						break;
					case 'a':
						c=0x07;
						break;
					case 'e':
						c=0x1b;
						break;
					case 'r':
						c=0x0d;
						break;
					}
				}
				break;
			case '^':
				if(funcstr[func])
				{
					c=(funcstr[func++] & 0x1f);
				}
				break;
			}

			if(!funcstr[func])
				func=-1;
		}
		else
		{
			if(WaitForChar(Input(),sw_remote?2000000:4000000))
			{
				j=Read(Input(),&c,1);
			}
			else
			{
/*
 * TODO: Handle read mode so that WaitForChar() isn't used on devices that
 *		 doesn't support it. Now this is SLOW with dpipe:, if works at all.
 */
				if(IoErr()== ERROR_ACTION_NOT_KNOWN)
				{
					j=Read(Input(),&c,1);
				}
			}
		}
		if(!j || j<0)
		{
			SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
			return 2;			/* received EOF */
		}

		if(mode==MODE_NORMAL && c==0x0c)
			printf("^L");

		Signals=SetSignal(0L,0L);	/* this is more compatible than SysBase->ThisTask->tc_SigRecvd */
		if(Signals & SIGBREAKF_CTRL_C)
		{
			printf("^C");
			c=0x0c;	/* refresh line */
			mode=0;
			SetSignal(0L,SIGBREAKF_CTRL_C);	/* clear pending break */
		}
		if(Signals & SIGBREAKF_CTRL_D)
		{
			SetSignal(0L,SIGBREAKF_CTRL_D);	/* clear BREAK_D */
		}

		if(c==0x12)	/* ^r - refresh line also */
			c=0x0c;

		if(c==0)
		{
			/* NUL (timeout 2s) */
			count++;
			if(sw_remote && (count/30)>=autologout)
			{
				SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
				return 3;
			}
			if(logged_in)
			{
				/* any messages to user? */
				while(j = who(COM_READ, 0, temp, (char *)ARGLEN))
				{
					if(j == 2)		/* Kicked out ?! */
					{
						SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
						return 4;
					}
					Write(Output(), "\a\n", 2);
					Write(Output(), temp, strlen(temp));
					c=0x0c;			/* refresh line */
				}

				if((count&0x0f)==1)		/* check once in 32 secs */
				{
					if(mailhome[0] && check_mail(mailhome,user.Loginname,user.Home))
					{
            			printf(printout(MSG_NEW_MAIL_ARRIVED));
						c=0x0c;			/* refresh line */
					}
				}
			}
			if(file=Lock("AXsh:etc/nologin",ACCESS_READ))
			{
				UnLock(file);
				if(!logged_in)
				{
					printf(printout(MSG_SHUTDOWN_FORCED));
					SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
					return 5;	/* EOF :-) */
				}
				printf(printout(MSG_SHUTDOWN_MSG),user.Loginname,thismachine);
				cat("AXsh:etc/nologin");
				if(!(user.UID & UID_SUPERUSER))
				{
					printf(printout(MSG_SHUTDOWN_FORCED));
					SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
					return 5;	/* EOF :-) */
				}
				else
				{
					printf(printout(MSG_SHUTDOWN_PLEASE));
				}
				/* we don't want to be too agressive to superuser :-) */
				c=0x0c;	/* refresh line */
			}
			if(!c)
				continue;
		}
		if(mode==MODE_NORMAL)
		{
			switch(c)
			{
			case 0x0c:	/* ^L - refresh*/
				printf("\n");
				prompt(pr);
				if(term!=DUMB)
					printf("\033[K");
				if(echo)
					printf("%s",a);
				if(j=strlen(a)-i)
				{
					if(term==VT100)
					{
						printf("\033[%dD",j);
					}
					else
					{
						if(term==ANSI)
						{
							for(;j>0;j--)
								printf("\033[D");
						}
						else
						{
							for(;j>0;j--)
								putchar('\b');
						}
					}
				}
				break;
			case 0x0a:	/* LF or CR */
			case 0x0d:
				if(a[0]=='!' && echo)
				{
					if(term==VT100)
					{
						if(i)
							printf("\033[%dD",i);
					}
					else
					{
						for(;i>0;i--)
							putchar('\b');
					}
					i=atoi(a+1);
					if(i>=commandshift && i<histc+commandshift)
						strcpy(a,history[i-commandshift]);
					i=strlen(a);
					if(term!=DUMB)
						printf("%s\033[K",a);
				}
				else
				{
					printf("%s",a+i);
					if(!strcmp(a,"history"))
					{
						printf("\n");
						for(i=0;i<histc;i++)
							printf("%d. %s\n",i+commandshift,history[i]);
						a[i=0]=0;
						prompt(pr);
						if(term!=DUMB)
							printf("\033[K");
					}
					else
						done=1;
				}
				break;
			case 0x1b:
				mode=MODE_ESC;
				break;
			case 0x9b:
				mode=MODE_CSI;
				altc=0;
				break;
			case 0x10:
				if(hist)	hist--;
				break;
			case 0x0e:
				if(hist<histc)	hist++;
				break;
			case 0x06:	/* crsr right */
				if(i<strlen(a))
				{
					if(echo)
					{
						if(term==DUMB)
							putchar(a[i]);
						else
							printf("\033[C");
					}
					i++;
				}
				break;
			case 0x02:	/* crsr left */
				if(i)
				{
					if(echo)
					{
						if(term==DUMB)
							putchar('\b');
						else
							printf("\033[D");
					}
					i--;
				}
				break;
			case 0x01:		/* ^a - goto start of line */
				if(echo)
				{
					if(term==VT100)
					{
						if(i)
							printf("\033[%dD",i);
					}
					else
					{
						while(i)
						{
							if(term==DUMB)
								putchar('\b');
							else
								printf("\033[D");
							i--;
						}
					}
				}
				i=0;
				break;
			case 0x05:		/* ^e - goto eol */
				if(echo)
					printf("%s",a+i);
				i=strlen(a);
				break;
			case 0x09:		/* TAB (expand command/filename) */
				if(echo && logged_in)
				{
					j=i-1;
					while(j>=0 && a[j]!=' ' && a[j]!='>' && a[j]!='\"')
						j--;
					strcpy(temp,a+j+1);
					temp[i-j-1]=0;
					k=j;
					while(k>=0 && a[k]==' ')
						k--;	/* See if we have spaces before the command */
					if(k>=0)
						fcomp(temp);
					else
						ccomp(temp);

					if(strlen(temp)+strlen(a)-i+j+2<lenght)
					{
						k=strlen(temp)+j+1;
						if(a[i])	/* insert to middle of line */
						{
							if(a[i]==' ' && temp[strlen(temp)-1]==' ')
							{
								strcat(temp,a+i+1);
							}
							else
							{
								strcat(temp,a+i);
							}
							strcpy(a+j+1,temp);
						}
						else
						{
							strcpy(a+j+1,temp);
						}
						printf("%s",a+i);

						i=strlen(a+k);
						if(i)
						{
							if(term==VT100)
							{
								printf("\033[%dD",i);
							}
							else
							{
								if(term==DUMB)
								{
									for(j=i;j>0;j--)
										putchar('\b');
								}
								else
								{
									for(j=i;j>0;j--)
										printf("\033[D");
								}
							}
						}
						i=k;
						oldhist=hist=histc;
					}
				}
				break;
			case 0x04:		/* ^D (only if IgnoreEof not set) */
				if(i==0 && a[0]=='\0' && ignoreeof)
				{
					printf("^D");
					SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
					return 6;		/* if EOF is not ignored, log out */
				}
				else
				if(a[i]=='\0' && echo && logged_in)	/* If on the EOL, show completions */
				{
					j=i-1;
					while(j>=0 && a[j]!=' ' && a[j]!='>' && a[j]!='\"')
						j--;
					strcpy(temp,a+j+1);
					temp[i-j-1]=0;
					printf("\n");

					k=j;
					while(k>=0 && a[k]==' ')
						k--;	/* See if we have spaces before the command */
					if(k>=0)
						fcomplist(temp);
					else
						ccomplist(temp);

					prompt(pr);
					if(term!=DUMB)
						printf("\033[K");
					if(echo)
						printf("%s",a);
					break;
				}
				/* Fall through */
			case 0x7f:		/* DEL & ^D */
				if(a[i])
				{
					strcpy(a+i,a+i+1);
					if(echo)
					{
						if(term==VT100)
						{
							printf("\033[P");
						}
						else
						{
							if(term==DUMB)
							{
								printf("%s ",a+i);
								for(j=strlen(a+i)+1;j>0;j--)
									putchar('\b');
							}
							else
							{
								printf("%s \033[%dD",a+i,strlen(a+i)+1);
							}
						}
					}
					oldhist=hist=histc;
				}
				break;
			case 0x08:		/* BS */
				if(i>0)
				{
					i--;
					j=i;
					while(a[j]=a[j+1])
						j++;
					if(echo)
					{
						printf("\b%s ",a+i);
						if(term==VT100)
						{
							printf("\033[%dD",strlen(a+i)+1);
						}
						else
						{
							if(term==ANSI)
							{
								for(j=strlen(a+i)+1;j>0;j--)
									printf("\033[D");
							}
							else
							{
								for(j=strlen(a+i)+1;j>0;j--)
									putchar('\b');
							}
						}
					}
					oldhist=hist=histc;
				}
				break;
			case 0x0b:	/* ^K - delete to the end of line */
				if(term!=DUMB)
				{
					printf("\033[K");
				}
				else
				{
					for(j=strlen(a+i);j>0;j--)
						putchar(' ');
					for(j=strlen(a+i);j>0;j--)
						putchar('\b');
				}
				strcpy(killbuf,a+i);
				a[i]='\0';
				oldhist=hist=histc;
				break;
			case 0x15:	/* ^U - clear start of the line */
				if(i)
				{
					if(term==VT100)
					{
						printf("\033[%dD",i);
					}
					else
					{
						if(term==DUMB)
						{
							for(j=i;j>0;j--)
								putchar('\b');
						}
						else
						{
							for(j=i;j>0;j--)
								printf("\033[D");
						}
					}
					j=strlen(a);	/* remember old length */
					strncpy(killbuf,a,i);
					killbuf[i]='\0';
					strcpy(a,a+i);

					if(term==VT100)
					{
						if(a[0])
							printf("%s\033[K\033[%dD",a,strlen(a));
						else
							printf("\033[K");
					}
					else
					{
						if(term==DUMB)
						{
							printf("%s",a);
							for(i=strlen(a);i<j;i++)
								putchar(' ');
							for(;i>0;i--)
								putchar('\b');
						}
						else
						{
							printf("%s\033[K",a);
							for(j=strlen(a);j>0;j--)
								printf("\033[D");
						}
					}
					i=0;
					oldhist=hist=histc;
				}
				break;
			case 0x17:	/* ^W - delete previous word */
				if(i)
				{
					j=i;
					if(a[i-1]==' ')
					{
						putchar('\b');
						j--;
					}
					else
					{
						while(j && a[j-1]!=' ')
						{
							putchar('\b');
							j--;
						}
					}
					strncpy(killbuf,a+j,i-j);
					killbuf[i-j]='\0';
					strcpy(a+j,a+i);

					if(term==VT100)
					{
						if(a[j])
							printf("%s\033[K\033[%dD",a+j,strlen(a+j));
						else
							printf("\033[K");
					}
					else
					{
						if(term==DUMB)
						{
							printf("%s",a+j);
							for(c=i-j;c>0;c--)
								putchar(' ');
							for(i=strlen(a+j)+i-j;i>0;i--)
								putchar('\b');
							c=0x17;	/* Just be sure it has no side effects */
						}
						else
						{
							printf("%s\033[K",a+j);
							for(i=strlen(a+j);i>0;i--)
								printf("\033[D");
						}
					}
					i=j;
					oldhist=hist=histc;
				}
				break;
			case 0x18:	/* ^X - clear line */
				if(strlen(a))
				{
					if(term==DUMB)
					{
						for(j=strlen(a+i);j>0;j--)
							putchar(' ');
						for(j=strlen(a);j>0;j--)
							putchar('\b');
						for(j=strlen(a);j>0;j--)
							putchar(' ');
						for(j=strlen(a);j>0;j--)
							putchar('\b');
					}
					else
					{
						if(i)
						{
							if(term==VT100)
							{
								printf("\033[%dD",i);
							}
							else
							{
								for(j=i;j>0;j--)
									printf("\033[D");
							}
						}
						printf("\033[K");
					}
					strcpy(killbuf,a);
					a[0]='\0';
					i=0;
					oldhist=hist=histc;
				}
				break;
			case 0x19:	/* ^Y - Yank text back (uses the funcstr-'hook' */
				strcpy(funcstr,killbuf);
				func=0;
				break;
			default:
				if(strlen(a)<lenght-1 && c>0x1f && (c<0x80 || c>0x9f)) /* we don't want control chars */
				{
					for(j=strlen(a);j>=i;j--) a[j+1]=a[j];
					a[i]=c;
					if(echo)
					{
						printf("%s",a+i);
						if(a[i+1])
						{
							if(term==VT100)
							{
								printf("\033[%dD",strlen(a+i+1));
							}
							else
							{
								if(term=DUMB)
								{
									for(j=strlen(a+i+1);j>0;j--)
										putchar('\b');
								}
								else
								{
									for(j=strlen(a+i+1);j>0;j--)
										printf("\033[D");
								}
							}
						}
					}
					i++;
					oldhist=hist=histc;
				}
			}
		}
		else
		if(mode==MODE_ESC)
		{
			if(c==0x5b)
			{	mode=MODE_CSI;	/* if it is [, we are in the sequence mode */
				altc=0;
			}
			else
				mode=MODE_NORMAL;
		}
		else
		if(mode==MODE_CSI)
		{
			switch(c)
			{
			case 'A':
				temp[altc]=0;
				if(altc==0)
				{
					if(hist)		/* crsr up */
						hist--;
				}
				else
				{
					if(temp[0]==' ')
					{	/* shift-left - goto start of line */
						if(echo)
						{
							if(term==VT100)
							{
								if(i)
									printf("\033[%dD",i);
							}
							else
							{
								while(i)
								{
									printf("\033[D");
									i--;
								}
							}
						}
						i=0;
					}
					else
						printf("<csi>%sA\n",temp);
				}
				mode=MODE_NORMAL;
				break;
			case 'B':
				if(hist<histc)	/* crsr down */
					hist++;
				mode=MODE_NORMAL;
				break;
			case 'C':
				if(i<strlen(a))	/* crsr right */
				{
					printf("\033[C");
					i++;
				}
				mode=MODE_NORMAL;
				break;
			case 'D':
				if(i)			/* crsr left */
				{
					printf("\033[D");
					i--;
				}
				mode=MODE_NORMAL;
				break;
			case 'Z':		/* shift-TAB */
			case 'T':		/* shift-up */
				temp[altc]=0;
				altc=0;

				if(echo)	/* history completion */
				{
					UBYTE	found[ARGLEN],name1[ARGLEN];
					int		len=strlen(a),d;
					BOOL	done=FALSE;

					lowercase(name1,a);

					found[0]=0;
					for(j=histc-1;j>=0;j--)
					{
						if(!strncmp(name1,history[j],len))
						{
							if(history[j][len]==0)		/* exact history name */
							{
								strcpy(found,name1);
								done=TRUE;
								break;
							}
							if(found[0])
							{
								d=len;
								while(found[d]==history[j][d])	d++;
								if(found[d])	/* the histories are not identical */
								{
									found[d]=0;
									done=FALSE;
								}
							}
							else
							{
								strcpy(found,history[j]);
								done=TRUE;
								if(!name1[0])	break;
							}
						}
					}
					if(!done)	putchar('\a');
					if(found[0])
					{
						if(strlen(found)+2<lenght)
						{
							strcpy(a+len,found+len);
							printf("%s",found+i);
						}
						else	putchar('\a');
					}
					i=strlen(a);
				}
				mode=MODE_NORMAL;
				break;
			case 'S':
				temp[altc]=0;
				altc=0;

				/* shift-down */
				mode=MODE_NORMAL;
				break;
			case 'r':
				temp[altc]=0;
				altc=0;

				if(!strncmp(temp,"1;1;",4))
				{
					Rows=atoi(temp+4);
					Columns=atoi(temp+6+((temp[6]==';')?1:0));
					if(logged_in)
					{
						sprintf(temp,"%d",Rows);
						who(COM_SET,NULL,"rows",temp);
						if(!ArpBase)
							SetVar("rows",temp,strlen(temp),GVF_LOCAL_ONLY);
						sprintf(temp,"%d",Columns);
						who(COM_SET,NULL,"columns",temp);
						if(!ArpBase)
							SetVar("columns",temp,strlen(temp),GVF_LOCAL_ONLY);
					}
				}
				else
					printf("Oops! Not exactly what I expected.. (<csi>%sr)\n",temp);

				mode=MODE_NORMAL;
				break;
			case '@':
				temp[altc]=0;
				altc=0;

				/* shift-right - goto eol */
				if(echo)
					printf("%s",a+i);
				i=strlen(a);

				mode=MODE_NORMAL;
				break;
			case '~':
				temp[altc]=0;
				altc=0;
				if(temp[0]=='?')
				{
					strcpy(funcstr,"HELP");
					who(COM_GET,NULL,"HELP",funcstr);
					func=0;
					/* HELP */
				}
				else
				{
					func=atoi(temp)+1;	/* get the key name */
					sprintf(funcstr,"F%d",func);
					who(COM_GET,NULL,funcstr,funcstr);
					func=0;
				}
				mode=MODE_NORMAL;
				break;
			case '|':
				temp[altc]=0;
				altc=0;
				if(!strncmp(temp,"11",2))	/* close gadget pressed */
				{
					SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
					return 7;					/* quit AXsh */
				}
				else
				if(!strncmp(temp,"12",2))	/* size changed */
				{
					Write(Output(),"\2330 q",4);
				}

				mode=MODE_NORMAL;
				break;
			case '{':
				temp[altc]=0;
				altc=0;
				printf("<csi>%s{\n",temp);

				mode=MODE_NORMAL;
				break;
			default:
				if((c>='a' && c<='z') || (c>='A' && c<='Z'))
				{
					temp[altc]=0;
					altc=0;

					sprintf(funcstr,"\\\\e[%s%c",temp,c);
					func=0;
					mode = MODE_NORMAL;
				}
				else
				{
					if(altc<ARGLEN)
						temp[altc++]=c;
				}
				break;
			}
			fflush(stdout);
		}

		if(hist!=oldhist && echo)
		{
			/* if we have selected an event */
			strcpy(a,history[hist]);
			if(i)
			{
				if(term==VT100)
				{
					printf("\033[%dD",i);	/* print new event and delete the rest of the line */
				}
				else
				{
					for(j=i;j>0;j--)
						printf("\033[D");	/*putchar('\b');*/
				}
			}
			printf("%s\033[K",a);						/* print new event */
			i=strlen(a);
			oldhist=hist;
		}
		fflush(stdout);
	}
	printf("\n");
	SetSignal(0L,SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
	/* Clear signals */

	if((hist==histc || hist<histc-HISTMOVE) && echo && a[0]) /* if the line was a new one or too far away and non-blank, add event */
	{
		commandcount++;
		strcpy(history[histc++],a);
		if(histc==HISTORY) /* max # of events reached, let's forget the oldest */
		{
			for(i=0;i<histc;i++)
				strcpy(history[i],history[i+1]);
			history[--histc][0]=0;
			commandshift++;
		}
	}

	if(echo)
	{
		sprintf(temp,"%s\n",a);	/* update the system log */
		updatelog(temp);
	}
	if(!sw_remote)
	{
		printf("%c11}",0x9b);	/* Do not report - Window closed */
		printf("%c12}",0x9b);	/* Do not report - Window size changed */
	}
	return 0;	/* everything ok */
}

int check_mail(char *mailhome,char *loginname,char *home)
{
	char temp[200];
	BPTR lock,file;
	static struct DateStamp lastmail={-1,-1,-1};
	static long mailsize=0;
	struct FileInfoBlock fib;
	int error=0;

	if(lastmail.ds_Days==-1)	/* first time around here get .lastlogin datestamp */
	{
		sprintf(temp,"%s.lastlogin",home);
		if(lock=Lock(temp,ACCESS_READ))
		{
			if(Examine(lock,&fib))
			{
				lastmail=fib.fib_Date;	/* remember the date */
			}
			UnLock(lock);
		}
	}

	sprintf(temp,"%s%s",mailhome,loginname);	/* any new mail to user? */
	if(lock=Lock(temp,ACCESS_READ))
	{
		if(Examine(lock,&fib))
		{
			if(lastmail.ds_Days<fib.fib_Date.ds_Days ||
				((lastmail.ds_Days==fib.fib_Date.ds_Days) && (lastmail.ds_Minute<fib.fib_Date.ds_Minute)) ||
				((lastmail.ds_Days==fib.fib_Date.ds_Days) && (lastmail.ds_Minute==fib.fib_Date.ds_Minute) && lastmail.ds_Tick<fib.fib_Date.ds_Tick))
			{
			    if(fib.fib_Size>mailsize)
			    {
	    			error=-1;
	    		}
    			sprintf(temp,"%s.lastlogin",home);	/* touch .lastlogin */
    			if(file=Open(temp,MODE_READWRITE))
    			{
    				Seek(file,OFFSET_END,0);
    				Write(file,"",0);
    				Close(file);
    			}
			}
			lastmail=fib.fib_Date;	/* remember the date */
    		mailsize=fib.fib_Size;
		}
		UnLock(lock);
	}
	/* else no mail at all */
	return error;
}
