home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / XSRC_117.ZIP / INTERPX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-08  |  70.1 KB  |  2,407 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*   XBBS SOURCE CODE copyright (c) 1990 by M. Kimes                        */
  4. /*   All Rights Reserved                                                    */
  5. /*                                                                          */
  6. /*    For complete details of the licensing restrictions, please refer      */
  7. /*    to the License agreement, which is published in its entirety in       */
  8. /*    the in the file LICENSE.XBS.                                          */
  9. /*                                                                          */
  10. /*    USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE      */
  11. /*    XBBS LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF            */
  12. /*    THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO       */
  13. /*    NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT M. KIMES         */
  14. /*    AT THE ADDRESS LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO USE   */
  15. /*    THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE XBBS LICENSING     */
  16. /*    AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU ARE ABLE TO REACH WITH      */
  17. /*    M. KIMES                                                              */
  18. /*                                                                          */
  19. /*                                                                          */
  20. /* You can contact M. Kimes at the following address:                       */
  21. /*                                                                          */
  22. /* M. Kimes                         1:380/16.0@FidoNet                      */
  23. /* 542 Merrick                      (318)222-3455 data                      */
  24. /* Shreveport, LA  71104                                                    */
  25. /*                                                                          */
  26. /*                                                                          */
  27. /* Please feel free to contact me at any time to share your comments about  */
  28. /* my software and/or licensing policies.                                   */
  29. /*                                                                          */
  30. /*--------------------------------------------------------------------------*/
  31. /*======================================================================*/
  32. /*  XBBS Bulletin Board System.....XBS file interpreter                 */
  33. /* This is the heart of XBBS and a really nasty function.  Will only    */
  34. /* compile via assembly due to bloated size.  Bleach.                   */
  35. /* This has to be reentrant.                                            */
  36. /*======================================================================*/
  37.  
  38. #include "msg.h"
  39. #include "xext.h"
  40.  
  41. extern struct _mboard far *marea;
  42. extern struct _fboard holdboard;
  43. extern struct _mboard holdmboard;
  44. extern char exporting;
  45. extern word maxareas;
  46. extern word higharea;
  47. word lastlevel[10]={
  48.     0,0,0,0,0,0,0,0,0,0
  49. };
  50.  
  51.  
  52. char pascal readfile (file,abort,pause,imbed)  /* READS FILE TO MODEM & SCREEN */
  53.  
  54.     char *file;
  55.     char abort;
  56.     char pause;
  57.     char imbed;
  58.  
  59. {
  60.  
  61.     static int outputhandle=-1;
  62.     static int inputhandle=-1;
  63.     int  handle=-1;
  64.     char ext[5];
  65.     char str[396];
  66.     char a;
  67.     word register x;
  68.     char arg;
  69.     char p;
  70.     char *pp;
  71.     char *cm;
  72.     char *b=NULL;
  73.     static char c[256];
  74.     static char d[396];
  75.     char tempause;
  76.     char filename[104];
  77.     static char label[33];
  78.     long markedplace;
  79.     word secl;
  80.     char alabel[33];
  81.     char hotkeys[37];
  82.     long markedspots[10];
  83.     char already=0;
  84.     word  nofiles=0;
  85.     ulong totalbytes=0;
  86.     char tempsafe;
  87.     struct ffblk f1;
  88.  
  89.  *label=0;
  90.  *alabel=0;
  91.  strcpy(filename,file);
  92.  
  93. restart:
  94.  
  95.  for (x=0;x<10;x++) markedspots[x]=0;
  96.  *hotkeys=0;
  97.  stripcr(filename);
  98.  arg = 0;
  99.  a='*';
  100.  redraw_stat(NULL);
  101.  right(ext,filename,4);
  102.  if (!stricmp(ext,".XBS") && !strchr(filename,'\\')) {
  103.    if (!strcmp(filename,"GOODBYE.XBS")) leaving=1;
  104.    strcpy(d,filename);
  105.    sprintf(filename,"%s%s",conf.menupath,d);
  106.  }
  107.  if (user.graphics) {
  108.                               /* REPLACE .XBS suffix with .GBS if available */
  109.       if (!stricmp(ext,".XBS")) {
  110.         b=strchr(filename,'.');
  111.         b++;
  112.         *b='G';
  113.         if ((handle=oopen(filename,O_RDONLY | O_BINARY | O_DENYNONE))==-1) *b='X';
  114.         cclose(handle);
  115.     }
  116.  }
  117. /* cls(); */
  118.  handle=oopen(filename,O_RDONLY | O_BINARY | O_DENYNONE);
  119.  
  120. GotGraphics:
  121.  
  122.  if (handle == -1) {
  123.    if (stricmp(ext,".XBS")) {
  124.      say_prompt(8);
  125.      lprint(filename);
  126.    }
  127.    return(2);
  128.  }
  129.  
  130.  if (eof(handle)) {
  131.    cclose(handle);
  132.    return (2);
  133.  }
  134.  
  135.  if(conf.logmenu) gprintf(LOGONLY,"Read menu %s",filename);
  136.  if (!pause) pauser=1;
  137.  tempause=pauser;
  138.  do {
  139.    getxbbstime();
  140.    b=fgetsx(str, 396, handle);
  141. BreakIn:
  142.    if (b==NULL) break;
  143.    if(conf.trace)redraw_stat(b);
  144.  
  145. /* Embedded command processing here */
  146.  
  147. if (imbed) {
  148.   do {
  149.     if (b==NULL) break;
  150.     cm=strchr(b,1);
  151.     if (cm) {
  152.       pauser=2;
  153.       if (strlen(cm) > 1) {
  154.         cm[0]='\0';
  155.         cm++;
  156.         printm(b);
  157.         arg=cm[0];
  158.         b = ++cm;
  159.         switch (arg) {
  160.  
  161.           case 'l':          /* SKIP LABELS (^a=Text[Enter]) */
  162.           case ';':             /* Skip comments */
  163.            b=NULL;
  164.            break;
  165.  
  166.  
  167.           case 't':          /* TIME */
  168.            a=*b;
  169.            b++;
  170.            switch (a) {
  171.              case 'c': {         /* CURRENT TIME */
  172.  
  173.                 struct time dos_time;
  174.  
  175.               gettime(&dos_time);
  176.               gprintf(0,saytime(&dos_time));
  177.              }
  178.              break;
  179.              case 'r':           /* TIME REMAINING */
  180.               gprintf(0,"%u",(word)(timelimit-((word)getxbbstime()/60)));
  181.              break;
  182.              case '=':           /* TIME BRANCHING */
  183.              case '<':           /* AND SETTING    */
  184.              case '>':
  185.              case '-':
  186.              case '+':
  187.                if(*b=='@') {
  188.                     b++;
  189.                     secl=(word)atol(variable[*b-'0']);
  190.                     b++;
  191.                }
  192.                else if (*b=='e') {
  193.                     b++;
  194.                     secl=lastlevel[*b-'0'];
  195.                     b++;
  196.                }
  197.                else secl=(word)atol(b);
  198.                b=strchr(b,'l');
  199.                if (a=='=') timelimit=((word)(getxbbstime()/60L)+(secl));
  200.                else if (a=='-') {
  201.                  if ((long)(timelimit-secl)<(long)0) timelimit=0;
  202.                  else timelimit-=secl;
  203.                }
  204.                else if (a=='+') {
  205.                  if (((long)timelimit+(long)secl)<(long)65535) timelimit+=secl;
  206.                }
  207.                if (b==NULL) break;
  208.                strcpy(label,b);
  209.                b=NULL;
  210.                if (a=='<') {
  211.                  if ((timelimit-(word)(getxbbstime()/60L))<secl) goto seeklabel;
  212.                }
  213.                else if ((timelimit-(word)(getxbbstime()/60L))>secl) goto seeklabel;
  214.               break;
  215.               case 'o':       /* Timer controls...0=off/save, 1=on/restore, 2=on */
  216.                a=*b-'0';
  217.                b++;
  218.                if(a<2) adjust_time(a);
  219.                else timer_off=0;
  220.               break;
  221.              case 'l':  /* Minutes since last caller */
  222.                {
  223.                     long temp;
  224.  
  225.                temp=((time(NULL)-conf.lastcall)/60L);
  226.                if(temp>65535L) level=65535; /* Max permissible */
  227.                else level=(word)temp;
  228.                }
  229.                break;
  230.              case 'e':           /* Time sensitive events       */
  231.              {                    /* @texx:xx:xx yy:yy:yy lLabel */
  232.                                  /* Branch to lLabel if time is */
  233.                                  /* not outside of hours spec'd */
  234.  
  235.                  struct time dos_time;
  236.  
  237.                  struct ftime {
  238.                   bit sec:  5;
  239.                   bit min:  6;
  240.                   bit hour: 5;
  241.                 };
  242.                 union tf {
  243.                   struct ftime ft;
  244.                   int x;
  245.                 } fdt;
  246.               b=strtok(b,":");
  247.               fdt.ft.hour=(unsigned)atoi(b);
  248.               fdt.ft.min=(unsigned)atoi(strtok(0,":"));
  249.               fdt.ft.sec=(unsigned)atoi(strtok(0," ,"));
  250.               secl=(word)fdt.x;
  251.               fdt.ft.hour=(unsigned)atoi(strtok(0,":"));
  252.               fdt.ft.min=(unsigned)atoi(strtok(0,":"));
  253.               fdt.ft.sec=(unsigned)atoi(strtok(0," ,"));
  254.               x=(word)fdt.x;
  255.               strcpy(label,strtok(0,"\n"));
  256.               gettime(&dos_time);
  257.               fdt.ft.hour=dos_time.ti_hour;
  258.               fdt.ft.min=dos_time.ti_min;
  259.               fdt.ft.sec=dos_time.ti_sec;
  260.               if ((word)fdt.x<secl || (word)fdt.x>x) goto seeklabel;
  261.               b=NULL;
  262.              }
  263.              break;
  264.            }
  265.            break;
  266.  
  267.           case 'd':          /* DATE */
  268.            a=*b;
  269.            b++;
  270.            switch (a) {
  271.              case 'c': {        /* CURRENT DATE */
  272.  
  273.                 struct date dos_date;
  274.  
  275.               getdate(&dos_date);
  276.               gprintf(0,saydate(&dos_date));
  277.               break;
  278.              }
  279.              case 'w':          /* DAY OF WEEK */
  280.               strncpy(c,getdttm(),3);
  281.               c[3]=0;
  282.               printm(c);
  283.               if (!stricmp(c,"Tue")) printm("s");
  284.               if (!stricmp(c,"Wed")) printm("nes");
  285.               if (!stricmp(c,"Thu")) printm("rs");
  286.               if (!stricmp(c,"Sat")) printm("ur");
  287.                 printm("day");
  288.              break;
  289.             case 'd':           /* BRANCH IF NOT EQUAL TO DAY OF WEEK */
  290.               stripcr(b);
  291.               strncpy(c,getdttm(),3);
  292.               c[3]=0;
  293.               strtok(b," ,");
  294.               strcpy(d,b);
  295.               strcpy(label,strtok(0," ,"));
  296.               b=NULL;
  297.               if (!stricmp(c,d)) goto seeklabel;
  298.               break;
  299.             case 'a':           /* BRANCH IF NOT EQUAL TO DAY   */
  300.             case 'm': {         /* BRANCH IF NOT EQUAL TO MONTH */
  301.                 struct date dos_date;
  302.               stripcr(b);
  303.               getdate(&dos_date);
  304.               arg=atoi(b);
  305.               strtok(b," ,");
  306.               strcpy(label,strtok(0," ,"));
  307.               b=NULL;
  308.               if (a=='m') {
  309.                     if (arg!=dos_date.da_mon) goto seeklabel;
  310.               }
  311.               else if (arg!=dos_date.da_day) goto seeklabel;
  312.               break;
  313.             }
  314.             case 'l':    {   /* # days since user's last call */
  315.  
  316.                 long temp;
  317.  
  318.                 temp=dostounix(&user.lastdate,&user.lasttime);
  319.                 level=(word)((time(NULL)-temp)/86400L);
  320.             }
  321.             break;
  322.            }
  323.           break;
  324.  
  325.           case 'D':          /* SET LABEL TO SEEK IF ABORTED */
  326.            strcpy(alabel,b);
  327.            b=NULL;
  328.            break;
  329.  
  330.           case 'u':          /* USER PARAMETERS */
  331.             a=*b;
  332.             b++;
  333.             user_param(a);
  334.            break;
  335.  
  336.           case 'j':           /* JUMP TO ANOTHER FILE (ABSOLUTE) */
  337.            *hotkeys=0;
  338.            markedplace=tell(handle);
  339.            if (markedplace<0) return (2);
  340.            cclose(handle);
  341.            strcpy(c,filename);
  342.            if ((*b-'0')<0 || (*b-'0')>9) {
  343.                 strcpy(filename,strtok(b," ,"));
  344.                 b=strtok(0," ,");
  345.            }
  346.            else {
  347.                 strcpy(filename,variable[*b-'0']);
  348.                 b++;
  349.                 if (*b==' ' || *b==',') b++;
  350.                 stripcr(b);
  351.            }
  352.            if (b!=NULL && *b!=0) {
  353.  
  354.                 struct ffblk f;
  355.  
  356.               if ((*b-'0')<0 || (*b-'0')>9) strcpy(label,b);
  357.               else strcpy(label,variable[*b-'0']);
  358.               b=NULL;
  359.               if (stristr(filename,".XBS") && !strchr(filename,'\\') && !strchr(filename,':')) {
  360.                 strcpy(d,filename);
  361.                 d[12]=0;
  362.                 sprintf(filename,"%s%s",conf.menupath,d);
  363.               }
  364.               if (findfirst(filename,&f,0)) {
  365.                 strcpy(filename,c);
  366.                 break;
  367.               }
  368.               markedplace=tell(handle);
  369.               cclose(handle);
  370.               if ((handle=oopen(filename,O_RDONLY | O_BINARY | O_DENYNONE))==-1) {
  371.                   gprintf(LOCALONLY,"\n\x4 Can't open `%s'\n",filename);
  372.                   strcpy(filename,c);
  373.                   if ((handle=oopen(filename,O_RDONLY | O_BINARY | O_DENYNONE))==-1) return (2);
  374.                   lseek(handle,markedplace,SEEK_SET);
  375.                   break;
  376.               }
  377.               goto seeklabel;
  378.            }
  379.            b=NULL;
  380.            goto restart;
  381.  
  382.           case 'H':           /* SETUP HOTKEY STRING */
  383.            strcpy(alabel,strtok(b," ,"));
  384.            strcat(alabel,"\n");
  385.            strncpy(hotkeys,strupr(strtok(0," ")),36);
  386.            stripcr(hotkeys);
  387.            hotkeys[36]=0;
  388.            b=strtok(0,"\n");
  389.            break;
  390.  
  391.           case 'J':           /* JUMP TO ANOTHER FILE (GOSUB) */
  392.            if (*b<('9'+1) && *b>('0'-1) && b[1]=='\n') {
  393.                 readfile(variable[*b-'0'],0,0,1);
  394.            }
  395.            else readfile(b,0,0,1);
  396.            b=NULL;
  397.            break;
  398.  
  399.           case 'q':           /* QUIT READING FILE */
  400.              goto donereading;
  401.  
  402.           case 'B':           /* HANG UP */
  403.            do_hangup(handle);
  404.  
  405.           case 'b':           /* BRANCH TO LABEL IN label */
  406. seeklabel2:                      /* Label in b */
  407.            if (b==NULL) break;
  408.            strcpy(label,b);
  409. seeklabel:                      /* Label already in label */
  410.            stripcr(label);
  411.            if(*label=='@') {  /* Variable label */
  412.                 a=label[1]-'0';
  413.                 strcpy(label,variable[a]);
  414.            }
  415.            if(*label=='#') {  /* Numeric label */
  416.                 a=label[1]-'0';
  417.                 sprintf(label,"l%u",lastlevel[a]);
  418.            }
  419.            if (eof(handle)) {
  420.               cclose(handle);
  421.               goto commanderror;
  422.            }
  423.            if (*label=='\01') {
  424.                 if (lseek(handle,atol(&label[1]),SEEK_SET)!=atol(&label[1]))
  425.                     lprint("\n\04Direct branch failure\n");
  426.                 goto BreakLabel;
  427.            }
  428. ReTry:
  429.            markedplace=findlabel(label,handle);
  430.            if (markedplace==-1) {
  431.             if (already) {
  432.                 cclose(handle);
  433.                 already=0;
  434.                 goto commanderror;
  435.             }
  436.             else {
  437.                 lseek(handle,0L,SEEK_SET);
  438.                 already++;
  439.                 goto ReTry;
  440.             }
  441.            }
  442.            else lseek(handle,markedplace,SEEK_SET);
  443.  
  444. BreakLabel:
  445.            already=0;
  446.            b=NULL;
  447.            *label=0;
  448.            break;
  449.  
  450.           case 'Z':           /* ASSIGN FILE TO READ ON COMPLETION */
  451.            a=*b;              /* 2 Set StartFile   */
  452.            b++;                  /* 1 Set FileToRead  */
  453.            switch (a)         /* 0 Zero FileToRead */
  454.             {
  455.              case '2':
  456.               strcpy(startfile,b);
  457.               stripcr(startfile);
  458.               b=NULL;
  459.              break;
  460.              case '1':
  461.               strcpy(filetoread,b);
  462.               stripcr(filetoread);
  463.               b=NULL;
  464.              break;
  465.              case '0':
  466.               *filetoread=0;
  467.               b=NULL;
  468.              break;
  469.             }
  470.            break;
  471.  
  472.           case'E':            /* RUN ANOTHER PROGRAM */
  473.            stripcr(b);
  474.            if (strlen(b)<2) break;
  475.            a=*b;
  476.            b++;
  477.            switch (a)
  478.             {
  479.             case 'S':         /* SHELL & SPAWN */
  480.             case 'I':
  481.             case 'O':
  482.             case 'D':
  483.             case 's':
  484.             case 'd':
  485.              strcpy(d,b);
  486.              b=NULL;
  487.              markedplace=tell(handle);
  488.              cclose(handle);
  489.              if (a=='S') spawnit(d,0,0);
  490.              else if (a=='I') spawnit(d,7,0);
  491.              else if (a=='O') spawnit(d,6,0);
  492.              else if (a=='s') spawnit(d,8,0);
  493.              else if (a=='d') spawnit(d,9,0);
  494.              else spawnit(d,3,0);
  495.              if (markedplace<0) return (2);
  496.              if ((handle=oopen(filename,O_RDONLY | O_BINARY | O_DENYNONE))==-1) return 2;
  497.              if (eof(handle)) {
  498.                 cclose(handle);
  499.                 return (2);
  500.              }
  501.              lseek(handle,markedplace,SEEK_SET);
  502.              break;
  503.             case 'E':           /* EXECUTE */
  504.              strcpy(d,b);
  505.              b=NULL;
  506.              cclose(handle);
  507.              spawnit(d,1,0);
  508.              b=NULL;
  509.              goto donereading;
  510.             case 'B':           /* BATCH EXIT */
  511.              a=atoi(b);
  512.              b=strchr(b,' ');
  513.              if(b)strcpy(d,b++);
  514.              else *d=0;
  515.              b=NULL;
  516.              cclose(handle);
  517.              spawnit(d,2,a);
  518.              goto donereading;
  519.             case 'X':           /* EXIT WITH ERRORLEVEL */
  520.              strcpy(d,b);
  521.              b=NULL;
  522.              cclose(handle);
  523.              spawnit("",4,atoi(d));
  524.              goto donereading;
  525.             case 'W':           /* WRITE CONVERTED STRING TO FILE */
  526.              strcpy(d,b);
  527.              b=NULL;
  528.              spawnit(d,5,0);
  529.              b=NULL;
  530.             break;
  531.             case 'w':            /* Write unconverted string to file */
  532.              strcpy(d,b);
  533.              b=NULL;
  534.              spawnit(d,10,0);
  535.              b=NULL;
  536.              break;
  537.             }
  538.            break;
  539.  
  540.           case'0':            /* VARIABLE MANIPULATION*/
  541.           case'1':
  542.           case'2':
  543.           case'3':
  544.           case'4':
  545.           case'5':
  546.           case'6':
  547.           case'7':
  548.           case'8':
  549.           case'9':
  550.  
  551.            p=*b;
  552.            b++;
  553.  
  554.            if(p=='b') {     /* Assign assocfile from var */
  555.                 strcpy(assocfile,variable[arg-'0']);
  556.                 break;
  557.            }
  558.  
  559.            if(p=='g') {         /* Environment variable manipulation */
  560.             if(!(pp=strtok(b," \n"))) {
  561.                 level=2;
  562.                 b=NULL;
  563.                 break;
  564.             }
  565.             b=strtok(0,"\r");
  566.             pp=getenv(pp);
  567.             level=0;
  568.             if(!pp){
  569.                 level=1;
  570.                 pp="";
  571.             }
  572.             if(*pp=='@') {
  573.                 if(isdigit(pp[1])) {
  574.                     a=pp[1]-'0';
  575.                     pp=variable[a];
  576.                 }
  577.             }
  578.             assignvar(pp,arg-'0');
  579.             break;
  580.            }
  581.            if(p=='l') {         /* Uppercase var */
  582.             strlwr(variable[arg-'0']);
  583.             break;
  584.            }
  585.            else if(p=='u') {    /* Lowercase var */
  586.             strupr(variable[arg-'0']);
  587.             break;
  588.            }
  589.            else if (p=='V') {      /* Compare two variables, branch on = */
  590.              a=*b-'0';
  591.              b++;
  592.              if (!strcmp(variable[arg-'0'],variable[a])) goto seeklabel2;
  593.              b=NULL;
  594.              break;
  595.            }
  596.            else if (p=='A') {      /* ASSIGN A VARIABLE */
  597.              strcpy(d,b);
  598.              stripcr(d);
  599.              b=NULL;
  600.              assignvar(d,arg-'0');
  601.             break;
  602.             }
  603.             else if(p=='a') {  /* Parse a var one char at a time */
  604.                                /* source a dest                  */
  605.                     a=*b-'0';
  606.                     b++;
  607.                     if (!*variable[arg-'0']) {
  608.                         *variable[a]=0;
  609.                     }
  610.                     else {
  611.                         *variable[a]=*variable[arg-'0'];
  612.                         variable[a][1]=0;
  613.                         memmove(variable[arg-'0'],&variable[arg-'0'][1],strlen(variable[arg-'0']));
  614.                     }
  615.                     break;
  616.             }
  617.             else if (p=='k') {    /* Copy keybuf into var */
  618.                 assignvar(keybuf,arg-'0');
  619.                 break;
  620.             }
  621.             else if (p=='=') {    /* Copy an operating var to a variable */
  622.                 sprintf(c,"*%s",stripcr(b));
  623.                 b=NULL;
  624.                 assignvar(convertstring(c),arg-'0');
  625.                 break;
  626.             }
  627.             else if (p=='U') { /* Put variable in user.variable */
  628.                 a=*b-'0';
  629.                 b++;
  630.                 if(a<5) {
  631.                     strncpy(user.variable[a],variable[arg-'0'],76);
  632.                     user.variable[a][75]=0;
  633.                 }
  634.                 break;
  635.             }
  636.             else if (p=='s') { /* Strip leading & trailing spaces */
  637.                 lstrip(variable[arg-'0']);
  638.                 rstrip(variable[arg-'0']);
  639.                 break;
  640.             }
  641.             else if (p=='p') { /* Parse a var */
  642.  
  643.                 a=(*b)-'0';
  644.                 b++;
  645.                 if (a>9) break;
  646.                 stripcr(b);
  647.                 strcpy(d,variable[arg-'0']);
  648.                 if (!*b) b=" ";
  649.                 if(strstr(d,b)==d) {
  650.                     *variable[a]=0;
  651.                     strcpy(d,&variable[arg-'0'][1]);
  652.                     strcpy(variable[arg-'0'],d);
  653.                     b=NULL;
  654.                     break;
  655.                 }
  656.                 pp=strtok(d,b);
  657.                 if (pp==NULL) *variable[a]=0;
  658.                 else {
  659.                     strcpy(variable[a],pp);
  660.                     pp=strtok(0,"\n");
  661.                     if (pp) strcpy(variable[arg-'0'],pp);
  662.                     else *variable[arg-'0']=0;
  663.                 }
  664.                 b=NULL;
  665.                 break;
  666.             }
  667.             else if (p=='|') {  /* Concatenate vars */
  668.                 a=*b-'0';
  669.                 b++;
  670.                 strncat(variable[arg-'0'],variable[a],81);
  671.                 variable[arg-'0'][81]=0;
  672.                 break;
  673.             }
  674.             else if (p=='/') {  /* Do MID$-like operation with var */
  675.                 strtok(b," ,");
  676.                 if(*b=='e') {
  677.                      b++;
  678.                      a=(char)lastlevel[*b-'0'];
  679.                 }
  680.                 else a=(char)atoi(b);
  681.                 level=0;
  682.                 if (a>strlen(variable[arg-'0']) || !a) {
  683.                     level=1;
  684.                     b=NULL;
  685.                     break;
  686.                 }
  687.                 strcpy(c,&variable[arg-'0'][a-1]);
  688.                 b=strtok(0," \n");
  689.                 if(*b=='e') {
  690.                      b++;
  691.                      a=(char)lastlevel[*b-'0'];
  692.                      b++;
  693.                 }
  694.                 else a=(char)atoi(b);
  695.                 if (a>=0 && (a<=strlen(c))) c[a]=0;
  696.                 assignvar(c,arg-'0');
  697.                 b=NULL;
  698.                 break;
  699.             }
  700.             else if (p=='P') {  /* PRINT A VARIABLE */
  701.               printm(variable[arg-48]);
  702.              break;
  703.             }
  704.             else if (p=='I')  /* INPUT A VARIABLE */
  705.              {
  706.               *alabel=0;
  707.               *hotkeys=0;
  708.               lines=0;
  709.               strcpy(d,b);
  710.               b=NULL;
  711.               c[0]=atoi(strtok(d," ,"));
  712.               for(x=1;x<=4;)
  713.                {
  714.                   c[x]=atoi(cm=strtok('\0'," ,"));
  715.                 if (!cm && x!=4) goto inputerror;
  716.                 ++x;
  717.                }
  718.               assignvar(genin(c[0],c[1],c[2],c[3],c[4]),arg-'0');
  719.              break;
  720.              }
  721.  
  722.              else if (p=='F')  /* CHECK EXISTENCE OF FILE AND GET NAME */
  723.                                /* (FINDFIRST) (U=Upload Path,          */
  724.                                /*  D=Download Path, N=No Path          */
  725.               {
  726.                a=toupper(*b);
  727.                b++;
  728.                stripcr(b);
  729.                if (a=='U') sprintf(c,"%s%s",fboard.upath,variable[arg-'0']);
  730.                else if (a=='D') sprintf(c,"%s%s",fboard.dpath,variable[arg-'0']);
  731.                else strcpy(c,variable[arg-'0']);
  732.                if (!findfirst(c,&f1,0)) {
  733.                     assignvar(f1.ff_name,arg-'0');
  734.                     level=0;
  735.                }
  736.                else level=1;
  737.                break;
  738.               }
  739.  
  740.              else if (p=='f') { /* FINDNEXT FILE AND GET NAME */
  741.                if (!findnext(&f1)) {
  742.                     assignvar(f1.ff_name,arg-'0');
  743.                     level=0;
  744.                }
  745.                else level=1;
  746.                break;
  747.              }
  748.              else if (p=='D') { /* Validate batch file d/l string */
  749.                                 /* level=1 no match level=2 not enuf time */
  750.                 ulong temp2;
  751.  
  752.                 stripcr(b);
  753.                 nofiles=0;
  754.                 level=0;
  755.                 strcpy(c,variable[arg-'0']);
  756.                 totalbytes=check_dls(c,&nofiles,1);
  757.                 if (!secl || !totalbytes) {
  758.                     level=1;
  759.                     break;
  760.                 }
  761.                 temp2=transfer_time(totalbytes,75);
  762.                 if (temp2>=(ulong)((ulong)timelimit-(getxbbstime()/60))) level=2;
  763.                 break;
  764.              }
  765.              else if (p=='+') { /* ADD ONE TO TIME STAMP OF FILE IN VAR */
  766.                 add_one(variable[arg-'0']);
  767.                 break;
  768.              }
  769.              else if (p=='C')  { /* COMPARE A VARIABLE    */
  770.                                  /* ! branch if not equal */
  771.                                  /* = branch if equal)    */
  772.                a=*b;
  773.                b++;
  774.                if (eof(handle)) {
  775.                   cclose(handle);
  776.                   goto commanderror;
  777.                }
  778.                strcpy(d,b);
  779.                stripcr(d);
  780.                b=fgetsx(str, 396, handle);
  781.                if (b==NULL) {
  782.                     cclose(handle);
  783.                     goto commanderror;
  784.                }
  785.                if (a=='!') {
  786.                    if (strcmp(d,variable[arg-'0'])!=0) goto seeklabel2;
  787.                }
  788.                else if (!strcmp(d,variable[arg-'0'])) goto seeklabel2;
  789.                b=NULL;
  790.                break;
  791.               }
  792.               else if(p=='c')  /* COPY ONE VARIABLE TO ANOTHER */
  793.                                /* source c dest                */
  794.                   {
  795.                     a=*b-'0';
  796.                     b++;
  797.                     assignvar(variable[arg-'0'],a);
  798.                     break;
  799.                   }
  800.               else if(p=='t')  /* Test variable as a number      */
  801.                                /* Set ERRORLEVEL if not in range */
  802.                   {
  803.                     level=0;
  804.                     b=strtok(b," ");
  805.                     if(*b=='e') {
  806.                         b++;
  807.                         secl=lastlevel[*b-'0'];
  808.                     }
  809.                     else secl=(word)atol(b);
  810.                     if (secl>(word)atol(variable[arg-'0'])) level=1;
  811.                     b=strtok(0," ");
  812.                     if(*b=='e') {
  813.                         b++;
  814.                         secl=lastlevel[*b-'0'];
  815.                     }
  816.                     else secl=(word)atol(b);
  817.                     if (secl<(word)atol(variable[arg-'0'])) level=1;
  818.                     b=NULL;
  819.                     break;
  820.                   }
  821.               else if (p=='T') { /* Do ON variable-as-# GOTO */
  822.                     b=strtok(b,",");
  823.                     for (x=0;x<(char)atoi(variable[arg-'0']);x++) {
  824.                         b=strtok(0,",\n");
  825.                     }
  826.                     if (b==NULL) {
  827.                         if (conf.debug) say_prompt(256);
  828.                         break;
  829.                     }
  830.                     strcpy(label,b);
  831.                     b=NULL;
  832.                     goto seeklabel;
  833.                }
  834.                else if (p=='E') {    /* Events */
  835.                     event[arg-'0'].secsleft=(ulong)atol(strtok(b,", "));
  836.                     b=strtok(0," \n,");
  837.                     b[12]=0;
  838.                     strcpy(event[arg-'0'].filename,b);
  839.                     if(conf.debug) gprintf(LOCALONLY,"\n\04Event #%hu @ %lu secs will read %s\n",arg-'0',event[arg-'0'].secsleft,event[arg-'0'].filename);
  840.                     b=NULL;
  841.                     break;
  842.                }
  843.                else if (p=='S' || p=='Z') {    /* Partial compare or INSTR */
  844.                     strcpy(d,b);            /* S is part comp, Z is instr */
  845.                     b=fgetsx(str, 396, handle);
  846.                     if (b==NULL) {
  847.                         cclose(handle);
  848.                         goto commanderror;
  849.                     }
  850.                     stripcr(d);
  851.                     if (p=='S') {
  852.                         if (!strncmp(d,variable[arg-'0'],strlen(d))) goto seeklabel2;
  853.                     }
  854.                     else {
  855.                         if (cm=strstr(variable[arg-'0'],d)) {
  856.                             level=(word)((int)cm-(int)variable[arg-'0'])+1;
  857.                             goto seeklabel2;
  858.                         }
  859.                     }
  860.                     break;
  861.                }
  862.                else if (p=='i') {  /* Do INSTR for vars */
  863.                     a=*b-'0';
  864.                     b++;
  865.                     if (a<0 || a>9) break;
  866.                     level=0;
  867.                     if (cm=strstr(variable[arg-'0'],variable[a])) {
  868.                         level=(word)((int)cm-(int)variable[arg-'0'])+1;
  869.                         goto seeklabel2;
  870.                     }
  871.                     b=NULL;
  872.                     break;
  873.                }
  874.                else if (p=='e') {  /* Get saved errorlevel */
  875.                     a=*b-'0';
  876.                     b++;
  877.                     if(a<0 || a>9) break;
  878.                     sprintf(variable[arg-'0'],"%u",lastlevel[a]);
  879.                     break;
  880.                }
  881.                else if (p=='d') {  /* Convert and print */
  882.                     printm(convertstring(variable[arg-'0']));
  883.                     break;
  884.                }
  885.             else b--;
  886.             break;
  887.  
  888.               case '+':           /* (CHANGE CURRENT FILENAME) AND RESTART */
  889.                 stripcr(b);
  890.                 if (strlen(b)) strcpy(filename,b);
  891.                 else strcpy(filename,file);
  892.                 b=NULL;
  893.                 cclose(handle);
  894.                 goto restart;
  895.  
  896.               case 'x':           /* LOGOFF */
  897.                safe=0;
  898.                cclose(handle);
  899.                fossil(FLUSHOUT,0);
  900.                if (*b>'0') baud=0;
  901.                fossil(DTR,DOWN);
  902.                baud=0;
  903.                leaving++;
  904.                logoff();
  905.                userno=0;
  906.                if(*b<'2') exit(254);
  907.  
  908.               case 'Q':           /* QUERY USERLIST */
  909.                userlist((word)atoi(b=strtok(b," ")));
  910.                b++;
  911.                break;
  912.  
  913.               case 'R':           /* RESTART AT LABEL */
  914.                strcpy(label,b);
  915.                lseek(handle,0L,SEEK_SET);
  916.                goto seeklabel;
  917.  
  918.               case '\x1b':        /* ANSI IF THEY GOT IT */
  919.                if(!user.graphics) b=NULL;
  920.               continue;
  921.  
  922.               case 'P':           /* PAUSE # SECONDS */
  923.                fossil(PURGEOUT,0);
  924.                sleep(atoi(b));
  925.                lines=0;
  926.                b=strchr(b,' ');
  927.               break;
  928.  
  929.               case 'a':           /* ABORT ON OR OFF */
  930.                abort=(char)atoi(b++);
  931.                break;
  932.  
  933.               case 'p':           /* PAUSE ON OR OFF */
  934.                pause=(char)atoi(b++);
  935.                tempause=1 - pause;
  936.                break;
  937.  
  938.               case 'Y':           /* DISABLE COMMANDS */
  939.                imbed=0;
  940.                break;
  941.  
  942.               case 'v':           /* CHANGE USER PARAMS */
  943.                 a=*b;
  944.                 b++;
  945.                 if(*b=='e') {
  946.                    secl=lastlevel[b[1]-'0'];
  947.                 }
  948.                 else secl=(word)atol(b);
  949.                 lines=0;
  950.                 if(change_parm(a,secl,f1.ff_fsize,totalbytes,nofiles,b)) b=NULL;
  951.                break;
  952.  
  953.               case 'h':           /* HALT UNTIL [Enter] HIT */
  954.                hitreturn();
  955.                 break;
  956.  
  957.               case 'S':              /* BRANCH ON SEC LEVELS */
  958.                   a=*b;              /*  </>  */
  959.                   b++;
  960.                   arg=b[0]-'0';       /* Sec#  */
  961.                   b++;
  962.                   if(*b=='e') secl=lastlevel[b[1]-'0'];
  963.                   else secl=(word)atoi(b);      /* Level */
  964.                   b=strchr(b,'l');
  965.                   if (b==NULL) break;
  966.                      strcpy(label,b);
  967.                   b=NULL;
  968.                    if (a=='<')
  969.                      {
  970.                       if (secl>user.stat[arg]) goto seeklabel;
  971.                      }
  972.                    else if (secl<user.stat[arg]) goto seeklabel;
  973.               break;
  974.  
  975.             case 'y':     /* SYSTEM PARAMETERS */
  976.                lines=0;
  977.                a=*b;
  978.                b++;
  979.                if(system_parms (a,*b)) b++;
  980.               break;
  981.  
  982.           case 'f':  /* Do raw dir, readany, readnew, filesbbs, readtext, etc. */
  983.            a=*b;
  984.            b++;
  985.             stripcr(b);
  986.             switch (a) {
  987.              case 'f':           /* FILES.BBS-style read (filename,type (0=down
  988.                                  1=up 2=new 4=new 8=asktodl 128=limitarea)) */
  989.                a=atoi(b);
  990.                strtok(b," ,");
  991.                b=strtok(0," ,");
  992.                cm=strtok(0," ,");
  993.                if(!cm)cm=saydate(&user.lastdate);
  994.                if(*cm=='@') {
  995.                     strcpy(c,variable[cm[1]-'0']);
  996.                     cm=c;
  997.                }
  998.                pp=strtok(0," ,");
  999.                if(pp && *pp=='@') {
  1000.                     strcpy(d,variable[pp[1]-'0']);
  1001.                     pp=d;
  1002.                }
  1003.                level=0;
  1004.                level=filesbbs(b,a,cm,pp);
  1005.                b=NULL;
  1006.                break;
  1007.              case 'r':           /* Raw dir...type (0-2) and directory */
  1008.                a=atoi(b);
  1009.                strtok(b," ,");
  1010.                rawdir(strtok(0," ,"),a);
  1011.                b=NULL;
  1012.              break;
  1013.              case 'a':           /* Read any, directory, extension (or null) */
  1014.                cm=strtok(b," ,");
  1015.                if (cm[0]=='*') cm[0]=0;
  1016.                b=strtok(0," ,");
  1017.                readany(b,cm,(char)atoi(strtok(0," ,")));
  1018.                b=NULL;
  1019.                cm=NULL;
  1020.              break;
  1021.              case 'n':           /* Read new files */
  1022.                readnew(strtok(b," ,"),(char)atoi(strtok(0," ,")));
  1023.                b=NULL;
  1024.              break;
  1025.              case 'd': {         /* Output file description in f1 */
  1026.                     struct fdate {
  1027.                          bit day:   5;
  1028.                          bit month: 4;
  1029.                          bit year:  7;
  1030.                     };
  1031.                     union df {
  1032.                          struct fdate fd;
  1033.                          int x;
  1034.                     } fdf;
  1035.                secl=baud;
  1036.                if (!secl) secl=1200;
  1037.                markedplace=(long)((((f1.ff_fsize)/secl)*1000)/80);
  1038.                fdf.x=f1.ff_fdate;
  1039.                gprintf(0,"%-12s (%lu bytes) %02u/%02u/%02u  %d mins %d secs @ %u baud\n",f1.ff_name,f1.ff_fsize,fdf.fd.month,fdf.fd.day,fdf.fd.year+80,(int)markedplace/60,(int)markedplace%60,secl);
  1040.                break;
  1041.              }
  1042.              case 'D':  {        /* Branch if drivespace < arg */
  1043.  
  1044.                     struct dfree drivefree;
  1045.  
  1046.                  a=*b;
  1047.                  b++;
  1048.                  getdfree((a-'@'),&drivefree);
  1049.                  strtok(b," ,");
  1050.                  b=strtok(0," ,");
  1051.                  if (b==NULL) break;
  1052.                  if ((long)drivefree.df_avail*(drivefree.df_bsec*drivefree.df_sclus)<atol(b)) {
  1053.                      b=strtok(0," ,");
  1054.                      if (b==NULL) break;
  1055.                      strcpy(label,b);
  1056.                      b=NULL;
  1057.                      goto seeklabel;
  1058.                  }
  1059.                  b=NULL;
  1060.                  break;
  1061.              }
  1062.              case 't':            /* Read straight text file */
  1063.                  if ((strlen(b)==1) && strchr("0123456789",*b)!=0) readtext (variable[*b-'0']);
  1064.                  else readtext (b);
  1065.                  b=NULL;
  1066.              break;
  1067.            }
  1068.            break;
  1069.  
  1070.           case 'F':      /* Set up FILE area */
  1071.            setup_file(b);
  1072.            b=NULL;
  1073.           break;
  1074.  
  1075.           case 'M':      /* Set up MESSAGE area */
  1076.            setup_msg(b);
  1077.            b=NULL;
  1078.           break;
  1079.  
  1080.           case 'X':         /* Write exit files */
  1081.            b=write_exit(b);
  1082.            break;
  1083.  
  1084.           case 'e':    /* ERRORLEVEL BRANCHING     */
  1085.                        /* < branch if <            */
  1086.                        /* > branch if >            */
  1087.                        /* 0 clear level            */
  1088.                        /* -- decrement level       */
  1089.                        /* ++ increment level       */
  1090.                        /* +#<#> inc saved level    */
  1091.                        /* -#<#> dec saved level    */
  1092.                        /* = set level              */
  1093.                        /* == branch if equal       */
  1094.                        /* s save level               */
  1095.                        /* r restore level           */
  1096.                        /* L level = lastread       */
  1097.                        /* l lastread = level       */
  1098.                        /* S put level in user var  */
  1099.                        /* V put user var in level  */
  1100.                        /* ~ not level              */
  1101.                        /* t time                   */
  1102.                        /* /+-*%|& level               */
  1103.                        /* U Upload K               */
  1104.                        /* u Upload #               */
  1105.                        /* D Dload K                   */
  1106.                        /* d Dload #                   */
  1107.                        /* K Dload K today           */
  1108.                        /* k Uload K today           */
  1109.                        /* E Last exit time           */
  1110.                        /* n Number calls           */
  1111.                        /* R Random number           */
  1112.                        /* F level = user.attr2     */
  1113.                        /* f user.attr2 = level     */
  1114.                        /* O level = tempuserno     */
  1115.                        /* o level = scroll lock    */
  1116.                        /* e>0 branch on any elevel */
  1117.                        /* @# level = strlen(var#)  */
  1118.                        /* ? Last prompt #           */
  1119.                        /* P # posts (as a word)    */
  1120.                        /* p level = #chat pages    */
  1121.                        /* a level = lastmsgarea    */
  1122.                        /* m level = #msgs in curr  */
  1123.                        /* M min write accs = level */
  1124.                        /* c leech% = level         */
  1125.              a=*b;
  1126.              b++;
  1127.              if (a=='0') level=0;
  1128.              else if (a=='-' && *b=='-') {
  1129.                 level--;
  1130.                 b++;
  1131.              }
  1132.              else if (a=='+' && *b=='+') {
  1133.                 level++;
  1134.                 b++;
  1135.              }
  1136.              else if((a=='+' || a=='-') && *b=='#') {
  1137.                 b++;
  1138.                 if(isdigit(*b)) {
  1139.                     if(a=='+') lastlevel[*b-'0']++;
  1140.                     else lastlevel[*b-'0']--;
  1141.                     b++;
  1142.                 }
  1143.             }
  1144.              else if (a=='@') {
  1145.                  level=strlen(variable[*b-'0']);
  1146.                  b++;
  1147.              }
  1148.              else if (a=='?') level=lastprompt;
  1149.              else if (a=='~') level=(~level);
  1150.              else if (a=='n') level=(word)user.times;
  1151.              else if (a=='t') level=(word)(getxbbstime()/60L);
  1152.              else if (a=='D') level=(word)user.downk;
  1153.              else if (a=='d') level=(word)user.downno;
  1154.              else if (a=='U') level=(word)user.upk;
  1155.              else if (a=='u') level=(word)user.upno;
  1156.              else if (a=='K') level=(word)user.dktoday;
  1157.              else if (a=='k') level=(word)user.uktoday;
  1158.              else if (a=='R') level=(word)random(32767);
  1159.              else if (a=='E') level=(word)lastexittime;
  1160.              else if (a=='L') level=(word)lastread[mboard.number-1];
  1161.              else if (a=='l') lastread[mboard.number-1]=(word)level;
  1162.              else if (a=='F') level=user.attr2;
  1163.              else if (a=='f') user.attr2=level;
  1164.              else if (a=='P') level=(word)user.posts;
  1165.              else if (a=='p') level=(word)pages;
  1166.              else if (a=='a') level=(word)user.lastmsgarea;
  1167.              else if (a=='O') level=tempuserno;
  1168.              else if (a=='o') level=chk_scroll_lock();
  1169.              else if (a=='M') mboard.minwrite=level;
  1170.              else if (a=='c') fboard.leechpercent=level;
  1171.              else if (a=='m') {
  1172.  
  1173.                 struct ffblk f;
  1174.                 char s[133];
  1175.  
  1176.                 sprintf(s,"%sXDATA.%03x",messpath,mboard.number);
  1177.                 if(findfirst(s,&f,0)) level=0;
  1178.                 else {
  1179.                     level=(word)(f.ff_fsize/(long)sizeof(struct _xmsg));
  1180.                 }
  1181.                 break;
  1182.              }
  1183.              else if (a=='S') {
  1184.                 a=*b-'0';
  1185.                 b++;
  1186.                 if(a<10)user.numvars[a]=level;
  1187.                 break;
  1188.              }
  1189.              else if (a=='V') {
  1190.                 a=*b-'0';
  1191.                 b++;
  1192.                 if(a<10)level=user.numvars[a];
  1193.                 break;
  1194.              }
  1195.              else if (a=='s') {
  1196.                 a=*b-'0';
  1197.                 b++;
  1198.                 lastlevel[a]=level;
  1199.                 break;
  1200.              }
  1201.              else if (a=='r') {
  1202.                 a=*b-'0';
  1203.                 b++;
  1204.                 level=lastlevel[a];
  1205.                 break;
  1206.              }
  1207.              else if (a=='=') {
  1208.               if(*b=='=') {
  1209.                 b++;
  1210.                 goto CompareLevel;
  1211.               }
  1212.               else {
  1213.                 if (*b=='@') {
  1214.                     b++;
  1215.                     level=(word)atol(variable[*b-'0']);
  1216.                 }
  1217.                 else if (*b=='$') {
  1218.                     b++;
  1219.                     stripcr(b);
  1220.                     level=(word)atol(lookup_var(b));
  1221.                 }
  1222.                 else {
  1223.                     level=(word)atol(b);
  1224.                 }
  1225.                 b=NULL;
  1226.               }
  1227.                 break;
  1228.              }
  1229.              else if (a=='+' || a=='-' || a=='|' || a=='/' || a=='*' || a=='%' || a=='&' || a=='^') {
  1230.                 if(*b=='@') {
  1231.                     b++;
  1232.                     secl=(word)atol(variable[*b-'0']);
  1233.                 }
  1234.                 else if (*b=='e') {
  1235.                     b++;
  1236.                     secl=lastlevel[*b-'0'];
  1237.                 }
  1238.                 else secl=(word)atol(b);
  1239.                 b=NULL;
  1240.                 switch ((int)a) {
  1241.                     case '+':   level += secl;
  1242.                                 break;
  1243.                     case '-':   level -= secl;
  1244.                                 break;
  1245.                     case '/':   level /= secl;
  1246.                                 break;
  1247.                     case '*':   level *= secl;
  1248.                                 break;
  1249.                     case '%':   level %= secl;
  1250.                                 break;
  1251.                     case '|':   level |= secl;
  1252.                                 break;
  1253.                     case '&':   level &= secl;
  1254.                                 break;
  1255.                     case '^':   level ^= secl;
  1256.                                 break;
  1257.                 }
  1258.                 break;
  1259.              }
  1260.              else {
  1261. CompareLevel:
  1262.                 if(*b=='e') {
  1263.                     b++;
  1264.                     secl=lastlevel[*b-'0'];
  1265.                     strtok(b," ,");
  1266.                 }
  1267.                 else secl=(word)atol(strtok(b," ,"));
  1268.                 strcpy(label,strtok(0," ,"));
  1269.                 b=NULL;
  1270.                 if (a=='<') {
  1271.                     if (secl>level) goto seeklabel;
  1272.                 }
  1273.                 else if (a=='>') {
  1274.                     if (secl<level) goto seeklabel;
  1275.                 }
  1276.                 else if(secl==level) goto seeklabel;
  1277.              }
  1278.            break;
  1279.  
  1280.            case 'L':       /* BRANCH ON USER PARAMS */
  1281.             a=*b;
  1282.             b++;
  1283.               switch (a) {
  1284.                 case 'F':
  1285.                  a=(char)atoi(strtok(b," ,"));
  1286.                  strcpy(label,strtok(0," ,"));
  1287.                  b=NULL;
  1288.                  if (a<1 || a>16) break;
  1289.                  secl=1;
  1290.                  secl=secl<<(--a);
  1291.                  if (user.attr2 & secl) goto seeklabel;
  1292.                  break;
  1293.                 case 'f':
  1294.                  a=(char)atoi(strtok(b," ,"));
  1295.                  strcpy(label,strtok(0," ,"));
  1296.                  if (a<1 || a>3) break;
  1297.                  switch (a) {
  1298.                     case 1: if (user.gen1) goto seeklabel;
  1299.                             break;
  1300.                     case 2: if (user.gen2) goto seeklabel;
  1301.                             break;
  1302.                     case 3: if (user.gen3) goto seeklabel;
  1303.                             break;
  1304.                  }
  1305.                  break;
  1306.                 case 's':
  1307.                  if(user.scrnclr) goto seeklabel2;
  1308.                  break;
  1309.                 case 'g':
  1310.                  if(user.fullscreen) goto seeklabel2;
  1311.                  break;
  1312.                 case 'A':
  1313.                  if (!user.ansimenus && user.graphics) goto seeklabel2;
  1314.                  break;
  1315.                 case 'm':
  1316.                  if(user.more) goto seeklabel2;
  1317.                  break;
  1318.                 case 'M':
  1319.                  if (user.arq) goto seeklabel2;
  1320.                  break;
  1321.                 case 'T':
  1322.                  if (user.twit) goto seeklabel2;
  1323.                  break;
  1324.                 case 'G':
  1325.                  if (user.graphics) goto seeklabel2;
  1326.                  break;
  1327.                 case 'N':
  1328.                  if (user.nokill) goto seeklabel2;
  1329.                  break;
  1330.                 case 'S':
  1331.                  if (user.commodore) goto seeklabel2;
  1332.                  break;
  1333.                 case 'E':
  1334.                  if (user.expert) goto seeklabel2;
  1335.                  break;
  1336.                 case 'H':
  1337.                  if (user.ignorehrs) goto seeklabel2;
  1338.                  break;
  1339.                 case 'D':
  1340.                  if (user.deleted) goto seeklabel2;
  1341.                  break;
  1342.                 case 'R':
  1343.                  if (user.ignorerat) goto seeklabel2;
  1344.                  break;
  1345.                 case 'n':
  1346.                 case 'h':
  1347.                  strcpy(c,strtok(b,","));
  1348.                  strcpy(label,strtok(0," ,"));
  1349.                  b=NULL;
  1350.                  if (a=='n') {
  1351.                     if (!stricmp(user.name,c)) goto seeklabel;
  1352.                  }
  1353.                  else if (!stricmp(user.handle,c)) goto seeklabel;
  1354.                  break;
  1355.              }
  1356.             arg=*b;
  1357.             b++;
  1358.             if(*b=='e') {
  1359.                 b++;
  1360.                 secl=lastlevel[*b-'0'];
  1361.                 strtok(b," ,");
  1362.             }
  1363.             else secl=(word)atol(strtok(b," ,"));
  1364.             strcpy(label,strtok(0," ,"));
  1365.             b=NULL;
  1366.             switch (a) {
  1367.                 case 'C':    /* COMPUTER TYPE */
  1368.                  if (arg=='!') {
  1369.                      if (user.comptype!=(byte)secl) goto seeklabel;
  1370.                  }
  1371.                  else if (user.comptype==(byte)secl) goto seeklabel;
  1372.                  break;
  1373.                 case 'k':    /* U/D KBYTE RATIO */
  1374.                  if (user.downno<(word)conf.startat) break;
  1375.                  if (arg=='<') {
  1376.                     if ((word)((user.downk+1)/(user.upk+1))<secl) goto seeklabel;
  1377.                  }
  1378.                  else if ((word)((user.downk+1)/(user.upk+1))>secl) goto seeklabel;
  1379.                  break;
  1380.                 case '#':    /* U/D # RATIO */
  1381.                  if (user.downno<(word)conf.startat) break;
  1382.                  if (arg=='<') {
  1383.                      if ((user.downno+1)/(user.upno+1)<secl) goto seeklabel;
  1384.                  }
  1385.                  else if ((user.downno+1)/(user.upno+1)>secl) goto seeklabel;
  1386.                  break;
  1387.                 case 'b': {  /* BAUD RATE */
  1388.  
  1389.                    word temp;
  1390.  
  1391.                  temp=baud;
  1392.                  if (!temp) temp=9600;
  1393.                  if (arg=='<') {
  1394.                     if (temp<secl) goto seeklabel;
  1395.                  }
  1396.                  else if (temp>secl) goto seeklabel;
  1397.                  break;
  1398.                 }
  1399.                 case 'v':    /* VIOLATIONS */
  1400.                  if (arg=='<') {
  1401.                     if (user.violations<(char)secl) goto seeklabel;
  1402.                  }
  1403.                  else if (user.violations>(char)secl) goto seeklabel;
  1404.                  break;
  1405.                 case 'a':  /* AGE */
  1406.                  if (arg=='<') {
  1407.                     if (age<(char)secl) goto seeklabel;
  1408.                  }
  1409.                  else if (age>(char)secl) goto seeklabel;
  1410.                  break;
  1411.                 case 'l':  /* LENGTH */
  1412.                  if (arg=='<') {
  1413.                     if (user.length<(char)secl) goto seeklabel;
  1414.                  }
  1415.                  else if (user.length>(char)secl) goto seeklabel;
  1416.                  break;
  1417.                 case 'w':  /* WIDTH */
  1418.                  if (arg=='<') {
  1419.                     if (user.width<(char)secl) goto seeklabel;
  1420.                  }
  1421.                  else if (user.width>(char)secl) goto seeklabel;
  1422.                  break;
  1423.                 case 'u':  /* Upload K today */
  1424.                  if (arg=='<') {
  1425.                     if (user.uktoday<secl) goto seeklabel;
  1426.                   }
  1427.                   else if (user.uktoday>secl) goto seeklabel;
  1428.                   break;
  1429.                 case 'd':  /* Download K today */
  1430.                  if (arg=='<') {
  1431.                     if (user.dktoday<secl) goto seeklabel;
  1432.                  }
  1433.                  else if (user.dktoday>secl) goto seeklabel;
  1434.                  break;
  1435.             }
  1436.             break;
  1437.  
  1438.              case 'c':     /* CHAT REQUEST */
  1439.               do_request(b);
  1440.              break;
  1441.  
  1442.              case '~':     /* CLEAR SCREEN */
  1443.               cls();
  1444.              break;
  1445.  
  1446.              case 'r':     /* READ A MESSAGE */
  1447.               a=(char)atoi(b);
  1448.               if(*b=='e') {
  1449.                 b++;
  1450.                 a=(char)lastlevel[*b-'0'];
  1451.               }
  1452.               strtok(b," ,");
  1453.               b=strtok(0," ,");
  1454.               if(*b=='@') {
  1455.                 b++;
  1456.                 readamessage(a,(word)atol(variable[*b-'0']));
  1457.               }
  1458.               else if (*b=='e') {
  1459.                 b++;
  1460.                 readamessage(a,lastlevel[*b-'0']);
  1461.               }
  1462.               else readamessage(a,(word)atol(b));
  1463.               b=NULL;
  1464.              break;
  1465.  
  1466.              case '@':        /* ASSIGN SELECTED READ VARS */
  1467.                 a=*b-'0';
  1468.                 b++;
  1469.                 stripcr(b);
  1470.                 switch((int)a) {
  1471.                     case 0:  *msgfrom=0;
  1472.                              *msgto=0;
  1473.                              *msgsubj=0;
  1474.                              *msgbody=0;
  1475.                              break;
  1476.                     case 1:  if ((*b-'0')<0 || (*b-'0')>9) {
  1477.                                 strncpy(msgfrom,b,36);
  1478.                                 msgfrom[35]=0;
  1479.                              }
  1480.                              else {
  1481.                                 strncpy(msgfrom,variable[*b-'0'],36);
  1482.                                 msgfrom[35]=0;
  1483.                              }
  1484.                              break;
  1485.                     case 3:  if ((*b-'0')<0 || (*b-'0')>9) {
  1486.                                 msgsubj[63]=0;
  1487.                              }
  1488.                              else {
  1489.                                 strncpy(msgsubj,variable[*b-'0'],64);
  1490.                                 msgsubj[63]=0;
  1491.                              }
  1492.                              break;
  1493.                     case 4:  if ((*b-'0')<0 || (*b-'0')>9) {
  1494.                                 strncpy(msgbody,b,80);
  1495.                                 msgto[80]=0;
  1496.                              }
  1497.                              else {
  1498.                                 strncpy(msgbody,variable[*b-'0'],80);
  1499.                                 msgbody[80]=0;
  1500.                              }
  1501.                              break;
  1502.                     case 2:  if ((*b-'0')<0 || (*b-'0')>9) {
  1503.                                 strncpy(msgto,b,36);
  1504.                                 msgto[35]=0;
  1505.                              }
  1506.                              else {
  1507.                                 strncpy(msgto,variable[*b-'0'],36);
  1508.                                 msgto[35]=0;
  1509.                              }
  1510.                              break;
  1511.                 }
  1512.                 b=NULL;
  1513.                 break;
  1514.  
  1515.              case 'i': {    /* File input to vars */
  1516.                 a=*(b++);
  1517.                 switch ((int)a) {
  1518.                     case 'i':   if(inputhandle==-1) {
  1519.                                     level=1;
  1520.                                     b++;
  1521.                                     break;
  1522.                                 }
  1523.                                 if(eof(inputhandle)) {
  1524.                                     level=1;
  1525.                                     b++;
  1526.                                     break;
  1527.                                 }
  1528.                                 if(fgetsx(variable[*b-'0'],80,inputhandle)==NULL) {
  1529.                                     level=1;
  1530.                                     b++;
  1531.                                     break;
  1532.                                 }
  1533.                                 variable[*b-'0'][79]=0;
  1534.                                 stripcr(variable[*b-'0']);
  1535.                                 b++;
  1536.                                 level=0;
  1537.                                 break;
  1538.                     case 'c':   if(*b=='i') {
  1539.                                         cclose(inputhandle);
  1540.                                         inputhandle=(-1);
  1541.                                 }
  1542.                                 else {
  1543.                                         cclose(outputhandle);
  1544.                                         outputhandle=(-1);
  1545.                                 }
  1546.                                 b++;
  1547.                                 break;
  1548.                     case 'a':
  1549.                     case 'm':   if(outputhandle!=-1) cclose(outputhandle);
  1550.                                 stripcr(b);
  1551.                                 if(*b=='@') {
  1552.                                     b++;
  1553.                                     arg=*b;
  1554.                                     b=variable[arg-'0'];
  1555.                                 }
  1556.                                 if(a=='m')outputhandle=ccreat(b,S_IWRITE);
  1557.                                 else outputhandle=oopen(b,O_RDWR | O_APPEND | O_BINARY | O_DENYWRITE);
  1558.                                 if(outputhandle==-1) level=1;
  1559.                                 else level=0;
  1560.                                 b=NULL;
  1561.                                 if(a=='a' && !level) lseek(outputhandle,0L,SEEK_END);
  1562.                                 break;
  1563.                     case 'w':   if(outputhandle==-1) {
  1564.                                     level=1;
  1565.                                     b=NULL;
  1566.                                     break;
  1567.                                 }
  1568.                                 if (*b=='@') {
  1569.                                     b++;
  1570.                                     if (_write(outputhandle,variable[*b-'0'],strlen(variable[*b-'0']))==-1) level=1;
  1571.                                     else {
  1572.                                         level=0;
  1573.                                         _write(outputhandle,"\r\n",2);
  1574.                                     }
  1575.                                 }
  1576.                                 else {
  1577.                                     stripcr(b);
  1578.                                     if(*b) if(_write(outputhandle,b,strlen(b))==-1) level=1;
  1579.                                     else {
  1580.                                         level=0;
  1581.                                         _write(outputhandle,"\r\n",2);
  1582.                                     }
  1583.                                 }
  1584.                                 b=NULL;
  1585.                                 break;
  1586.                     case 'o':   if(inputhandle!=-1) cclose(inputhandle);
  1587.                                 stripcr(b);
  1588.                                 if(*b=='@') {
  1589.                                     b++;
  1590.                                     arg=*b;
  1591.                                     b=variable[arg-'0'];
  1592.                                 }
  1593.                                 inputhandle=oopen(b,O_RDONLY | O_BINARY | O_DENYNONE);
  1594.                                 if(inputhandle==-1) level=1;
  1595.                                 else level=0;
  1596.                                 b=NULL;
  1597.                                 break;
  1598.                     case 'r':   if(inputhandle!=-1) level=(word)lseek(inputhandle,0L,SEEK_SET);
  1599.                                 else level=1;
  1600.                                 break;
  1601.                 }
  1602.                 break;
  1603.              }
  1604.  
  1605.              case 'I': {   /* SCAN NODELIST */
  1606.  
  1607.               struct nodeidx nid;
  1608.               char temp[6];
  1609.  
  1610.                   a=*b-'0';
  1611.                   b++;
  1612.                   if(!*b || *b=='\n') {
  1613.                       say_prompt(418);
  1614.                       helpnum=557;
  1615.                       strcpy(temp,genin(5,0,1,0,NUM));
  1616.                       helpnum=0;
  1617.                       if (!atoi(temp)) {
  1618.                           b=NULL;
  1619.                           break;
  1620.                       }
  1621.                       nid.zone=(word)atol(temp);
  1622.                       say_prompt(419);
  1623.                       helpnum=558;
  1624.                       strcpy(temp,genin(5,0,1,0,NUM));
  1625.                       helpnum=0;
  1626.                       if (!atoi(temp)) {
  1627.                          b=NULL;
  1628.                          break;
  1629.                       }
  1630.                       nid.net=(word)atol(temp);
  1631.                       if (a) {
  1632.                           say_prompt(420);
  1633.                           helpnum=559;
  1634.                           strcpy(temp,genin(5,0,1,0,NUM));
  1635.                           helpnum=0;
  1636.                           if (!atoi(temp)) {
  1637.                             b=NULL;
  1638.                             break;
  1639.                           }
  1640.                           nid.node=(word)atol(temp);
  1641.                       }
  1642.                       else nid.node=0;
  1643.                   }
  1644.                   else {
  1645.                     if(*b=='@') {
  1646.                         b++;
  1647.                         arg=*b;
  1648.                         b=variable[arg-'0'];
  1649.                     }
  1650.                     strcpy(c,b);
  1651.                     nid.zone=(word)atol(strtok(c,":"));
  1652.                     nid.net=(word)atol(strtok(0,"/"));
  1653.                     nid.node=(word)atol(strtok(0,"\n"));
  1654.                   }
  1655.                   nid.type=255;
  1656.                   if (nodelist(&nid,1)==(-1)){
  1657.                     if (!a) say_prompt(421);
  1658.                     b=NULL;
  1659.                     break;
  1660.                   }
  1661.                   nid.type=0;
  1662.                   if (!a) {
  1663.                     lines=3;
  1664.                     pauser=1;
  1665.                     while(nodelist(&nid,2)>(-1)) if (toupper(inkey())=='S') break;
  1666.                     pauser=tempause;
  1667.                   }
  1668.                   b=NULL;
  1669.                   break;
  1670.               }
  1671.  
  1672.              case 'w':     /* WRITE A MESSAGE */
  1673.                 if(user.stat[0]<mboard.minwrite) {
  1674.                     say_prompt(591);
  1675.                     b=NULL;
  1676.                     break;
  1677.                 }
  1678.               tempsafe=safe;
  1679.               safe=0;
  1680.               a=(char)atoi(strtok(b," ,"));
  1681.               if (!a) {
  1682.                   arg=(char)atoi(strtok(0," ,"));
  1683.                   if (!(level=(word)askwrite(arg))) {
  1684.                     if (!(level=(word)writemessage(arg))) {
  1685.                         level=(word)makemessage(arg);
  1686.                     }
  1687.                   }
  1688.               }
  1689.               else if (a==1) {
  1690.                 if (!(level=(word)askwrite(atoi(strtok(0," ,"))))) {
  1691.                     writemessage((char)atoi(strtok(0," ,")));
  1692.                 }
  1693.               }
  1694.               else if (a==2) {
  1695.                 level=(word)askwrite(atoi(strtok(0," ,")));
  1696.               }
  1697.               else if (a==3) {
  1698.                 level=(word)makemessage(atoi(strtok(0," ,")));
  1699.               }
  1700.               safe=tempsafe;
  1701.               b=NULL;
  1702.              break;
  1703.  
  1704.  
  1705.              case '*':        /* Go to Bulls-mode */
  1706.                 stripcr(b);
  1707.                 b=strtok(b," ,");
  1708.                 if(*b=='@') b=variable[b[1]-'0'];
  1709.                 dobulls(b,(char)atoi(strtok(0," ,")));
  1710.                 b=NULL;
  1711.                 break;
  1712.  
  1713.              case '&':        /* Find file/msg areas in list files */
  1714.                  do_list(b);
  1715.                  b=NULL;
  1716.                 break;
  1717.  
  1718.              case 'A':      /* Add comment from text file to log */
  1719.               addtolog(convertstring(stripcr(b)));
  1720.               b=NULL;
  1721.               break;
  1722.  
  1723.              case 'z':      /* OUTPUT A QUOTE */
  1724.               do_quote(b);
  1725.               b=NULL;
  1726.              break;
  1727.  
  1728.              case '!':      /* TURN ON COM WATCHDOG */
  1729.               a=atoi(b);
  1730.               b=NULL;
  1731.               if ((baud) && (a>0)) {
  1732.                 update();
  1733.                 fossil(WATCHDOG,1);
  1734.                 say_prompt(13);
  1735.               }
  1736.               else {
  1737.                 fossil(WATCHDOG,0);
  1738.                 say_prompt(14);
  1739.               }
  1740.              break;
  1741.  
  1742.              case 's':     /* Get msg header of a msg# */
  1743.               if(*b=='@') {
  1744.                   b++;
  1745.                   level=(word)atol(variable[*b-'0']);
  1746.               }
  1747.               else if(*b=='e') {
  1748.                   b++;
  1749.                   level=lastlevel[*b-'0'];
  1750.               }
  1751.               else level=(word)atol(b);
  1752.               level=get_mess(level);
  1753.               b=NULL;
  1754.              break;
  1755.  
  1756.              case 'C':     /* Check MBoard Stats */
  1757.               a=*b;
  1758.               b++;
  1759.               if (!isdigit(a)) {
  1760.                 tellabout(0);
  1761.                 break;
  1762.               }
  1763.               secl=tellabout(a-'0');
  1764.               if (secl) goto seeklabel2;
  1765.               b=NULL;
  1766.               break;
  1767.  
  1768.              case 'k':        /* Stuff/clear macro buffer */
  1769.                 b=do_macro_buffer(b);
  1770.                 break;
  1771.  
  1772.  
  1773.              case 'N':      /* Msgarea readloop */
  1774.                 do_readloop(b);
  1775.                 b=NULL;
  1776.                 break;
  1777.  
  1778.  
  1779.              case 'K':     /* U/D STUFF */
  1780.                 a=*b;
  1781.                 b++;
  1782.                 b=stripcr(b);
  1783.                 switch (a) {
  1784.                     case 'u': upload("",0);     /* Upload any file   */
  1785.                                b=NULL;
  1786.                               break;
  1787.                     case 'V': strtok(b,",");
  1788.                               cm=strtok(0,"\n");
  1789.                               if(!*cm) cm="";
  1790.                               upload(var_trans(b),*cm);      /* Upload specific file */
  1791.                               b=NULL;
  1792.                               break;
  1793.                     case 'v': strtok(b," ,");   /* Upload variable name */
  1794.                               arg=0;
  1795.                               pp=strtok(0," \n");
  1796.                               if(*pp=='@'){
  1797.                                 p=pp[1];
  1798.                                 pp=variable[p-'0'];
  1799.                               }
  1800.                               upload(variable[(char)atoi(b)],pp[0]);
  1801.                               b=NULL;
  1802.                               break;
  1803.                     case 'c': if(isleech(fboard.leechpercent)) {
  1804.                                 say_prompt(598);
  1805.                                 b=NULL;
  1806.                                 break;
  1807.                               }
  1808.                     case 'd':                       /* D/L any file      */
  1809.                               askdl(NULL,0,NULL,0);
  1810.                               b=NULL;
  1811.                               break;
  1812.                     case 'C': if(isleech(fboard.leechpercent)) {
  1813.                                 say_prompt(598);
  1814.                                 b=NULL;
  1815.                                 break;
  1816.                               }
  1817.                     case 'D':                       /* D/L specific file */
  1818.                               b=strtok(var_trans(b)," ,");
  1819.                               arg=(char)atoi(strtok(0," ,"));
  1820.                               askdl(b,arg,strtok(0," ,"),0);
  1821.                               b=NULL;
  1822.                               break;
  1823.                                                     /* D/L variable name */
  1824.                     case 'k':
  1825.                               a=(char)atoi(strtok(b," ,"));
  1826.                               arg=(char)atoi(strtok(0," ,"));
  1827.                               cm=strtok(0," ,");
  1828.                               pp=strtok(0," \n");
  1829.                               if(!pp)pp="";
  1830.                               if(*pp=='@'){
  1831.                                 p=pp[1];
  1832.                                 pp=variable[p-'0'];
  1833.                               }
  1834.                               askdl(variable[a],arg,cm,pp[0]);
  1835.                               b=NULL;
  1836.                               break;
  1837.                     case 'K':                        /* Set d/l credits   */
  1838.                                                      /* for variable name */
  1839.                     case 'U': arg=atoi(b);           /* Add u/l credits   */
  1840.                                                      /* for variable name */
  1841.                               {
  1842.                                 struct protocol proto;
  1843.  
  1844.                                 proto.key=*b;
  1845.                                 proto.dszlog=0;
  1846.                                 proto.noname=0;
  1847.                                 strcpy(c,variable[arg]);
  1848.                                 if(a=='U')getentry(c,&proto);
  1849.                                 else check_dls(c,&level,2);
  1850.                               }
  1851.                               b=NULL;
  1852.                               break;
  1853.                     case 'a': user.uktoday=lastlevel[*b-'0'];
  1854.                               strcat(b,"\n");
  1855.                               b++;
  1856.                               break;
  1857.                     case 'A': user.dktoday=lastlevel[*b-'0'];
  1858.                               strcat(b,"\n");
  1859.                               b++;
  1860.                               break;
  1861.                     case 'l': arg=*b-'0';
  1862.                               stripcr(b++);
  1863.                               if(*b=='@') b=variable[b[1]-'0'];
  1864.                               if(!*b) find_filearea(say_prompt(446),"___",user.stat[arg]);
  1865.                               else find_filearea(b,"___",user.stat[arg]);
  1866.                               b=NULL;
  1867.                               break;
  1868.                     case 'n': arg=*b-'0';
  1869.                               stripcr(b++);
  1870.                               if(*b=='@') b=variable[b[1]-'0'];
  1871.                               if(!*b) next_filearea(say_prompt(446),user.stat[arg]);
  1872.                               else next_filearea(b,user.stat[arg]);
  1873.                               b=NULL;
  1874.                               break;
  1875.                     case 'N': b=NULL;
  1876.                               next_filearea(NULL,0);
  1877.                               break;
  1878.                     case 'm': stripcr(b);
  1879.                               if(*b=='@') b=variable[b[1]-'0'];
  1880.                               if(!*b) next_msgarea(say_prompt(486));
  1881.                               else next_msgarea(b);
  1882.                               b=NULL;
  1883.                               break;
  1884.                     case 'M': b=NULL;
  1885.                               next_msgarea(NULL);
  1886.                               break;
  1887.                 }
  1888.              break;
  1889.  
  1890.              case 'G':    /* Special ANSI Input */
  1891.                 do_special_ANSI_input(b);
  1892.                 b=NULL;
  1893.                 break;
  1894.  
  1895.              case '$':
  1896.                 a=*b-'0';
  1897.                 b++;
  1898.                 switch ((int)a) {
  1899.                     case 0:  strcpy(startfile,var_trans(b)); /* Reset gosub stacks and start a new file */
  1900.                              stripcr(startfile);
  1901.                              cclose(handle);
  1902.                              return 255;
  1903.                     case 1:  if(safe) {
  1904.                                  strcpy(startfile,var_trans(b)); /* Set startfile and longjmp (restart) */
  1905.                                  stripcr(startfile);
  1906.                                  cclose(handle);
  1907.                                  longjmp(envbuf,99);
  1908.                              }
  1909.                     case 2:  disablesub=(*b-'0');
  1910.                              b++;
  1911.                              break;
  1912.                     case 3:  disablejump=(*b-'0');
  1913.                              b++;
  1914.                 }
  1915.                 break;
  1916.  
  1917.              case '|':        /* Link to hypertext functions */
  1918.                 b=do_hyper(b);
  1919.                 break;
  1920.  
  1921.              case 'W':  /* Mark/Return to a place */
  1922.                 a=*b-'0';
  1923.                 b++;
  1924.                 arg=(char)atoi(var_trans(b));
  1925.                 if (arg>9) arg=0;
  1926.                 b=NULL;
  1927.                 if (!a) {
  1928.                      if (!markedspots[arg]) break;
  1929.                      lseek(handle,markedspots[arg],SEEK_SET);
  1930.                 }
  1931.                 else markedspots[arg]=tell(handle);
  1932.                 break;
  1933.  
  1934.             case '-':   /* Adjust security levels */
  1935.                 a=*b-'0';
  1936.                 b++;
  1937.                 secl=(word)atol(var_trans(b));
  1938.                 b=NULL;
  1939.                 if (a<10) user.stat[a]=secl;
  1940.                 break;
  1941.  
  1942.             case '_':    /* Tie-in to unused func for expansion by users */
  1943.                 user_func(b);
  1944.                 b=NULL;
  1945.                 break;
  1946.  
  1947.             case '\\':  /* Change Alternate Zone:Net/Node */
  1948.                 do_alt_addr(b);
  1949.                 b=NULL;
  1950.                 break;
  1951.  
  1952.             case ':':   /* Change message path temporarily */
  1953.                 change_msgpath(b);
  1954.                 b=NULL;
  1955.                 break;
  1956.  
  1957.             case '':   /* Turn "hot"/"cold" on/off or test cold */
  1958.                 if (*b=='0') user.cold=0;
  1959.                 else if (*b=='1') user.cold=1;
  1960.                 else level=(word)user.cold;
  1961.                 b++;
  1962.                 break;
  1963.  
  1964.             case '':    /* Emit if special (commodore) flag is set */
  1965.                 if (!user.commodore) b=NULL;
  1966.                 continue;
  1967.  
  1968.             case '':   /* Emit if high ASCII can be received */
  1969.                if(!user.hiok && !user.graphics) b=NULL;
  1970.                continue;
  1971.  
  1972.             case '':   /* Emit if ASCII only (no graphics at all) */
  1973.                if(user.graphics || user.hiok) b=NULL;
  1974.                continue;
  1975.  
  1976.             case '':   /* Emit if user.hiok (high ASCII) is on */
  1977.                if(!user.hiok) b=NULL;
  1978.                continue;
  1979.  
  1980.             case '':   /* Emit if arq flag is set */
  1981.                if(!user.arq) b=NULL;
  1982.                continue;
  1983.  
  1984.             case '':   /* Emit if genx flag is set */
  1985.                if(*b=='1') if(!user.gen1) b=NULL;
  1986.                if(*b=='2') if(!user.gen2) b=NULL;
  1987.                if(*b=='3') if(!user.gen3) b=NULL;
  1988.                if(b)b++;
  1989.                continue;
  1990.  
  1991.             case ' ':   /* Emit if expert flag is set */
  1992.                if(!user.expert) b=NULL;
  1993.                continue;
  1994.  
  1995.             case ' ':   /* Emit if twit flag is set */
  1996.                if(!user.twit) b=NULL;
  1997.                continue;
  1998.  
  1999.             case '':   /* Emit if flag a is set */
  2000.                a=(char)atoi(var_trans(b));
  2001.                pp=b;
  2002.                b=strchr(pp,',');
  2003.                if(b) {
  2004.                     b++;
  2005.                    if(a>0 && a<17) {
  2006.                         secl=1;
  2007.                         secl=secl<<(a-1);
  2008.                         if(!(user.attr2 & a)) b=NULL;
  2009.                    }
  2010.                }
  2011.                continue;
  2012.  
  2013.             case '':   /* Put variable into input stream as text */
  2014.                 strcpy(str,variable[*b-'0']);
  2015.                 b=str;
  2016.                 goto BreakIn;
  2017.  
  2018.  
  2019.             case '':   /* Display line locally only */
  2020.                 lprint(convertstring(--b));
  2021.                 b=NULL;
  2022.                 break;
  2023.  
  2024.             case '':   /* Convert line and display */
  2025.                 strncpy(str,convertstring(b),396);
  2026.                 str[395]=0;
  2027.                 b=str;
  2028.                 break;
  2029.  
  2030.             case '':   /* Set help # */
  2031.                 helpnum=(word)atol(var_trans(b));
  2032.                 b=NULL;
  2033.                 break;
  2034.  
  2035.             case '?':    /* Random branching */
  2036.                 arg=(char)random(*var_trans(b)-'0');
  2037.                 b++;
  2038.                 strtok(b,",");
  2039.                 while (arg) {
  2040.                     b=strtok(0,",");
  2041.                     arg--;
  2042.                 }
  2043.                 if(*b==',')b++;
  2044.                 goto seeklabel2;
  2045.  
  2046.             case 'g':    /* Assign to dlstr */
  2047.                 stripcr(b);
  2048.                 if(!*b) *dlstr=0;
  2049.                 else {
  2050.                     strncpy(dlstr,convertstring(var_trans(b)),80);
  2051.                     dlstr[79]=0;
  2052.                 }
  2053.                 break;
  2054.  
  2055.             case '/':    /* Keyqueue routines */
  2056.                 a=*b;
  2057.                 b++;
  2058.                 if(a=='c') {
  2059.                     strset(keyqueue,0);
  2060.                     keyptr=0;
  2061.                 }
  2062.                 else {
  2063.                     a-='0';
  2064.                     if(!keyptr && !*keyqueue) {
  2065.                         strset(variable[a],0);
  2066.                         lprint("\x4 Empty\n");
  2067.                         break;
  2068.                     }
  2069.                     arg=keyptr;
  2070.                     p=0;
  2071.                     while(keyqueue[arg] && arg<81) {
  2072.                         variable[a][p++]=keyqueue[arg++];
  2073.                         variable[a][p]=0;
  2074.                     }
  2075.                     if(keyptr) {
  2076.                         arg=0;
  2077.                         while(keyqueue[arg] && arg<keyptr && p<81) {
  2078.                             variable[a][p++]=keyqueue[arg++];
  2079.                             variable[a][p]=0;
  2080.                         }
  2081.                     }
  2082.                 }
  2083.                 break;
  2084.  
  2085.             case '=':   /* Assign msginfo */
  2086.                 stripcr(b);
  2087.                 strncpy(msginfo,var_trans(b),81);
  2088.                 msginfo[80]=0;
  2089.                 b=NULL;
  2090.                 break;
  2091.  
  2092.             case '\'':   /* ANSI pull-downs */
  2093.                 do_pulldowns(b,lastlevel);
  2094.                 b=NULL;
  2095.                 break;
  2096.  
  2097.             case '\"':   /* Clear from current line to end of screen */
  2098.                 a=(char)wherey();
  2099.                 for(p=a;p<(user.length+1);p++) {
  2100.                     if(p<24) printm("\x1b[K");
  2101.                     else mprint("\x1b[K");
  2102.                     if(p<23) printm("\n");
  2103.                     else mprint("\x1b[K");
  2104.                 }
  2105.                 if(user.length<23) {
  2106.                     for(p=user.length;p<24;p++) {
  2107.                         lprint("\x1b[K");
  2108.                         if(p<23) lprint("\n");
  2109.                     }
  2110.                 }
  2111.                 break;
  2112.  
  2113.             case '.':   /* Invoke Doors-mode */
  2114.                 stripcr(b);
  2115.                 if(!*b)a=3;
  2116.                 else {
  2117.                     a=*b-'0';
  2118.                     b++;
  2119.                 }
  2120.                 pp=strtok(b," \n");
  2121.                 if(*pp=='@') pp=variable[pp[1]-'0'];
  2122.                 xdoor(pp,a);
  2123.                 b=NULL;
  2124.                 break;
  2125.  
  2126.             case ',':   /* Invoke Files-mode */
  2127.                  stripcr(b);
  2128.                  if(!*b) a=2;
  2129.                  else {
  2130.                      a=*b-'0';
  2131.                      b++;
  2132.                  }
  2133.                  pp=strtok(b," \n");
  2134.                  if(*pp=='@') pp=variable[pp[1]-'0'];
  2135.                  xfile(pp,a);
  2136.                  b=NULL;
  2137.                 break;
  2138.  
  2139.             case 'U':   /* Update user's record in USERS.BBS, & lastread reload/save */
  2140.                  a=*b;
  2141.                  if(a=='1' || a=='2') {
  2142.                     b++;
  2143.                     if(a=='1') load_lastread();
  2144.                     else save_lastread();
  2145.                  }
  2146.                  else {
  2147.                     update();
  2148.                     if(a=='0') b++;
  2149.                  }
  2150.                 break;
  2151.  
  2152.             case '[':
  2153.             case '{':
  2154.             case '}':
  2155.             case ']':
  2156.             case '`':   do_picks(arg,b,lastlevel);
  2157.                         b=NULL;
  2158.                         break;
  2159.  
  2160.  
  2161.                 case 'T':   /* Set slow printing mode */
  2162.                     a=*b;
  2163.                     b++;
  2164.                     if(a=='@') {
  2165.                          slowprint=(char)atoi(variable[*b]);
  2166.                         b++;
  2167.                     }
  2168.                     else if(a=='e') {
  2169.                         slowprint=(char)lastlevel[*b];
  2170.                         b++;
  2171.                     }
  2172.                     else {
  2173.                         b--;
  2174.                         slowprint=(char)atoi(b);
  2175.                         while(*b && *b!=' ' && *b!='\n') b++;
  2176.                         if(*b==' ')b++;
  2177.                     }
  2178.                     break;
  2179.  
  2180.                 case 'V':   /* Named variables */
  2181.                     a=*b;
  2182.                     b++;
  2183.                     lstrip(b);
  2184.                     stripcr(b);
  2185.                     switch ((int)a) {
  2186.                         case 'D':   delete_var(b);
  2187.                                     b=NULL;
  2188.                                     break;
  2189.                         case 'a':
  2190.                         case 'A':   pp=strtok(b,"=");
  2191.                                     cm=strtok(0,"\n");
  2192.                                     if(a=='A')assign_var(pp,cm);
  2193.                                     else assign_var(pp,convertstring(cm));
  2194.                                     b=NULL;
  2195.                                     break;
  2196.                         case 'P':   b=lookup_var(b);
  2197.                                     break;
  2198.                         case 'p':   b=lookup_var(b);
  2199.                                     strncpy(str,convertstring(b),396);
  2200.                                     str[395]=0;
  2201.                                     b=str;
  2202.                                     break;
  2203.                         case 'S':   b=lookup_var(b);
  2204.                                     goto BreakIn;
  2205.                         case 's':   b=lookup_var(b);
  2206.                                     strncpy(str,convertstring(b),396);
  2207.                                     str[395]=0;
  2208.                                     b=str;
  2209.                                     goto BreakIn;
  2210.                         case 'F':   free_vars();
  2211.                                     b=NULL;
  2212.                                     break;
  2213.                         default:    level=5;    /* Syntax error */
  2214.                                     b-=2;
  2215.                                     break;
  2216.                     }
  2217.                     break;
  2218.  
  2219.                 case '>':   /* Fidonet packet export */
  2220.                     cm=strtok(b,", \n");
  2221.                     marea=NULL;
  2222.                     if((word)atol(b)==0) {
  2223.                         memcpy(&holdboard,&fboard,sizeof(struct _fboard));
  2224.                         memcpy(&holdmboard,&mboard,sizeof(struct _mboard));
  2225.                         load_areas(say_prompt(486));
  2226.                     }
  2227.                     export_mail((word)atol(b),(word)atol(cm));
  2228.                     if(marea) {
  2229.                         ffree(marea);
  2230.                         maxareas=0;
  2231.                         memcpy(&fboard,&holdboard,sizeof(struct _fboard));
  2232.                         memcpy(&mboard,&holdmboard,sizeof(struct _mboard));
  2233.                     }
  2234.                     b=NULL;
  2235.                     break;
  2236.  
  2237.                 case 'O':   /* Set system variables */
  2238.                     setsystem(b);
  2239.                     b=NULL;
  2240.                     break;
  2241.  
  2242.                 case 'n':   /* Run a .MNU file */
  2243.                     stripcr(b);
  2244.                     xmenu(b);
  2245.                     b=NULL;
  2246.                     break;
  2247.  
  2248.                 case 'm':   /* Manipulate shadow user buffer */
  2249.                     a=*b;
  2250.                     b++;
  2251.                     stripcr(b);
  2252.                     level=0;
  2253.                     if(a!='0' && a!='1') {
  2254.                         if(!finduser(0,var_trans(b))) level=1;
  2255.                     }
  2256.                     else {
  2257.                         if(a=='0') {
  2258.                             if(!load_user((word)atol(var_trans(b)))) level=1;
  2259.                         }
  2260.                         else if(a=='1') {
  2261.                             if(!save_user((word)atol(var_trans(b)))) level=1;
  2262.                         }
  2263.                         else if(a=='2') {
  2264.                             save_lastread();
  2265.                         }
  2266.                         else if(a=='3') {
  2267.                             load_lastread();
  2268.                         }
  2269.                     }
  2270.                     b=NULL;
  2271.                     break;
  2272.  
  2273.                 case 'o':
  2274.                     ansi_interface(b);
  2275.                     b=NULL;
  2276.                     break;
  2277.  
  2278.                 case '\x14':    /* CTRL_T, print to modem only */
  2279.                     stripcr(b);
  2280.                     mprint(convertstring(b));
  2281.                     b=NULL;
  2282.                     break;
  2283.  
  2284.                 case '\x15':    /* CTRL_U, bit fields in user str vars */
  2285.                     a=*b;
  2286.                     b++;
  2287.                     arg=*b-'0';
  2288.                     b++;
  2289.                     if(a!='c') {
  2290.                         if(*b!='e') {
  2291.                             secl=(word)atol(b);
  2292.                             b=strchr(b,' ');
  2293.                             if(b)b++;
  2294.                         }
  2295.                         else {
  2296.                             b++;
  2297.                             secl=lastlevel[*b-'0'];
  2298.                             b++;
  2299.                         }
  2300.                     }
  2301.                     switch ((int)a) {
  2302.                         case 's':   BitOn(user.variable[arg],secl);
  2303.                                     break;
  2304.                         case 'r':   BitOff(user.variable[arg],secl);
  2305.                                     break;
  2306.                         case 't':   level=IsBit(user.variable[arg],secl);
  2307.                                     break;
  2308.                         case 'c':   strset(user.variable[arg],0);
  2309.                                     break;
  2310.                     }
  2311.  
  2312.  
  2313. errorreturn:
  2314.  
  2315.             default: printm("\x1");
  2316.                      break;
  2317.         }
  2318.        }
  2319.       }
  2320.      } while (cm);
  2321.  }
  2322.    pauser=tempause;
  2323.    p=0;
  2324.    if (b!=NULL && *b) p=printm(b);
  2325.    a=toupper(inkey());
  2326.    if (*hotkeys) {
  2327.         if (a) {
  2328.             if (strchr(hotkeys,a)) {
  2329.                 variable[0][0]=a;
  2330.                 variable[0][1]=0;
  2331.                 *hotkeys=0;
  2332.                 fossil(PURGEOUT,0);
  2333.                 fossil(PURGEIN,0);
  2334.                 goto donereading;
  2335.             }
  2336.         }
  2337.    }
  2338.    if (safe && !disablesub && !leaving) if (*conf.subkey[0]) {
  2339.         if (a) {
  2340.             for (x=0;x<10;x++) {
  2341.                 if(!*conf.subkey[x]) break;
  2342.                 if(a==*conf.subkey[x]) {
  2343.                    disablesub=1;
  2344.                    readfile(conf.subfile[x],0,0,1);
  2345.                    disablesub=0;
  2346.                    break;
  2347.                 }
  2348.             }
  2349.         }
  2350.    }
  2351.    if (!abort && (a == 'S' || a == ' ' || p)) {
  2352.       goto donereading;
  2353.    }
  2354.    if (!pause && (a == 'P' || a == 19)) pauseit();
  2355.  }
  2356.  while (!eof(handle));
  2357.  
  2358. donereading:
  2359.  
  2360.  if (*hotkeys) {
  2361.     *hotkeys=0;
  2362.     *alabel=0;
  2363.  }
  2364.  if (*alabel && !eof(handle)) {
  2365.     strcpy(label,alabel);
  2366.     *alabel=0;
  2367.     goto seeklabel;
  2368.  }
  2369.  cclose(handle);
  2370.  pauser=0;
  2371.   if (stristr(filename,"GOODBYE.")!=NULL) {
  2372.    leaving=1;
  2373.    fossil(FLUSHOUT,0);
  2374.    fossil(DTR,DOWN);
  2375.    baud=0;
  2376.    logoff();
  2377.    userno=0;
  2378.    exit(254);
  2379.  }
  2380.  if (*filetoread) {
  2381.  
  2382. gprintf(LOCALONLY,"\nFile to read: %s\n",filetoread);
  2383.  
  2384.     imbed=1;
  2385.     strcpy(filename,filetoread);
  2386.     *filetoread=0;
  2387.     goto restart;
  2388.  }
  2389.  return 0;
  2390.  
  2391. inputerror:
  2392.  gprintf(LOCALONLY | LOGONLY,say_prompt(15));
  2393.  goto Commonerror;
  2394. commanderror:
  2395.      if (eof(handle)==-1) {
  2396.         cclose(handle);
  2397.         goto Commonerror;
  2398.      }
  2399.     gprintf(LOCALONLY | LOGONLY,"ERROR: EOF during command");
  2400. Commonerror:
  2401.  if (conf.debug) {
  2402.      gprintf(LOCALONLY | LOGONLY,"%s%s (LL: %s)",say_prompt(16),filename,label);
  2403.      lprint("\n");
  2404.  }
  2405.  return 3;
  2406. }
  2407.