AZTEC C CROOT
william edwards
edwards at h-sc1.UUCP
Wed Aug 21 02:37:49 AEST 1985
I had a request to post this, so here it is. These are some
modifications and additions to the Aztec C croot, which add
wildcard expansion and pipes. * I did not write these *. I
merely keyed in and debugged somewhat what I found in the
March 1985 issue of Dr. Dobb's Journal. Please refer to that
for a * commented * version of this code. There are two files
here: the first is C source for these routines, and the
second is assembler source for a loader. These modules
replace the croot which comes with Aztec C.
----croot.c----------------------------------------
/* 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);
}
----------ldldr.asm---------------------------------------------
; LDLDR.ASM -- asm support for Manx pipes
closec equ 16
reads equ 20
sdma equ 26
fcb equ 5ch
tpa equ 100h
tbuff equ 80h
bdos equ 05h
bdosv equ 06h
loader:
lxi d,tpa
load1:
push d
push b
mvi c,sdma
call bdos
pop d
push d
mvi c,reads
call bdos
pop b
pop d
ora a
jz tpa - 8
mov d,b
mov e,c
mvi c,closec
call bdos
mvi c,sdma
lxi d,tbuff
call bdos
jmp tpa
load2:
lxi h,80h
dad d
xchg
jmp tpa-46
public loadldr_
loadldr_:
lxi d,loader
lxi h,tpa-49
mvi b,49
L1:
ldax d
mov m,a
inx d
inx h
dcr b
jnz L1
lxi b,fcb
lxi d,tpa
lhld bdosv
sphl
jmp tpa-49
end
More information about the Comp.sources.unix
mailing list