#define MAIN_PROG

#include "bbs.h"

#undef MAIN_PROG
#include <graphics/displayinfo.h>
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include "deadline.h"
void ModemOffHook(void);
int NotRelative=TRUE;
BOOL ReadComputerTypes(void);
int   LastValidUser = 2;
int Dropped_Hook=0;
int pignotes;
char langtitle[80];
char lang[20];
extern char *MyVerStr;
struct Commands HCmds;
char *SkipdFiles;
int relogon;
int templogon;
extern __far struct Library *DOSBase;
void LoadKey(void);
void (*dumfunc)(char *s);
void (*secfunc)(APTR s,APTR d);
void Randomize(void);
int DeCode(void);
void AllocateConfs(int NumConfs);
void DeAllocateConfs(void);
ULONG *GetConfData(char *s);
void AddConfItem(struct List *galist,char *tag,char *data);

struct NewScreen MYNewScreen =
 {
 0,0,640,200,3,0,1,  /* leftedge,topedge,Width,Height,Depth,DetailPen, BlockPen */
 HIRES,CUSTOMSCREEN,NL,           /* display modes,screen type,Font */
 NL,NL,NL                           /* Title,screen gadgets,CustomBitMap  */
};

struct NewWindow MYNewWindow = {
  0,12,640, 188,      /* left edge, top edge, width, height */
  0, 1, NL,
  ACTIVATE|BACKDROP|BORDERLESS,
  NL, NL, NL, NL, NL, 70, 30, 704, 480, CUSTOMSCREEN
};

struct NewWindow PaneStatus =
{ 0,11,640,28,3,4, NL,SIMPLE_REFRESH,NL,NL,NL,NL,NL,0,0,640,40, CUSTOMSCREEN};

struct NewWindow CloseIt = {
  0,0,28,10,0,1,          /* 0,0,587,10,0,1 */
  GADGETUP|GADGETDOWN,NOCAREREFRESH|BORDERLESS,
  NL,NL,NL,NL,NL,0,0,640,40,CUSTOMSCREEN
};

struct Gadget MG =
 {NL,0,0,0,0,GADGHCOMP|GADGIMAGE,RELVERIFY, BOOLGADGET,NL,NL,NL,NL,0,NL};

/* this has to stay the same size since below we set the 20th pos to the node number */
#define OPENIT_WINTITLE  "AmiExpress BBS Node xxx"

struct NewWindow OpenIt = {
  0,11,300,23,0,1,            /* 0,0,587,10,0,1 */
  CLOSEWINDOW,WINDOWDRAG|WINDOWDEPTH|NOCAREREFRESH|WINDOWCLOSE,
  NL,NL,OPENIT_WINTITLE,         /* Convert to AmiExpress BBS Node xxx */
  NL,NL,0,0,640,40,WBENCHSCREEN
};

struct NewWindow ZmodemStats = {
  170,50,350,125,0,1,         /* 0,0,587,10,0,1 */
  CLOSEWINDOW,WINDOWDRAG|NOCAREREFRESH|WINDOWCLOSE,
  NL,NL,NL, NL,NL,0,0,350,130,CUSTOMSCREEN };


/* moved from flagfiles.c ..was static */
char *IsInList(char *s,char *c,int *length);  /* also used in check_list.c */

void CheckDeadLine(ULONG mytime);
int AddFlagtoList(char *s)
{
 char *p;
 int stat;

 if(strlen(s)>1) {
     strupr(s);
     strcat(s," ");
     if(strlen(flaglist)+strlen(s)>2040) {
         AEPutStr("Too many flags\r\n");
         return(1);
     }
     if(!(p=IsInList(flaglist,s,&stat)))     strcat(flaglist,s);
     return(2);
 }
 return(0);
}

 /* remove file from Nodework (normally t: dir) that tells who is online
 (each node )*/

static void ClearUser(void)

{

 sprintf(GSTR1,"%snode%ld.user",NodeWork,Cmds->AcLvl[LVL_NODE_NUMBER]);
 DeleteFile(GSTR1);

 sprintf(GSTR1,"%snode%ld.userkeys",NodeWork,Cmds->AcLvl[LVL_NODE_NUMBER]);
 DeleteFile(GSTR1);
}

