#include "bbs.h"
#include <dos/dostags.h>
#include <workbench/workbench.h>
#include <clib/icon_protos.h>
char Xprlib[100];
char prototitle[100];
char XprOpts[200];
extern UBYTE serin[];
int StartProcess(char *s,ULONG Stack);
/*extern struct Commands *Cmds;
extern struct User User;
extern char MAINMENU_Li[];
*/
int Async;
#define STRNULL ""
int notvaliddoor=0;
int UpperCheck(char str1[],char str2[]);
int CheckInUse(char *str);
void RemoveEnvDoor(char *str);
void DoorLog(char Type,char *str);
int ErrorDoorInUse;
int DOORTYPE;
int DoorAccessHigher;
char DoorPassWord[20];
UBYTE ServerCommand[255];
ULONG DoorStack=4096L;   
char *LookUp(char str[],char File[],int Private);                      
int CustomCommand(char Location[],char CustomCmd[],int Private)
{
   FILE *fi;
   register int i=0;
   char str[256];
   char RunIt[256];
   char TempCmd[256];
   notvaliddoor=0;
   ErrorDoorInUse=0;
   DoorAccessHigher=FALSE;
   Async=TRUE;
   strlim(ServerCommand,CustomCmd,195);StripReturn(ServerCommand);
   strcpy(RunIt,Location);
   strlim(TempCmd,CustomCmd,195);
   while(TempCmd[i]!='\0')
   {
      if(TempCmd[i]==' ') { TempCmd[i]='\0'; break; }
      i++;
   }
  
   strcpy(str,LookUp(TempCmd,RunIt,Private));

   StripReturn(str);
   if(*(str)!='\0' && Cmds->AcLvl[LVL_NODE_NUMBER]<10 && !notvaliddoor && !ErrorDoorInUse)
   {
        if((fi=fopen(str,"r"))==NULL) 
        {
            AEPutStr("Error, can't locate Custom Command\n\r");
            return(0);
        } fclose(fi);
        SetEnvStat(ENV_DOORS);
        switch(DOORTYPE)
        {
          case 'I': sprintf(RunIt,"%s %d",str,Cmds->AcLvl[LVL_NODE_NUMBER]);
                    break;
          case 'P': sprintf(RunIt,"%sUtils/PARADOOR %s %d",Cmds->BBSLoc,str,Cmds->AcLvl[LVL_NODE_NUMBER]);
                    break;
          case 'R': sprintf(RunIt,"%sUtils/REXXDOOR %d %s",Cmds->BBSLoc,Cmds->AcLvl[LVL_NODE_NUMBER],str);
                    break;
          default:  sprintf(RunIt,"%s %d",str,Cmds->AcLvl[LVL_NODE_NUMBER]);
                    break;
        }
        if(DOORTYPE=='R') DOORTYPE='X';

        DoorLog(DOORTYPE,TempCmd);
        if(!StartProcess(RunIt,50000L))
        { AEPutStr("Error Loading Module\r\n\r\n"); return(1); } 
        if(DOORTYPE=='M')
        { 
          RemoveEnvDoor(TempCmd); DoorLog(DOORTYPE,STRNULL);return(1);
        }
        if(Control(Cmds->AcLvl[LVL_NODE_NUMBER],DOORTYPE,DOORTYPE))
        { 
          RemoveEnvDoor(TempCmd);
          DoorLog(DOORTYPE,STRNULL);
          PurgeLine();
          return(2);
        } 
        else 
        { 
          RemoveEnvDoor(TempCmd); 
          DoorLog(DOORTYPE,STRNULL);
          return(1); 
        }
   }
   if(ErrorDoorInUse) 
   { 
     sprintf(TempCmd,"%sUserInDoor",Cmds->BBSLoc);
     if(!ChecktoDisplay(TempCmd,RunIt,1,0))
	{
       AEPutStr("This Door is in use at this time\r\n");
	}
     return(1);
   }
   if(notvaliddoor)
   {                 
      if(!Private)
      {
        if(DoorAccessHigher)
        AEPutStr("\r\nCommand requires higher access.\r\n\r\n");
        else
        AEPutStr("\r\nNo such command!!  Use '?' for command list.\r\n\r\n");
      }
      return(1);
   }
   return(0);
}
char *LookUp(char str[],char File[],int Private)
{
   register int i;
   FILE *fi;
   char CMD[80];
   char ReturnStr[80];
   char BBSCMD[80];
   char Access[6];
   char LineType;
   fi=fopen(File,"r"); if(fi==NULL) return("");
   while(fgets(CMD,80,fi)!=NULL)
   {
       if(strlen(CMD)<11){ continue;}
       sprintf(BBSCMD,"%.10s",CMD);
       strcpy(ReturnStr,&CMD[15]);
       DOORTYPE=CMD[10];
       LineType=CMD[11];
       Access[0]=CMD[12];Access[1]=CMD[13];Access[2]=CMD[14];
       Access[3]='\0';
         StripReturn(ReturnStr);
         i=strlen(BBSCMD)-1;
         while(i>-1) { if(BBSCMD[i]<=32) BBSCMD[i]='\0'; else break; i--; }
         if(UpperCheck(str,BBSCMD))
         {
            if(LineType=='S' || LineType=='s') 
            {
              if(CheckInUse(str)) ErrorDoorInUse=1; 
            }
            if(User.Sec_Status<atoi(Access)) DoorAccessHigher=TRUE;
            if((User.Sec_Status>=atoi(Access) || Private) && atoi(Access)!=0 && ErrorDoorInUse==0)
            {
              fclose(fi); return(ReturnStr);
            }
            else notvaliddoor=1;
         }
         if(!ErrorDoorInUse && LineType=='S') RemoveEnvDoor(str);
   }       
   fclose(fi);
   if(notvaliddoor) strcpy(MAINMENU_Li,"");
    
   return("");
}
int UpperCheck(char str1[],char str2[])
{
   strupr(str1);
   strupr(str2);
   if(*(str2)=='*')
   {
      if(!strcmp(str1,str2+1)) return(1);
      if(!strnicmp(str1,str2+1,strlen(str2+1))) 
      { strcpy(MAINMENU_Li,""); return(0); }
   }
   
   if(!strcmp(str1,str2))
       return(1);
   return(0);
}

