home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / CROOT.ZIP / CROOT.C
Encoding:
Text File  |  1988-07-28  |  14.5 KB  |  491 lines

  1. Article 2674 (56 more) in net.sources:
  2. From: edwards@h-sc1.UUCP (william edwards)
  3. Subject: AZTEC C CROOT
  4. Message-ID: <543@h-sc1.UUCP>
  5. Date: 20 Aug 85 16:37:49 GMT
  6. Date-Received: 26 Aug 85 06:26:24 GMT
  7. Reply-To: edwards@h-sc1.UUCP (william edwards)
  8. Distribution: net
  9. Organization: Harvard Univ. Science Center
  10. Lines: 477
  11. Keywords: pipes execl wildcards Aztec CP/M
  12. Summary: Aztec C croot for CP/M-80
  13.  
  14. --MORE--(4%)
  15. I had a request to post this, so here it is.  These are some
  16. modifications and additions to the Aztec C croot, which add
  17. wildcard expansion and pipes.  * I did not write these *.  I
  18. merely keyed in and debugged somewhat what I found in the
  19. March 1985 issue of Dr. Dobb's Journal.  Please refer to that
  20. for a * commented * version of this code.  There are two files
  21. here: the first is C  source for these routines, and the
  22. second is assembler source for a loader.  These modules
  23. replace the croot which comes with Aztec C.
  24.  
  25. ----croot.c----------------------------------------
  26. /* Copyright (C) 1981,1982 by Manx Software Systems.
  27.    Copyright (C) 1982  Thomas Fenwick.
  28.    Copyright (c) 1985 Allen Holub.
  29.  
  30.    Manx Software Systems is in no way responsible for this program.
  31.    These portions may be reproduced for personal, non-profit use,
  32.    only.  All other use is prohibited.  You should replace the croot in
  33.    libc.lib with this module.  This posting includes a couple of
  34.    minor hacks by wse */
  35.  
  36. #include "fcntl.h"
  37. #include "errno.h"
  38. #include "io.h"
  39.  
  40. #define MAXARGS 128
  41. #define MAXBUF 128
  42. #define LOADERSIZE 49
  43. #define DEF_FCB 0x5c
  44. #define FCBSIZE 36
  45. #define NULL 0
  46. #define QUOTE 0x22
  47. #define CBUF    ((char *)0x80)
  48. #define CBUFEND (char *)(0x80+128-LOADERSIZE)
  49.  
  50. #define srchfirst(fcb) (bdos (0x11, (fcb)) & 0xff)
  51. #define srchnext(fcb) (bdos (0x12, (fcb)) & 0xff)
  52. #define bdosopen(fcb)  (bdos (0x0f, (fcb)) & 0xff)
  53. #define isalnum(c) (c >= 0x20 && c <= 0x7e)
  54. int badfd(), noper();
  55.  
  56. /*
  57.  * channel table: relates fd's to devices
  58.  */
  59. struct channel  chantab[] = {
  60.          {
  61.                 2, 0, 1, 0, noper, 2    }
  62.         ,
  63.         {
  64.                 0, 2, 1, 0, noper, 2    }
  65.         ,
  66.         {
  67.                 0, 2, 1, 0, noper, 2    }
  68.         ,
  69.         {
  70.                 0, 0, 0, 0, badfd, 0    }
  71.         ,
  72.         {
  73.                 0, 0, 0, 0, badfd, 0    }
  74.         ,
  75.         {
  76.                 0, 0, 0, 0, badfd, 0    }
  77.         ,
  78.         {
  79.                 0, 0, 0, 0, badfd, 0    }
  80.         ,
  81.         {
  82.                 0, 0, 0, 0, badfd, 0    }
  83.         ,
  84.         {
  85.                 0, 0, 0, 0, badfd, 0    }
  86.         ,
  87.         {
  88.                 0, 0, 0, 0, badfd, 0    }
  89.         ,
  90.         {
  91.                 0, 0, 0, 0, badfd, 0    }
  92.         ,
  93. };
  94.  
  95. static char *Argv[MAXARGS];
  96. static char Argbuf[MAXBUF];
  97. static int Argc;
  98.  
  99. static int Doingpipe = 0;
  100. static char *Cmdtail;
  101.  
  102. char *Pipe_in = "$PIPE.IN\0\0\0\0";
  103. char *Pipe_out = "$PIPE.OUT\0\0\0";
  104.  
  105. Croot()
  106. {
  107.         register char *cp, *fname;
  108.         register int k;
  109.  
  110.         clear (Argbuf, MAXBUF, (char) 32);
  111.         blockmv(Argbuf, (char *)0x81, 127);
  112.         clear (CBUF, MAXBUF, (char) 32);
  113.         Argbuf[*CBUF & 0x7f] = 0;
  114.         Argv[0] = "";
  115.         cp = Argbuf;
  116.         Argc = 1;
  117.         while (Argc < MAXARGS)
  118.         {
  119.                 while (*cp == ' ' || *cp == '\t')
  120.                         ++cp;
  121.                 if (*cp == 0)
  122.                 {
  123.                         break;
  124.                 }
  125.                 else if (*cp == '|')
  126.                 {
  127.                         Doingpipe = 1;
  128.                         Cmdtail = ++cp;
  129.                         fname = Pipe_out;
  130.                         k = 1;
  131.                         goto redir2;
  132.                 }
  133.                 else if (*cp == '>')
  134.                 {               /* redirect output */
  135.                         k = 1;
  136.                         goto redirect;
  137.                 }
  138.                 else if (*cp == '<')
  139.                 {  /* redirect input */
  140.                         k = 0;
  141. redirect:
  142.                         while (*++cp == ' ' || *cp == '\t')
  143.                                 ;
  144.                         fname = cp;
  145.                         while (*++cp)
  146.                         {
  147.                                 if (*cp == ' ' || *cp == '\t')
  148.                                 {
  149.                                         *cp++ = 0;
  150.                                         break;
  151.                                 }
  152.                         }
  153. redir2:
  154.  
  155.                         close(k);
  156.                         if (k)
  157.                                 k = creat(fname, 0666);
  158.                         else
  159.                                 k = open(fname, O_RDONLY);
  160.                         if (k == -1)
  161.                         {
  162.                                 strcpy
  163.                                 (0x80, "Can't open file for redirection: ");
  164.                                 strcat(0x80, fname);
  165.                                 strcat(0x80, "\n");
  166.                                 write(2, 0x80, strlen(0x80));
  167.                                 exit(10);
  168.                         }
  169.                         if (Doingpipe)
  170.                                 break;
  171.                 }
  172.                 else if (*cp == QUOTE)
  173.                 {
  174.                         Argv[Argc++] == ++cp;
  175.                         while (*cp && (*cp != '"'))
  176.                         {
  177.                                 cp++;
  178.                         }
  179.                         *cp++ = 0;
  180.                 }
  181.                 else if (haswild (cp))
  182.                 {
  183.                         Argc += do_wild (cp, Argv + Argc, MAXARGS - Argc - 1);
  184.                                 goto skippast;
  185.                         }
  186.                                 else
  187.                                 {
  188.                                         Argv[Argc++] = cp;
  189. skippast:
  190.                                         while (*++cp)
  191.                                         {
  192.                                                 if (*cp == ' ' || *cp == '\t')
  193.                                                 {
  194.                                                         *cp++ = 0;
  195.                                                         break;
  196.                                                 }
  197.                                         }
  198.                                 }
  199.                 }
  200.                 exit(main(Argc,Argv));
  201.         }
  202.  
  203.         exit(code)
  204.         {
  205.                 register char *tailp, *src, *dest;
  206.                 static char buff[MAXARGS];
  207.  
  208.                 clear (buff, MAXARGS, NULL);
  209.                 closall_();
  210.                 unlink (Pipe_in);
  211.                 if ( code )
  212.                         unlink("A:$$$.SUB");
  213. #ifdef DEBUG
  214.                 perr ("\r\nFirst Cmdtail = ");
  215.                 perr (Cmdtail);
  216.                 perr ("\r\n");
  217. #endif
  218.                 if (Doingpipe)
  219.                 {
  220.                         rename (Pipe_out, Pipe_in);
  221.                         while (*Cmdtail == ' ')
  222.                                 Cmdtail++;
  223.                         tailp = Cmdtail;
  224.                         while (*tailp && *tailp != ' ')
  225.                                 tailp++;
  226.                         if (*tailp)
  227.                                 *tailp++ = '\0';
  228.                         sprintf (buff, "%s < %s", tailp, Pipe_in);
  229. #ifdef DEBUG
  230.                         perr ("\r\nnext Cmdtail = ");
  231.                         perr (Cmdtail);
  232.                         perr ("\r\n");
  233.                         perr ("\r\nbuff = ");
  234.                         perr (buff);
  235.                         perr ("\r\n");
  236. #endif
  237.                         execl (Cmdtail, buff);
  238.                         perr ("Couldn't open file at end of pipe: ");
  239.                         perr (Cmdtail);
  240.                         perr (".COM");
  241.                         unlink ("A:$$$.SUB");
  242.                         unlink ("$$$.SUB");
  243.                 }
  244.                 boot_();
  245.         }
  246.  
  247.         execl (name, args)
  248.  
  249.         char *name, *args;
  250.  
  251.         {
  252.                 register char *cp, *dest, **argp;
  253.  
  254.                 sprintf (CBUF, "%s.%s", name, "COM");
  255.                 initfcb ((char *) CBUF, (char *) DEF_FCB);
  256. #ifdef DEBUG
  257.                 perr ("\r\nargs: ");
  258.                 perr (args);
  259.                 perr ("\r\n");
  260. #endif
  261.                 if (bdosopen (DEF_FCB) == 0xff)
  262.                         return (0);
  263.                 dest = CBUF + 1;
  264.                 for (argp = &args; *argp && dest < CBUFEND; argp++)
  265.                 {
  266.                         for (cp = *argp;
  267.                             *cp && dest < CBUFEND;
  268.                             *dest++ = *cp++);
  269.                         *dest++ = ' ';
  270.                 }
  271.                 *dest = '\0';
  272.                 *CBUF = (int) dest - (int) CBUF;
  273. #ifdef DEBUG
  274.                 perr ("\r\nCBUF: ");
  275.                 perr (CBUF);
  276.                 perr ("\r\n");
  277. #endif
  278.                 loadldr();
  279.  
  280.         }
  281.  
  282.  
  283.         perr (str)
  284.  
  285.         char *str;
  286.  
  287.         {
  288.                 while (*str)
  289.                         bdos (2, *str++);
  290.         }
  291.  
  292.         badfd()
  293.         {
  294.                 errno = EBADF;
  295.                 return -1;
  296.         }
  297.  
  298.         noper()
  299.         {
  300.                 return 0;
  301.         }
  302.  
  303.  
  304.         initfcb (filename, fcb)
  305.  
  306.         char *filename, *fcb;
  307.  
  308.         {
  309.                 register char *fp;
  310.                 register int i;
  311.  
  312.                 for (i = FCBSIZE, fp = fcb; --i > 0; *fp++ = 0)
  313.                         ;
  314.                 if (*filename && filename[1] == ':')
  315.                 {
  316.                         *fcb = (char) (toupper (*filename) - 'A' + 1);
  317.                         filename += 2;
  318.                 }
  319.                 expand_name (fcb, filename);
  320.         }
  321.  
  322.         expand_name (dest, src)
  323.  
  324.         char *dest, *src;
  325.  
  326.         {
  327.                 register char *dot, *end, i;
  328.  
  329.                 dot = ++dest;
  330.                 for (i = 11; --i >= 0;)
  331.                         *dot++ = *(src) ? ' ' : '?';
  332.                 dot = &dest[8];
  333.                 end = &dest[10];
  334.                 while (*src && *src != ' ')
  335.                 {
  336.                         if (*src == '*')
  337.                         {
  338.                                 if (dest < dot)
  339.                                 {
  340.                                         while (dest < dot)
  341.                                                 *dest++ = '?';
  342.                                 }
  343.                                 else
  344.                                 {
  345.                                         while (dest <= end)
  346.                                                 *dest++ = '?';
  347.                                 }
  348.                         }
  349.                         else if (*src == '.')
  350.                                 dest = dot;
  351.                         else
  352.                                 *dest++ = *src;
  353.                         src++;
  354.                 }
  355.         }
  356.  
  357.         int do_wild (fname, argv, maxarg)
  358.  
  359.                 char *fname, **argv;
  360.                 int maxarg;
  361.  
  362.         {
  363.                 register char *dest, *src;
  364.                 register unsigned int tmp;
  365.                 register int i, argc = 0;
  366.                 extern char *alloc();
  367.  
  368.                 initfcb ((char *) fname, (char *) DEF_FCB);
  369.                 if ((tmp = srchfirst (DEF_FCB)) != 0xff)
  370.                 {
  371.                         do
  372.                         {
  373.                                 if ((dest = fname = alloc (13)) == 0)
  374.                                 {
  375.                                         perr ("Not enough memory to expand wildcard");
  376.                                         exit (1);
  377.                                 }
  378.                                 src = ((char *) ((tmp << 5) + 0x80)) + 1;
  379.                                 if (*(fname + 1) == ':')
  380.                                 {
  381.                                         *dest++ = *fname;
  382.                                         *dest++ = ':';
  383.                                 }
  384.                                 for (i = 1; i <= 11; i++)
  385.                                 {
  386.                                         if ((*src & 0x7f) != ' ')
  387.                                                 *dest++ = *src++;
  388.                                         else
  389.                                                 src++;
  390.                                         if (i == 8)
  391.                                         {
  392.                                                 if ((*src & 0x7f) == ' ')
  393.                                                         break;
  394.                                                 else
  395.                                                         *dest++ = '.';
  396.                                         }
  397.                                 }
  398.                                 *dest = '\0';
  399.                                 argv[argc++] = fname;
  400.                                 tmp = srchnext (DEF_FCB);
  401.                         }
  402.                                 while ((tmp != 0xff) && (argc < maxarg));
  403.                 }
  404.                 return (argc);
  405.         }
  406.  
  407.                 haswild (str)
  408.  
  409.                 char *str;
  410.  
  411.         {
  412.                 register int c;
  413.  
  414.                 do
  415.                 {
  416.                         c = *str++;
  417.                         if (c == '*' || c == '?')
  418.                                 return (1);
  419.                 }
  420.                         while (c && c != ' ');
  421.                 return (0);
  422.         }
  423. ----------ldldr.asm---------------------------------------------
  424. ; LDLDR.ASM -- asm support for Manx pipes
  425.  
  426. closec  equ     16
  427. reads   equ     20
  428. sdma    equ     26
  429.  
  430. fcb     equ     5ch
  431. tpa     equ     100h
  432. tbuff   equ     80h
  433. bdos    equ     05h
  434. bdosv   equ     06h
  435.  
  436. loader:
  437.         lxi     d,tpa
  438.  
  439. load1:
  440.         push    d
  441.         push    b
  442.         mvi     c,sdma
  443.         call    bdos
  444.         pop     d
  445.         push    d
  446.         mvi     c,reads
  447.         call    bdos
  448.         pop     b
  449.         pop     d
  450.         ora     a
  451.         jz      tpa - 8
  452.         mov     d,b
  453.         mov     e,c
  454.         mvi     c,closec
  455.         call    bdos
  456.         
  457.         mvi     c,sdma
  458.         lxi     d,tbuff
  459.         call    bdos
  460.         jmp     tpa
  461.  
  462. load2:
  463.         lxi     h,80h
  464.         dad     d
  465.         xchg
  466.         jmp     tpa-46
  467.  
  468.         public  loadldr_
  469.  
  470. loadldr_:
  471.         lxi     d,loader
  472.         lxi     h,tpa-49
  473.         mvi     b,49
  474.  
  475. L1:
  476.         ldax    d
  477.         mov     m,a
  478.         inx     d
  479.         inx     h
  480.  
  481.         dcr     b
  482.         jnz     L1
  483.         lxi     b,fcb
  484.         lxi     d,tpa
  485.         lhld    bdosv
  486.         sphl
  487.  
  488.         jmp     tpa-49
  489.  
  490.         end
  491.  
  492.