static void Display_Logo(void)
{
 ConPutStr("\014[1;33m\n\n\n\n\n                               Express BBS[0m\n\n");
 ConPutStr("                             Initializing...");
}

static char PortName[30];  /* our MsgPort Name, Node # appended */

#define RN 37L            /* current library version */

static void Init_System(BYTE iconats)
{


if(iconats)
	{
     IconifySig=0L;
	KEYIN=0; 
	ICON=1;
	}
else
	{
     ICON=0;
	OpenDisplay();
	Display_Logo();
	}
 OpenTimer();
 TimerSig=1L<<TimerPort->mp_SigBit;

 MyClearStatusPane();     /* (RTS) clear status pane & install user */

if(!(HistoryBuf=(UBYTE *)AllocMem(MAXHIST*250,MEMF_CLEAR)))
     ShutDown("No memory for history");

 if(OpenSerial(Cmds->OpeningBaud,(UBYTE)8,(UBYTE)1)!=0) {
     sprintf(GSTR3,"Can't open %s!",Cmds->SerDev);
     ShutDown(GSTR3);
 }
 if(!TrapDoor)
 {
   IntDoReset(Sopt->OffHook);
   Delay(60L);
   SerPutStr(Cmds->MInit);
   SerPutChar("\r");
   Delay(60L);
 }
 PurgeLine();


}
int Menu(void);
int Logon_Sequence(void);


extern struct myst my_struct;


extern int BatchError;        /**** BatchError Flg ****/

int SHUTBATCH = 0;

char WorkStr[255];

BOOL FileWrap = FALSE;          /* 11w */
BOOL DupeYes = FALSE;
BOOL QuickAllowed = TRUE;
char SysopCommand[100];

/* end 11w */
void options(void);

int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */

   /******************************************************************\
    *                              MAIN()                            *
   \******************************************************************/
