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