int CheckInUse(char *str)
{
   FILE *fi;
   
   char TestIt[256];
   sprintf(TestIt,"T:%s",str);
   StripReturn(TestIt);
   strupr(TestIt);
   fi=fopen(TestIt,"r");
   if(fi==NULL)
   {
     fi=fopen(TestIt,"w");
     fclose(fi);
     ErrorDoorInUse=0; return(0);
   }
   fclose(fi);
   return(1);
}

void RemoveEnvDoor(char *str)
{
   char TestIt[256];
   sprintf(TestIt,"T:%s",str);
   StripReturn(TestIt);
   unlink(TestIt);
}
void DoorLog(char Type,char *str)
{

  FILE *fi;
  long TSys;
  char string[200];
  char str1[200];
  if(!Sopt->Toggles[2]) return;
                  TSys=time(NULL);
  sprintf(str1,"%s",ctime(&TSys));
  str1[strlen(str1)-1]='\0';
  if(str[0]!=NULL)
  sprintf(string,"[%-25.25s] %s - %c - %-10.10s\n",str1,User.Name,Type,str);
  else
  sprintf(string,"[%-25.25s] %s - %c - Exiting\n",str1,User.Name,Type);

  sprintf(str1,"%sNode%d/DoorLog",Cmds->BBSLoc,Cmds->AcLvl[LVL_NODE_NUMBER]);
  fi=fopen(str1,"a");
  fprintf(fi,"%s",string);
  fclose(fi);

}

struct TagItem tags[]={ {SYS_Input,0},{SYS_Output,0},{SYS_Asynch,TRUE},{NP_StackSize,0},{NP_Priority,0},{TAG_DONE,0}};

int StartProcess(char *s,ULONG Stack)
{
    int temp;
    tags[3].ti_Data=Stack;
    tags[4].ti_Data=Cmds->TaskPri;
    if(Async) tags[2].ti_Data=TRUE; else tags[2].ti_Data=FALSE;
    temp=SystemTagList(s,tags);
    /*if(temp==-1)
    {
      return(0);
    }*/
    return(1);
}

//void __regargs xprsequence(void);

void GetProtocol(void)
{
  char string[100];
  register int i;
  strcpy(Xprlib,"INTERNAL"); strcpy(prototitle,"Internal Zmodem");
}

void ClearProtocol(void)
{
     strcpy(Xprlib,"INTERNAL"); strcpy(prototitle,"Internal Zmodem");
}