static void closelibs(void);
char SingleName[] = "AEStat ";
extern unsigned long doorextsig;
int Valer=0;
struct Library *IconBase=NL;
void main(int argc,char *argv[])
{
  BPTR tempfh;
  struct MsgPort *tempport;
  AnsiColor=1;
  mytask=(struct Process *)FindTask(NULL);
  doorextsig=AllocSignal(-1L);
IO_Flags[IOFLAG_FIL_IN]=0;
PagedFlag=0;
 FileWrap=FALSE;     /****** Default for file description wrap ******/
 ComputerTypes[0] = NL;
 ComputerEntries = DeBuG = ShutDownFlag = ZWindow = OnlineEdit = SysopStatus= 
 NOFKeys = FreeDownloads = ICON = AWAITLOGON = ICONATS = TrueReset = 0;
 DStatBar=KEYIN=1;
 CaptureFP=NL;
 
 DOSBase=(struct Library *)OpenLibrary("dos.library",0L);
 if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",RN)))
       ShutDown("Can't open intuition.library");

 if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",RN)))
     ShutDown("Can't open  intuition.library");
 if(!(GadToolsBase=(struct Library *)OpenLibrary("gadtools.library",0L)))
     ShutDown("Can't open  GadToolsLibrary");
 if(!(UtilityBase = (struct UtilityBase *)OpenLibrary("utility.library",RN)))
     ShutDown("Can't open utility.library");

 if(!(RexxSysBase = (struct RexxSysBase *)OpenLibrary("rexxsyslib.library",0)))
     puts("rexxsyslib.library not found, AREXX port disabled\n");
  AslBase=OpenLibrary("asl.library",0L);
 IconBase=OpenLibrary("icon.library",0L);
  /*----------------------- Get our Config File ------------------------- */

 strcpy(GSTR1,argv[1]);
//Commented out for the time being. (JOE)

 SkipdFiles=AllocMem(32000L,MEMF_CLEAR|MEMF_PUBLIC);
CreateServerRP(argv[1][0]-'0');
DoorSig=ResControl(Cmds->AcLvl[LVL_NODE_NUMBER]);
 LoadKey();
 Valer=DeCode();
   if(Sopt->Toggles[10])
   {SingleNode=(struct SinglePort *)Sopt->s;
    MasterNode=(struct MultiPort *)Sopt->t;
   }

/** see if we already exist */
 /*-- Get out port name and check if we are already running --*/
 sprintf(PortName,"%s%d",PORT_NAME,Cmds->AcLvl[LVL_NODE_NUMBER]);  /* cfg port */

 if(tempport=FindPort(PortName)) {
     sprintf(GSTR3,"Node %d already running!\n",Cmds->AcLvl[LVL_NODE_NUMBER]);
     ShutDown(GSTR3);
 }

 if(!(MyRexxPort=(struct MsgPort *) CreatePort(PortName,0L))) {
     sprintf(GSTR3,"Can't create Port: %s",PortName);
     ShutDown(GSTR3);
 }

 RexxSig = 1L << MyRexxPort->mp_SigBit;

 Online_Baud = Online_BaudR=Cmds->OpeningBaud;   //(RTS) added Online_Baud

 sprintf(NodeStr,"%sNode%u/",Cmds->BBSLoc,Cmds->AcLvl[LVL_NODE_NUMBER]);

  /** * * FIX WHEN TITLE CHANGES  suppose the file string is shorter then 20 ? */
 sprintf(OpenIt.Title+20,"%03d",Cmds->AcLvl[LVL_NODE_NUMBER]);
 sprintf(GSTR1,"%sAmiXnet/MyNode",Cmds->BBSLoc);
 strcpy(Sopt->BBSConfig,"");
 sprintf(GSTR1,"%sConfConfig",Cmds->BBSLoc);
 Boards_Are_Active=Cmds->NumConf;
 AllocateConfs(Boards_Are_Active);
 strcpy(NodeWork,Cmds->BBSLoc);
 if(!Sopt->StatBar) DStatBar=0;
 if(Sopt->UserData[0]!='\0') strcpy(UserDataLoc,Sopt->UserData); else sprintf(UserDataLoc,"%sUser.Data",Cmds->BBSLoc);
 if(Sopt->UserKey[0]!='\0') strcpy(UserKeyLoc,Sopt->UserKey); else sprintf(UserKeyLoc,"%sUser.keys",Cmds->BBSLoc);
 if(Sopt->OffHook[0]=='\0')
 {
    strcpy(Sopt->OffHook,"ATM0H1");
 }
 

//addition for 0 bitplane option (JOE)
  
 BitPlanes=Sopt->BitPlanes;
if(Sopt->TrapDoor){ TrapDoor=TRUE; sprintf(TrapConnect,"CONNECT %ld",atol(argv[2]));}
	if(BitPlanes>4||BitPlanes<0)
		{
		BitPlanes=3;
		}
		MYNewScreen.LeftEdge=(UWORD)Sopt->LeftEdge;
		MYNewScreen.TopEdge=(UWORD)Sopt->TopEdge;
		MYNewScreen.Width=(UWORD)Sopt->Width;
		MYNewScreen.Height=(UWORD)Sopt->Height;
		MYNewWindow.Height=MYNewScreen.Height-MYNewWindow.TopEdge;
		MYNewWindow.Width=MYNewScreen.Width;
		PaneStatus.Width=MYNewScreen.Width;
          if(Sopt->Toggles[6]){
              MYNewScreen.BlockPen=7;
              MYNewWindow.BlockPen=7;
           }
		if(MYNewScreen.Height>399&&BitPlanes!=0)
			{
			MYNewScreen.ViewModes=MYNewScreen.ViewModes|LACE;
			if(BitPlanes>4)
				{
				BitPlanes=4;
				}
			}
	if(BitPlanes==0)
		{
		PaneStatus.Height+=11;
		ZmodemStats.Type=WBENCHSCREEN;
    
		PaneStatus.Type=WBENCHSCREEN;
		CloseIt.Type=WBENCHSCREEN;
		MYNewWindow.Type=WBENCHSCREEN;
		MYNewWindow.LeftEdge=MYNewScreen.LeftEdge;
		MYNewWindow.Width=MYNewScreen.Width;
		PaneStatus.TopEdge=MYNewScreen.TopEdge;
            MYNewWindow.TopEdge=MYNewScreen.TopEdge;
            MYNewWindow.Height=MYNewScreen.Height;
		PaneStatus.LeftEdge=MYNewScreen.LeftEdge;
		CloseIt.TopEdge=MYNewScreen.TopEdge;
		CloseIt.LeftEdge=MYNewScreen.LeftEdge;
          ZmodemStats.LeftEdge=MYNewWindow.LeftEdge+(MYNewWindow.Width/4);
          ZmodemStats.TopEdge=MYNewWindow.TopEdge+(MYNewWindow.Height/4);
		}
	if(BitPlanes<2)
		{
		PaneStatus.DetailPen=0;
		PaneStatus.BlockPen=1;
		}

 sprintf(WorkStr,"%sNode%u/Work/",Cmds->BBSLoc,Cmds->AcLvl[LVL_NODE_NUMBER]);

 Forbid();
 SetTaskPri(FindTask(0),(LONG)Cmds->TaskPri);
 Permit();

 my_struct.max_desclines = 8;
 my_struct.numlastcallers = 0;
 my_struct.flags = 0;
 my_struct.lastcallerlevel = 255;
 my_struct.callerlist = NL;


if(Sopt->ShutDown[0]!=NULL) { SHUTBATCH=1;  }
if(Sopt->Interlace) { MYNewScreen.ViewModes=MYNewScreen.ViewModes|LACE; }
if(Sopt->QLogon) QuickAllowed=FALSE;
if(Sopt->TakeCredits) TakeCredits=TRUE;
if(Sopt->Iconify) ICONATS=1; else ICONATS=0;
if(Sopt->Toggles[0]) TrueReset=TRUE;
if(Sopt->Toggles[1]) NotRelative=FALSE;
/****** Toggles[2]=DoorLog 
        Toggles[3]=StartLog
        Toggles[4]=No TimeOut
        Toggles[5]=No MCI Msgs
*******/
sprintf(GSTR1,"%snode%d.user",Cmds->BBSLoc,Cmds->AcLvl[LVL_NODE_NUMBER]);
if(TLock(GSTR1)) DeleteFile(GSTR1);

sprintf( titlebar,"    AmiExpress BBS (c)%s  %s                      Node %ld",GetDate(),MyVerStr,Cmds->AcLvl[LVL_NODE_NUMBER]);
sprintf(ptitlebar,"       AmiExpress BBS (c)%s  %s                      Node %ld",GetDate(),MyVerStr,Cmds->AcLvl[LVL_NODE_NUMBER]);

if(BitPlanes!=0)
	{
	MYNewScreen.DefaultTitle=(UBYTE *)&titlebar;
	}
else
	{
	  PaneStatus.Title=(UBYTE *)&ptitlebar; // Used in 0 bitplanes(JOE)
     MYNewWindow.Title=(UBYTE *)&titlebar;
	}


 Randomize();   /* 11w Check for Cycle Screens */
                                //(RTS)
 if(!(ReadComputerTypes()))     ShutDown("Computer Types Error");
                  /* Read in callers log to process for last callers util */

  /* read the BBS:NodeX/Callerslog */
 sprintf(GSTR1,"%sCallerslog",NodeStr);



 SySChat=Cmds->AcLvl[LVL_DEFAULT_CHAT_ON];      /* set Sysop Chat Mode */
 if(Sopt->Toggles[9]) { QuietNode=TRUE; SendQuietFlag(1); }
                        else { QuietNode=FALSE; SendQuietFlag(0); }
 /* get top uploader/download cps */

/****** (11w) Auto Config LCFIles and ZOOM ******/
 Startup_Time=time(NL);
 sprintf(GSTR1,ctime(&Startup_Time));
 GSTR1[strlen(GSTR1)-1]='\0';
 sprintf(GSTR2,"####### BBS Node %d started on %s #######\n",Cmds->AcLvl[LVL_NODE_NUMBER],GSTR1);
 StartLog(GSTR2);
 Init_System(ICONATS);
 relogon=0; templogon=0;
 //CheckDeadLine(Startup_Time);
 FOREVER {
     strcpy(User.Pass,"");
     Time_limit=1800L;
     User.LineLength=24;
     Time_holder=0;

     strcpy(Conference_Location,"");
    

     if(!TrapDoor){ Reset_System(1); }

     MCIViewSafe=TRUE;


     BeenUDd=LogON=0;
     ValidUser=2;
     NumHistItems=0;
     WhichHist=0;
     HistorySelect=0;
     Whence_The_Logon=AWAIT_LOGON;
    if(Cmds->AcLvl[29]) ADD_BIT(ACS_DO_CALLERSLOG);
       if(Sopt->Toggles[14]) ADD_BIT(ACS_WILDCARDS);
     Whence_The_Logon=Await_Logon();   /* User logged on system */
     if(Whence_The_Logon==REMOTE_LOGON) SetEnvStat(ENV_CONNECT);
Relogon:
     strcpy(flaglist,"");
     strcpy(GSTR1,Cmds->BBSLoc);
	strcat(GSTR1,"SystemStats");
	System_Calls=IntFromFile(GSTR1,GSTR2);
	System_Calls++;
	IntToFile(GSTR1,System_Calls);
     if(relogon) { Whence_The_Logon=templogon; relogon=0; }
     BatchError = 0;

     NewSinceFlag=0;
    if(TrapDoor) Whence_The_Logon=REMOTE_LOGON;
     templogon=Whence_The_Logon;
     switch(Whence_The_Logon) {
         case SYSOP_LOGON:
             Sysop_Account_Sequence();
             ValidUser=1;
             CheckUserOnLine(&User,0);
             break;
         case LOCAL_LOGON:
         case REMOTE_LOGON:
             if(KEYIN&&Cmds->AcLvl[LVL_SCREEN_TO_FRONT]&&MYScreen)    ScreenToFront(MYScreen);
             GI1=Logon_Sequence();      /* User logged on SYstem */
             if(GI1!=SUCCESS) {
                goto Skip;
             }
             break;
         case SUSPEND_LOGON:
             goto DownUnder;
     }                        /* end switch */
strcpy(lang,"TXT.GR"); 
if(QuickFlag) goto byp;
         
/*---11w Cycle screens --- */
 
if(User.Sec_Status > Cmds->PSAcLvl[0] && Whence_The_Logon!=SYSOP_LOGON) {
             sprintf(GSTR1,"%sLogon",Sopt->NodeScreen);
     
     if(ChecktoDisplay(GSTR1,GSTR3,1,0)) DoPause();
  }
/*--- end 11w cycle screens --- */

//--------------------------------------------------------
byp: ;

     GI1=Menu();
                      /*  RTS  OUR MAIN ONLINE USER LOOP */
     SetEnvStat(ENV_NOTACTIVE);
     if(CaptureFP) {
         fclose(CaptureFP);
         CaptureFP=NL;
     }
     Check_Online_Status();
     ChatFlag=0;
     flaglist[0]='\0';

 Skip:
     ClearUser();


     if(ValidUser!=2) {

         if(ValidUser==3)    (void)LogOffLog("UUCP feed completed");
         else  {
             if(GI1==STANDARD_LOGOFF)    LogOffLog("N");
              else   LogOffLog("Loss Carrier");
         }
     }
     if(User.Sec_Status!=0 && User.Slot_Number!=0 && ValidUser==1) {

         PagedFlag=0;
         if(SysopStatus) {
             User.Sec_Status=TSI.AccessLevel;
             User.Sec_Board=TSI.RatioType;
             User.Sec_Library=TSI.Ratio;
             User.Time_Total=TSI.TimeTotal;
             memcpy(User.Conference_Access,TSI.ConfAc,10);
             SysopStatus=0;
         }
         StatPrintUser(&User);
        
         strcpy(User_keys.UserName,User.Name);
         strupr(User_keys.UserName);
         User_keys.Number=User.Slot_Number;

         if(NewSinceFlag) {
             User.NewSinceDate=time(NL);
             
         }
          SaveMsgPointers();
          NewSinceFlag=0;
          User.Time_Last_On=time(NULL);

         Save_Account(&User,&User_keys,0,0);    /* Reseave users account after logoff */


         ReservedName[0]='\0';
         if(KEYIN&&Cmds->AcLvl[LVL_SCREEN_TO_FRONT]&&MYScreen)
         {   ScreenToBack(MYScreen);}
             if(!relogon) ModemOffHook();
             if(Sopt->Logoff[0]!='\0')
             {
             sprintf(GSTR1,"execute %s",Sopt->Logoff,Cmds->AcLvl[LVL_NODE_NUMBER]);
				if(tempfh=Open("NIL:",MODE_OLDFILE))
					{
					Execute(GSTR1,tempfh,tempfh);
					Close(tempfh);
					}
             }
         if(relogon) goto Relogon;
         
     }
DownUnder:
     CheckShutDown();
    if(TrapDoor) ShutDown("!");
 }
}
void CheckShutDown(void)
{
 if(ShutDownFlag==1) {
            ReplyMsg((struct Message *) SDReplyRexx);
     ShutDown("!");
 }
 if(ShutDownFlag==2) {
         ReplyMsg((struct Message *) SReplyRexx);
         SuspendBBS();
         Display_Logo();
         ReInitModem();
  }
  ShutDownFlag=0;
}


