page@swan.ulowell.edu (Bob Page) (10/25/88)
Submitted-by: dillon@cory.berkeley.edu (Matt Dillon) Posting-number: Volume 2, Issue 23 Archive-name: unix/shell211.2 # This is a shell archive. Remove anything before this line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # This archive contains the following files: # Makefile # TODO # c.asm # comm1.c # comm2.c # if `test ! -s Makefile` then echo "writing Makefile" cat > Makefile << '\Rogue\Monster\' # SHELL makefile for AZTEC C EXE = srcc:shell SYMS = ram:symbols.m SYM = comp:include/symbols.m AUX = $(EXE) TODO examples.txt shell.h SRC1 = execom.c SRC2 = comm2.c SRC3 = set.c SRC4 = sub.c SRC5 = main.c SRC6 = globals.c SRC7 = comm1.c SRC8 = run.c SRC9 = fexec1.c SRCA = fexec2.asm SRCB = c.asm SRCC = sort.c SRCD = hat.c OBJ1 = vd0:execom.o OBJ2 = vd0:comm2.o OBJ3 = vd0:set.o OBJ4 = vd0:sub.o OBJ5 = vd0:main.o OBJ6 = vd0:globals.o OBJ7 = vd0:comm1.o OBJ8 = vd0:run.o OBJ9 = vd0:fexec1.o OBJA = vd0:fexec2.o OBJB = vd0:c.o OBJC = vd0:sort.o OBJD = vd0:hat.o SRCS = $(SRC1) $(SRC2) $(SRC3) $(SRC4) $(SRC5) $(SRC6) $(SRC7) $(SRC8) $(SRC9) $(SRCA) $(SRCB) $(SRCC) $(SRCD) OBJS = $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6) $(OBJ7) $(OBJ8) $(OBJ9) $(OBJA) $(OBJB) $(OBJC) $(OBJD) CFLAGS = +L +I$(SYMS) $(EXE): $(SYMS) $(OBJS) ln +Q $(OBJS) -lsup32 -ldres -lc32 -o $(EXE) arc: -delete ram:shell.arc arc a ram:shell $(SRCS) arc a ram:shell $(AUX) $(SYMS): $(SYM) copy $(SYM) $(SYMS) $(OBJ1): $(SRC1) cc $(CFLAGS) $*.c -o $(OBJ1) $(OBJ2): $(SRC2) cc $(CFLAGS) $*.c -o $(OBJ2) $(OBJ3): $(SRC3) cc $(CFLAGS) $*.c -o $(OBJ3) $(OBJ4): $(SRC4) cc $(CFLAGS) $*.c -o $(OBJ4) $(OBJ5): $(SRC5) cc $(CFLAGS) $*.c -o $(OBJ5) $(OBJ6): $(SRC6) cc $(CFLAGS) $*.c -o $(OBJ6) $(OBJ7): $(SRC7) cc $(CFLAGS) $*.c -o $(OBJ7) $(OBJ8): $(SRC8) cc $(CFLAGS) $*.c -o $(OBJ8) $(OBJ9): $(SRC9) cc $(CFLAGS) $*.c -o $(OBJ9) $(OBJA): $(SRCA) as $*.asm -o $(OBJA) $(OBJB): $(SRCB) as $*.asm -o $(OBJB) $(OBJC): $(SRCC) cc $(CFLAGS) $*.c -o $(OBJC) $(OBJD): $(SRCD) cc $(CFLAGS) $*.c -o $(OBJD) \Rogue\Monster\ else echo "will not over write Makefile" fi if [ `wc -c Makefile | awk '{printf $1}'` -ne 1665 ] then echo `wc -c Makefile | awk '{print "Got " $1 ", Expected " 1665}'` fi if `test ! -s TODO` then echo "writing TODO" cat > TODO << '\Rogue\Monster\' -SetFileDate() routine in comm2.c -set xx " x" initial space ignored in quoted section. -change -f to -e -version -history rel. -flag copy noisy. recompile version LATTICE free_memory(). PIPE/PARALLEL implimentation: a | b -pipe a || b -execute in parallel parallel break each command into: command, parameters input redirection or pipe in output redirection or pipe out call command executor MUST always specify redirection file names. command executor: If not pipe segment (last seg is not considered a pipe) execute via shell else execute a RUN via shell send pipe terminate command for input and output pipe's in case RUN failed. external(avlist, infilename, outfilename) char **avlist; char *infilename; NULL means take last pipe segment char *outfilename; NULL means send to next pipe segment { figure out aux. names (for pipes). if (outfilename == NULL) { exec a c:RUN >file <file if (infilename == NULL) /* Ensure pipe has been cleared */ pipeclear inpipe if (outfilename == NULL) pipeclear outpipe } else { open pert. files exec a ......... close pert. files } } \Rogue\Monster\ else echo "will not over write TODO" fi if [ `wc -c TODO | awk '{printf $1}'` -ne 1200 ] then echo `wc -c TODO | awk '{print "Got " $1 ", Expected " 1200}'` fi if `test ! -s c.asm` then echo "writing c.asm" cat > c.asm << '\Rogue\Monster\' ;:ts=8 ; Copyright (C) 1986,1987 by Manx Software Systems, Inc. ; ; Initial startup routine for Aztec C. ; NOTE: code down to "start" must be placed at beginning of ; all programs linked with Aztec Linker using small ; code or small data. mc68881 entry .begin public .begin FAR code FAR data .begin move.l a0,-(sp) lea _SysRegs,a0 movem.l d0-d7/a0-a6,(a0) move.l (sp)+,a0 bsr _geta4 ;get A4 lea __H1_end,a1 lea __H2_org,a2 cmp.l a1,a2 ;check if BSS and DATA together bne start ;no, don't have to clear move.w #((__H2_end-__H2_org)/4)-1,d1 bmi start ;skip if no bss move.l #0,d2 loop move.l d2,(a1)+ ;clear out memory dbra d1,loop start move.l sp,__savsp ;save stack pointer move.l 4,a6 ;get Exec's library base pointer move.l a6,_SysBase ;put where we can get it movem.l d0/a0,-(sp) ;save CLI command parameters btst.b #4,$129(a6) ;check for 68881 flag in AttnFlags beq x1 ;skip if not lea x2,a5 jsr -30(a6) ;do it in supervisor mode bra x1 x2 clr.l -(sp) frestore (sp)+ ;reset the ffp stuff rte ;and return x1 lea dos_name,a1 ;get name of dos library jsr -408(a6) ;open the library any version move.l d0,_DOSBase ;set it up bne x3 ;skip if okay move.l #$38007,d7 ;AG_OpenLib | AO_DOSLib jsr -108(a6) ;Alert bra x4 x3 jsr __main ;call the startup stuff x4 add.w #8,sp ;pop args rts ;and return dos_name: dc.b 'dos.library',0 public _geta4 _geta4: far data lea __H1_org+32766,a4 rts public __main,__H0_org dseg public _SysRegs public _SysBase,__savsp,_DOSBase public __H1_org,__H1_end,__H2_org,__H2_end \Rogue\Monster\ else echo "will not over write c.asm" fi if [ `wc -c c.asm | awk '{printf $1}'` -ne 2456 ] then echo `wc -c c.asm | awk '{print "Got " $1 ", Expected " 2456}'` fi if `test ! -s comm1.c` then echo "writing comm1.c" cat > comm1.c << '\Rogue\Monster\' /* * COMM1.C * * (c)1986 Matthew Dillon 9 October 1986 * * SLEEP * NUMBER -handles values as commands, actually a NULL command. * CAT * COMMENT * DIR -also handles DEVINFO * QUIT -also handles EXIT * ECHO * SOURCE * CD * MKDIR * MV * RM * HISTORY * MEM * FOREACH * FOREVER * * NOTE: SET/UNSET/ALIAS/UNALIAS handled in SET.C * */ #include "shell.h" #include <stdio.h> extern LOCK *CreateDir(), *CurrentDir(), *ParentDir(); extern LOCK *Lock(), *DupLock(); extern long disp_entry(); struct FileLock *Clock; do_sleep() { register int i; if (ac == 2) { i = atoi(av[1]); while (i > 0) { Delay (50*2); i -= 2; if (CHECKBREAK()) break; } } return (0); } do_number() { return (0); } do_cat() { FILE *fi; short i; char buf[256]; if (ac == 1) { while (fgets(buf, 256, stdin)) { Write(Cout, buf, strlen(buf)); if (CHECKBREAK()) break; } clearerr(stdin); } for (i = 1; i < ac; ++i) { if (fi = fopen (av[i], "r")) { while (fgets (buf, 256, fi)) { Write(Cout, buf, strlen(buf)); if (CHECKBREAK()) break; } fclose(fi); } else { fhprintf (Cerr, "could not open %s\n", av[i]); } } return (0); } /* * comment file string */ do_comment(str) char *str; { register char *ptr = next_word(next_word(str)); if (SetComment(av[1], ptr) == 0) { perror(av[1]); return(1); } return(0); } do_dir(garbage, com) char *garbage; { register struct DPTR *dp; register struct InfoData *info; char *name; char br = 0; register short i; int stat; short longmode = 1; short dcomment = 1; short avstart = 1; register long total = 0; if (av[1][0] == '-') { ++avstart; for (i = 1; av[1][i]; ++i) { switch(av[1][i]) { case 's': longmode = 0; break; case 'l': longmode = 1; break; case 'C': dcomment = 0; break; } } } if (ac == avstart) av[ac++] = ""; for (i = avstart; !br && i < ac; ++i) { if ((dp = dopen (av[i], &stat)) == NULL) continue; if (com < 0) { info = (struct InfoData *)AllocMem(sizeof(struct InfoData), MEMF_PUBLIC); if (Info (dp->lock, info)) { int bpb = info->id_BytesPerBlock; fhprintf (Cout, "Unit:%2ld Errs:%3ld Bytes: %-7ld Free: %-7ld %%full: %ld\n", info->id_UnitNumber, info->id_NumSoftErrors, bpb * info->id_NumBlocks, bpb * (info->id_NumBlocks - info->id_NumBlocksUsed), info->id_NumBlocksUsed * 100 / info->id_NumBlocks ); } else { perror (av[i]); } FreeMem (info, sizeof(*info)); } else { if (stat) { while (dnext (dp, &name, &stat)) { total += disp_entry (dp->fib, longmode, dcomment); if (CHECKBREAK()) { br = 1; break; } } } else { total += disp_entry(dp->fib, longmode, dcomment); } } dclose (dp); } fhprintf (Cout, "TOTAL: %ld\n", total); return (0); } static long disp_entry(fib, lengthy, comment) register struct FileInfoBlock *fib; { char str[6]; char dstr[32]; register char *dirstr; str[5] = '\0'; str[0] = (fib->fib_Protection & FIBF_READ) ? '-' : 'r'; str[1] = (fib->fib_Protection & FIBF_WRITE) ? '-' : 'w'; str[2] = (fib->fib_Protection & FIBF_EXECUTE) ? '-' : 'x'; str[3] = (fib->fib_Protection & FIBF_DELETE) ? '-' : 'd'; str[4] = (fib->fib_Protection & FIBF_ARCHIVE) ? '-' : 'a'; dirstr = (fib->fib_DirEntryType < 0) ? " " : "DIR"; fhprintf (Cout, "%s %6ld %s %-20s", str, (long)fib->fib_Size, dirstr, fib->fib_FileName ); if (lengthy) fhprintf (Cout, " %s", datetos(&fib->fib_Date, dstr, "D M Y h:m")); if (comment) fhprintf (Cout, " %s", fib->fib_Comment); fhprintf(Cout, "\n"); return ((long)fib->fib_Size); } do_quit() { if (Src_stack) { Quit = 1; return(do_return()); } main_exit (0); } do_echo(str) char *str; { register char *ptr; char nl = 1; for (ptr = str; *ptr && *ptr != ' '; ++ptr); if (*ptr == ' ') ++ptr; if (av[1] && strcmp (av[1], "-n") == 0) { nl = 0; ptr += 2; if (*ptr == ' ') ++ptr; } Write(Cout, ptr, strlen(ptr)); if (nl) Oputs(""); return (0); } do_source(str) char *str; { register FILE *fi; register char *buf; buf = malloc(256); if (buf == NULL) { Eputs ("no memory"); goto error; } if (Src_stack == MAXSRC) { Eputs ("Too many source levels"); error: if ((long)av[0] == -1) UnLock(av[1]); return(-1); } if ((long)av[0] == -1) { long oldir = (long)CurrentDir(av[1]); fi = fopen("", "r"); UnLock(CurrentDir(oldir)); } else { fi = fopen (av[1], "r"); } if (fi == NULL) { fhprintf(Cerr, "Cannot open %s\n", next_word(str)); return(-1); } set_var(LEVEL_SET, V_PASSED, next_word(next_word(str))); ++H_stack; Src_pos[Src_stack] = 0; Src_base[Src_stack] = (long)fi; ++Src_stack; while (fgets(buf, 256, fi)) { register int len = strlen(buf); buf[len-1] = 0; /* remove \n */ Src_pos[Src_stack - 1] += len; /* + (1 + actual length) */ if (Verbose) Eputs(buf); exec_command (buf); if (CHECKBREAK()) break; } --H_stack; --Src_stack; unset_level(LEVEL_LABEL + Src_stack); unset_var(LEVEL_SET, V_PASSED); fclose (fi); return (0); } /* * CD * * CD(str, -1) -do pwd and display current cd. if str = NULL don't disp. * CD(str, 0) -do CD operation. * * standard operation: breakup path by '/'s and process independantly * x: -reset cwd base * .. -remove last cwd element * N -add N or /N to cwd */ do_cd(str, com) register char *str; { static char cwd[256]; register char sc, *ptr; char *name; if (com < 0) { register struct FileLock *lock, *newlock; register FIB *fib; short i, len; fib = (FIB *)AllocMem(sizeof(FIB), 0); Clock = (struct FileLock *)((PROC *)FindTask(0))->pr_CurrentDir; if (!Clock) CurrentDir(Clock = Lock(":", ACCESS_READ)); lock = DupLock(Clock); cwd[i = 255] = '\0'; while (lock) { newlock = ParentDir(lock); Examine(lock, fib); name = fib->fib_FileName; if (*name == '\0') /* HACK TO FIX RAM: DISK BUG */ name = "ram"; len = strlen(name); if (newlock) { if (i == 255) { i -= len; bmov(name, cwd + i, len); } else { i -= len + 1; bmov(name, cwd + i, len); cwd[i+len] = '/'; } } else { i -= len + 1; bmov(name, cwd + i, len); cwd[i+len] = ':'; } UnLock(lock); lock = newlock; } FreeMem(fib, sizeof(FIB)); bmov(cwd + i, cwd, 256 - i); if (str) Oputs(cwd); goto cdset; } str = next_word(str); if (*str == '\0') Oputs(cwd); str[strlen(str)+1] = '\0'; /* add second \0 on end */ while (*str) { for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr); switch (*ptr) { case ':': sc = ptr[1]; ptr[1] = '\0'; if (attempt_cd(str)) strcpy(cwd, str); ptr[1] = sc; break; case '\0': case '/': *ptr = '\0'; if (strcmp(str, "..") == 0 || str == ptr) str = "/"; if (*str && attempt_cd(str)) { if (*str == '/') { rmlast(cwd); } else { if (cwd[0] == 0 || cwd[strlen(cwd)-1] != ':') strcat(cwd, "/"); strcat(cwd, str); } } break; } str = ptr + 1; } cdset: set_var(LEVEL_SET, V_CWD, cwd); return (0); } attempt_cd(str) char *str; { register struct FileLock *oldlock, *filelock; if (filelock = Lock(str, ACCESS_READ)) { if (isdir(str)) { UnLock(CurrentDir(filelock)); Clock = filelock; return(1); } UnLock(filelock); ierror(str, 212); } else { ierror(str, 205); } return (0); } /* * remove last component. Start at end and work backwards until reach * a '/' */ rmlast(str) char *str; { register char *ptr = str + strlen(str) - 1; while (ptr != str && *ptr != '/' && *ptr != ':') --ptr; if (*ptr != ':') ptr[0] = '\0'; else ptr[1] = '\0'; } do_mkdir() { register short i; register struct FileLock *lock; for (i = 1; i < ac; ++i) { if (lock = CreateDir (av[i])) { UnLock (lock); continue; } perror (av[i]); } return (0); } /* * MV file1 file2 * MV file1 file2....fileN dir */ do_mv() { char dest[256]; register short i, len; register char *str; --ac; if (isdir(av[ac])) { len = strlen(av[ac]); for (i = 1; i < ac; ++i) { str = av[i] + strlen(av[i]) - 1; while (str >= av[i] && *str != '/' && *str != ':') --str; ++str; if (*str == 0) { ierror(av[i], 508); return (-1); } strcpy(dest, av[ac]); if (dest[0] && dest[len-1] != ':' && dest[len-1] != '/') strcat(dest, "/"); strcat(dest, str); if (Rename(av[i], dest) == 0) break; } if (i == ac) return (1); } else { i = 1; if (ac != 2) { ierror("mv:", 507); return (-1); } if (Rename (av[1], av[2])) return (0); } perror (av[i]); return (-1); } do_rm() { register short i, recur; recur = (strncmp(av[1], "-r", 2)) ? 0 : 1; for (i = 1 + recur; i < ac; ++i) { if (isdir(av[i]) && recur) rmdir(av[i]); if (!DeleteFile(av[i])) perror(av[i]); } return (0); } rmdir(name) char *name; { register LOCK *lock, *cwd; register FIB *fib; register char *buf; buf = (char *)AllocMem(256, 0); fib = (FIB *)AllocMem(sizeof(FIB), 0); if (lock = Lock(name, ACCESS_READ)) { cwd = CurrentDir(lock); if (Examine(lock, fib)) { buf[0] = 0; while (ExNext(lock, fib)) { if (isdir(fib->fib_FileName)) rmdir(fib->fib_FileName); if (buf[0]) { if (!DeleteFile(buf)) perror(buf); } strcpy(buf, fib->fib_FileName); } if (buf[0]) { if (!DeleteFile(buf)) perror(buf); } } UnLock(CurrentDir(cwd)); } else { perror(name); } FreeMem(fib, sizeof(FIB)); FreeMem(buf, 256); } do_history() { register struct HIST *hist; register short i = H_tail_base; register short len = (av[1]) ? strlen(av[1]) : 0; for (hist = H_tail; hist; hist = hist->prev) { if (len == 0 || strncmp(av[1], hist->line, len) == 0) { fhprintf (Cout, "%3ld ", i); Oputs (hist->line); } ++i; if (CHECKBREAK()) break; } return (0); } do_mem() { register long cfree, ffree; extern long AvailMem(); Forbid(); cfree = AvailMem (MEMF_CHIP); ffree = AvailMem (MEMF_FAST); Permit(); if (ffree) fhprintf (Cout, "FAST memory:%10ld\n", ffree); fhprintf (Cout, "CHIP memory:%10ld\n", cfree); fhprintf (Cout, "Total -----:%5ld K\n", (ffree + cfree) >> 10); return (0); } /* * foreach var_name ( str str str str... str ) commands * spacing is important (unfortunetly) * * ac=0 1 2 3 4 5 6 7 * foreach i ( a b c ) echo $i * foreach i ( *.c ) "echo -n "file ->";echo $i" */ do_foreach() { register short i, cstart, cend, old; register char *cstr, *vname, *ptr, *scr, *args; cstart = i = (*av[2] == '(') ? 3 : 2; while (i < ac) { if (*av[i] == ')') break; ++i; } if (i == ac) { Eputs ("')' expected"); return (-1); } ++H_stack; cend = i; vname = strcpy(malloc(strlen(av[1])+1), av[1]); cstr = compile_av (av, cend + 1, ac); ptr = args = compile_av (av, cstart, cend); while (*ptr) { while (*ptr == ' ' || *ptr == 9) ++ptr; scr = ptr; if (*scr == '\0') break; while (*ptr && *ptr != ' ' && *ptr != 9) ++ptr; old = *ptr; *ptr = '\0'; set_var (LEVEL_SET, vname, scr); if (CHECKBREAK()) break; exec_command (cstr); *ptr = old; } --H_stack; free (args); free (cstr); unset_var (LEVEL_SET, vname); free (vname); return (0); } do_forever(str) register char *str; { long rcode = 0; register char *ptr = next_word(str); ++H_stack; for (;;) { if (CHECKBREAK()) { rcode = 20; break; } if (exec_command (ptr) < 0) { str = get_var(LEVEL_SET, V_LASTERR); rcode = (str) ? atoi(str) : 20; break; } } --H_stack; return (rcode); } \Rogue\Monster\ else echo "will not over write comm1.c" fi if [ `wc -c comm1.c | awk '{printf $1}'` -ne 12245 ] then echo `wc -c comm1.c | awk '{print "Got " $1 ", Expected " 12245}'` fi if `test ! -s comm2.c` then echo "writing comm2.c" cat > comm2.c << '\Rogue\Monster\' /* * COMM2.C * * * (c)1986 Matthew Dillon Feb 1987 * * ABORTLINE * RETURN * STRHEAD * STRTAIL * IF * LABEL * GOTO * INC * INPUT * VER * CP * SHELLSTAT * SETENV * UNSETENV * IPC * CLDRES * */ #include "shell.h" #include <libraries/dos.h> #include <libraries/dosextens.h> #include <local/ipc.h> typedef struct CommandLineInterface CLI; extern LOCK *CurrentDir(), *Lock(), *CreateDir(); extern IPCMSG *SendIPC(); do_cldres() { if (DResBase) CloseLibrary(DResBase); DResBase = NULL; } /* * do_ipc appname[.project] command */ do_ipc(command) char *command; { IPCMSG *msg; char *str = next_word(next_word(command)); char *ptr; char appname[64]; char *cmd; long result; if (!DResBase) DResBase = (long)OpenLibrary("dres.library", 0); if (!DResBase) { puts("Unable to open dres.library"); return(-1); } for (ptr = av[1]; *ptr && *ptr != '.'; ++ptr); if (*ptr == '.') { if (cmd = malloc(strlen(ptr+1)+strlen(str)+2)) { strcpy(cmd, ptr+1); strcpy(cmd + strlen(cmd) + 1, str); } } else { if (cmd = malloc(strlen(str)+2)) { cmd[0] = 0; strcpy(cmd+1, str); } } if (!cmd) return(-1); strcpy(appname, av[1]); appname[ptr - av[1]] = 0; strcat(appname, ".CMD"); msg = SendIPC(appname, cmd, strlen(cmd)+strlen(str)+2, 0); free(cmd); if (!msg) return(-1); WaitMsg(msg); if (msg->RFlags & IF_ERROR) { if (msg->RFlags & IF_NOAPP) printf("Application not found"); else printf("Operation Failed"); if (msg->RBuf) printf(": %s\n", msg->RBuf); puts(""); if (!msg->Error) msg->Error = 20; } else { if (msg->RBuf) Oputs(msg->RBuf); } result = msg->Error; FreeIPC(msg); return(result); } do_abortline() { Exec_abortline = 1; return (0); } do_return() { Exec_abortline = 1; if (Src_stack) { fseek (Src_base[Src_stack - 1], 0, 2); return ((ac < 2) ? 0 : atoi(av[1])); } else { main_exit ((ac < 2) ? 0 : atoi(av[1])); } } /* * STRHEAD * * place a string into a variable removing everything after and including * the 'break' character or until a space is found in the string. * * strhead varname breakchar string * */ do_strhead() { register char *str = av[3]; register char bc = *av[2]; while (*str && *str != bc) ++str; *str = '\0'; set_var (LEVEL_SET, av[1], av[3]); return (0); } do_strtail() { register char *str = av[3]; register char bc = *av[2]; while (*str && *str != bc) ++str; if (*str) ++str; set_var (LEVEL_SET, av[1], str); return (0); } /* * if A < B <, >, =, <=, >=, !=, where A and B are either: * nothing * a string * a value (begins w/ number) * * if -[!]f file * */ do_if(garbage, com) char *garbage; { register char *v1, *v2, *v3, result, num; register int n1, n2; switch (com) { case 0: if (If_stack && If_base[If_stack - 1]) { if (If_stack == MAXIF) { ierror(NULL, 510); } else { If_base[If_stack++] = 1; } break; } result = num = 0; v1 = av[1]; switch(ac) { case 2: /* if $var; */ if (v1[0] == 0 || (v1[1] == 0 && v1[0] == ' ')) goto do_result; result = 1; /* fall through */ case 1: /* if */ goto do_result; case 3: /* if -flag name */ if (*v1 == '-') ++v1; if (*v1 == '!') { ++v1; result = 1 - result; } switch(*v1) { case 'f': { LOCK *lock; mountrequest(0); if (lock = Lock(av[2], SHARED_LOCK)) { result = 1 - result; UnLock(lock); } mountrequest(1); } break; default: goto splug; } goto do_result; case 4: goto cond; } splug: ierror(NULL, 500); goto do_result; cond: v1 = av[1]; v2 = av[2]; v3 = av[3]; while (*v1 == ' ') ++v1; while (*v2 == ' ') ++v2; while (*v3 == ' ') ++v3; if (*v1 >= '0' && *v1 <= '9') { num = 1; n1 = atoi(v1); n2 = atoi(v3); } while (*v2) { switch (*v2++) { case '>': result |= (num) ? (n1 > n2) : (strcmp(v1, v3) > 0); break; case '<': result |= (num) ? (n1 < n2) : (strcmp(v1, v3) < 0); break; case '=': result |= (num) ? (n1 == n2) : (strcmp(v1, v3) ==0); break; default: ierror (NULL, 503); break; } } do_result: if (If_stack == MAXIF) ierror(NULL,510); else If_base[If_stack++] = !result; break; case 1: if (If_stack > 1 && If_base[If_stack - 2]) break; if (If_stack) If_base[If_stack - 1] ^= 1; break; case 2: if (If_stack) --If_stack; break; } SDisable = (If_stack) ? If_base[If_stack - 1] : 0; return (0); } do_label() { char aseek[32]; if (Src_stack == 0) { ierror (NULL, 502); return (-1); } sprintf (aseek, "%ld %ld", Src_pos[Src_stack-1], If_stack); set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek); return (0); } do_goto() { register long new; register long pos; register char *lab; if (Src_stack == 0) { ierror (NULL, 502); } else { lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]); if (lab == NULL) { ierror (NULL, 501); } else { pos = atoi(lab); fseek (Src_base[Src_stack - 1], pos, 0); Src_pos[Src_stack - 1] = pos; new = atoi(next_word(lab)); if (new > MAXIF) new = MAXIF; for (; If_stack < new; ++If_stack) If_base[If_stack] = 0; If_stack = new; } } Exec_abortline = 1; return (0); /* Don't execute rest of this line */ } do_inc(garbage, com) char *garbage; { register char *var; char num[32]; if (ac == 3) com = atoi(av[2]); var = get_var (LEVEL_SET, av[1]); if (var) { sprintf (num, "%ld", atoi(var)+com); set_var (LEVEL_SET, av[1], num); } return (0); } do_input() { char in[256]; if (Ogets(in)) set_var (LEVEL_SET, av[1], in); return (0); } do_ver() { Oputs (VERSION); return (0); } /* * CP file (to current directory) * CP [-r] dir (to current directory) * CP file file * CP file file file... destdir * CP [-r] dir dir dir... destdir */ do_cp() { register short recur, i, ierr; register char *destname; register char destisdir; register FIB *fib; char copysilent = (get_var(LEVEL_SET, V_COPYSILENT) != NULL); if (get_var(LEVEL_SET, V_COPYDATE) != NULL) copysilent |= 2; ierr = 0; fib = (FIB *)AllocMem(sizeof(FIB), 0); recur = (strncmp(av[1], "-r", 2)) ? 0 : 1; destname = av[ac - 1]; if (ac < recur + 3) { ++ac; destname = ""; } /* * ierr = 500; * goto done; */ destisdir = isdir(destname); if (ac > recur + 3 && !destisdir) { ierr = 507; goto done; } /* * copy set: reduce to: * file to file file to file * dir to file (NOT ALLOWED) * file to dir dir to dir * dir to dir dir to dir * */ for (i = recur + 1; i < ac - 1; ++i) { short srcisdir = isdir(av[i]); if (srcisdir) { struct FileLock *srcdir, *destdir; if (!destisdir) { /* disallow dir to file */ ierr = 507; goto done; } if (!(destdir = Lock(destname, ACCESS_READ))) { ierr = 205; goto done; } if (!(srcdir = Lock(av[i], ACCESS_READ))) { ierr = 205; UnLock(destdir); goto done; } ierr = copydir(srcdir, destdir, recur, copysilent, 1); UnLock(srcdir); UnLock(destdir); if (ierr) break; } else { /* FILE to DIR, FILE to FILE */ struct FileLock *destdir, *srcdir, *tmp; char *destfilename; srcdir = (struct FileLock *)((PROC *)FindTask(NULL))->pr_CurrentDir; if (destisdir) { if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)){ if (tmp) UnLock(tmp); ierr = 205; goto done; } UnLock(tmp); destdir = Lock(destname, ACCESS_READ); destfilename = fib->fib_FileName; } else { destdir = srcdir; destfilename = destname; copysilent |= 1; } ierr = copyfile(av[i], srcdir, destfilename, destdir, copysilent, 0); if (destisdir) UnLock(destdir); if (ierr) break; } } done: FreeMem(fib, sizeof(*fib)); if (ierr) { ierror("cp", ierr); return(20); } return(0); } copydir(srcdir, destdir, recur, silent, tab) register struct FileLock *srcdir, *destdir; { LOCK *cwd; register FIB *srcfib; register LOCK *destlock, *srclock; DATESTAMP DS; int ierr; ierr = 0; srcfib = (FIB *)AllocMem(sizeof(FIB), 0); if (Examine(srcdir, srcfib)) { DS = srcfib->fib_Date; if (!(silent & 1)) printf("%*s%s (DIR)\n", tab, "", srcfib->fib_FileName); while (ExNext(srcdir, srcfib)) { if (srcfib->fib_DirEntryType < 0) { ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir,silent,tab+4); if (ierr) break; } else { if (recur) { cwd = CurrentDir(srcdir); if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) { CurrentDir(destdir); if (!(destlock = Lock(srcfib->fib_FileName, ACCESS_READ))) { if (destlock = CreateDir(srcfib->fib_FileName)) { UnLock(destlock); if (silent & 2) { setfiledate(srcfib->fib_FileName, &DS); if (srcfib->fib_Comment[0]) SetComment(srcfib->fib_FileName, srcfib->fib_Comment); } destlock = Lock(srcfib->fib_FileName, ACCESS_READ); } } if (destlock) { ierr = copydir(srclock, destlock, recur, silent, tab+4); UnLock(destlock); } else { ierr = IoErr(); } UnLock(srclock); } else { ierr = IoErr(); } CurrentDir(cwd); if (ierr) break; } } } } else { ierr = IoErr(); } FreeMem(srcfib, sizeof(FIB)); return(ierr); } copyfile(srcname, srcdir, destname, destdir, silent, tab) char *srcname, *destname; struct FileLock *srcdir, *destdir; { LOCK *cwd; DATESTAMP DS; int i, ierr; char *buf; char *com = NULL; long buflen; long fhs, fhd; if (!(silent&1)) printf("%*s%s\n", tab, "", srcname); for (buflen = 65536; buflen; buflen >>= 1) { if (buf = AllocMem(buflen, MEMF_PUBLIC)) break; } if (buf == NULL) return(103); /* ERROR_NO_FREE_STORE */ ierr = 0; cwd = (LOCK *)CurrentDir(srcdir); if (silent & 2) { register FIB *fib = (FIB *)AllocMem(sizeof(FIB), MEMF_PUBLIC); register LOCK *lock = Lock(srcname, ACCESS_READ); if (lock && fib && Examine(lock, fib)) { if (fib->fib_Comment[0]) { com = malloc(strlen(fib->fib_Comment)+1); strcpy(com, fib->fib_Comment); } DS = fib->fib_Date; } else { silent &= ~2; } if (lock) UnLock(lock); if (fib) FreeMem(fib, sizeof(FIB)); } fhs = Open(srcname, 1005); if (fhs == NULL) { ierr = 205; goto fail; } CurrentDir(destdir); fhd = Open(destname, 1006); if (fhd == NULL) { ierr = IoErr(); Close(fhs); goto fail; } while ((i = Read(fhs, buf, buflen)) > 0) { if (CHECKBREAK()) { ierr = 509; break; } if (Write(fhd, buf, i) != i) { ierr = IoErr(); break; } if (CHECKBREAK()) { ierr = 509; break; } } if (i < 0) ierr = IoErr(); Close(fhd); Close(fhs); if (!ierr && (silent & 2)) { setfiledate(destname, &DS); if (com) SetComment(destname, com); } fail: if (com) free(com); FreeMem(buf, buflen); CurrentDir(cwd); return(ierr); } do_shellstat() { { register short i = 0; register unsigned long mask = ((TASK *)FindTask(NULL))->tc_SigAlloc; printf("Signals: %08lx ", mask); while (mask) { if (mask & 1) ++i; mask >>= 1; } printf("(%ld)\n", i); } /* { register PROC *proc = (PROC *)FindTask(NULL); register CLI *cli = (CLI *)((long)proc->pr_CLI << 2); if (proc) { long stack; printf("pr_TaskNum: %ld\n", proc->pr_TaskNum); printf("pr_CIS: %08lx\n", proc->pr_CIS); printf("pr_COS: %08lx\n", proc->pr_COS); printf("cli_standardinput : %08lx\n", cli->cli_StandardInput); printf("cli_standardoutput: %08lx\n", cli->cli_StandardOutput); printf("cli_currentinput : %08lx\n", cli->cli_CurrentInput); printf("cli_currentoutput : %08lx\n", cli->cli_CurrentOutput); printf("cli_Module : %08lx\n", cli->cli_Module); printf("STACK: %ld bytes, %08lx %08lx %08lx (%ld Free)\n", cli->cli_DefaultStack*4, proc->pr_ReturnAddr - cli->cli_DefaultStack*4, &stack, proc->pr_ReturnAddr, (long)&stack - (long)proc->pr_ReturnAddr + cli->cli_DefaultStack*4 ); } } */ return(0); } do_printenv() { register long lock; register FIB *fib = (FIB *)malloc(sizeof(FIB)); register short i; char buf[256]; long fh; if (lock = (long)Lock("ENV:", SHARED_LOCK)) { if (Examine(lock, fib)) { while (ExNext(lock, fib)) { sprintf(buf, "%-10s ", fib->fib_FileName); Write(Cout, buf, strlen(buf)); sprintf(buf, "ENV:%s", fib->fib_FileName); if (fh = Open(buf, 1005)) { while ((i = Read(fh, buf, sizeof(buf))) > 0) { Write(Cout, buf, i); } Close(fh); Oputs(""); } else { Oputs("<unable to open>"); } } } UnLock(lock); } free(fib); return(0); } do_setenv(command) char *command; { long fh; char buf[256]; short ierr = 0; if (ac <= 2) return(0); strcpy(buf, "ENV:"); strcat(buf, av[1]); if (fh = Open(buf, 1006)) { register char *str = next_word(next_word(command)); Write(fh, str, strlen(str)); Close(fh); } else { ierr = IoErr(); } return(ierr); } do_unsetenv() { char buf[256]; short i; for (i = 1; i < ac; ++i) { strcpy(buf, "ENV:"); strcat(buf, av[i]); DeleteFile(buf); } return(0); } \Rogue\Monster\ else echo "will not over write comm2.c" fi if [ `wc -c comm2.c | awk '{printf $1}'` -ne 13801 ] then echo `wc -c comm2.c | awk '{print "Got " $1 ", Expected " 13801}'` fi echo "Finished archive 2 of 2" # if you want to concatenate archives, remove anything after this line exit -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.