/* Copyright (C) 1981,1982 by Manx Software Systems. Copyright (C) 1982 Thomas Fenwick. Copyright (c) 1985 Allen Holub. Manx Software Systems is in no way responsible for this program. These portions may be reproduced for personal, non-profit use, only. All other use is prohibited. You should replace the croot in libc.lib with this module. This posting includes a couple of minor hacks by wse */ #include "fcntl.h" #include "errno.h" #include "io.h" #define MAXARGS 128 #define MAXBUF 128 #define LOADERSIZE 49 #define DEF_FCB 0x5c #define FCBSIZE 36 #define NULL 0 #define QUOTE 0x22 #define CBUF ((char *)0x80) #define CBUFEND (char *)(0x80+128-LOADERSIZE) #define srchfirst(fcb) (bdos (0x11, (fcb)) & 0xff) #define srchnext(fcb) (bdos (0x12, (fcb)) & 0xff) #define bdosopen(fcb) (bdos (0x0f, (fcb)) & 0xff) #define isalnum(c) (c >= 0x20 && c <= 0x7e) int badfd(), noper(); /* * channel table: relates fd's to devices */ struct channel chantab[] = { { 2, 0, 1, 0, noper, 2 } , { 0, 2, 1, 0, noper, 2 } , { 0, 2, 1, 0, noper, 2 } , { 0, 0, 0, 0, badfd, 0 } , { 0, 0, 0, 0, badfd, 0 } , { 0, 0, 0, 0, badfd, 0 } , { 0, 0, 0, 0, badfd, 0 } , { 0, 0, 0, 0, badfd, 0 } , { 0, 0, 0, 0, badfd, 0 } , { 0, 0, 0, 0, badfd, 0 } , { 0, 0, 0, 0, badfd, 0 } , }; static char *Argv[MAXARGS]; static char Argbuf[MAXBUF]; static int Argc; static int Doingpipe = 0; static char *Cmdtail; char *Pipe_in = "$PIPE.IN\0\0\0\0"; char *Pipe_out = "$PIPE.OUT\0\0\0"; Croot() { register char *cp, *fname; register int k; clear (Argbuf, MAXBUF, (char) 32); blockmv(Argbuf, (char *)0x81, 127); clear (CBUF, MAXBUF, (char) 32); Argbuf[*CBUF & 0x7f] = 0; Argv[0] = ""; cp = Argbuf; Argc = 1; while (Argc < MAXARGS) { while (*cp == ' ' || *cp == '\t') ++cp; if (*cp == 0) { break; } else if (*cp == '|') { Doingpipe = 1; Cmdtail = ++cp; fname = Pipe_out; k = 1; goto redir2; } else if (*cp == '>') { /* redirect output */ k = 1; goto redirect; } else if (*cp == '<') { /* redirect input */ k = 0; redirect: while (*++cp == ' ' || *cp == '\t') ; fname = cp; while (*++cp) { if (*cp == ' ' || *cp == '\t') { *cp++ = 0; break; } } redir2: close(k); if (k) k = creat(fname, 0666); else k = open(fname, O_RDONLY); if (k == -1) { strcpy (0x80, "Can't open file for redirection: "); strcat(0x80, fname); strcat(0x80, "\n"); write(2, 0x80, strlen(0x80)); exit(10); } if (Doingpipe) break; } else if (*cp == QUOTE) { Argv[Argc++] == ++cp; while (*cp && (*cp != '"')) { cp++; } *cp++ = 0; } else if (haswild (cp)) { Argc += do_wild (cp, Argv + Argc, MAXARGS - Argc - 1); goto skippast; } else { Argv[Argc++] = cp; skippast: while (*++cp) { if (*cp == ' ' || *cp == '\t') { *cp++ = 0; break; } } } } exit(main(Argc,Argv)); } exit(code) { register char *tailp, *src, *dest; static char buff[MAXARGS]; clear (buff, MAXARGS, NULL); closall_(); unlink (Pipe_in); if ( code ) unlink("A:$$$.SUB"); #ifdef DEBUG perr ("\r\nFirst Cmdtail = "); perr (Cmdtail); perr ("\r\n"); #endif if (Doingpipe) { rename (Pipe_out, Pipe_in); while (*Cmdtail == ' ') Cmdtail++; tailp = Cmdtail; while (*tailp && *tailp != ' ') tailp++; if (*tailp) *tailp++ = '\0'; sprintf (buff, "%s < %s", tailp, Pipe_in); #ifdef DEBUG perr ("\r\nnext Cmdtail = "); perr (Cmdtail); perr ("\r\n"); perr ("\r\nbuff = "); perr (buff); perr ("\r\n"); #endif execl (Cmdtail, buff); perr ("Couldn't open file at end of pipe: "); perr (Cmdtail); perr (".COM"); unlink ("A:$$$.SUB"); unlink ("$$$.SUB"); } boot_(); } execl (name, args) char *name, *args; { register char *cp, *dest, **argp; sprintf (CBUF, "%s.%s", name, "COM"); initfcb ((char *) CBUF, (char *) DEF_FCB); #ifdef DEBUG perr ("\r\nargs: "); perr (args); perr ("\r\n"); #endif if (bdosopen (DEF_FCB) == 0xff) return (0); dest = CBUF + 1; for (argp = &args; *argp && dest < CBUFEND; argp++) { for (cp = *argp; *cp && dest < CBUFEND; *dest++ = *cp++); *dest++ = ' '; } *dest = '\0'; *CBUF = (int) dest - (int) CBUF; #ifdef DEBUG perr ("\r\nCBUF: "); perr (CBUF); perr ("\r\n"); #endif loadldr(); } perr (str) char *str; { while (*str) bdos (2, *str++); } badfd() { errno = EBADF; return -1; } noper() { return 0; } initfcb (filename, fcb) char *filename, *fcb; { register char *fp; register int i; for (i = FCBSIZE, fp = fcb; --i > 0; *fp++ = 0) ; if (*filename && filename[1] == ':') { *fcb = (char) (toupper (*filename) - 'A' + 1); filename += 2; } expand_name (fcb, filename); } expand_name (dest, src) char *dest, *src; { register char *dot, *end, i; dot = ++dest; for (i = 11; --i >= 0;) *dot++ = *(src) ? ' ' : '?'; dot = &dest[8]; end = &dest[10]; while (*src && *src != ' ') { if (*src == '*') { if (dest < dot) { while (dest < dot) *dest++ = '?'; } else { while (dest <= end) *dest++ = '?'; } } else if (*src == '.') dest = dot; else *dest++ = *src; src++; } } int do_wild (fname, argv, maxarg) char *fname, **argv; int maxarg; { register char *dest, *src; register unsigned int tmp; register int i, argc = 0; extern char *alloc(); initfcb ((char *) fname, (char *) DEF_FCB); if ((tmp = srchfirst (DEF_FCB)) != 0xff) { do { if ((dest = fname = alloc (13)) == 0) { perr ("Not enough memory to expand wildcard"); exit (1); } src = ((char *) ((tmp << 5) + 0x80)) + 1; if (*(fname + 1) == ':') { *dest++ = *fname; *dest++ = ':'; } for (i = 1; i <= 11; i++) { if ((*src & 0x7f) != ' ') *dest++ = *src++; else src++; if (i == 8) { if ((*src & 0x7f) == ' ') break; else *dest++ = '.'; } } *dest = '\0'; argv[argc++] = fname; tmp = srchnext (DEF_FCB); } while ((tmp != 0xff) && (argc < maxarg)); } return (argc); } haswild (str) char *str; { register int c; do { c = *str++; if (c == '*' || c == '?') return (1); } while (c && c != ' '); return (0); }