void SuspendBBS(void)
{
 BYTE LICON;

 Whence_The_Logon=SUSPEND_LOGON;
 LICON=ICON;

 if(!ICON) {
    IconifyAE();
 }

/* ... Skipped ALL thist !!!! DID NOT WAUT */
 if(SEROUT && ReadSerReq) {
     AbortIO(ReadSerReq);
     WaitIO(ReadSerReq);
 }
 CloseSerial();

 Time_system=time(NL);

 sprintf(GSTR3,"BBS has been suspended at %s",ctime(&Time_system));
 StartLog(GSTR3);

 while(Whence_The_Logon==SUSPEND_LOGON) {
     Wait(RexxSig);
     CheckRexxMessage();
 }
 Time_system=time(NL);

 sprintf(GSTR3,"BBS has received resume @ %s",ctime(&Time_system));
 StartLog(GSTR3);

 if(OpenSerial(Cmds->OpeningBaud,(UBYTE)8,(UBYTE)1)!=0) {
     sprintf(GSTR3,"Can't re-open %s!",Cmds->SerDev);
     ShutDown(GSTR3);
 }


 if(!LICON)  {  /* got msg to LICON this (Uniconify this */
    UnIconifyAE(0);
 }


}

static void closelibs(void)
{
 DeAllocateConfs();

 if(IconBase)                CloseLibrary(IconBase);
 if(AslBase)                 CloseLibrary(AslBase);
 if(UtilityBase)             CloseLibrary((struct Library *) UtilityBase);
 if(RexxSysBase)             CloseLibrary((struct Library *) RexxSysBase);
 if(GadToolsBase)            CloseLibrary((struct Library *) GadToolsBase);
 if(GfxBase)                 CloseLibrary((struct Library *) GfxBase);
 if(IntuitionBase)           CloseLibrary((struct Library *) IntuitionBase);
  CloseLibrary(DOSBase);
}

