#include "bbs.h"

extern int Online_Baud;
int width;
extern int gnsflag;
extern long Time_Last_On;
extern char *ComputerTypes[];
extern int System_Calls;
extern char Conference_Location[];
extern int LineCount;
extern int NotRelative;
extern int CN;
//extern BOOL MCIDoor;
extern int MCIViewSafe;
int mciinterpret(int dtlen,char image[],BOOL returnit);
int mciread(BPTR fi,char *b,int *pos,int *myeof);
int mciread(BPTR fi,char *b,int *pos,int *myeof)
{
  register int returnval;
  if(*(b+(*pos))==NULL)
  {
    if(*myeof) return(0);
    if((returnval=FRead(fi,(APTR)b,1L,400L))<400L) *myeof=1;
    *(b+returnval)='\0';
    *pos=0; returnval=(int)b[*pos]; (*pos) +=1; return(returnval);
  }
  returnval=(int)b[*pos]; (*pos)+=1;
  return(returnval);
}
int mcisend(char *filename)
{
   BPTR fi;
   char image[200];
   char myimage[402];
   BOOL returnit=FALSE;
   int stats;
   UBYTE dot='|';
   int dtlen;
   int myeof=0;
   int pos=0;
   BOOL noteof;
   char ch[10];
   ch[1]='\0';
   myimage[0]='\0';
   if(!MCIViewSafe && !GET_BIT(ACS_MCI_MSG)) return(SUCCESS);
   fi=Open(filename,MODE_OLDFILE); if(fi==NULL) return(SUCCESS);
   while((ch[0]=mciread(fi,myimage,&pos,&myeof))!=NULL)
   {
      if(ch[0]==13 || ch[0]==12 || ch[0]==10) 
      { 
         AEPutStr("\r\n");
         if(stats=CheckForPause())
         {
           AEPutStr("\r\n");
           Close(fi);
           ConPutStr("[ p");
           return(stats);
         } 
         
      
      if(SCheckInput())
      {
         stats=ReadChar(1L);
         if(stats<0) 
         { Close(fi);
           ConPutStr("[ p");
           return(stats);
         }
      } continue;
      }   
      if(ch[0]=='~')
      {
        dtlen=0;
        image[0]='\0';
        while((noteof=mciread(fi,myimage,&pos,&myeof))!=NULL)
        {
          ch[0]=noteof;
          image[dtlen]=noteof;
          if(image[0]<' ') { image[1]='\0';break; }
          if(dot==(UBYTE)noteof || noteof==' ') break;
          if(noteof==10 || noteof==12 || noteof==13)
          { ch[0]='\0'; returnit=TRUE; break;}
          dtlen++;
          
          if(dtlen>100) { Close(fi); return(SUCCESS);}
        }
        if(!noteof) { Close(fi); return(SUCCESS); }
        image[dtlen]='\0';
        if(stats=mciinterpret(dtlen,image,returnit)!=SUCCESS)
        {Close(fi); return(stats); break;}
      }
      else AEPutStr(ch);
    } 
    Close(fi);
ConPutStr("[ p");
          
  return(SUCCESS);
}
int mciputstr(char *str)
{
   register int i;
   char image[200];
   BOOL returnit=FALSE;
   UBYTE dot='|';
   int dtlen;
   int stats;
   BOOL noteof;
   char ch[10];
   i=0; 
   if(!MCIViewSafe && !GET_BIT(ACS_MCI_MSG)) return(SUCCESS);
   while(*(str+i)!=NULL)
   {
      ch[0]=*(str+i); i++;
      if(ch[0]==13 || ch[0]==12 || ch[0]==10) 
      { 
         AEPutStr("\r\n");
         if(stats=CheckForPause())
         {
           AEPutStr("\r\n");
           return(stats);
         } 
         
      
      if(SCheckInput())
      {
         stats=ReadChar(1L);
         if(stats<0) 
         { 
           return(stats);
         }
      } continue;
      }
      if(ch[0]=='~')
      {
        dtlen=0;
        image[0]='\0';
        noteof=TRUE;
        while(1)
        {
          if(*(str+i)==NULL) { noteof=FALSE; break; }
          ch[0]=*(str+i);
          image[dtlen]=ch[0];
          if(image[0]<' ') {  i++; image[1]='\0';break; }
          if(dot==(UBYTE)ch[0] || ch[0]==' ') { i++;break; }
          if(ch[0]==10 || ch[0]==12 || ch[0]==13)
          { ch[0]='\0'; i++;  returnit=TRUE; break;}
          dtlen++; i++;
          
          if(dtlen>100) { return(SUCCESS);}
          if(ch[0]=='r' && dtlen==1) break;
        }
        if(image[0]=='r') { image[dtlen]='1'; image[0]='n'; dtlen++; }
        if(!noteof) { return(SUCCESS); }
        image[dtlen]='\0';
        if(mciinterpret(dtlen,image,returnit)!=SUCCESS) break;
       }
      else {ch[1]='\0'; AEPutStr(ch);}
    }
  return(SUCCESS);
}

