home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / AZTEC-C / AZ-CROOT.LBR / AZ-CROOT.CQ / AZ-CROOT.C
Text File  |  2000-06-30  |  13KB  |  398 lines

  1. /* Copyright (C) 1981,1982 by Manx Software Systems.
  2.    Copyright (C) 1982  Thomas Fenwick.
  3.    Copyright (c) 1985 Allen Holub.
  4.  
  5.    Manx Software Systems is in no way responsible for this program.
  6.    These portions may be reproduced for personal, non-profit use,
  7.    only.  All other use is prohibited.  You should replace the croot in
  8.    libc.lib with this module.  This posting includes a couple of
  9.    minor hacks by wse */
  10.  
  11. #include "fcntl.h"
  12. #include "errno.h"
  13. #include "io.h"
  14.  
  15. #define MAXARGS 128
  16. #define MAXBUF 128
  17. #define LOADERSIZE 49
  18. #define DEF_FCB 0x5c
  19. #define FCBSIZE 36
  20. #define NULL 0
  21. #define QUOTE 0x22
  22. #define CBUF    ((char *)0x80)
  23. #define CBUFEND (char *)(0x80+128-LOADERSIZE)
  24.  
  25. #define srchfirst(fcb) (bdos (0x11, (fcb)) & 0xff)
  26. #define srchnext(fcb) (bdos (0x12, (fcb)) & 0xff)
  27. #define bdosopen(fcb)  (bdos (0x0f, (fcb)) & 0xff)
  28. #define isalnum(c) (c >= 0x20 && c <= 0x7e)
  29. int badfd(), noper();
  30.  
  31. /*
  32.  * channel table: relates fd's to devices
  33.  */
  34. struct channel  chantab[] = {
  35.          {
  36.                 2, 0, 1, 0, noper, 2    }
  37.         ,
  38.         {
  39.                 0, 2, 1, 0, noper, 2    }
  40.         ,
  41.         {
  42.                 0, 2, 1, 0, noper, 2    }
  43.         ,
  44.         {
  45.                 0, 0, 0, 0, badfd, 0    }
  46.         ,
  47.         {
  48.                 0, 0, 0, 0, badfd, 0    }
  49.         ,
  50.         {
  51.                 0, 0, 0, 0, badfd, 0    }
  52.         ,
  53.         {
  54.                 0, 0, 0, 0, badfd, 0    }
  55.         ,
  56.         {
  57.                 0, 0, 0, 0, badfd, 0    }
  58.         ,
  59.         {
  60.                 0, 0, 0, 0, badfd, 0    }
  61.         ,
  62.         {
  63.                 0, 0, 0, 0, badfd, 0    }
  64.         ,
  65.         {
  66.                 0, 0, 0, 0, badfd, 0    }
  67.         ,
  68. };
  69.  
  70. static char *Argv[MAXARGS];
  71. static char Argbuf[MAXBUF];
  72. static int Argc;
  73.  
  74. static int Doingpipe = 0;
  75. static char *Cmdtail;
  76.  
  77. char *Pipe_in = "$PIPE.IN\0\0\0\0";
  78. char *Pipe_out = "$PIPE.OUT\0\0\0";
  79.  
  80. Croot()
  81. {
  82.         register char *cp, *fname;
  83.         register int k;
  84.  
  85.         clear (Argbuf, MAXBUF, (char) 32);
  86.         blockmv(Argbuf, (char *)0x81, 127);
  87.         clear (CBUF, MAXBUF, (char) 32);
  88.         Argbuf[*CBUF & 0x7f] = 0;
  89.         Argv[0] = "";
  90.         cp = Argbuf;
  91.         Argc = 1;
  92.         while (Argc < MAXARGS)
  93.         {
  94.                 while (*cp == ' ' || *cp == '\t')
  95.                         ++cp;
  96.                 if (*cp == 0)
  97.                 {
  98.                         break;
  99.                 }
  100.                 else if (*cp == '|')
  101.                 {
  102.                         Doingpipe = 1;
  103.                         Cmdtail = ++cp;
  104.                         fname = Pipe_out;
  105.                         k = 1;
  106.                         goto redir2;
  107.                 }
  108.                 else if (*cp == '>')
  109.                 {               /* redirect output */
  110.                         k = 1;
  111.                         goto redirect;
  112.                 }
  113.                 else if (*cp == '<')
  114.                 {  /* redirect input */
  115.                         k = 0;
  116. redirect:
  117.                         while (*++cp == ' ' || *cp == '\t')
  118.                                 ;
  119.                         fname = cp;
  120.                         while (*++cp)
  121.                         {
  122.                                 if (*cp == ' ' || *cp == '\t')
  123.                                 {
  124.                                         *cp++ = 0;
  125.                                         break;
  126.                                 }
  127.                         }
  128. redir2:
  129.  
  130.                         close(k);
  131.                         if (k)
  132.                                 k = creat(fname, 0666);
  133.                         else
  134.                                 k = open(fname, O_RDONLY);
  135.                         if (k == -1)
  136.                         {
  137.                                 strcpy
  138.                                 (0x80, "Can't open file for redirection: ");
  139.                                 strcat(0x80, fname);
  140.                                 strcat(0x80, "\n");
  141.                                 write(2, 0x80, strlen(0x80));
  142.                                 exit(10);
  143.                         }
  144.                         if (Doingpipe)
  145.                                 break;
  146.                 }
  147.                 else if (*cp == QUOTE)
  148.                 {
  149.                         Argv[Argc++] == ++cp;
  150.                         while (*cp && (*cp != '"'))
  151.                         {
  152.                                 cp++;
  153.                         }
  154.                         *cp++ = 0;
  155.                 }
  156.                 else if (haswild (cp))
  157.                 {
  158.                         Argc += do_wild (cp, Argv + Argc, MAXARGS - Argc - 1);
  159.                                 goto skippast;
  160.                         }
  161.                                 else
  162.                                 {
  163.                                         Argv[Argc++] = cp;
  164. skippast:
  165.                                         while (*++cp)
  166.                                         {
  167.                                                 if (*cp == ' ' || *cp == '\t')
  168.                                                 {
  169.                                                         *cp++ = 0;
  170.                                                         break;
  171.                                                 }
  172.                                         }
  173.                                 }
  174.                 }
  175.                 exit(main(Argc,Argv));
  176.         }
  177.  
  178.         exit(code)
  179.         {
  180.                 register char *tailp, *src, *dest;
  181.                 static char buff[MAXARGS];
  182.  
  183.                 clear (buff, MAXARGS, NULL);
  184.                 closall_();
  185.                 unlink (Pipe_in);
  186.                 if ( code )
  187.                         unlink("A:$$$.SUB");
  188. #ifdef DEBUG
  189.                 perr ("\r\nFirst Cmdtail = ");
  190.                 perr (Cmdtail);
  191.                 perr ("\r\n");
  192. #endif
  193.                 if (Doingpipe)
  194.                 {
  195.                         rename (Pipe_out, Pipe_in);
  196.                         while (*Cmdtail == ' ')
  197.                                 Cmdtail++;
  198.                         tailp = Cmdtail;
  199.                         while (*tailp && *tailp != ' ')
  200.                                 tailp++;
  201.                         if (*tailp)
  202.                                 *tailp++ = '\0';
  203.                         sprintf (buff, "%s < %s", tailp, Pipe_in);
  204. #ifdef DEBUG
  205.                         perr ("\r\nnext Cmdtail = ");
  206.                         perr (Cmdtail);
  207.                         perr ("\r\n");
  208.                         perr ("\r\nbuff = ");
  209.                         perr (buff);
  210.                         perr ("\r\n");
  211. #endif
  212.                         execl (Cmdtail, buff);
  213.                         perr ("Couldn't open file at end of pipe: ");
  214.                         perr (Cmdtail);
  215.                         perr (".COM");
  216.                         unlink ("A:$$$.SUB");
  217.                         unlink ("$$$.SUB");
  218.                 }
  219.                 boot_();
  220.         }
  221.  
  222.         execl (name, args)
  223.  
  224.         char *name, *args;
  225.  
  226.         {
  227.                 register char *cp, *dest, **argp;
  228.  
  229.                 sprintf (CBUF, "%s.%s", name, "COM");
  230.                 initfcb ((char *) CBUF, (char *) DEF_FCB);
  231. #ifdef DEBUG
  232.                 perr ("\r\nargs: ");
  233.                 perr (args);
  234.                 perr ("\r\n");
  235. #endif
  236.                 if (bdosopen (DEF_FCB) == 0xff)
  237.                         return (0);
  238.                 dest = CBUF + 1;
  239.                 for (argp = &args; *argp && dest < CBUFEND; argp++)
  240.                 {
  241.                         for (cp = *argp;
  242.                             *cp && dest < CBUFEND;
  243.                             *dest++ = *cp++);
  244.                         *dest++ = ' ';
  245.                 }
  246.                 *dest = '\0';
  247.                 *CBUF = (int) dest - (int) CBUF;
  248. #ifdef DEBUG
  249.                 perr ("\r\nCBUF: ");
  250.                 perr (CBUF);
  251.                 perr ("\r\n");
  252. #endif
  253.                 loadldr();
  254.  
  255.         }
  256.  
  257.  
  258.         perr (str)
  259.  
  260.         char *str;
  261.  
  262.         {
  263.                 while (*str)
  264.                         bdos (2, *str++);
  265.         }
  266.  
  267.         badfd()
  268.         {
  269.                 errno = EBADF;
  270.                 return -1;
  271.         }
  272.  
  273.         noper()
  274.         {
  275.                 return 0;
  276.         }
  277.  
  278.  
  279.         initfcb (filename, fcb)
  280.  
  281.         char *filename, *fcb;
  282.  
  283.         {
  284.                 register char *fp;
  285.                 register int i;
  286.  
  287.                 for (i = FCBSIZE, fp = fcb; --i > 0; *fp++ = 0)
  288.                         ;
  289.                 if (*filename && filename[1] == ':')
  290.                 {
  291.                         *fcb = (char) (toupper (*filename) - 'A' + 1);
  292.                         filename += 2;
  293.                 }
  294.                 expand_name (fcb, filename);
  295.         }
  296.  
  297.         expand_name (dest, src)
  298.  
  299.         char *dest, *src;
  300.  
  301.         {
  302.                 register char *dot, *end, i;
  303.  
  304.                 dot = ++dest;
  305.                 for (i = 11; --i >= 0;)
  306.                         *dot++ = *(src) ? ' ' : '?';
  307.                 dot = &dest[8];
  308.                 end = &dest[10];
  309.                 while (*src && *src != ' ')
  310.                 {
  311.                         if (*src == '*')
  312.                         {
  313.                                 if (dest < dot)
  314.                                 {
  315.                                         while (dest < dot)
  316.                                                 *dest++ = '?';
  317.                                 }
  318.                                 else
  319.                                 {
  320.                                         while (dest <= end)
  321.                                                 *dest++ = '?';
  322.                                 }
  323.                         }
  324.                         else if (*src == '.')
  325.                                 dest = dot;
  326.                         else
  327.                                 *dest++ = *src;
  328.                         src++;
  329.                 }
  330.         }
  331.  
  332.         int do_wild (fname, argv, maxarg)
  333.  
  334.                 char *fname, **argv;
  335.                 int maxarg;
  336.  
  337.         {
  338.                 register char *dest, *src;
  339.                 register unsigned int tmp;
  340.                 register int i, argc = 0;
  341.                 extern char *alloc();
  342.  
  343.                 initfcb ((char *) fname, (char *) DEF_FCB);
  344.                 if ((tmp = srchfirst (DEF_FCB)) != 0xff)
  345.                 {
  346.                         do
  347.                         {
  348.                                 if ((dest = fname = alloc (13)) == 0)
  349.                                 {
  350.                                         perr ("Not enough memory to expand wildcard");
  351.                                         exit (1);
  352.                                 }
  353.                                 src = ((char *) ((tmp << 5) + 0x80)) + 1;
  354.                                 if (*(fname + 1) == ':')
  355.                                 {
  356.                                         *dest++ = *fname;
  357.                                         *dest++ = ':';
  358.                                 }
  359.                                 for (i = 1; i <= 11; i++)
  360.                                 {
  361.                                         if ((*src & 0x7f) != ' ')
  362.                                                 *dest++ = *src++;
  363.                                         else
  364.                                                 src++;
  365.                                         if (i == 8)
  366.                                         {
  367.                                                 if ((*src & 0x7f) == ' ')
  368.                                                         break;
  369.                                                 else
  370.                                                         *dest++ = '.';
  371.                                         }
  372.                                 }
  373.                                 *dest = '\0';
  374.                                 argv[argc++] = fname;
  375.                                 tmp = srchnext (DEF_FCB);
  376.                         }
  377.                                 while ((tmp != 0xff) && (argc < maxarg));
  378.                 }
  379.                 return (argc);
  380.         }
  381.  
  382.                 haswild (str)
  383.  
  384.                 char *str;
  385.  
  386.         {
  387.                 register int c;
  388.  
  389.                 do
  390.                 {
  391.                         c = *str++;
  392.                         if (c == '*' || c == '?')
  393.                                 return (1);
  394.                 }
  395.                         while (c && c != ' ');
  396.                 return (0);
  397.         }
  398.