void ShutDown(char *s)
{
 BPTR tempfh;
 struct RexxMsg *rexxmsg=NL;
 Startup_Time=time(NL);
 sprintf(GSTR1,ctime(&Startup_Time));
 GSTR1[strlen(GSTR1)-1]='\0';
 SetEnvStat(ENV_SHUTDOWN); Delay(10L);

 sprintf(GSTR2,"####### BBS Node %d shutdown @ %s#######\n",Cmds->AcLvl[LVL_NODE_NUMBER],GSTR1);
 StartLog(GSTR2);
 if(SHUTBATCH) {
    sprintf(GSTR1,"execute %s %d",Sopt->ShutDown,Cmds->AcLvl[LVL_NODE_NUMBER]);
    if(tempfh=Open("NIL:",MODE_OLDFILE))     {
         Execute(GSTR1,tempfh,tempfh);
         Close(tempfh);
    }
}
 if(ComputerTypes[0]!=NL)     FreeMem(ComputerTypes[0],ComputerEntries*90);
 if(HistoryBuf)               FreeMem(HistoryBuf,MAXHIST*250);

 if(MyRexxPort) {
     while(rexxmsg = (struct RexxMsg *) GetMsg((struct MsgPort *) MyRexxPort))
       ReplyMsg((struct Message *) rexxmsg);
     DeletePort((struct MsgPort *) MyRexxPort);
 }

 DeleteServerRP();
 DeleteResControl();

 if(!ICON)  CloseConsole();
 if(SEROUT) CloseSerial();
  CloseTimer();
 FreeSignal(doorextsig);
 if(Iconify){ CloseWindow(Iconify);}
 if(StatusPane && DStatBar) { CloseWindow(StatusPane); }
 if(MYwindow) { CloseWindow(MYwindow);}
 if(BitPlanes!=0)
 {
 if(closeimage) DisposeObject(closeimage);
 if(drinfo) FreeScreenDrawInfo(MYScreen, drinfo);
 if(MYScreen) CloseScreen(MYScreen); 
 }
 FreeMem(SkipdFiles,32000L);
 closelibs();              /* closes All Libraries open */

 exit(0);
}

