Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!ames!ptsfa!ihnp4!inuxc!pur-ee!j.cc.purdue.edu!h.cc.purdue.edu!s.cc.purdue.edu!doc From: doc@s.cc.purdue.edu (Craig Norborg) Newsgroups: comp.sources.amiga Subject: Shell 2.06M sources (part 2 of 2) Message-ID: <252@s.cc.purdue.edu> Date: Mon, 8-Jun-87 13:38:11 EDT Article-I.D.: s.252 Posted: Mon Jun 8 13:38:11 1987 Date-Received: Thu, 11-Jun-87 05:45:16 EDT Reply-To: doc@s.cc.purdue.edu (Craig Norborg) Distribution: world Organization: Purdue University Computing Center Lines: 2551 Approved: doc@j.cc.purdue.edu Here is part 2 of 2 of Steve Drew's version of Matt Dillon's shell for Aztec C. -Craig Norborg comp.sources.amiga moderator # This is a shell archive. # Remove everything above and includeing the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # Xshar: Extended Shell Archiver. # This is part 2 out of 2. # Run the following text with /bin/sh to create: # comm1.c # comm2.c # execom.c # rawconsole.c # run.c # shell.h # This archive created: Mon Jun 8 12:26:55 1987 # By: Craig Norborg (Purdue University Computing Center) cat << \SHAR_EOF > comm1.c /* * COMM1.C * * Matthew Dillon, August 1986 * * version 2.06M (Manx Version and Additions) by Steve Drew 28-May-87 * */ #include "shell.h" typedef struct FileInfoBlock FIB; #define DIR_SHORT 0x01 #define DIR_FILES 0x02 #define DIR_DIRS 0x04 extern int has_wild; char cwd[256]; /* Parse the options specified in sw[] Setting a bit for each one found */ get_opt(sw,count) char *sw; int *count; { int l,i = 0, opt = 0; char *c,*s; while((++i < ac) && (av[i][0] == '-')) { for (c = av[i]+1; *c ; c++) { for(l = 0,s = sw;*s && *s != *c; ++s) ++l; if (*s) opt |= (1 << l); } } *count = i; return(opt); } do_sleep() { register int i; if (ac == 2) { i = atoi(av[1]); while (i > 0) { Delay ((long)100); i -= 2; if (CHECKBREAK()) break; } } return (0); } do_number() { return (0); } do_cat() { FILE *fopen(), *fi; int i; char buf[256]; if (ac == 1) { while (gets(buf)) { if (CHECKBREAK()) break; puts(buf); } clearerr(stdin); return (0); } for (i = 1; i < ac; ++i) { if ((fi = fopen (av[i], "r")) != 0) { while (fgets(buf,256,fi)) { fputs(buf,stdout); fflush(stdout); if (CHECKBREAK()) { breakreset(); break; } } fclose (fi); } else { ierror(av[i], 205); } } return (0); } do_devinfo() { struct DPTR *dp; struct InfoData *info; int stat,i; char *p,*s,*get_pwd(),*index(); if (ac == 1) { ++ac; av[1] = ""; } for (i=1; i < ac; ++i) { if (!(dp = dopen (av[i], &stat))) continue; info = (struct InfoData *)AllocMem((long)sizeof(struct InfoData), MEMF_PUBLIC); if (Info (dp->lock, info)) { s = get_pwd(dp->lock); p = index(s,':'); *p = '\0'; printf ("Unit:%2ld Errs:%3ld Used: %-4ld %3ld%% Free: %-4ld Volume: %s\n", info->id_UnitNumber, info->id_NumSoftErrors, info->id_NumBlocksUsed, (info->id_NumBlocksUsed * 100)/ info->id_NumBlocks, (info->id_NumBlocks - info->id_NumBlocksUsed), s); } else { pError (av[i]); } FreeMem (info,(long) sizeof(*info)); dclose(dp); } return(0); } /* things shared with display_file */ char lspec[128]; int filecount, col; long bytes, blocks; /* * the args passed to do_dir will never be expanded */ do_dir() { void display_file(); int i, options; col = filecount = 0; bytes = blocks = 0L; *lspec = '\0'; options = get_opt("sfd",&i); if (ac == i) { ++ac; av[i] = ""; } if (!(options & (DIR_FILES | DIR_DIRS))) options |= (DIR_FILES | DIR_DIRS); for (; i < ac; ++i) { char **eav; int c,eac; if (!(eav = expand(av[i], &eac))) continue; QuickSort(eav, eac); for(c=0;c < eac && !breakcheck();++c) display_file(options,eav[c]); free_expand (eav); if (CHECKBREAK()) break; } if (col) printf("\n"); if (filecount > 1) { blocks += filecount; /* account for dir blocks */ printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount); } return (0); } void display_file(options,filestr) int options; char *filestr; { long atol(); int isadir,slen; char sc; char *c,*s,*fi; struct FileLock *lock; char *get_pwd(); char *strcpy(); /* if current dir different from lspec then look for ':' or '/' if found lock it and get_pwd. else then use cwd. */ for(s = c = filestr; *c; ++c) if (*c == ':' || *c == '/') s = c; if (*s == ':') ++s; sc = *s; *s = '\0'; c = filestr; if (!*c) c = cwd; if (strcmp (c, &lspec)) { strcpy(lspec, c); if (col) printf("\n"); if (lock = (struct FileLock *)Lock(c,SHARED_LOCK)) { printf ("Directory of %s\n", get_pwd(lock)); UnLock(lock); } col = 0; } *s = sc; if (sc == '/') s++; slen = strlen(s); fi = s + slen + 1; isadir = (fi[9] =='D'); if (!(((options & DIR_FILES) && isadir) || ((options & DIR_DIRS) && !isadir))) return; if (options & DIR_SHORT) { if ((col == 3) && slen >18) { printf("\n"); col = 0; } if (isadir) { printf ("\033[3m"); } if (slen >18) { printf(" %-37s",s); col += 2; } else { printf(" %-18s",s); col++; } if (col > 3) { printf("\n"); col = 0; } if (isadir) printf("\033[0m"); } else /* print full info */ printf(" %-24s %s",s ,fi); fflush(stdout); fi[12] = fi[17] = '\0'; bytes += atol(fi+6); blocks += atol(fi+13); filecount++; return; } /* converts dos date stamp to a time string of form dd-mmm-yy */ char * dates(dss) struct DateStamp *dss; { register struct tm tm; register long time, t; register int i; static char timestr[20]; static char months[12][4] = { "Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec" }; static char days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; time = dss->ds_Days * 24 * 60 * 60 + dss->ds_Minute * 60 + dss->ds_Tick/TICKS_PER_SECOND; tm.tm_sec = time % 60; time /= 60; tm.tm_min = time % 60; time /= 60; tm.tm_hour= time % 24; time /= 24; tm.tm_wday= time % 7; tm.tm_year= 78 + (time/(4*365+1)) * 4; time %= 4 * 365 + 1; while (time) { t = 365; if ((tm.tm_year&3) == 0) t++; if (time < t) break; time -= t; tm.tm_year++; } tm.tm_yday = ++time; for (i=0;i<12;i++) { t = days[i]; if (i == 1 && (tm.tm_year&3) == 0) t++; if (time <= t) break; time -= t; } tm.tm_mon = i; tm.tm_mday = time; sprintf(timestr,"%02d-%s-%2d %02d:%02d:%02d\n",tm.tm_mday, months[tm.tm_mon],tm.tm_year, tm.tm_hour,tm.tm_min,tm.tm_sec); return(timestr); } date() { struct DateStamp dss; char *dates(); DateStamp(&dss); printf("%s",dates(&dss)); return(0); } 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; } printf("%s",ptr); fflush(stdout); if (nl) printf("\n"); return (0); } do_source(str) char *str; { register FILE *fi; char buf[256]; if (Src_stack == MAXSRC) { fprintf (stderr,"Too many source levels\n"); return(-1); } if ((fi = fopen (av[1], "r")) == 0) { ierror(av[1], 205); 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)) { buf[strlen(buf)-1] = '\0'; Src_pos[Src_stack - 1] += 1+strlen(buf); if (Verbose) fprintf(stderr,"%s\n",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); } /* * return ptr to string that contains full cwd spec. */ char * get_pwd(flock) struct FileLock *flock; { char *ptr; char *name; int err=0; static char pwdstr[256]; struct FileLock *lock, *newlock; FIB *fib; int i, len; lock = (struct FileLock *)DupLock(flock); fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); pwdstr[i = 255] = '\0'; while (lock) { newlock = (struct FileLock *)ParentDir(lock); if (!Examine(lock, fib)) ++err; 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, pwdstr + i, len); } else { i -= len + 1; bmov(name, pwdstr + i, len); pwdstr[i+len] = '/'; } } else { i -= len + 1; bmov(name, pwdstr + i, len); pwdstr[i+len] = ':'; } UnLock(lock); lock = newlock; } FreeMem(fib, (long)sizeof(FIB)); movmem(pwdstr + i, pwdstr, 256 - i); if (err) return(cwd); return(pwdstr); } /* * set process cwd name and $_cwd, if str != NULL also print it. */ do_pwd(str) char *str; { char *ptr; if ((struct FileLock *)Myprocess->pr_CurrentDir == 0) attempt_cd(":"); /* if we just booted 0 = root lock */ strcpy(cwd,get_pwd(Myprocess->pr_CurrentDir,1)); if (str) puts(cwd); set_var(LEVEL_SET, V_CWD, cwd); /* put the current dir name in our CLI task structure */ ptr = (char *)((ULONG)((struct CommandLineInterface *) BADDR(Myprocess->pr_CLI))->cli_SetName << 2); ptr[0] = strlen(cwd); movmem(cwd,ptr+1,(int)ptr[0]); return(0); } /* * CD * * 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) char *str; { char sc, *ptr; int err=0; str = next_word(str); if (*str == '\0') { puts(cwd); return(0); } 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'; err = attempt_cd(str); ptr[1] = sc; break; case '\0': case '/': *ptr = '\0'; if (strcmp(str, "..") == 0 || str == ptr) str = "/"; if (*str) err = attempt_cd(str); break; } if (err) break; str = ptr + 1; } do_pwd(NULL); /* set $_cwd */ return(err); } attempt_cd(str) char *str; { struct FileLock *oldlock, *filelock; if (filelock = (struct FileLock *)Lock(str, ACCESS_READ)) { if (isdir(str)) { if (oldlock = (struct FileLock *)CurrentDir(filelock)) UnLock(oldlock); return (0); } UnLock(filelock); ierror(str, 212); } else { ierror(str, 205); } return (-1); } do_mkdir() { register int i; register struct FileLock *lock; for (i = 1; i < ac; ++i) { if (lock = (struct FileLock *)Lock(av[i],ACCESS_READ)) { ierror(av[i],203); UnLock (lock); continue; } if (lock = (struct FileLock *)CreateDir (av[i])) { UnLock (lock); continue; } pError (av[i]); } return (0); } do_mv() { char dest[256]; register int i; char *str; --ac; if (isdir(av[ac])) { for (i = 1; i < ac; ++i) { str = av[i] + strlen(av[i]) - 1; while (str != av[i] && *str != '/' && *str != ':') --str; if (str != av[i]) ++str; if (*str == 0) { ierror(av[i], 508); return (-1); } strcpy(dest, av[ac]); if (dest[strlen(dest)-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("", 507); return (-1); } if (Rename (av[1], av[2])) return (0); } pError (av[i]); return (-1); } rm_file(file) char *file; { if (has_wild) printf(" %s...",file); fflush(stdout); if (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n"); } do_rm() { int i, recur; recur = get_opt("r",&i); for (; i < ac; ++i) { if (CHECKBREAK()) break; if (isdir(av[i]) && recur) rmdir(av[i]); if (!(recur && av[i][strlen(av[i])-1] == ':')) rm_file(av[i]); } return (0); } rmdir(name) char *name; { register struct FileLock *lock, *cwd; register FIB *fib; register char *buf; buf = (char *)AllocMem(256L, MEMF_PUBLIC); fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); if (lock = (struct FileLock *)Lock(name, ACCESS_READ)) { cwd = (struct FileLock *) CurrentDir(lock); if (Examine(lock, fib)) { buf[0] = 0; while (ExNext(lock, fib)) { if (CHECKBREAK()) break; if (isdir(fib->fib_FileName)) rmdir(fib->fib_FileName); if (buf[0]) { rm_file(buf); } strcpy(buf, fib->fib_FileName); } if (buf[0] && !CHECKBREAK()) { rm_file(buf); } } UnLock(CurrentDir(cwd)); } else { pError(name); } FreeMem(fib, (long)sizeof(FIB)); FreeMem(buf, 256L); } do_history() { register struct HIST *hist; register int i = H_tail_base; register int 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) { printf ("%3d ", i); puts (hist->line); } ++i; if (CHECKBREAK()) break; } return (0); } do_mem() { long cfree, ffree; extern long AvailMem(); Forbid(); cfree = AvailMem (MEMF_CHIP); ffree = AvailMem (MEMF_FAST); Permit(); if (ffree) { printf ("FAST memory: %ld\n", ffree); printf ("CHIP memory: %ld\n", cfree); } printf ("Total Free: %ld\n", cfree + ffree); 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 int 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) { fprintf (stderr,"')' expected\n"); 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) char *str; { int rcode = 0; 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); } SHAR_EOF cat << \SHAR_EOF > comm2.c /* * COMM2.C * * (c)1986 Matthew Dillon 9 October 1986 * * version 2.06M (Manx Version and Additions) by Steve Drew 28-May-87 * */ #include "shell.h" typedef struct FileInfoBlock FIB; /* Casting conveniences */ #define BPTR_TO_C(strtag, var) ((struct strtag *)(BADDR( (ULONG) var))) #define PROC(task) ((struct Process *)task) #define ROOTNODE ((struct RootNode *)DOSBase->dl_Root) #define CLI(proc) (BPTR_TO_C(CommandLineInterface, proc->pr_CLI)) /* Externs */ extern int has_wild; /* flag set if any arg has a ? or * */ extern struct DosLibrary *DOSBase; /* dos library base pointer */ /* globals */ int cp_update; int cp_date; 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]; 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]; 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) */ do_if(garbage, com) char *garbage; { char *v1, *v2, *v3, result, num; int n1, n2; switch (com) { case 0: if (If_stack && If_base[If_stack - 1]) { If_base[If_stack++] = 1; break; } result = num = 0; if (ac <= 2) { /* if $var; */ if (ac == 1 || strlen(av[1]) == 0 || (strlen(av[1]) == 1 && *av[1] == ' ')) goto do_result; result = 1; goto do_result; } if (ac != 4) { ierror(NULL, 500); break; } 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_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; } disable = (If_stack) ? If_base[If_stack - 1] : 0; if (If_stack >= MAXIF) { fprintf(stderr,"If's too deep\n"); disable = If_stack = 0; return(-1); } return (0); } do_label() { char aseek[32]; if (Src_stack == 0) { ierror (NULL, 502); return (-1); } sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack); set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek); return (0); } do_goto() { int new; long pos; 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)); 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; { char *var; char num[32]; if (ac == 3) com = atoi(av[2]); var = get_var (LEVEL_SET, av[1]); if (var) { sprintf (num, "%d", atoi(var)+com); set_var (LEVEL_SET, av[1], num); } return (0); } do_input() { char in[256]; if ((gets(in)) != 0) set_var (LEVEL_SET, av[1], in); return (0); } do_ver() { puts (VERSION); return (0); } do_ps() { /* this code fragment based on ps.c command by Dewi Williams */ register ULONG *tt; /* References TaskArray */ register int count; /* loop variable */ register UBYTE *port; /* msgport & ptr arith */ register struct Task *task; /* EXEC descriptor */ char strbuf[64]; /* scratch for btocstr() */ char *btocstr(); /* BCPL BSTR to ASCIIZ */ tt = (unsigned long *)(BADDR(ROOTNODE->rn_TaskArray)); printf("Proc Command Name CLI Type Pri. Address Directory\n"); Forbid(); /* need linked list consistency */ for (count = 1; count <= (int)tt[0] ; count++) {/* or just assume 20?*/ if (tt[count] == 0) continue; /* nobody home */ /* Start by pulling out MsgPort addresses from the TaskArray * area. By making unwarranted assumptions about the layout * of Process and Task structures, we can derive these * descriptors. Every task has an associated process, since * this loop drives off a CLI data area. */ port = (UBYTE *)tt[count]; task = (struct Task *)(port - sizeof(struct Task)); /* Sanity check just in case */ if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue; /* or complain? */ btocstr(CLI(PROC(task))->cli_CommandName, strbuf); printf("%2d %-21s",count,strbuf); strcpy(strbuf,task->tc_Node.ln_Name); strbuf[11] = '\0'; printf("%-11s",strbuf); printf(" %3d %8lx %s\n", task->tc_Node.ln_Pri,task, btocstr(CLI(PROC(task))->cli_SetName, strbuf)); } Permit(); /* outside critical region */ return(0); } char * btocstr(b, buf) ULONG b; char *buf; { register char *s; s = (char *)BADDR(b); /* Shift & get length-prefixed str */ movmem(s +1, buf, s[0]); buf[s[0]] = '\0'; return buf; } /* * CP [-d] [-u] file file * CP [-d] [-u] file file file... destdir * CP [-r][-u][-d] dir dir dir... destdir */ char *errstr; /* let's be alittle more informative */ do_copy() { register int recur, ierr; register char *destname; register char destisdir; register FIB *fib; int i,opt; errstr = ""; ierr = 0; fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); opt = get_opt("rud",&i); recur = (opt & 0x01); cp_update = (opt & 0x02); cp_date = (!(opt & 0x04)); /* the default is keep orignal file date */ destname = av[ac - 1]; if (ac < i + 2) { ierr = 500; goto done; } destisdir = isdir(destname); if (ac > i + 2 && !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 < ac - 1; ++i) { short srcisdir = isdir(av[i]); if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */ continue; /* getting copied if specified */ /* from wild expansion */ if (CHECKBREAK()) break; if (srcisdir) { struct FileLock *srcdir, *destdir; if (!destisdir) { if (destdir = (struct FileLock *)Lock(destname, ACCESS_READ)) { UnLock(destdir); ierr = 507; /* disallow dir to file */ goto done; } if (destdir = (struct FileLock *)CreateDir(destname)) UnLock(destdir); destisdir = 1; } if (!(destdir = (struct FileLock *)Lock(destname, ACCESS_READ))) { ierr = 205; errstr = destname; goto done; } if (!(srcdir = (struct FileLock *)Lock(av[i], ACCESS_READ))) { ierr = 205; errstr = av[i]; UnLock(destdir); goto done; } ierr = copydir(srcdir, destdir, recur); UnLock(srcdir); UnLock(destdir); if (ierr) break; } else { /* FILE to DIR, FILE to FILE */ struct FileLock *destdir, *srcdir, *tmp; char *destfilename; srcdir = (struct FileLock *)(Myprocess->pr_CurrentDir); if ((tmp = (struct FileLock *)Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)){ if (tmp) UnLock(tmp); ierr = 205; errstr = av[i]; goto done; } UnLock(tmp); if (destisdir) { destdir = (struct FileLock *)Lock(destname, ACCESS_READ); destfilename = fib->fib_FileName; } else { destdir = srcdir; destfilename = destname; } printf(" %s..",av[i]); fflush(stdout); ierr = copyfile(av[i], srcdir, destfilename, destdir); if (destisdir) UnLock(destdir); if (ierr) break; } } done: FreeMem(fib, (long)sizeof(*fib)); if (ierr) { ierror(errstr, ierr); return(20); } return(0); } copydir(srcdir, destdir, recur) register struct FileLock *srcdir, *destdir; { struct FileLock *cwd; register FIB *srcfib; register struct FileLock *destlock, *srclock; int ierr; static int level; level++; ierr = 0; srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); if (Examine(srcdir, srcfib)) { while (ExNext(srcdir, srcfib)) { if (CHECKBREAK()) break; if (srcfib->fib_DirEntryType < 0) { printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName); fflush(stdout); ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir); if (ierr) break; } else { if (recur) { cwd = (struct FileLock *)CurrentDir(srcdir); if (srclock = (struct FileLock *)Lock(srcfib->fib_FileName, ACCESS_READ)) { CurrentDir(destdir); if (!(destlock = (struct FileLock *) Lock(srcfib->fib_FileName))) { destlock = (struct FileLock *)CreateDir(srcfib->fib_FileName); printf("%*s%s (Dir)....[Created]\n",(level-1) * 6, " ",srcfib->fib_FileName); /* UnLock and re Lock if newly created dir for file_date() to work properly. */ if (destlock) UnLock(destlock); destlock = (struct FileLock *)Lock(srcfib->fib_FileName); } else printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName); if (destlock) { ierr = copydir(srclock, destlock, recur); UnLock(destlock); } else { ierr = (int)((long)IoErr()); } UnLock(srclock); } else { ierr = (int)((long)IoErr()); } CurrentDir(cwd); if (ierr) break; } } } } else { ierr = (int)((long)IoErr()); } --level; FreeMem(srcfib, (long)sizeof(FIB)); return(ierr); } copyfile(srcname, srcdir, destname, destdir) char *srcname, *destname; struct FileLock *srcdir, *destdir; { struct FileLock *cwd; struct FileHandle *f1, *f2; struct DateStamp *ds; long i; int stat,ierr; char *buf; struct DPTR *dp, *dps = NULL; buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR); if (buf == NULL) { ierr = 103; goto fail; } ierr = 0; cwd = (struct FileLock *)CurrentDir(srcdir); f1 = Open(srcname, MODE_OLDFILE); if (f1 == NULL) { errstr = srcname; ierr = 205; goto fail; } dps = dopen(srcname,&stat); ds = &dps->fib->fib_Date; CurrentDir(destdir); if (cp_update && (dp = dopen (destname, &stat))) { long desttime,srctime; struct DateStamp *dd; dd = &dp->fib->fib_Date; desttime = dd->ds_Days * 24 * 60 * 60 + dd->ds_Minute * 60 + dd->ds_Tick/TICKS_PER_SECOND; srctime = ds->ds_Days * 24 * 60 * 60 + ds->ds_Minute * 60 + ds->ds_Tick/TICKS_PER_SECOND; if (srctime <= desttime && !strcmp(dps->fib->fib_FileName,dp->fib->fib_FileName)) { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; } dclose(dp); } f2 = Open(destname, MODE_NEWFILE); if (f2 == NULL) { Close(f1); ierr = (int)((long)IoErr()); errstr = destname; goto fail; } while (i = Read(f1, buf, 8192L)) if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; } Close(f2); Close(f1); if (!ierr) { #ifdef AZTEC_C if (cp_date) file_date(ds,destname); #endif printf("..copied\n"); } else { DeleteFile(destname); printf("..Not copied.."); } fail: dclose(dps); if (buf) FreeMem(buf, 8192L); CurrentDir(cwd); return(ierr); } #ifdef AZTEC_C /* since 3.20a did'nt have dos_packet() */ file_date(date,name) struct DateStamp *date; char *name; { UBYTE *ptr; struct MsgPort *task; struct FileLock *dirlock; struct DPTR *tmp; int stat; long ret, dos_packet(); if (!(task = (struct MsgPort *)DeviceProc(name))) return(1); if (tmp = dopen(name, &stat)) { dirlock = (struct FileLock *)ParentDir(tmp->lock); ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC); strcpy((ptr + 1),tmp->fib->fib_FileName); *ptr = strlen(tmp->fib->fib_FileName); dclose(tmp); ret = dos_packet(task,34L,NULL,dirlock, (ULONG)&ptr[0] >> 2L,date); FreeMem(ptr,64L); UnLock(dirlock); } } #endif SHAR_EOF cat << \SHAR_EOF > execom.c /* * EXECOM.C * * Matthew Dillon, 10 August 1986 * Finally re-written. * * version 2.06M (Manx Version and Additions) by Steve Drew 28-May-87 * * */ #include "shell.h" #define F_EXACT 0 #define F_ABBR 1 #define ST_COND 0x03 #define ST_NAME 0x02 #define ST_NOEXP 0x04 int has_wild = 0; /* set if any arg has wild card */ struct COMMAND { int (*func)(); short minargs; short stat; int val; char *name; }; extern char *format_insert_string(); extern char *mpush(), *exarg(); extern int do_run(), do_number(); extern int do_quit(), do_set_var(), do_unset_var(); extern int do_echo(), do_source(), do_mv(); extern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history(); extern int do_mem(), do_cat(), do_dir(), do_devinfo(), do_inc(); extern int do_foreach(), do_return(), do_if(), do_label(), do_goto(); extern int do_input(), do_ver(), do_sleep(), do_help(); extern int do_strhead(), do_strtail(); extern int do_copy(), date(), do_ps(); extern int do_forever(), do_abortline(); static struct COMMAND Command[] = { do_run , 0, 0, 0 , "\001", do_number , 0, 0, 0 , "\001", do_set_var , 0, 0, LEVEL_ALIAS, "alias", do_abortline, 0, 0, 0, "abortline", do_cd , 0, 0, 0 , "cd", do_cat , 0, 0, 0 , "cat", do_copy , 1, 0, 0 , "copy", date , 0, 0, 0 , "date", do_dir , 0, ST_NOEXP, 0 , "dir", do_inc , 1, 0, -1 , "dec", do_devinfo , 0, 0, 0 , "devinfo", do_echo , 0, 0, 0 , "echo", do_if , 0, ST_COND, 1 , "else", do_if , 0, ST_COND, 2 , "endif", do_foreach , 3, 0, 0 , "foreach", do_forever , 1, 0, 0 , "forever", do_goto , 1, 0, 0 , "goto", do_help , 0, 0, 0 , "help", do_history , 0, 0, 0 , "history", do_if , 1, ST_COND, 0 , "if", do_inc , 1, 0, 1 , "inc", do_input , 1, 0, 0 , "input", do_label , 1, ST_COND, 0 , "label", do_mem , 0, 0, 0 , "mem", do_mkdir , 0, 0, 0 , "mkdir", do_mv , 2, 0, 0 , "mv", do_ps , 0, 0, 0, "ps", do_pwd , 0, 0, 0 , "pwd", do_quit , 0, 0, 0 , "quit", do_return , 0, 0, 0 , "return", do_rm , 0, 0, 0 , "rm", do_run , 1, ST_NAME, 0 , "run", do_set_var , 0, 0, LEVEL_SET , "set", do_sleep , 0, 0, 0, "sleep", do_source , 0, 0, 0 , "source", do_strhead , 3, 0, 0 , "strhead", do_strtail , 3, 0, 0 , "strtail", do_unset_var, 0, 0, LEVEL_ALIAS, "unalias", do_unset_var, 0, 0, LEVEL_SET , "unset", do_ver , 0, 0, 0 , "version", '\0' , 0, 0, 0 , NULL }; static unsigned char elast; /* last end delimeter */ static char Cin_ispipe, Cout_ispipe; exec_command(base) char *base; { register char *scr; register int i; char buf[32]; if (!H_stack) { add_history(base); sprintf(buf, "%d", H_tail_base + H_len); set_var(LEVEL_SET, V_HISTNUM, buf); } scr = malloc((strlen(base) << 2) + 2); /* 4X */ preformat(base, scr); i = fcomm(scr, 1); return ((i) ? -1 : 1); } isalphanum(c) char c; { if (c >= '0' && c <= '9') return (1); if (c >= 'a' && c <= 'z') return (1); if (c >= 'A' && c <= 'Z') return (1); if (c == '_') return (1); return (0); } preformat(s, d) register char *s, *d; { register int si, di, qm; si = di = qm = 0; while (s[si] == ' ' || s[si] == 9) ++si; while (s[si]) { if (qm && s[si] != '\"' && s[si] != '\\') { d[di++] = s[si++] | 0x80; continue; } switch (s[si]) { case ' ': case 9: d[di++] = ' '; while (s[si] == ' ' || s[si] == 9) ++si; if (s[si] == 0 || s[si] == '|' || s[si] == ';') --di; break; case '*': case '?': d[di++] = 0x80; case '!': d[di++] = s[si++]; break; case '#': d[di++] = '\0'; while (s[si]) ++si; break; case ';': case '|': d[di++] = s[si++]; while (s[si] == ' ' || s[si] == 9) ++si; break; case '\\': d[di++] = s[++si] | 0x80; if (s[si]) ++si; break; case '\"': qm = 1 - qm; ++si; break; case '^': d[di++] = s[++si] & 0x1F; if (s[si]) ++si; break; case '$': /* search end of var name and place false space */ d[di++] = 0x80; d[di++] = s[si++]; while (isalphanum(s[si])) d[di++] = s[si++]; d[di++] = 0x80; break; default: d[di++] = s[si++]; break; } } d[di++] = 0; d[di] = 0; if (debug & 0x01) { fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d); } } /* * process formatted string. ' ' is the delimeter. * * 0: check '\0': no more, stop, done. * 1: check $. if so, extract, format, insert * 2: check alias. if so, extract, format, insert. goto 1 * 3: check history or substitution, extract, format, insert. goto 1 * * 4: assume first element now internal or disk based command. * * 5: extract each ' ' or 0x80 delimited argument and process, placing * in av[] list (except 0x80 args appended). check in order: * * '$' insert string straight * '>' setup stdout * '>>' setup stdout flag for append * '<' setup stdin * '*' or '?' do directory search and insert as separate args. * * ';' 0 '|' end of command. if '|' setup stdout * -execute command, fix stdin and out (|) sets * up stdin for next guy. */ fcomm(str, freeok) register char *str; { static int alias_count; int p_alias_count = 0; char *istr; char *nextstr; char *command; char *pend_alias = NULL; char err = 0; has_wild = 0; ++alias_count; mpush_base(); if (*str == 0) goto done1; step1: if (alias_count == MAXALIAS || ++p_alias_count == MAXALIAS) { fprintf(stderr,"Alias Loop\n"); err = 20; goto done1; } if (*str == '$') { if (istr = get_var (LEVEL_SET, str + 1)) str = format_insert_string(str, istr, &freeok); } istr = NULL; if (*(unsigned char *)str < 0x80) istr = get_var (LEVEL_ALIAS, str); /* only if not \command */ *str &= 0x7F; /* remove \ teltail */ if (istr) { if (*istr == '%') { pend_alias = istr; } else { str = format_insert_string(str, istr, &freeok); goto step1; } } if (*str == '!') { char *p, c; /* fix to allow !cmd1;!cmd2 */ for(p = str; *p && *p != ';' ; ++p); c = *p; *p = '\0'; istr = get_history(str); *p = c; replace_head(istr); str = format_insert_string(str, istr, &freeok); goto step1; } nextstr = str; command = exarg(&nextstr); if (*command == 0) goto done0; if (pend_alias == 0) { register int ccno; ccno = find_command(command); if (Command[ccno].stat & ST_COND) goto skipgood; } if (disable) { while (elast && elast != ';' && elast != '|') exarg(&nextstr); goto done0; } skipgood: { register char *arg, *ptr, *scr; short redir; short doexpand; short cont; short inc; ac = 1; av[0] = command; step5: /* ac = nextac */ if (!elast || elast == ';' || elast == '|') goto stepdone; av[ac] = '\0'; cont = 1; doexpand = redir = inc = 0; while (cont && elast) { int ccno = find_command(command); ptr = exarg(&nextstr); inc = 1; arg = ""; cont = (elast == 0x80); switch (*ptr) { case '<': redir = -2; case '>': if (Command[ccno].stat & ST_NAME) { /* don't extract */ redir = 0; /* <> stuff if its */ arg = ptr; /* external cmd. */ break; } ++redir; arg = ptr + 1; if (*arg == '>') { redir = 2; /* append >> (not impl yet) */ ++arg; } cont = 1; break; case '$': if ((arg = get_var(LEVEL_SET, ptr + 1)) == NULL) arg = ptr; break; case '*': case '?': if ((Command[ccno].stat & ST_NOEXP) == 0) doexpand = 1; arg = ptr; break; default: arg = ptr; break; } /* Append arg to av[ac] */ for (scr = arg; *scr; ++scr) *scr &= 0x7F; if (av[ac]) { register char *old = av[ac]; av[ac] = mpush(strlen(arg)+1+strlen(av[ac])); strcpy(av[ac], old); strcat(av[ac], arg); } else { av[ac] = mpush(strlen(arg)+1); strcpy(av[ac], arg); } if (elast != 0x80) break; } /* process expansion */ if (doexpand) { char **eav, **ebase; int eac; has_wild = 1; eav = ebase = expand(av[ac], &eac); inc = 0; if (eav) { if (ac + eac + 2 > MAXAV) { ierror (NULL, 506); err = 1; } else { QuickSort(eav, eac); for (; eac; --eac, ++eav) av[ac++] = strcpy(mpush(strlen(*eav)+1), *eav); } free_expand (ebase); } } /* process redirection */ if (redir && !err) { register char *file = (doexpand) ? av[--ac] : av[ac]; if (redir < 0) Cin_name = file; else { Cout_name = file; Cout_append = (redir == 2); } inc = 0; } /* check elast for space */ if (inc) { ++ac; if (ac + 2 > MAXAV) { ierror (NULL, 506); err = 1; /* error condition */ elast = 0; /* don't process any more arguemnts */ } } if (elast == ' ') goto step5; } stepdone: av[ac] = '\0'; /* process pipes via files */ if (elast == '|' && !err) { static int which; /* 0 or 1 in case of multiple pipes */ which = 1 - which; Cout_name = (which) ? Pipe1 : Pipe2; Cout_ispipe = 1; } if (err) goto done0; { register int i, len; char save_elast; register char *avline; save_elast = elast; for (i = len = 0; i < ac; ++i) len += strlen(av[i]) + 1; avline = malloc(len+1); for (len = 0, i = ((pend_alias) ? 1 : 0); i < ac; ++i) { if (debug & 0x02) { fprintf (stderr, "AV[%2d] %d :%s:\n", i, strlen(av[i]), av[i]); } strcpy(avline + len, av[i]); len += strlen(av[i]); if (i + 1 < ac) avline[len++] = ' '; } avline[len] = 0; if (pend_alias) { /* special % alias */ register char *ptr, *scr; for (ptr = pend_alias; *ptr && *ptr != ' '; ++ptr); set_var (LEVEL_SET, pend_alias + 1, avline); free (avline); scr = malloc((strlen(ptr) << 2) + 2); preformat (ptr, scr); fcomm (scr, 1); unset_var (LEVEL_SET, pend_alias + 1); } else { /* normal command */ register int ccno; long oldcin = (long)Input(); long oldcout = (long)Output(); #ifndef AZTEC_C extern struct _dev _devtab[]; #endif struct _dev *stdfp; fflush(stdout); ccno = find_command (command); if ((Command[ccno].stat & ST_NAME) == 0) { if (Cin_name) { if ((Cin = (long)Open(Cin_name,1005L)) == 0L) { ierror (NULL, 504); err = 1; Cin_name = '\0'; } else { Myprocess->pr_CIS = Cin; _devtab[stdin->_unit].fd = Cin; } } if (Cout_name) { if (Cout_append) { if ((Cout = (long)Open(Cout_name, 1005L)) != 0L) Seek(Cout, 0L, 1L); } else { Cout = (long)Open(Cout_name,1006L); } if (Cout == NULL) { err = 1; ierror (NULL, 504); Cout_name = '\0'; Cout_append = 0; } else { Myprocess->pr_COS = Cout; _devtab[stdout->_unit].fd = Cout; } } } if (ac < Command[ccno].minargs + 1) { ierror (NULL, 500); err = -1; } else if (!err) { i = (*Command[ccno].func)(avline, Command[ccno].val); if (i < 0) i = 20; err = i; } free (avline); if (Exec_ignoreresult == 0 && Lastresult != err) { Lastresult = err; seterr(); } if ((Command[ccno].stat & ST_NAME) == 0) { if (Cin_name) { fflush(stdin); clearerr(stdin); Close(Cin); } if (Cout_name) { fflush(stdout); clearerr(stdout); stdout->_flags &= ~_DIRTY; /* because of nil: device */ Close(Cout); Cout_append = 0; } } /* the next few lines solve a bug with fexecv and bcpl programs */ /* that muck up the input/output streams which causes GURUs */ Myprocess->pr_CIS = _devtab[stdin->_unit].fd = oldcin; Myprocess->pr_COS = _devtab[stdout->_unit].fd = oldcout; } if (Cin_ispipe && Cin_name) DeleteFile(Cin_name); if (Cout_ispipe) { Cin_name = Cout_name; /* ok to assign.. static name */ Cin_ispipe = 1; } else { Cin_name = '\0'; } Cout_name = '\0'; Cout_ispipe = 0; elast = save_elast; } mpop_tobase(); /* free arguments */ mpush_base(); /* push dummy base */ done0: { char *str; if (err && E_stack == 0) { str = get_var(LEVEL_SET, V_EXCEPT); if (err >= ((str)?atoi(str):1)) { if (str) { ++H_stack; ++E_stack; exec_command(str); --E_stack; --H_stack; } else { Exec_abortline = 1; } } } if (elast != 0 && Exec_abortline == 0) err = fcomm(nextstr, 0); Exec_abortline = 0; if (Cin_name) DeleteFile(Cin_name); Cin_name = NULL; Cin_ispipe = 0; } done1: mpop_tobase(); if (freeok) free(str); --alias_count; return ((int)err); /* TRUE = error occured */ } char * exarg(ptr) unsigned char **ptr; { register unsigned char *end; register unsigned char *start; start = end = *ptr; while (*end && *end != 0x80 && *end != ';' && *end != '|' && *end != ' ') ++end; elast = *end; *end = '\0'; *ptr = end + 1; return ((char *)start); } static char **Mlist; mpush_base() { char *str; str = malloc(5); *(char ***)str = Mlist; str[4] = 0; Mlist = (char **)str; } char * mpush(bytes) { char *str; str = malloc(5 + bytes + 2); /* may need 2 extra bytes in do_run() */ *(char ***)str = Mlist; str[4] = 1; Mlist = (char **)str; return (str + 5); } mpop_tobase() { register char *next; while (Mlist) { next = *Mlist; if (((char *)Mlist)[4] == 0) { free (Mlist); Mlist = (char **)next; break; } free (Mlist); Mlist = (char **)next; } } /* * Insert 'from' string in front of 'str' while deleting the * first entry in 'str'. if freeok is set, then 'str' will be * free'd */ char * format_insert_string(str, from, freeok) char *str; char *from; int *freeok; { register char *new1, *new2; register unsigned char *strskip; int len; for (strskip = (unsigned char *)str; *strskip && *strskip != ' ' && *strskip != ';' && *strskip != '|' && *strskip != 0x80; ++strskip); len = strlen(from); new1 = malloc((len << 2) + 2); preformat(from, new1); len = strlen(new1) + strlen(strskip); new2 = malloc(len+2); strcpy(new2, new1); strcat(new2, strskip); new2[len+1] = 0; free (new1); if (*freeok) free (str); *freeok = 1; return (new2); } find_command(str) char *str; { int i; int len = strlen(str); if (*str >= '0' && *str <= '9') return (1); for (i = 0; Command[i].func; ++i) { if (strncmp (str, Command[i].name, len) == 0) return (i); } return (0); } do_help() { register struct COMMAND *com; int i= 0; for (com = &Command[2]; com->func; ++com) { printf ("%-12s", com->name); if (++i % 6 == 0) printf("\n"); } printf("\n"); return(0); } SHAR_EOF cat << \SHAR_EOF > rawconsole.c /* * RawConsole.c * * Shell 2.06M 28-May-87 * console handling, command line editing support for Shell * using new console packets from 1.2. * Written by Steve Drew. (c) 14-Oct-86. * 16-Dec-86 Slight mods to rawgets() for Disktrashing. * */ extern int aux; /* for use with aux: */ #include "shell.h" void setraw(onoff) { if (onoff) set_raw(); else set_con(); } char * rawgets(line,prompt) char *line, *prompt; { char *get_var(); char *gets(); register int n, pl; register int max, i; unsigned char c1,c2,c3; char fkeys[5]; char *s; int fkey; int insert = 1; char rep[14]; static int width; int recall = -1; struct HIST *hist; if (aux) { printf("%s",prompt); fflush(stdout); } if (!IsInteractive(Input()) || aux ) return(gets(line)); if (WaitForChar((long)Input(), 100L) || /* don't switch to 1L ...*/ stdin->_bp < stdin->_bend) { /* else causes read err's*/ /* printf("%s",prompt); */ gets(line); return(line); } setraw(1); printf("%s",prompt); max = pl = i = strlen(prompt); strcpy(line,prompt); if (!width) width = 77; if (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0; while((c1 = getchar()) != 255) { if (c1 < 156) switch(c1) { case 155: c2 = getchar(); switch(c2) { case 'A': /* up arrow */ n = ++recall; case 'B': /* down arrow */ line[pl] = '\0'; if (recall >= 0 || c2 == 'A') { if (c2 == 'B') n = --recall; if (recall >= 0) { for(hist = H_head; hist && n--; hist = hist->next); if (hist) strcpy(&line[pl],hist->line); else recall = H_len; } } if (i != pl) printf("\233%dD",i); printf("\015\233J%s",line); i = max = strlen(line); break; case 'C': /* right arrow*/ if (i < max) { i++; printf("\233C"); } break; case 'D': /* left arrow */ if (i > pl) { i--; printf("\233D"); } break; case 'T': /* shift up */ case 'S': /* shift down */ break; case ' ': /* shift -> <-*/ c3 = getchar(); break; default: c3 = getchar(); if (c3 == '~') { fkey = c2; fkeys[0] = 'f'; if (c2 == 63) { strcpy(&line[pl],"help"); goto done; } } else if (getchar() != '~') { /* window was resized */ while(getchar() != '|'); printf("\2330 q"); /* get window bounds */ n = 0; while((rep[n] = getchar()) != 'r' && n++ < 14 ); width = (rep[n-3] - 48) * 10 + rep[n-2] - 48; rep[n-1] = '\0'; set_var (LEVEL_SET, "_width", &rep[n-3]); break; } else { fkey = c3; fkeys[0] = 'F'; } sprintf(fkeys+1,"%d",fkey - 47); if (!(s = get_var(LEVEL_SET, fkeys))) break; strcpy(&line[pl], s); printf("%s",&line[pl]); goto done; break; } break; case 8: if (i > pl) { i--; printf("\010"); } else break; case 127: if (i < max) { int j,t,l = 0; movmem(&line[i+1],&line[i],max-i); --max; printf("\233P"); j = width - i % width - 1; /* amount to end */ t = max/width - i/width; /* no of lines */ for(n = 0; n < t; n++) { l += j; /* no. of char moved */ if (j) printf("\233%dC",j); /* goto eol */ printf("%c\233P",line[width*(i/width+n+1)-1]); j = width-1; } if (t) printf("\233%dD",l+t); /* get back */ } break; case 18: n = i/width; if (n) printf("\233%dF",n); printf("\015\233J%s",line); i = max; break; case 27: case 10: break; case 1: insert ^= 1; break; case 21: case 24: case 26: if (i > pl) printf("\233%dD",i-pl); i = pl; if (c1 == 26) break; printf("\233J"); max = i; line[i] = '\0'; break; case 11: /* ^K */ printf("\233J"); max = i; line[i] = '\0'; break; case 28: /* ^\ */ setraw(0); return(NULL); case 5: printf("\233%dC",max - i); i = max; break; case 13: line[max] = '\0'; done: printf("\233%dC\n",max - i); setraw(0); strcpy(line, &line[pl]); return(line); default: if (c1 == 9) c1 = 32; if (c1 > 31 & i < 256) { if (i < max && insert) { int j,t,l = 0; movmem(&line[i], &line[i+1], max - i); printf("\233@%c",c1); t = max/width - i/width; j = width - i % width - 1; for(n = 0; n < t; n++) { l += j; if (j) printf("\233%dC",j); printf("\233@%c",line[width*(i/width+n+1)]); j = width-1; } if (t) printf("\233%dD",l + t); ++max; } else { if (i == pl && max == i) printf("\015%s",line); putchar(c1); } line[i++] = c1; if (max < i) max = i; line[max] = '\0'; } } } setraw(0); return(NULL); } SHAR_EOF cat << \SHAR_EOF > run.c /* * RUN.C * * (c)1986 Matthew Dillon 9 October 1986 * * RUN handles running of external commands. * * version 2.06M (Manx Version and Additions) by Steve Drew 28-May-87 * */ #include "shell.h" char *FindIt(); do_run(str) char *str; { int i, try = -1; int run = 0; char buf[128]; char runcmd[128]; char *save, *path, *index(); char *p = av[0]; char **args = av+1; while(*p++) *p &= 0x7F; /* allow "com mand" */ while(*args) { /* if any arg contains a space then */ if (index(*args,' ')) { /* surround with quotes, since must */ i = strlen(*args); /* of specified via "arg u ment" on */ movmem(*args,(*args)+1,i);/* original command line. */ args[0][0] = args[0][i+1] = '\"'; /* mpush in execom.c has */ args[0][i+2] = '\0'; /* allowed for these 2 extra bytes. */ } ++args; } if (path = FindIt(av[0],"",buf)) { if (!strcmp(av[0],"run") || !strcmp(av[0],"ru")) { /* was a run */ if (FindIt(av[1],"",runcmd)) { run = 1; save = av[1]; av[1] = runcmd; } } if ((try = fexecv(path, av)) == 0) i = wait(); if (run) av[1] = save; } else { APTR original; original = Myprocess->pr_WindowPtr; Myprocess->pr_WindowPtr = (APTR)(-1); if ((try = fexecv(av[0], av)) == 0) i = wait(); Myprocess->pr_WindowPtr = original; } if (try) { long lock; char *copy; if ((path = FindIt(av[0],".sh",buf)) == NULL) { fprintf(stderr,"Command Not Found %s\n",av[0]); return (-1); } av[1] = buf; /* particular to do_source() */ copy = malloc(strlen(str)+3); strcpy(copy+2,str); copy[0] = 'x'; copy[1] = ' '; i = do_source(copy); free(copy); } return (i); } char * FindIt(cmd, ext, buf) char *cmd; char *ext; char *buf; { long lock = 0; char hasprefix = 0; APTR original; char *ptr, *s = NULL; original = Myprocess->pr_WindowPtr; for (ptr = cmd; *ptr; ++ptr) { if (*ptr == '/' || *ptr == ':') hasprefix = 1; } if (!hasprefix) { Myprocess->pr_WindowPtr = (APTR)(-1); s = get_var(LEVEL_SET, V_PATH); } strcpy(buf, cmd); strcat(buf, ext); while ((lock = (long)Lock(buf, ACCESS_READ)) == 0) { if (*s == NULL || hasprefix) break; for(ptr = s; *s && *s != ','; s++) ; strcpy(buf, ptr); buf[s-ptr] = '\0'; strcat(buf, cmd); strcat(buf, ext); if (*s) s++; } Myprocess->pr_WindowPtr = original; if (lock) { UnLock(lock); return(buf); } return(NULL); } SHAR_EOF cat << \SHAR_EOF > shell.h /* * SHELL.H * * (c)1986 Matthew Dillon 9 October 1986 * * * SHELL include file.. contains shell parameters and extern's * * version 2.06M (Manx Version and Additions) by Steve Drew 28-May-87 * */ #include #include #include #include #include #include #include #include #include #include #include #include #define bmov movmem #define STDBUF 1 #define MAXAV 256 /* Max. # arguments */ #define MAXSRC 5 /* Max. # of source file levels */ #define MAXIF 10 /* Max. # of if levels */ #define MAXALIAS 20 /* Max. # of alias levels */ #define LEVEL_SET 0 /* which variable list to use */ #define LEVEL_ALIAS 1 #define LEVEL_LABEL 2 #define V_PROMPT "_prompt" /* your prompt (ascii command) */ #define V_HIST "_history" /* set history depth (value) */ #define V_HISTNUM "_histnum" /* set history numbering var */ #define V_DEBUG "_debug" /* set debug mode */ #define V_VERBOSE "_verbose" /* set verbose for source files */ #define V_STAT "_maxerr" /* worst return value to date */ #define V_LASTERR "_lasterr" /* return value from last comm. */ #define V_CWD "_cwd" /* current directory */ #define V_EXCEPT "_except" /* "nnn;command" */ #define V_PASSED "_passed" /* passed arguments to source fle*/ #define V_PATH "_path" /* search path for external cmds */ /* EXECOM.C defines */ #define FL_DOLLAR 0x01 /* One of the following */ #define FL_BANG 0x02 #define FL_PERCENT 0x04 #define FL_QUOTE 0x08 #define FL_IDOLLAR 0x10 /* Any or all of the following may be set */ #define FL_EOC 0x20 #define FL_EOL 0x40 #define FL_OVERIDE 0x80 #define FL_WILD 0x100 #define FL_MASK (FL_DOLLAR|FL_BANG|FL_PERCENT|FL_QUOTE) #define VERSION "V2.06M (c)1986 Matthew Dillon. Manx version by Steve Drew" #ifndef NULL #define NULL 0L #endif #define CHECKBREAK() ( breakcheck() ? (printf("^C\n"),1) : 0) #ifndef AZTEC_C struct _dev { long fd; short mode; }; #endif struct HIST { struct HIST *next, *prev; /* doubly linked list */ char *line; /* line in history */ }; struct PERROR { int errnum; /* Format of global error lookup */ char *errstr; }; struct DPTR { /* Format of directory fetch pointer */ struct FileLock *lock; /* lock on directory */ struct FileInfoBlock *fib; /* mod'd fib for entry */ }; extern struct HIST *H_head, *H_tail; extern struct PERROR Perror[]; extern struct DPTR *dopen(); extern char *set_var(), *get_var(), *next_word(); extern char *get_history(), *compile_av(); extern char *malloc(), *strcpy(), *strcat(); extern char **expand(); extern char *av[]; extern char *Current; extern int H_len, H_tail_base, H_stack; extern int E_stack; extern int Src_stack, If_stack; extern int ac; extern int debug, Rval, Verbose, disable, Quit; extern int Lastresult; extern int Exec_abortline, Exec_ignoreresult; extern int S_histlen; extern long Uniq; extern long Cin, Cout, Cout_append; extern char *Cin_name, *Cout_name; extern char Cin_type, Cout_type; /* these variables are in transition */ extern char *Pipe1, *Pipe2; extern long Src_base[MAXSRC]; extern long Src_pos[MAXSRC]; extern char If_base[MAXIF]; extern struct Process *Myprocess; SHAR_EOF