int mciinterpret(int dtlen,char *image,BOOL returnit)
{
   char prt[200];
   char tprt[200];
   char confname[100]; char confloc[100];
   int stats;
   int width,pt,temp;
    prt[0]='\0';
        if(image[0]=='~')
        {
          strcpy(prt,image);
        }else
        {
          width=-1;pt=0;
          while(pt<dtlen)
          {
            switch(image[pt])
            {
              case 'M': sprintf(tprt,"%d",User.Messages_Posted);
                        strlim(prt,tprt,width); width=-1; break;
              case 'A': sprintf(tprt,"%d",User.Sec_Status);
                        strlim(prt,tprt,width); width=-1; break;
              case 'S': 
                switch(image[pt+1])
                {
                   case 'C':
                        sprintf(tprt,"%d",System_Calls);
                        strlim(prt,tprt,width); width=-1; break;
                   case 'S':
                        if(!Restricted(&image[pt+3]))
                        { 
                          if(!MCIViewSafe && AllowedView(&image[pt+3])){
                          gnsflag=0;MenuSend24(&image[pt+3],LineCount);}
                          else
                          if(MCIViewSafe)
                          {gnsflag=0;MenuSend24(&image[pt+3],LineCount);}
                        } break;
                   case 'P':
                        stats=DoPause();
                        if(stats<0) return(stats);
                        strcpy(prt,""); break;
                   case 'R':
                        gnsflag=0; sprintf(prt,"%s%d",&image[pt+3],rnd(width)+1);
                        if(ChecktoDisplay(prt,tprt,0,0)<0) return(NO_CARRIER); strcpy(prt,""); width=-1; break;
                   default:
                        sprintf(tprt,"%d",User.Slot_Number);
                        strlim(prt,tprt,width); width=-1; break;
             
                }break;
              case 'N': strlim(prt,User.Name,width); width=-1; break;
              case '#': strlim(prt,User.PhoneNumber,width); width=-1; break;
              case 'c': sprintf(prt,"[3%cm",image[pt+1]); break;
              case 'z': sprintf(prt,"[4%cm",image[pt+1]); break;
              case 'n': temp=image[pt+1]-'0'; if(temp<=0 || temp>9) temp=1;
                        while(temp)
                        { 
                          AEPutStr("\r\n");
                          if(stats=CheckForPause())
                          {
                            AEPutStr("\r\n");
                            return(stats);
                          } temp--; 
                        }
                        strcpy(prt,"");
                        break;
              case 'T':
                   switch(image[pt+1])
                   {
                     case 'C': sprintf(tprt,"%u",User.Times_Called);
                               strlim(prt,tprt,width); width=-1; break;
                     case 'L': sprintf(tprt,"%ld",User.Time_Limit/60L);
                               strlim(prt,tprt,width); width=-1; break;
                     case 'R': sprintf(tprt,"%ld",Time_limit/60L);
                               strlim(prt,tprt,width); width=-1; break;
                    } break;
              case 'C':
                   switch(image[pt+1])
                   {
                     case 'A': strlim(prt,User.Conference_Access,width); width=-1; break;
                     case 'R': strcpy(prt,""); 
                               if(image[pt+2]!='\0' && image[pt+3]!='\0')
                               strcpy(prt,&image[pt+3]);prt[0]=HtKey(prt);
                              AEPutStr("\r\n");
                               LineCount=0;
                             strcpy(prt,""); break;
                     case 'E': strcpy(prt,"CE"); break;
                     case 'D': strcpy(prt,"CD"); break;
                     case 'T': 
                               strcpy(tprt,GetTheTime(NULL));
                               strlim(prt,tprt,width); width=-1; break;
                     case 'C': 
                               
                               strcpy(prt,&image[pt+3]);
                               if(MCIViewSafe)
                               {
                                  sprintf(tprt,"%sCommands/SysCmd/",Cmds->BBSLoc);
                                  if(!CustomCommand(tprt,prt,1))
                                  {
                                    sprintf(tprt,"%sCommands/BBSCmd/",Cmds->BBSLoc);
                                    if(!CustomCommand(tprt,prt,1))
                                    {
                                      sprintf(tprt,"%sCommands/conf%dCmd/",Cmds->BBSLoc,CN);
                                      CustomCommand(tprt,prt,1);
                                    }
                                  }
                               }
                               else
                               {
                                    sprintf(tprt,"%sCommands/BBSCmd/",Cmds->BBSLoc);
                                    if(!CustomCommand(tprt,prt,0))
                                    {
                                      sprintf(tprt,"%sCommands/conf%dcmd/",Cmds->BBSLoc,CN);
                                      CustomCommand(tprt,prt,0);
                                    }
                               }
                               strcpy(prt,"");
                               break;
                     case 'L': stats = 0; width=0;if(image[pt+2]!='\0') tprt[0]=image[pt+2];
                               else tprt[0]=' '; tprt[1]='\0';
                                 while(stats<Boards_Are_Active)
                                 {
                                      
                                   if(IsValidConf(stats) || NotRelative)
                                   {
                                     GetConfName(confname,confloc,stats);
                                     width++;
                                     sprintf(prt,"                     [32m%3d[33m) [35m",width);
                                     AEPutStr(prt);
                                     temp=strlen(confname);
                                     while(temp<30) { AEPutStr(tprt); temp++; }
                                     sprintf(prt,"[36m%s[0m\r\n",confname);
                                     AEPutStr(prt);
                                   }
                                   stats++;
                                 }
                                 GetConfName(confname,confloc,CN-1);
                               strcpy(prt,""); width = -1;break;
                   }
                   break;
              case 'D': 
                   switch(image[pt+1])
                   {
                     case 'T': strcpy(tprt,GetTheDate(NULL));strlim(prt,tprt,width); width=-1; break;
                     case 'B': sprintf(tprt,"%ld",User.Bytes_Download);
                               strlim(prt,tprt,width); width=-1; break;
                     default: strcpy(prt,""); break;
                   }break;
               case 'F':
                 switch(image[pt+1])
                 {
                   case 'U': sprintf(tprt,"%d",User.Uploads);
                             strlim(prt,tprt,width); width=-1; break;
                   case 'D': sprintf(tprt,"%d",User.Downloads);
                             strlim(prt,tprt,width); width=-1; break;
                   default: strcpy(prt,"F"); break;
                 }break;
               case 'H':
                 switch(image[pt+1])
                 {
                   case 'W': strlim(prt,ComputerTypes[User.Sec_Bulletin],width); width=-1; break;
                 }break;
               case 'L':
                 switch(image[pt+1])
                 {
                   case 'C':
                      sprintf(tprt,"%s",ctime(&Time_Last_On));
                      tprt[strlen(tprt)-1]='\0';
                      strlim(prt,tprt,width); width=-1;
                      break;
                   case 'G':
                      sprintf(tprt,"%d",Cmds->AcLvl[LVL_NODE_NUMBER]);
                      strlim(prt,tprt,width); width=-1; break;
                   
                 }break;
               case 'U':
                 switch(image[pt+1])
                 {
                   case 'L': strlim(prt,User.Location,width); width=-1; break;
                   case 'B': sprintf(tprt,"%ld",User.Bytes_Upload);
                             strlim(prt,tprt,width); width=-1; break;
                 } break;
               case 'B':
                 switch(image[pt+1])
                 {
                   case 'D': sprintf(tprt,"%ld",User.Daily_Bytes_Limit);
                             strlim(prt,tprt,width); width=-1; break;
                   case 'R': sprintf(tprt,"%d",Online_Baud);
                             strlim(prt,tprt,width); width=-1; break;
                   default: strcpy(prt,"B"); break;
                 }break;
               case 'W': if(width<0) width=1;
                   Delay((LONG)width); width=-1; break;
               case 'b':
                 sprintf(prt,"[4%cm",image[pt+1]); break;
               case 'h':
                 while(image[pt+1]!='0')
                 {
                    AEPutStr("\b \b"); image[pt+1] -=1;
                 } break;
               case 'q':
                 strcpy(prt,"[0m"); break;
               case 'x': temp=atoi(&image[pt+1]);
                         sprintf(tprt,"[%dH",temp);
                         strcpy(prt,tprt); break;
               case 'y': temp=atoi(&image[pt+1]);
                         sprintf(tprt,"[%d;",temp);
                         strcpy(prt,tprt); break;
  
               case 'f':
                 temp=image[pt+1]-'0';
                 if(temp==0) strcpy(prt,"\x9B\x48");
               else strcpy(prt,"\x0c"); break;
               case '0':
               case '1':
               case '2':
               case '3':
               case '4':
               case '5':
               case '6':
               case '7':
               case '8':
               case '9':
                 if(pt==0)
                 {
                    width=atoi(image); if(width>80) width=80;
                    while(image[pt]>='0' && image[pt]<='9') pt++;break;
                 }
                 
                 break; 
              default: strcpy(prt,image);
               }
            if(width==-1)break;
           }
         }        
        AEPutStr(prt);
        if(returnit==TRUE)
        { AEPutStr("\r\n");
         if(stats=CheckForPause())
         {
           AEPutStr("\r\n");
           return(stats);
         }
         returnit=FALSE;
       } 
  return(SUCCESS);
}
int Restricted(char *str)
{
   BPTR  FLock;
   char image[200];
   int bad=TRUE;
   struct FileInfoBlock *FBlock;
   if((FLock=Lock(str,ACCESS_READ))!=0)
   {
     if((FBlock=(struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL)) == NULL)
     { 
       AEPutStr("\r\nCan't allocate memory to lock file!!\r\n"); bad=TRUE; 
     }
     else 
     { 
       if((Examine(FLock,FBlock))==0)
       {  
         AEPutStr("\r\nCan't get informations from file.\r\n"); 
         bad=TRUE;  
       }
       else
       { 
     
         if(!strnicmp(FBlock->fib_Comment,"Restricted",10))
         { 
           AEPutStr("\r\n "); AEPutStr(str); 
           AEPutStr("\r\n >>Restricted File<< Updating CallersLog\r\n");
           sprintf(image,"\tAttempt to examine RESTRICTED file [%.100s]\n",str);
           CallersLog(image);
           bad=TRUE;
         }
         else  
         {  
           bad=FALSE;//!AllowedView(FBlock->fib_Comment);  
         }
       }
       FreeDosObject(DOS_FIB,FBlock);
    }
    UnLock(FLock);
   }
    return(bad);
}
int AllowedView(char *str)
{
   BPTR  FLock;
   char image[200];
   struct FileInfoBlock *FBlock;
   if((FLock=Lock(str,ACCESS_READ))!=0)
   {
     if((FBlock=(struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL))==NULL)
     { 
       AEPutStr("\r\nCan't allocate memory to lock file!!\r\n"); 
     }
     else 
     { 
       if((Examine(FLock,FBlock))==0)
       {  
         AEPutStr("\r\nCan't get informations from file.\r\n"); 
           
       }
       else
       { 
         if(!strnicmp(FBlock->fib_Comment,"Allowed",7))
         {
           FreeDosObject(DOS_FIB,FBlock);
           UnLock(FLock);return(TRUE);
         }
           if(!strwild(FBlock->fib_Comment,"{~~~}Allowed",'~',12))
           { 
             strcpy(image,FBlock->fib_Comment);
             if(atoi(&image[1])<=User.Sec_Status)
             {
               FreeDosObject(DOS_FIB,FBlock);
                UnLock(FLock);return(TRUE);
             }
           }
         
       }
       FreeDosObject(DOS_FIB,FBlock);

    }
    UnLock(FLock);
   }
    return(FALSE);
}
/*
int strwild(char *str,char *str1,char wild,int len)
{
   register int i=0;
   char im1[200];char im2[200];
   strcpy(im1,str);
   strcpy(im2,str1);
   strupr(im1);strupr(im2);
   if(im1[0]=='\0') return(1);
   while(im1[i] && i<len)
   {
     if(im2[i]=='\0') return(1);
     if(im2[i]==wild ) { i++; continue; }
     if(im1[i]!=im2[i]) return(1);
     i++;
   }
   return(0);
}
*/