void ModemOffHook(void)
{
   if(Cmds->SerDev[0]!='\0')
                 {
                   
                  if(Sopt->Toggles[17])
                 {
                   Reset_System(0);
				IntDoReset(Sopt->OffHook);
				IO_Flags[IOFLAG_SER_IN]=0;
				IO_Flags[IOFLAG_SER_OUT]=0;
				IO_Flags[IOFLAG_SCR_OUT]=1;
				IO_Flags[IOFLAG_KBD_IN]=1;
                 }else
                 {
                   DropDTR();Delay(25L);//Reset_System(0);
                   IntDoReset(Sopt->OffHook);
                   Delay(5L);
                   Dropped_Hook=1;
                 IO_Flags[IOFLAG_SER_IN]=0;
                 IO_Flags[IOFLAG_SER_OUT]=0;
                 IO_Flags[IOFLAG_SCR_OUT]=1;
                 IO_Flags[IOFLAG_KBD_IN]=1;
                 }
                 }
}

void AllocateConfs(int NumConfs)
{
   register int i;
   char image[100];
   char image1[100];
   ULONG *dobj;
   MemConf=(ULONG *)AllocMem(((ULONG)NumConfs+1L)*(ULONG)sizeof(ULONG),MEMF_CLEAR|MEMF_PUBLIC);
   for(i=0;i<NumConfs;i++)
   {
     GetConfName(image1,image,i);
       dobj=GetConfData(image);
       //*(MemConf+(ULONG)i)=(ULONG)dobj;
       MemConf[i]=(ULONG)dobj;
   }
   //*(MemConf+(ULONG)i)=NULL;
   MemConf[i]=NULL;
}
struct ConfItem
{
  struct MinNode l;
  char Tag[100];
  char Data[100];
};

