home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / modem / byepc300.arc / BYESHELL.ARC / SHELL.C < prev    next >
Text File  |  1987-10-24  |  21KB  |  1,030 lines

  1. /*
  2. **  File:    <shell.c>
  3. **
  4. **  Purpose:    Security Command Line Processor for BYE-PC
  5. **
  6. **  Author:    R.E. Starr, Jr.
  7. **
  8. **  Date:    12/31/86
  9. **
  10. **  Revisons:    1.04 - (03/28/87)  Modified caller status word to
  11. **            allow up to 16 disk drives in system.
  12. **
  13. **        1.05 - (03/30/87)  Modified to check for precsence
  14. **            of BYE-PC before calling any external functions.
  15. **            This allows SHELL to function without BYE-PC.
  16. **
  17. **        1.06 - (03/31/87)  Added 'getdrive()' to read the
  18. **            current default drive instead of keeping up
  19. **            with it in a storage location.
  20. **
  21. **        1.07 - (04/05/87)  Added redirection checking
  22. **
  23. **        1.08 - (05/01/87)  Added command line options for
  24. **            debugging and status level settings.
  25. **
  26. **        1.09 - (05/01/87)  Added missing drive table to map
  27. **            out invalid/non-supported drives.
  28. **
  29. **        1.10 - (05/08/87)  Modified for byexface ver 2.00
  30. */
  31.  
  32. #include <stdio.h>    /* std Microsoft C headers */
  33. #include <stdlib.h>
  34. #include <conio.h>
  35. #include <ctype.h>
  36. #include <process.h>
  37. #include <signal.h>
  38. #include <string.h>
  39. #include <direct.h>
  40. #include <dos.h>
  41. #include <time.h>
  42. #include "byexface.h"    /* BYE-PC interface functions */
  43.  
  44.  
  45.     /* SHELL configuration section */
  46.  
  47. /* #define PCURS    * define for dos cursor with path name */
  48. #define MAX_DRV 'C'    /* max drives in system, 16 max. (A-P) */
  49.  
  50. #define VER    1    /* SHELL Version# */
  51. #define REV    10    /* SHELL Revision# */
  52.  
  53. #define BYE_VER 3    /* minimum BYE-PC version# required */
  54. #define BYE_REV 0    /* minimum BYE-PC revision# required */
  55.  
  56. #define BIT_0    0x0001
  57. #define BIT_1    0x0002
  58. #define BIT_2    0x0004
  59. #define BIT_3    0x0008
  60. #define BIT_4    0x0010
  61. #define BIT_5    0x0020
  62. #define BIT_6    0x0040
  63. #define BIT_7    0x0080
  64.  
  65.  
  66.     /* function declarations */
  67.  
  68. void commands(), intrinsic(), extrinsic();
  69. void pset_parms(), pset_flags(), pflags_error();
  70.  
  71. int binary(), break_handler();
  72. int drv_cmd(), null_cmd(), type_cmd(), time_cmd();
  73. int dos_cmd(), exit_cmd(), cd_cmd(), format_cmd(), dir_cmd();
  74.  
  75.  
  76.     /* static data declarations */
  77.  
  78. static char Com_spec[64];        /* file spec of COMMAND.COM */
  79. static char Errors = 0;         /* # of persistant Errors */
  80. static char Bye_flg = 1;        /* BYE-PC loaded flag */
  81. static char Debug = 0;            /* BYE-PC not loaded mode */
  82. static unsigned Cstat = 0;        /* caller status level */
  83. static unsigned Csw = 0;        /* debug mode status flags */
  84.  
  85.  
  86.    /* ----------------------- NOTE ----------------------------*/
  87.    /* The following table is searched using a binary search    */
  88.    /* and all strings must be in assending alphabetical order. */
  89.    /* ---------------------------------------------------------*/
  90.  
  91. #define PCMDS  (sizeof(cmdpri) / sizeof(struct key))
  92. #define RPATHS (sizeof(rpath) / sizeof(struct paths))
  93. #define IPATHS (sizeof(ipath) / sizeof(struct paths))
  94. #define MDRIVE (sizeof(mdrvs))
  95.  
  96.  
  97.     /* missing system drives */
  98.  
  99. char mdrvs[] =            /* missing drive map */
  100.     {
  101.     'D',            /* drive D: not supported */
  102.     'E',            /* drive E: not supported */
  103.     };
  104.  
  105.     /* intrinsic command table functions */
  106.  
  107. struct key
  108.     {
  109.     char *keyword;        /* pointer to intrinsic key words */
  110.     int (*key_fxn)();        /* pointer to intrinsic functions */
  111.     };
  112. struct key cmdpri[] =        /* primary command set */
  113.     {
  114.     "ASSIGN", null_cmd,
  115.     "ATTRIB", null_cmd,
  116.     "BACKUP", null_cmd,
  117.     "BASIC", null_cmd,
  118.     "BASICA", null_cmd,
  119.     "BREAK", null_cmd,
  120.     "CD", cd_cmd,
  121.     "CHDIR", cd_cmd,
  122.     "COMMAND", null_cmd,
  123.     "COMP", null_cmd,
  124.     "COPY", null_cmd,
  125.     "CTTY", null_cmd,
  126.     "DATE", time_cmd,
  127.     "DEL", null_cmd,
  128.     "DIR", dir_cmd,
  129.     "DISKCOMP", null_cmd,
  130.     "DISKCOPY", null_cmd,
  131.     "DOS", dos_cmd,
  132.     "ERASE", null_cmd,
  133.     "EXE2BIN", null_cmd,
  134.     "EXIT", exit_cmd,
  135.     "FDISK", null_cmd,
  136.     "FORMAT", format_cmd,
  137.     "GRAFTABL", null_cmd,
  138.     "GRAPHICS", null_cmd,
  139.     "JOIN", null_cmd,
  140.     "KEYBFR", null_cmd,
  141.     "KEYBGR", null_cmd,
  142.     "KEYBIT", null_cmd,
  143.     "KEYBSP", null_cmd,
  144.     "KEYBUK", null_cmd,
  145.     "LABEL", null_cmd,
  146.     "MD", null_cmd,
  147.     "MKDIR", null_cmd,
  148.     "MODE", null_cmd,
  149.     "PATH", null_cmd,
  150.     "PRINT", null_cmd,
  151.     "PROMPT", null_cmd,
  152.     "RD", null_cmd,
  153.     "RECOVER", null_cmd,
  154.     "REN", null_cmd,
  155.     "RESTORE", null_cmd,
  156.     "RMDIR", null_cmd,
  157.     "SELECT", null_cmd,
  158.     "SET", null_cmd,
  159.     "SHARE", null_cmd,
  160.     "SHELL", null_cmd,
  161.     "SYS", null_cmd,
  162.     "TIME", time_cmd,
  163.     "TREE", null_cmd,
  164.     "TYPE", type_cmd,
  165.     "VER", null_cmd,
  166.     "VERIFY", null_cmd,
  167.     "VOL", null_cmd,
  168.     };
  169.  
  170.     /* invalid and restricted DOS paths */
  171.  
  172. struct paths
  173.     {
  174.     char *path;         /* pointer to paths */
  175.     };
  176.  
  177. struct paths ipath[] =        /* illegal DOS path names */
  178.     {
  179.     "SYSTEM",
  180.     "DOS",
  181.     "XBBS",
  182.     };
  183.  
  184. struct paths rpath[] =        /* restriced DOS path names */
  185.     {
  186.     "UPLOADS",
  187.     "PRIVATE",
  188.     };
  189.  
  190.  
  191. /*
  192. **  Function:    void main()
  193. **
  194. **  Paramters:    int argc;
  195. **        char *argv[];
  196. **
  197. **  Purpose:    Main shell calling routine
  198. **
  199. **  Return:    void
  200. */
  201.  
  202. main(argc, argv)
  203.  
  204.  int argc;
  205.  char *argv[];
  206.     {
  207.     int rtn, n;
  208.     char *ptr;
  209.     char inp_buf[80];
  210.     char tmp_buf[80];
  211.     extern struct cmdpri;
  212.  
  213.     Debug = 0;
  214.     Csw = 0;
  215.     pset_parms(argc, argv);    /* check cmd line line flags */
  216.  
  217.     if (signal(SIGINT, break_handler) == (int(*)()) -1)
  218.     printf("\nWARNING: Can't disable CTRL-BREAK interrupt!\n");
  219.  
  220.     if (rtn = _bye_check(BYE_VER, BYE_REV))
  221.     {
  222.     if (rtn == 1)
  223.         {
  224.         Bye_flg = 0;
  225.         if (Debug)
  226.         printf("\nWARNING: BYE-PC not loaded - 'EXIT' to quit SHELL\n");   /* internal error */
  227.         else
  228.         exit(1);
  229.         }
  230.     else
  231.         {
  232.         printf("\nSHELL ERROR: BYE-PC ");    /* internal error */
  233.         switch(rtn)
  234.         {
  235.         case 2:
  236.             printf("loaded is the wrong Version!\n");
  237.             break;
  238.         case 3:
  239.             printf("loaded is the wrong Revision!\n");
  240.             break;
  241.         default:
  242.             printf("returned invalid error code!\n");
  243.             break;
  244.         }
  245.         exit(1);
  246.         }
  247.     }
  248.     get_comspec(Com_spec);        /* get file spec for COMMAND.COM */
  249.     if (Bye_flg)
  250.     {
  251.     _bye_setbreak(CTRL_BRK);    /* now enable ctrl-breaks  */
  252.     Cstat = _bye_getcsw();        /* get callers status */
  253.     }
  254.     else
  255.     Cstat = (Csw != NULL) ? Csw : 0xff00;
  256.                     /* since we trap them here */
  257.     while(1)
  258.     {
  259.     if (Bye_flg)
  260.         Cstat = _bye_getcsw();    /* reset callers status */
  261.     if (!get_cmd(inp_buf, 63))    /* get a line from stdin */
  262.         continue;
  263.     ptr = strupr(inp_buf);        /* make string upper case */
  264.     while(*ptr == ' ')        /* skip over leading spaces */
  265.         *ptr++;
  266.     strcpy(inp_buf, ptr);        /* remove all leading spaces */
  267.     strcpy(tmp_buf, ptr);        /* make a copy of input str  */
  268.     if (tmp_buf[0] == '\0')     /* loop if no data entered   */
  269.         continue;
  270.     printf("\n");
  271.     if (tmp_buf[1] == ':')
  272.         {
  273.         if (tmp_buf[2] == '\0')
  274.         {
  275.         drv_cmd(tmp_buf);
  276.         continue;
  277.         }
  278.         else
  279.         {
  280.         if (bad_drive(inp_buf)) /* check drive first */
  281.             continue;
  282.         *ptr++;         /* execute on another drive */
  283.         *ptr++;
  284.         strcpy(tmp_buf, ptr);
  285.         }
  286.         }
  287.     if ((ptr = strchr(tmp_buf, ' ')) != NULL)
  288.         *ptr = '\0';
  289.     if ((n = binary(tmp_buf, cmdpri, PCMDS)) != EOF)
  290.         (*cmdpri[n].key_fxn)(inp_buf);  /* do function internally */
  291.     else
  292.         extrinsic(inp_buf);         /* DOS system call.     */
  293.     }
  294.     }
  295.  
  296.  
  297. /*
  298. **  Function:    void extrinsic(input_string)
  299. **
  300. **  Parms:    char *input_string
  301. **
  302. **  Purpose:    Passes the string to the system to execute as
  303. **        a system command it possible.
  304. **
  305. **  Return:    void
  306. */
  307.  
  308. void extrinsic(input_string)
  309.  
  310.  char *input_string;
  311.     {
  312.     int status;
  313.  
  314.     if (!(*input_string))        /* any command to try? */
  315.     return;             /*    no, reuturn.       */
  316.     if (bad_path(input_string, 1))  /* check for bad paths */
  317.     return;
  318.     Errors = 0;             /* reset persistant error ctr */
  319.     status = system(input_string);
  320.     if (status)
  321.     printf("\n[EXEC of COMMAND.COM failed!]\n");
  322.     }
  323.  
  324.  
  325. /*
  326. **  Function:    void prompt()
  327. **
  328. **  Parms:    void
  329. **
  330. **  Purpose:    Shows the cursor prompt
  331. **
  332. **  Return:    void
  333. */
  334.  
  335. prompt()
  336.  {
  337. #ifdef PCURS
  338.  char pathbuf[51];
  339.  
  340.  if (getcwd(pathbuf, 50) == NULL)    /* read current directory */
  341.     strcpy(pathbuf, "ERROR");
  342.  printf("\n[%s]==>>", pathbuf);
  343. #else
  344.  printf("\n%c>", (char)getdrive() + 'A');
  345. #endif
  346.  }
  347.  
  348.  
  349. /*
  350. **  Function:    get_cmd(buffer, len)
  351. **
  352. **  Parms:    char *buffer;    -> ptr to a input buffer.
  353. **        int len;    -> max input line length
  354. **
  355. **  Purpose:    Collects input from stdin and stores in buffer
  356. **
  357. **  Return:    0 = no data or first character is a ';'
  358. **        1 = data received from input
  359. */
  360.  
  361. int get_cmd(buffer, len)
  362.  
  363.  char *buffer;
  364.  int len;
  365.     {
  366.     int c, i, flg, stat;
  367.  
  368.     prompt();                /* display cursor */
  369.     stat = flg = 1;
  370.     c = '\0';
  371.     i = 0;
  372.     while((i < len) && flg)
  373.     {
  374.     c = getch();
  375.     switch(c)
  376.         {
  377.         case NULL:
  378.         getch();
  379.         break;
  380.         case '\b':
  381.         if (!i)
  382.             break;
  383.         printf("\b \b");
  384.         *buffer--;
  385.         i--;
  386.         break;
  387.         case '\t':
  388.         break;
  389.         case '\r':
  390.         case '\n':
  391.         if (!i)
  392.             stat = 0;
  393.         flg = 0;
  394.         break;
  395.         default:
  396.         if (c == ';' && i == 0)
  397.             stat = 0;
  398.         putch(c);        /* echo the character back */
  399.         *buffer++ = c;
  400.         i++;
  401.         break;
  402.         }
  403.     }
  404.     *buffer = '\0';        /* terminate string */
  405.     if (!stat && i > 0)
  406.     stat = 0;
  407.     return(stat);
  408.     }
  409.  
  410.  
  411. /*
  412. **  Function:    int getdrive()
  413. **
  414. **  Parms:    void
  415. **
  416. **  Purpose:    Returns the current default disk drive (0=A, 1=B,,,).
  417. **
  418. **  Return:    drive code.
  419. */
  420.  
  421. int getdrive()
  422.  {
  423.  union REGS inregs, outregs;
  424.  
  425.  inregs.h.ah = 0x19;         /* read default drive */
  426.  intdos(&inregs, &outregs);
  427.  return((int)outregs.h.al);
  428.  }
  429.  
  430.  
  431. /*
  432. **  Function:    void get_comspec(buffer);
  433. **
  434. **  Parms:    char *buffer; -> storage for COMSPEC.
  435. **
  436. **  Purpose:    Gets the sytem environment variable COMSPEC.
  437. **
  438. **  Return:    void
  439. **
  440. */
  441.  
  442. get_comspec(buffer)
  443.  
  444.  char *buffer;
  445.     {
  446.     strcpy(buffer, getenv("COMSPEC"));
  447.     if (buffer[0] == NULL)
  448.     {
  449.     printf("\n[No COMSPEC variable in Environment!]\n");
  450.     exit(1);
  451.     }
  452.     }
  453.  
  454.  
  455. /*
  456. **  Function:    int break_handler()
  457. **
  458. **  Parms:    void
  459. **
  460. **  Purpose:    Traps all control breaks from local keyboard
  461. **
  462. **  Return:    void
  463. */
  464.  
  465. break_handler()
  466.  {
  467.  prompt();
  468.  signal(SIGINT, break_handler);     /* reset break point */
  469.  }
  470.  
  471.  
  472. /*
  473. **  Function:    show_error()
  474. **
  475. **  Parms:    char *s;    -> pointer to string
  476. **
  477. **  Purpose:    Prints an error message from a string and is delimited
  478. **        by the first space character.
  479. **
  480. **  Return:    void
  481. */
  482.  
  483. show_error(s)
  484.  
  485.  char *s;
  486.     {
  487.     char buf[21];
  488.     char *ptr;
  489.  
  490.     strncpy(buf, s, 20);
  491.     ptr = strchr(buf, ' ');
  492.     if (ptr != NULL)
  493.     *ptr = '\0';
  494.     if (Errors > 6)        /* hangup on persistant hackers, we  */
  495.     {            /* are through giving them warnings! */
  496.     printf("\n[LAST WARNING!]\n\n\n");
  497.     if (Bye_flg)
  498.         _bye_warmboot();
  499.     }
  500.     if (++Errors >= 2)
  501.     printf("\n[WARNING");    /* warn caller not to keep trying */
  502.     else
  503.     printf("\n[ERROR");    /* tell caller they cant do this! */
  504.     printf(": %s is not allowed!]\n", buf);
  505.     }
  506.  
  507.  
  508. /*
  509. **  Function:    int bad_redir(s)
  510. **
  511. **  Parms:    char *s; --> cmd line input string.
  512. **
  513. **  Purpose:    Check for any redirection symbols
  514. **
  515. **  Return:    1 = invalid redirection found
  516. **        0 = no redirection found
  517. */
  518.  
  519. int bad_redir(s)
  520.  
  521.  char *s;
  522.     {
  523.     char *p;
  524.  
  525.     if (Cstat == 0xffff)
  526.     return(0);
  527.     if ((p = strpbrk(s, "<|>")) != NULL)
  528.     {
  529.     printf("\n[I/O Redirection Invalid]\n");
  530.     return(1);
  531.     }
  532.     return(0);
  533.     }
  534.  
  535.  
  536. /*
  537. **  Function:    int bad_drive(s)
  538. **
  539. **  Parms:    char *s; --> cmd line input string.
  540. **
  541. **  Purpose:    Check the string for any drive extensions and test
  542. **        for any illegal drive codes. If caller status is
  543. **        FFFFh, the drive check is ignored.
  544. **
  545. **  Return:    1 = invalid drive
  546. **        0 = drive is ok
  547. */
  548.  
  549. bad_drive(s)
  550.  
  551.  char *s;
  552.     {
  553.     int c, d;
  554.     char *ptr, *token;
  555.     unsigned stat;
  556.  
  557.     if (Cstat == 0xffff)
  558.     return(0);
  559.     stat = ((Cstat >> 8) & 0x0F) + 1;        /* get callers status */
  560.  
  561.     ptr = strchr(s, (int)':');            /* any drive codes?   */
  562.     while(ptr)
  563.     {
  564.     *ptr--;                 /* back up to drive name */
  565.     d = (int)*ptr++;            /* get the drive letter */
  566.     d = toupper(d);
  567.     c = (d - '@');                /* convert to zero base */
  568.     if (c > stat || d > MAX_DRV)
  569.         {
  570.         printf("\n[Invalid Drive]\n");  /* status not high enough */
  571.         return(1);
  572.         }
  573.     if (missing_drv(d))
  574.         return(1);
  575.     *ptr++;
  576.     ptr = strchr(ptr, (int)':');        /* any drive codes?   */
  577.     }
  578.     return(0);
  579.     }
  580.  
  581.  
  582. /*
  583. **  Function:    int missing_drv(d)
  584. **
  585. **  Parms:    char d; --> drive code to test.
  586. **
  587. **  Purpose:    Scan the missing drive table for any missing drives
  588. **        in the system. Return
  589. **
  590. **  Return:    1 = invalid path
  591. **        0 = path is ok
  592. */
  593.  
  594. int missing_drv(d)
  595.  
  596.  int d;
  597.     {
  598.     int i, c;
  599.  
  600.     for (i = 0; i < MDRIVE; i++)
  601.     {
  602.     c = (int)mdrvs[i];
  603.     if (toupper(d) == toupper(c))
  604.         {
  605.         printf("\n[Drive Not Supported]\n");
  606.         return(1);
  607.         }
  608.     }
  609.     return(0);
  610.     }
  611.  
  612.  
  613. /*
  614. **  Function:    int bad_path(s, flg)
  615. **
  616. **  Parms:    char *s; --> cmd line input string.
  617. **        int flg; --> 0=does not require starting slash
  618. **
  619. **  Purpose:    Check the string for any invalid paths. If the
  620. **        caller status word is FFFFh, the check is ignored.
  621. **
  622. **  Return:    1 = invalid path
  623. **        0 = path is ok
  624. */
  625.  
  626. bad_path(s, flg)
  627.  
  628.  char *s;
  629.  int flg;
  630.     {
  631.     int i;
  632.     char *ptr;
  633.  
  634.     ptr = s;
  635.     if (bad_drive(s))            /* check drive numbers */
  636.     return(1);
  637.     if (bad_redir(s))            /* check for redirection */
  638.     return(1);
  639.     if (Cstat == 0xffff)        /* skip it if sysop */
  640.     return(0);
  641.     if (flg)
  642.     {
  643.     if ((ptr = strchr(s, '\\')) == NULL)
  644.         return(0);
  645.     }
  646.     for (i = 0; i < IPATHS; i++)
  647.     {
  648.     if (strstr(ptr, ipath[i].path))  /* scan for invalid paths */
  649.         {
  650.         printf("\n[Illegal Path Name]\n");
  651.         return(1);
  652.         }
  653.     }
  654.     if (!(Cstat & BIT_2))
  655.     {
  656.     for (i = 0; i < RPATHS; i++)
  657.         {
  658.         if (strstr(ptr, rpath[i].path))  /* scan for restricted paths */
  659.         {
  660.         printf("\n[Path Access Restricted]\n");
  661.         return(1);
  662.         }
  663.         }
  664.     }
  665.     return(0);
  666.     }
  667.  
  668.  
  669. /*
  670. **  Function:    int binary(*word, tab, n);
  671. **
  672. **  Paramters:    char *word --> pointer to string to search for
  673. **        struct tab --> command table structure
  674. **        int n       --> number of commands in command table
  675. **
  676. **  Purpose:    Performs a binary search of the command table structure
  677. **        passed in the structure 'tab'. The strings are compared
  678. **        without regard to case.
  679. **
  680. **  Return:    EOF = command not found, else return the index of the
  681. **        command in the command table (0 to n).
  682. */
  683.  
  684. int binary(word, tab, n)
  685.  
  686.  char *word;
  687.  struct key tab[];
  688.  int n;
  689.     {
  690.     int low, high, mid, cond;
  691.  
  692.     low = 0;
  693.     high = n - 1;
  694.     while (low <= high)
  695.     {
  696.     mid = (low + high) / 2;
  697.     if ((cond = strcmpi(word, tab[mid].keyword)) < 0)
  698.         high = mid - 1;
  699.     else if (cond > 0)
  700.         low = mid + 1;
  701.     else
  702.         return(mid);
  703.     }
  704.     return(-1);
  705.     }
  706.  
  707.  
  708. /*
  709. **  Function:    null_cmd(s);
  710. **
  711. **  Parms:    char *s; --> cmd line input string.
  712. **
  713. **  Purpose:    Sends all commands that are not allowed and error msg.
  714. **
  715. **  Return:    void
  716. */
  717.  
  718. null_cmd(s)
  719.  
  720.  char *s;
  721.     {
  722.     show_error(s);
  723.     }
  724.  
  725.  
  726. /*
  727. **  Function:    void dos_cmd(s);
  728. **
  729. **  Parms:    char *s; --> cmd line input string.
  730. **
  731. **  Purpose:    Executes COMMAND.COM as a child process.
  732. **
  733. **  Return:    void
  734. */
  735.  
  736. dos_cmd(s)
  737.  
  738.  char *s;
  739.     {
  740.     int status;
  741.  
  742.     if (!(Cstat & BIT_6))
  743.     {
  744.     show_error(s);
  745.     return;
  746.     }
  747.     status = spawnlp(P_WAIT, Com_spec, Com_spec, NULL);
  748.     if (status)
  749.     printf("\n[EXEC of COMMAND.COM failed!]\n");
  750.     else
  751.     printf("\nSHELL Command Processor for BYE-PC \n");
  752.     printf("Copyright MCODE Software (c) 1986, 1987\n\n");
  753.     }
  754.  
  755.  
  756. /*
  757. **  Function:    exit_cmd(s)
  758. **
  759. **  Parms:    char *s; --> cmd line input string.
  760. **
  761. **  Purpose:    Exits the command processor shell to DOS.
  762. **
  763. **  Return:    void
  764. */
  765.  
  766. exit_cmd(s)
  767.  
  768.  char *s;
  769.     {
  770.     if (Debug)
  771.     {
  772.     printf("\nExiting SHELL DEBUG Mode to DOS...\n");
  773.     }
  774.     else if (!(Cstat & BIT_7))
  775.     {
  776.     show_error(s);
  777.     return;
  778.     }
  779.     else
  780.     {
  781.     printf("\nWARNING: Exiting SHELL to DOS...\n");
  782.     }
  783.     exit(0);
  784.     }
  785.  
  786.  
  787. /*
  788. **  Function:    cd_cmd(s)
  789. **
  790. **  Parms:    char *s; --> cmd line input string.
  791. **
  792. **  Purpose:    Traps all of the DOS CD commands.
  793. **
  794. **  Return:    void
  795. */
  796.  
  797. cd_cmd(s)
  798.  
  799.  char *s;
  800.     {
  801.     int i;
  802.  
  803.     if (!(Cstat & BIT_3))
  804.     {
  805.     show_error(s);
  806.     return;
  807.     }
  808.     else
  809.     {
  810.     if (bad_path(s, 0))
  811.         return(1);
  812.     extrinsic(s);            /* status is ok */
  813.     }
  814.     }
  815.  
  816.  
  817. /*
  818. **  Function:    void drv_cmd(s)
  819. **
  820. **  Parms:    char *s; --> cmd line input string.
  821. **
  822. **  Purpose:    Check with BYE before allowing a drive change.
  823. **
  824. **  Return:    void
  825. */
  826.  
  827. drv_cmd(s)
  828.  
  829.  char *s;
  830.     {
  831.     int c, d;
  832.     unsigned stat;
  833.  
  834.     stat = ((Cstat >> 8) & 0x0F) + 1;
  835.     d = *s;                    /* get drive letter */
  836.     d = toupper(d);
  837.     c = ((int)*s - '@');
  838.     if (c > stat || d > MAX_DRV)
  839.     printf("\n[Invalid Drive]\n");        /* status high enough? */
  840.     else if (missing_drv(d))            /* a missing drive?    */
  841.     return(1);
  842.     else
  843.     extrinsic(s);                /* status is ok */
  844.     }
  845.  
  846.  
  847. /*
  848. **  Function:    void fmt_cmd(s)
  849. **
  850. **  Parms:    char *s; --> cmd line input string.
  851. **
  852. **  Purpose:    Hangup on the destructive caller.
  853. **
  854. **  Return:    void
  855. */
  856.  
  857. format_cmd(s)
  858.  
  859.  char *s;
  860.     {
  861.     if (Bye_flg)
  862.     _bye_warmboot();
  863.     }
  864.  
  865.  
  866. /*
  867. **  Function:    void dir_cmd(s)
  868. **
  869. **  Parms:    char *s; --> cmd line input string.
  870. **
  871. **  Purpose:    Checks for valid dir paths.
  872. **
  873. **  Return:    void
  874. */
  875.  
  876. dir_cmd(s)
  877.  
  878.  char *s;
  879.     {
  880.     int c;
  881.     unsigned stat;
  882.  
  883.     if (bad_path(s, 0))     /* check for any bad paths */
  884.     return;
  885.     extrinsic(s);
  886.     }
  887.  
  888.  
  889. /*
  890. **  Function:    void type_cmd(s)
  891. **
  892. **  Parms:    char *s; --> cmd line input string.
  893. **
  894. **  Purpose:    Checks for valid type paths.
  895. **
  896. **  Return:    void
  897. */
  898.  
  899. type_cmd(s)
  900.  
  901.  char *s;
  902.     {
  903.     int c;
  904.     unsigned stat;
  905.  
  906.     if (bad_path(s, 0))     /* check for any bad paths */
  907.     return;
  908.     extrinsic(s);
  909.     }
  910.  
  911.  
  912. /*
  913. **  Function:    void time_cmd(s)
  914. **
  915. **  Parms:    char *s; --> cmd line input string.
  916. **
  917. **  Purpose:    Show the current system time.
  918. **
  919. **  Return:    void
  920. */
  921.  
  922. time_cmd(s)
  923.  
  924.  char *s;
  925.     {
  926.     struct tm *newtime;
  927.     char *am_pm = "PM";
  928.     time_t long_time;
  929.  
  930.     time(&long_time);
  931.     newtime = localtime(&long_time);
  932.     if (newtime->tm_hour < 12)
  933.     am_pm = "AM";
  934.     if (newtime->tm_hour > 12)
  935.     newtime->tm_hour -= 12;
  936.     printf("\n%.19s %s\n", asctime(newtime), am_pm);
  937.     }
  938.  
  939.  
  940. /*
  941. **  Function:    void pset_parms()
  942. **
  943. **  Arguments:    int cnt;    --> number of command lines entered
  944. **        char *s[];  --> pointers to command line strings
  945. **
  946. **  Purpose:    Reads all of the command line options separated by
  947. **        spaces and '/' or '-'  to determine valid options.
  948. **
  949. **  Return:    <none>
  950. */
  951.  
  952. void pset_parms(cnt, args)
  953.  
  954.  int cnt;
  955.  char *args[];
  956.     {
  957.     int i;
  958.     char *token;
  959.  
  960.     if (cnt <= 1)
  961.     return;
  962.     for (i = 1; i < cnt; ++i)
  963.     {
  964.     token = strtok(args[i], "/-");
  965.     while(token != (char *)NULL)
  966.         {
  967.         pset_flags(token);
  968.         token = strtok(NULL, "/-");
  969.         }
  970.     }
  971.     }
  972.  
  973.  
  974. /*
  975. **  Function:    void pflags_error()
  976. **
  977. **  Arguments:    char s[];   --> unknown options string
  978. **
  979. **  Purpose:    Displays the invalid options string entered at
  980. **        the command line and exits back to dos.
  981. **
  982. **  Return:    <none>
  983. */
  984.  
  985. void pflags_error(s)
  986.  
  987.  char s[];
  988.     {
  989.     printf("\n\nBYE-PC Security SHELL Version %1d.%-2.2d\n", VER, REV);
  990.     printf("Copyright (c) 1986, 1987, MCODE Software\n\n");
  991.     printf("Valid Options:\n\n");
  992.     printf("\t-d .........Debug mode, with BYE-PC not loaded.\n");
  993.     printf("\t-s:{nnn}....Set CSW upon execution (decimal).\n");
  994.     printf("\n");
  995.     exit(1);
  996.     }
  997.  
  998.  
  999. /*
  1000. **  Function:    void pset_parms()
  1001. **
  1002. **  Arguments:    int cnt;    --> number of command lines entered
  1003. **        char *s[];  --> pointers to command line strings
  1004. **
  1005. **  Purpose:    Reads all of the command line options separated by
  1006. **        spaces ,'/', or a '-' to determine valid options.
  1007. **
  1008. **    Syntax: -d ..........debug mode, BYEXFACE calls omitted.
  1009. **        -s:{nnn} ....set caller status word to 0-65535
  1010. **
  1011. **  Return:    void
  1012. */
  1013.  
  1014. void pset_flags(flg)
  1015.  
  1016.  char flg[];
  1017.     {
  1018.     char f[65];
  1019.     strcpy(f, flg);            /* make a copy of the string */
  1020.     strupr(f);                /* make upper case */
  1021.  
  1022.     if (!strcmp(f, "D"))
  1023.     Debug = 1;
  1024.     else if (!strncmp(f, "S:", 2))
  1025.     Csw = (unsigned)atoi(&f[2]);
  1026.     else
  1027.     pflags_error(f);
  1028.     }
  1029.  
  1030.