ULONG *GetConfData(char *s)
{
    FILE *fi;
    char image[102];
    char temp[30];
    int i=0;
    struct List *conflist;
    conflist=AllocMem(sizeof(struct List),MEMF_PUBLIC|MEMF_CLEAR);
    NewList(conflist);

    sprintf(image,"%sSCREENS",s);
    fi=fopen(image,"r");
    if(fi!=NULL)
    {
      fgets(image,80,fi); sr(image);
      AddConfItem(conflist,"SCREENS",image);
      fclose(fi);
    }
   sprintf(image,"%sFORWARDMAIL",s);
    fi=fopen(image,"r");
    if(fi!=NULL)
    {
      fgets(image,80,fi); sr(image);
      AddConfItem(conflist,"FORWARDMAIL",image);
      fclose(fi);
    }
sprintf(image,"%sFREEDOWNLOADS",s);
    fi=fopen(image,"r");
    if(fi!=NULL)
    {
      AddConfItem(conflist,"FREEDOWNLOADS","");
      fclose(fi);
    }
    sprintf(image,"%sULPATHS",s);
    i=1;
    fi=fopen(image,"r");
    if(fi)
    {
       while(fgets(image,80,fi)!=NULL)
      {
        //sprintf(temp,"%sLcfiles/",s);
        sr(image);
        //if(!stricmp(temp,image)) continue;
        sprintf(temp,"ULPATH.%d",i);
        AddConfItem(conflist,temp,image);
        i++;
      }
      fclose(fi);
    }
  sprintf(temp,"ULPATH.%d",i);
  sprintf(image,"%sUpload/",s);
    AddConfItem(conflist,temp,image);
  sprintf(image,"%sPATHS",s);
  
  fi=fopen(image,"r");
  if(fi)
    {
      i=1; while(fgets(image,80,fi)!=NULL)
      {
        //sprintf(temp,"%sLcfiles/",s);
        sr(image);
        //if(!stricmp(temp,image)) continue;
        sprintf(temp,"DLPATH.%d",i);
        AddConfItem(conflist,temp,image);
        i++;
      }
      fclose(fi);
    }
    sprintf(image,"%sNDIRS",s);
   fi=fopen(image,"r");
    if(fi)
    {
      fgets(image,80,fi);
      fclose(fi);
      sr(image);
      AddConfItem(conflist,"NDIRS",image);
    }
  return((ULONG *)conflist);
}
void AddConfItem(struct List *galist,char *tag,char *data)
{
   struct ConfItem *it;
   it=AllocMem(sizeof(struct ConfItem),MEMF_CLEAR);
   strcpy(it->Tag,tag);
   strcpy(it->Data,data);
   AddTail((struct List *)galist,(struct Node *)it);
}
void FreeConfItems(struct List *galist)
{
   struct ConfItem *it;
   struct ConfItem *tt;
  it=(struct ConfItem *)(galist->lh_Head);
   while(tt=(struct ConfItem *)(it->l.mln_Succ))
     {
        FreeMem(it,sizeof(struct ConfItem));
        it=tt;
     }
}
void DeAllocateConfs(void)
{
   register int i=0;
   struct List *dobj;
   if(MemConf)
   {
   while(*(MemConf+(ULONG)i)!=NULL)
   {
     //dobj=(struct DiskObject *)*(MemConf+(ULONG)i);
     dobj=(struct List *)MemConf[i];
     FreeConfItems(dobj);
     FreeMem(dobj,sizeof(struct List));
     i +=1;
   }
   i +=1;
   FreeMem(MemConf,(ULONG)i*(ULONG)sizeof(ULONG));
  }
}
#define NumVersion 235L
struct EnCode
{
  UBYTE TAG[6];
  ULONG Sysop[40];
  ULONG BBSName[50];
  ULONG RealName[40];
  ULONG Location[40];
  ULONG LocationLength;
  ULONG RealNameLength;
  ULONG SerialNumber;
  ULONG Version;
  ULONG SysopLength;
  ULONG BBSNameLength;
  ULONG RegNum;
  ULONG TotalReg;
};

struct EnCode BBSid;
char seccode[65];
ULONG KeyName[] = { 1100L,1119L,1111L,1113L,1100L,1114L,1114L,1045L,1106L,1100L,1120L,0L };
int DeCode(void)
{
   register int i;
   ULONG totalsize=0L;
   char string[200];
   i=0;
   if(Valer==-1) { dumfunc=(&ConPutStr); return(0); }
   while(i<BBSid.SysopLength)
   {
     //Cmds->SysopName[i]=BBSid.Sysop[i]-BBSid.RegNum;
     totalsize +=BBSid.Sysop[i];
     i++;
   }
   //Cmds->SysopName[i]='\0';
   i=0;
   while(i<BBSid.RealNameLength)
   {
     totalsize +=BBSid.RealName[i];
     i++;
   }
   i=0;
   while(i<BBSid.BBSNameLength)
   {
     Cmds->BBSName[i]=BBSid.BBSName[i]-BBSid.RegNum;
     totalsize +=BBSid.BBSName[i];
     i++;
   }
   
   Cmds->BBSName[i]='\0';
   if(BBSid.Version-BBSid.RegNum!=NumVersion) { dumfunc=(&ConPutStr); return(0); }
   if(totalsize!=BBSid.TotalReg || totalsize==0 )
   {
    pignotes=BBSid.SerialNumber;
     //secfunc(&dumfunc,&ConPutStr);
    dumfunc=(&ConPutStr); return(0);
   }
   //secfunc(&dumfunc,&SerPutStr);
   dumfunc=(&SerPutStr);
   return(1);
}

void LoadKey(void)
{
   FILE *fi;
   register int i;
   char string[200];
   char temp[200];
   i=0;
   while(KeyName[i]!=0L)
   {
     temp[i]=(char)(KeyName[i]-999L);
     i++;
   }
   temp[i]='\0';
   sprintf(string,"%s%s",Cmds->BBSLoc,temp);
   fi=fopen(string,"rb");
   if(fi==NULL) { Valer=-1; return; }
   fread((APTR)&(BBSid.Sysop),sizeof(struct EnCode)-6L,1,fi);
  
   //fread((APTR)&seccode[0],64,1,fi);
   
   BBSid.RegNum -=(ULONG)(sizeof(struct EnCode)+20);
   fclose(fi);
   //CacheClearU();
   //secfunc=&seccode[0];
}

void CheckDeadLine(ULONG num)
{
  if(num>deadtime)
    ShutDown("!");
}