page@swan.ulowell.edu (Bob Page) (12/06/88)
Submitted-by: PERUGIA@ICNUCEVM.BITNET (Cesare Dieni) Posting-number: Volume 2, Issue 87 Archive-name: unix/shell301a.1 [This is a command line interpreter similar to the unix 'csh'. It is based on Matt Dillon's shell with Steve Drew's additions. I do not have a list of the changes between the original and this version. See 'shell.doc' (in part 3) for the full story. ..Bob] # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # comm1.c # comm2.c # comm3.c # execom.c # This archive created: Mon Dec 5 17:24:55 1988 cat << \SHAR_EOF > comm1.c /* * COMM1.C * * Matthew Dillon, August 1986 * * Version 2.07M by Steve Drew 10-Sep-87 * * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88 * */ extern char *v_passed, *v_gotofwd, *v_cwd, *v_lasterr; #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; { register char *c,*s; unsigned int l,i = 0; options=0; 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) options |= (1 << l); } } *count = i; return options; } do_sleep() { int i; if (ac == 2) { i = atoi(av[1]); while (i > 0) { Delay (100L); i -= 2; if (CHECKBREAK()) break; } } return 0; } do_protect() { register long mask=0xf; register char *s, *p, *flags="DEWRAPSH"; register unsigned int i; for (s=av[--ac]; *s; s++) if (p=index(flags,Toupper(*s))) mask^=(1 << (p-flags)); else ierror(av[ac],500); for (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]); return 0; } do_filenote() { char *note=av[--ac]; register unsigned int i; for (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]); return 0; } do_cat() { FILE *fopen(), *fi; register unsigned int lctr; unsigned int i; char buf[256]; get_opt("n",&i); if (i>=ac) { while (gets(buf) && !dobreak()) { if (options) printf("%4d ",++lctr); puts(buf); } } for (; i<ac; i++) if (fi = fopen (av[i], "r")) { lctr=0; while (fgets(buf,256,fi) && !dobreak()) { if (options) printf("%4d ",++lctr); printf("%s",buf); } fclose (fi); } else pError(av[i]); } do_info() { BPTR lock; struct InfoData *info; unsigned int size, free; char *p,*s,*state; struct DirectoryEntry *de_head=NULL, *de; info=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC); AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY ); Myprocess->pr_WindowPtr = (APTR)(-1); printf ("Unit Size Bytes Used Blk/By-Free Full Errs Status Name\n"); for (de=de_head; de; de=de->de_Next) { printf("%-5s",de->de_Name); if (lock=Lock(de->de_Name,ACCESS_READ)) { if (Info(lock, info)) { s = get_pwd(lock); if (p=index(s,':')) *p = '\0'; size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024; free = (((info->id_NumBlocks-info->id_NumBlocksUsed))* info->id_BytesPerBlock)/ 1024; switch(info->id_DiskState) { case ID_WRITE_PROTECTED: state="Read Only "; break; case ID_VALIDATED: state="Read/Write"; break; case ID_VALIDATING: state="Validating"; break; } printf("%4d%c%6ld%7ld%7ld%4d%c%4ld%%%4ld %s %s\n", (size>1024) ? ((size+512) >> 10) : size, (size>1024) ? 'M' : 'K', info->id_BytesPerBlock, info->id_NumBlocksUsed, info->id_NumBlocks-info->id_NumBlocksUsed, (free>1024) ? ((free+512) >> 10) : free, (free>1024) ? 'M' : 'K', (info->id_NumBlocksUsed * 100)/info->id_NumBlocks, info->id_NumSoftErrors, state, s); } else pError (de->de_Name); UnLock(lock); } else puts(" No disk present"); } FreeDAList(&de_head); Myprocess->pr_WindowPtr = NULL; FreeMem(info,(long)sizeof(struct InfoData)); 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; col = filecount = 0; bytes = blocks = 0L; *lspec = '\0'; 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; BPTR lock; /* 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=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[12] =='D'); if (!(((options & DIR_FILES) && !isadir) || ((options & DIR_DIRS) && isadir))) return; if (isadir) printf ("\23333m"); if (options & DIR_SHORT) { if (col==3 && slen>18) { printf("\n"); col = 0; } if (slen>18) { printf(" %-37s",s); col+= 2; } else { printf(" %-18s",s); col++; } if (col > 3) { printf("\n"); col=0; } } else printf(" %-24s %s",s ,fi); if (isadir) printf("\2330m"); fflush(stdout); fi[16] = fi[21] = '\0'; bytes += atol(fi+10); blocks += atol(fi+17); filecount++; return; } do_quit() { if (Src_stack) { Quit = 1; return(do_return()); } main_exit(0); } do_echo(str) register char *str; { char nl=1; for (; *str && *str != ' '; ++str); if (*str==' ') ++str; if (av[1] && !strcmp(av[1],"-n")) { nl = 0; str += 2; if (*str==' ') ++str; } printf("%s",str); if (nl) printf("\n"); fflush(stdout); return 0; } do_source(str) char *str; { register FILE *fi; char buf[256]; if (Src_stack == MAXSRC) { ierror(NULL,217); 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)) { int len = strlen(buf); buf[len-1] = '\0'; Src_pos[Src_stack - 1] += len; if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf); exec_command (buf); if (CHECKBREAK()) break; } --H_stack; --Src_stack; if (forward_goto) ierror(NULL,501); forward_goto = 0; unset_level(LEVEL_LABEL + Src_stack); unset_var(LEVEL_SET, v_gotofwd); unset_var(LEVEL_SET, v_passed); fclose (fi); return (0); } /* * return ptr to string that contains full cwd spec. */ char *get_pwd(flock) BPTR flock; { static char pwdstr[130]; PathName(flock, pwdstr, 128L); return pwdstr; } /* * set process cwd name and $_cwd, if str != NULL also print it. */ do_pwd(str) char *str; { char *ptr; if (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 */ CtoBStr(cwd, Mycli->cli_SetName, 128L); /* ptr=(char *)((ULONG)Mycli->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; { BPTR oldlock, filelock; if (filelock=Lock(str, ACCESS_READ)) { if (isdir(str)) { if (oldlock=CurrentDir(filelock)) UnLock(oldlock); return (0); } UnLock(filelock); ierror(str, 212); } else ierror(str, 205); return -1; } do_mkdir() { register unsigned int i; BPTR lock; for (i=1; i<ac; ++i) { if (exists(av[i])) ierror(av[i],203); else if (lock=CreateDir(av[i])) UnLock (lock); else pError(av[i]); } return 0; } do_mv() { char *dest, buf[256]; int dirflag; register unsigned int i; dirflag=isdir(dest=av[--ac]); if (ac>3 && !dirflag) { ierror(dest, 507); return (-1); } for (i=1; i<ac; ++i) { strcpy(buf, dest); if (dirflag) TackOn(buf, BaseName(av[i])); if (Rename(av[i],buf)==0) { pError(av[i]); return -1; } } return 0; } int dirstoo; all_args(args, action, dirsflag) char *args; int (*action)(); { unsigned int i; get_opt(args, &i); dirstoo=dirsflag; for (; i<ac && !dobreak(); ++i) if (isdir(av[i])) { if (options & 1) recurse(av[i], action); else if (dirstoo) (*action)(av[i]); } else (*action)(av[i]); return 0; } char *searchstring; search_file(s) char *s; { FILE *fopen(), *fi; unsigned int lctr, len=strlen(searchstring); int yesno; char buf[256], lowbuf[256], first; register char *p, *l, *t; if (!(options & 2)) for (t=searchstring; *t=Toupper(*t); t++); first=*searchstring; if ((fi=fopen(s, "r"))==NULL) { pError(s); return; } lctr=0; if (!(options & 32)) printf("Examining %s...\n",s); while (fgets(buf,256,fi) && !dobreak()) { lctr++; if (options & 4) yesno=compare_ok(searchstring,buf); else { yesno=0; p=buf; if (!(options & 2)) { l=lowbuf; /* p is already =buf */ while (*l++=Toupper(*p++)); /* lowbuf=upper(buf) */ p=lowbuf; } while (p=index(p,first)) if (!strncmp(p++,searchstring,len)) { yesno=1; break; } } if (yesno ^ ((options & 16)!=0) ) { /* default: print line numbers */ if (!(options & 8)) printf("%4d ",lctr); printf("%s",buf); } } fclose (fi); } do_search() { searchstring=av[--ac]; all_args("rcwneq", search_file, 0); return 0; } rm_file(file) char *file; { if (has_wild) printf(" %s...",file); if (options & 2) SetProtection(file,0L); if (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n"); } do_rm() { all_args("rp", rm_file, 1); return 0; } recurse(name, action) char *name; int (*action)(); { register BPTR lock, cwd; register FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC); char *namecopy=malloc(256); if (name[0] =='\0') return; namecopy[0]=0; if (lock=Lock(name,ACCESS_READ)) { cwd =CurrentDir(lock); if (Examine(lock, fib)) while (ExNext(lock, fib) && !CHECKBREAK()) { if (*namecopy) { (*action)(namecopy); namecopy[0]=0; } if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action); else strcpy(namecopy,fib->fib_FileName); } if (*namecopy) (*action)(namecopy); UnLock(CurrentDir(cwd)); if (dirstoo) (*action)(name); } else pError(name); free(namecopy); FreeMem(fib, (long)sizeof(FIB)); } do_history() { register struct HIST *hist; int i = H_tail_base; int len = (av[1]) ? strlen(av[1]) : 0; for (hist = H_tail; hist && !dobreak(); hist = hist->prev) if (len == 0 || !strncmp(av[1], hist->line, len)) printf("%3d %s", i++, hist->line); 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\nCHIP memory: %ld\n", ffree, cfree); printf("Total Free: %ld\n", cfree+ffree); return 0; } /* * foreach var_name ( str str str str... str ) commands * spacing is important (unfortunately) * * 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; register char *cstr, *vname; char **fav; 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]); fav = (char **)malloc(sizeof(char *) * (ac)); cstr = compile_av (av, cend + 1, ac, ' '); for (i = cstart; i < cend; ++i) { fav[i] = av[i]; } for (i = cstart; i < cend; ++i) { set_var (LEVEL_SET, vname, fav[i]); if (CHECKBREAK()) break; exec_command (cstr); } --H_stack; free (fav); 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); } extern struct Window *w; extern struct IntuitionBase *IntuitionBase; do_window() { long x, y, maxwidth, maxheight, arg[5]; unsigned int i; struct Screen *screen; struct Window *window; get_opt("slfbaq", &i); if (options & 1) SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height)); if (options & 2) { x=-w->LeftEdge; y=-w->TopEdge; MoveWindow(w,x,y); x=IntuitionBase->ActiveScreen->Width -w->Width; y=IntuitionBase->ActiveScreen->Height-w->Height; SizeWindow(w,x,y); } if (options & 4) WindowToFront(w); if (options & 8) WindowToBack(w); if (options & 16) ActivateWindow(w); if(ac >= 5) { Errno = 0; for(i=1; i<5; i++) { arg[i] = myatol(av[i]); if (Errno || arg[i] < 0) { ierror(av[i], 500); return 20; } } maxwidth = w->WScreen->Width; maxheight= w->WScreen->Height; if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) { ierror(NULL, 500); return 20; } x = -w->LeftEdge; y = -w->TopEdge; MoveWindow(w, x, y); x = arg[3] - w->Width; y = arg[4] - w->Height; SizeWindow(w, x, y); x = arg[1]; y = arg[2]; MoveWindow(w, x, y); } if(options & 32) { for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) { printf("\nScreen \"%s\" (%dx%d):\n", screen->Title, screen->Width, screen->Height ); for (window=screen->FirstWindow; window; window=window->NextWindow) { printf("\tWindow\t\"%s\" (%dx%d)\n", window->Title, window->Width, window->Height ); } } return 0; } printf("\014"); return 0; } setsystemtime(ds) struct DateStamp *ds; { struct timerequest tr; long secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND; if (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) { fprintf(stderr,"Clock error: can't open timer device\n"); return; } tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE; tr.tr_node.io_Message.mn_Node.ln_Pri = 0L; tr.tr_node.io_Message.mn_Node.ln_Name = NULL; tr.tr_node.io_Message.mn_ReplyPort = NULL; tr.tr_node.io_Command = TR_SETSYSTIME; tr.tr_time.tv_secs = secs; tr.tr_time.tv_micro = 0L; if (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n"); CloseDevice (&tr); } char tday[10]; char *dates(dss) struct DateStamp *dss; { static char timestr[40]; char tdate[10], ttime[10]; struct DateTime dt; struct DateStamp *myds=&(dt.dat_Stamp); dt.dat_Format=FORMAT_DOS; dt.dat_StrDay=tday; dt.dat_StrDate=tdate; dt.dat_StrTime=ttime; dt.dat_Flags=NULL; myds->ds_Days=dss->ds_Days; myds->ds_Minute=dss->ds_Minute; myds->ds_Tick=dss->ds_Tick; StamptoStr(&dt); sprintf(timestr,"%s %s\n",tdate,ttime); timestr[18]='\n'; timestr[19]='\0'; /* protection against bad timestamped files */ return timestr; } date() { struct DateStamp dss; register unsigned short i; struct DateTime dt; dt.dat_Format=FORMAT_DOS; if (ac==1) { DateStamp(&dss); printf("%s %s",tday,dates(&dss)); } else { DateStamp(& (dt.dat_Stamp)); for (i=1; i<ac; i++) { dt.dat_StrDate=NULL; dt.dat_StrTime=NULL; dt.dat_Flags=DTF_FUTURE; if (index(av[i],':')) dt.dat_StrTime=av[i]; else dt.dat_StrDate=av[i]; if (StrtoStamp(&dt)) ierror(av[i],500); } setsystemtime( & (dt.dat_Stamp) ); } return 0; } SHAR_EOF cat << \SHAR_EOF > comm2.c /* * COMM2.C * * (c)1986 Matthew Dillon 9 October 1986 * * Version 2.07M by Steve Drew 10-Sep-87 * * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88 * */ extern char *v_gotofwd; /* Casting conveniences */ #define BPTR_TO_C(strtag, var) ((struct strtag *)(BADDR( (ULONG) var))) #define PROC(task) ((struct Process *)task) #define CLI(proc) (BPTR_TO_C(CommandLineInterface, proc->pr_CLI)) /* Externs */ extern int has_wild; /* flag set if any arg has a ? or * */ /* globals */ int cp_update; int cp_date; do_abortline() { Exec_abortline = 1; return 0; } do_return() { register int retcode=(ac<2 ? 0 : atoi(av[1])); Exec_abortline = 1; if (Src_stack) { FILE *ptr = (FILE *)Src_base[Src_stack - 1]; ptr->_bp = ptr->_bend; ptr->_flags |= _EOF; /* fseek (Src_base[Src_stack - 1], 0L, 2); */ return retcode; } else main_exit(retcode); } /* * STRHEAD * * place a string into a variable removing everything after and including * the 'break' character * * strhead varname breakchar string * */ do_strhead() { char *s; if (s=index(av[3],*av[2])) *s='\0'; set_var (LEVEL_SET, av[1], av[3]); } do_strtail() { char *s; if (s=index(av[3],*av[2])) s++; else s=av[3]; set_var (LEVEL_SET, av[1], s); } long dptrtosecs(d) struct DPTR *d; { register struct DateStamp *ds=(&d->fib->fib_Date); return ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND; } long timeof(s) char *s; { struct DPTR *d; int dummy; long n; if ( (d=dopen(s,&dummy))==NULL ) return 0L; n=dptrtosecs(d); dclose(d); return n; } /* * if -f file (exists) or: * * if A < B <, >, =, <=, >=, <>, where A and B are either: * nothing * a string * a value (begins w/ number) */ do_if(garbage, com) char *garbage; { int result; int i; switch (com) { case 0: if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1; else { get_opt("rftmdn",&i); result=evalif(i); If_base[If_stack++]=(options & 32 ? result : !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; } if (forward_goto) disable = If_base[If_stack - 1] = 0; return 0; } evalif(i) register unsigned int i; { char c; long num, t0; long AvailMem(); switch(options & ~32) { case 0: if (ac-i != 3) return (ac>i && *av[i]); Errno=0; num=Atol(av[i])-Atol(av[i+2]); if (Errno) num=strcmp(av[i],av[i+2]); if (num < 0) c='<'; else if (num > 0) c='>'; else if (num ==0) c='='; return index(av[i+1], c) != NULL; case 1: return do_rpn(NULL,i); case 2: return exists(av[i]); case 4: t0=timeof(av[i++]); for ( ; i<ac ; i++) if (t0<=timeof(av[i])) return 1; return 0; case 8: return (AvailMem( (long)MEMF_FAST )!=0); case 16: return (isdir(av[i])!=0); default: ierror(NULL,500); 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); if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd))) forward_goto = 0; 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) { forward_goto = 1; set_var (LEVEL_SET, v_gotofwd, av[1]); return(0); } 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, num[32]; if (ac>2) com *= atoi(av[2]); if (var = get_var (LEVEL_SET, av[1])) { sprintf (num, "%d", atoi(var)+com); set_var (LEVEL_SET, av[1], num); } } do_input() { char in[256], *p,*s; unsigned int i; for (i=1; i < ac; ++i) if (gets(in)) { for(p = in; *p; p = s) { s = next_word(p); if (*s) *(s-1) = 0xA0; } set_var (LEVEL_SET, av[i], in); } return 0; } do_ver() { puts("Shell V3.01A\n\ (c)1986 Matthew Dillon\n\ Manx (M) versions by Steve Drew\n\ ARP (A) versions by Carlo Borreo & Cesare Dieni\n"); return 0; } do_ps() { /* this code fragment based on ps.c command by Dewi Williams */ register int count; /* loop variable */ struct Task *task; /* EXEC descriptor */ char strbuf[64+1]; /* scratch for btocstr() */ char cmd[40+1]; /* holds cmd name */ long ncli; printf("Proc Command Name CLI Type Pri. Address Directory\n"); Forbid(); ncli=(long)FindCLI(0L); for (count = 1; count <= ncli ; count++) /* or just assume 20?*/ if (task = (struct Task *)FindCLI((long)count)) { if (task==NULL) continue; /* Sanity check just in case */ if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue; /* or complain? */ BtoCStr(cmd, CLI(PROC(task))->cli_CommandName, 40L); BtoCStr(strbuf,CLI(PROC(task))->cli_SetName , 64L); printf("%2d %-20.20s %-11.11s %3d %8lx %s\n", count, cmd, task->tc_Node.ln_Name, task->tc_Node.ln_Pri, task, strbuf); } Permit(); return 0; } /* * 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; errstr = ""; ierr = 0; fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); get_opt("rud",&i); recur = (options & 0x01); cp_update = (options & 0x02); cp_date = (!(options & 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 && !dobreak(); ++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 (srcisdir) { BPTR srcdir, destdir; if (!destisdir) { if (exists(destname)) { ierr = 507; /* disallow dir to file */ goto done; } if (destdir = CreateDir(destname)) UnLock(destdir); destisdir = 1; } if (!(destdir = Lock(destname, ACCESS_READ))) { ierr = 205; errstr = destname; goto done; } if (!(srcdir = 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 */ BPTR destdir, srcdir, tmp; char *destfilename; srcdir = (BPTR)(Myprocess->pr_CurrentDir); if ((tmp = 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 = 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 BPTR srcdir, destdir; { BPTR cwd; register FIB *srcfib; register BPTR 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 = CurrentDir(srcdir); if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) { CurrentDir(destdir); if (!(destlock = Lock(srcfib->fib_FileName))) { destlock = CreateDir(srcfib->fib_FileName); printf("%*s%s (Dir)....[Created]\n",(level-1) * 6, " ",srcfib->fib_FileName); /* UnLock and re Lock if newly created for file_date() to work properly */ if (destlock) UnLock(destlock); destlock = 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; BPTR srcdir, destdir; { BPTR cwd; BPTR f1, f2; long i; int stat,ierr; char *buf; struct DPTR *dp, *dps = NULL; if ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL) { ierr = 103; goto fail; } ierr = 0; cwd = CurrentDir(srcdir); if ((f1=Open(srcname, MODE_OLDFILE))==NULL) { errstr = srcname; ierr = 205; goto fail; } dps = dopen(srcname,&stat); CurrentDir(destdir); if (cp_update) { dp=dopen(destname, &stat); if ( dptrtosecs(dp) >= dptrtosecs(dps) && !strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName)) { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; } dclose(dp); } if ((f2=Open(destname, MODE_NEWFILE))==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) { if (cp_date) file_date(&dps->fib->fib_Date, destname); printf("..copied\n"); } else DeleteFile(destname); fail: dclose(dps); if (buf) FreeMem(buf, 8192L); CurrentDir(cwd); return(ierr); } do_touch() { struct DateStamp ds; register unsigned int i; DateStamp(&ds); for (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500); } file_date(date,name) struct DateStamp *date; char *name; { long packargs[7]; UBYTE *ptr; struct MsgPort *task; BPTR dirlock; struct DPTR *tmp; int stat; if (!(task = (struct MsgPort *)DeviceProc(name))) return(1); if (tmp = dopen(name, &stat)) { dirlock = ParentDir(tmp->lock); ptr=AllocMem(65L,MEMF_PUBLIC); CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L); dclose(tmp); packargs[1]=dirlock; packargs[2]=(ULONG)ptr >> 2L; packargs[3]=(long)date; SendPacket(ACTION_SET_DATE,packargs,task); UnLock(dirlock); FreeMem(ptr,65L); } return 0; } do_addbuffers() { long packargs[7]; long n; struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]); if (!task) { ierror(av[1],510); return 20; } Errno=0; n=myatol(av[2]); if (Errno) return 20; packargs[0]=n; SendPacket(ACTION_MORE_CACHE,packargs,task); return 0; } do_relabel() { long packargs[7]; UBYTE *ptr; long n; struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]); if (!task) { ierror(av[1],510); return 20; } ptr=AllocMem(65L,MEMF_PUBLIC); CtoBStr(av[2],(ULONG)ptr >> 2L,64L); packargs[0]=(ULONG)ptr >> 2L; SendPacket(ACTION_RENAME_DISK,packargs,task); FreeMem(ptr,65L); changedisk(task); return 0; } do_diskchange() { struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]); if (!task) { ierror(av[1],510); return 20; } changedisk(task); return 0; } changedisk(task) struct MsgPort *task; { long packargs[7]; packargs[0]=1L; SendPacket(ACTION_INHIBIT,packargs,task); packargs[0]=0L; SendPacket(ACTION_INHIBIT,packargs,task); } SHAR_EOF cat << \SHAR_EOF > comm3.c /* * COMM3.C * * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88 * */ do_assign() { switch(ac) { case 1: assignlist(); break; case 2: doassign(av[1], NULL); break; case 3: doassign(av[1], av[2]); break; default: ierror(NULL, 500); break; } return 0; } char *assign_errors[4]={ "", "Name %s is not valid\n", "Weird error\n", "Can't cancel %s\n" }; doassign(log, phy) char *log, *phy; { int last=strlen(log) - 1; if (log[last] != ':') fprintf(stderr, "Bad name %s\n", log); else { log[last] = 0; fprintf(stderr,assign_errors[Assign(log, phy)],log); } } assignlist() { struct DirectoryEntry *de_head=NULL, *de; char buf[256]; BPTR lock; int ctr=0; AddDADevs(&de_head, DLF_DEVICES | DLF_VOLUMES | DLF_DIRS); printf("Devices:\n"); for (de=de_head; de && de->de_Type==DLX_DEVICE; de=de->de_Next) { printf("%-8s",de->de_Name); if (ctr++ == 5) { ctr=0; printf("\n"); } } printf("\n\nVolumes:\n"); for ( ; de && (de->de_Type==DLX_VOLUME || de->de_Type==DLX_UNMOUNTED); de=de->de_Next ) printf( "%-16s %s\n", de->de_Name, de->de_Type == DLX_VOLUME ? "[Mounted]" : "" ); printf("\nDirectories:\n"); for (; de && de->de_Type==DLX_ASSIGN; de=de->de_Next) { if (lock=Lock(de->de_Name, ACCESS_READ)) { PathName(lock, buf, 256L); UnLock(lock); } else strcpy(buf,"Unexisting lock"); printf("%-20s%s\n",de->de_Name,buf); } FreeDAList(&de_head); } do_join() { BPTR sou, dest; char *buffer; unsigned int i; long n; char *namedest=av[--ac]; get_opt("r", &i); if (options==0 && exists(namedest)) { ierror(namedest,203); return 20; } if ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; } if ( (dest=Open(namedest, MODE_NEWFILE)) == NULL ) { pError(namedest); goto fail1; } for (i=1; i<ac; i++) { if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]); else while( (n=Read(sou, buffer, 8192L)) > 0 ) if (Write(dest, buffer, n) != n) { pError(namedest); Close(sou); goto fail2; } Close(sou); } fail2: Close(dest); fail1: free(buffer); return 0; } #define BUFDIM 512L #define MAXSTR 256 int minstr; strings_in_file(s) char *s; { char c; char readbuf[BUFDIM+1], strbuf[MAXSTR+1]; register unsigned int i, strctr=0; BPTR fh; int out, n; if ( fh=Open(s, MODE_OLDFILE) ) { fprintf(stderr, "Strings in %s (len>=%d):\n",s,minstr); while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() ) for (i=0; i<n; i++) { c=readbuf[i]; if (c<0x20 || c>0x7f) { out=(strctr>=minstr); if (!out) strctr=0; } else { strbuf[strctr++]=c; out=(strctr>=BUFDIM); } if (out) { strbuf[strctr]='\0'; puts(strbuf); strctr=0; } } Close(fh); } else pError(s); } do_strings() { minstr=(int)myatol(av[--ac]); all_args("r", strings_in_file, 0); return 0; } BPTR myfile[MAXMYFILES]; do_open() { long mode; unsigned int n; switch (av[2][0]) { case 'r': mode=MODE_OLDFILE; break; case 'w': mode=MODE_NEWFILE; break; default : ierror(NULL,500); return; } Errno=0; n=(unsigned int)myatol(av[3]); if (Errno) return 20; if (n<0 || n>MAXMYFILES) { ierror(av[3],500); return 20; } myfile[n]=Open(av[1],mode); return (myfile[n]==NULL); } do_close() { register unsigned int i; int n; for (i=1; i<ac; i++) { Errno=0; n=(int)myatol(av[i]); if (Errno) return 20; if (n<0 || n>MAXMYFILES) { ierror(av[i],500); return 20; } myclose(n); } return 0; } myclose(n) { if (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; } } do_fileslist() { register unsigned short i; int flag=0; printf("Open files:"); for (i=0; i<MAXMYFILES; i++) if (myfile[i]) { printf(" %d",i); flag=1; } if (!flag) printf(" None!"); printf("\n"); } BPTR extOpen(name,mode) char *name; long mode; { if (name[0]=='.') return myfile[atoi(name+1)]; return Open(name,mode); } extClose(fh) BPTR fh; { register unsigned short i; for (i=0; i<MAXMYFILES; i++) if (myfile[i]==fh) return; Close(fh); } do_resident(avline) char *avline; { unsigned int i; BPTR seg; struct ResidentPrgNode *p; char *args; get_opt("ar", &i); switch (options) { case 0: ObtainSemaphore (& (ArpBase->ResPrgProtection) ); if (p=ArpBase->ResidentPrgList) { printf("Name Users\n"); for (; p; p=p->rpn_Next) printf("%-16s %-3ld\n",p->rpn_Name,p->rpn_Usage); } else printf("No resident program(s)\n"); ReleaseSemaphore(& (ArpBase->ResPrgProtection) ); break; case 1: for (; i<ac; i++) if ( (seg=(BPTR)LoadPrg(av[i])) && AddResidentPrg(seg,av[i]) ) printf("OK! %s is now resident\n", BaseName(av[i])); else pError(av[i]); break; case 2: for (; i<ac; i++) if (RemResidentPrg(av[i])) ierror(av[i],202); else printf("Removed %s\n",av[i]); break; default: ierror(NULL,500); break; } } struct ProcessControlBlock pcb={ 4000, /* pcb_StackSize */ 0, /* pcb_Pri */ }; /* remaining field are NULL */ do_truerun(avline, backflag) char *avline; { char name[200]; char *FindIt(); if (backflag) { pcb.pcb_Control=NULL; pcb.pcb_Input=pcb.p_Output=Open("NIL:",MODE_OLDFILE); } else { pcb.pcb_Control=PRB_SAVEIO; pcb.pcb_Input=pcb.p_Output =NULL; } if (FindIt(av[1], "", name)) ASyncRun(name,next_word(next_word(avline)),&pcb); else ierror(av[1],205); return 0; } int exists(name) char *name; { BPTR lock; if (lock=Lock(name,ACCESS_READ)) { UnLock(lock); return 1; } return 0; } do_aset() { Setenv(av[1],av[2]); return 0; } #define HTYPELINE 16L htype_a_file(s) char *s; { BPTR fh; long n, filesize=0; char buf[HTYPELINE+1]; register unsigned int i; if ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; } while ( (n=Read(fh,buf,HTYPELINE))>0 && !dobreak()) { printf("%06lx: ",filesize); filesize+=n; for (i=0; i<n; i++) { printf( (i&3) ? "%02x" : " %02x",(int)(unsigned char)buf[i]); if (buf[i]<=0x20) buf[i]='.'; } for ( ; i<HTYPELINE; i++) printf( (i&3) ? " " : " "); buf[i]=0; printf(" %s\n",buf); } Close(fh); return 0; } do_htype() { all_args("", htype_a_file, 0); return 0; } do_stack() { long n; if (ac>1) { n=myatol(av[1]); if (!Errno) Mycli->cli_DefaultStack=(long)(n >> 2L); } else printf("current stack size is %ld bytes\n", (long)Mycli->cli_DefaultStack << 2L); } long myatol(s) char *s; { long n; Errno=0; n=Atol(s); if (Errno==ERRBADINT) ierror(s,511); else Errno=0; return n; } do_fault() { struct PERROR *p; register unsigned int i; int n; for (i=1; i<ac; i++) { n=(int)myatol(av[i]); if (!Errno) { for (p=Perror; p->errnum && p->errnum!=n; p++); if (p->errnum) printf("Fault %d: %s\n",n,p->errstr); else printf("Fault %d not recognized\n",n); } } return 0; } struct rpncommand { char *str; int parsin, parsout; }; struct rpncommand rpn[]={ "+", 2, 1, "-", 2, 1, "*", 2, 1, "/", 2, 1, "%", 2, 1, "&", 2, 1, "|", 2, 1, "~", 1, 1, ">", 2, 1, "<", 2, 1, "==", 2, 1, "!", 1, 1, ".", 1, 0, "CR", 0, 0, "EXISTS", 1, 1, "STR", 0, 1, "PRINT",1, 0, "$", 1, 1, "HELP", 0, 0, "LEN", 1, 1, "STRCMP", 2, 1, "[]", 2, 1, "SETVAR", 2, 0, "DUP", 1, 2, "DROP", 1, 0, "SWAP", 2, 2, "ATOL", 1, 1, NULL, 0, 1, /* this looks for a number */ }; do_rpn(garbage,ifflag) /* ifflag!=0 if called from if */ char *garbage; { register long n0, n1; long t; unsigned int i, j; int sp=0; long stack[100]; struct rpncommand *temp; i=1; if (ifflag) get_opt("rn",&i); for (; i<ac; i++) { for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ; n0=stack[sp-1]; n1=stack[sp-2]; sp -= (rpn[j].parsin); if (sp<0) { fprintf(stderr, "Empty stack\n"); return 1; } switch (j) { case 0: n0 += n1; break; case 1: n0 = n1-n0; break; case 2: n0 *= n1; break; case 3: n0 = n1/n0; break; case 4: n0 %= n1; break; case 5: n0 &= n1; break; case 6: n0 |= n1; break; case 7: n0 = ~n0; break; case 8: n0 = (n1 > n0); break; case 9: n0 = (n1 < n0); break; case 10: n0 = (n0 == n1); break; case 11: n0 = !n0; break; case 12: printf("%ld", n0); break; case 13: printf("\n"); break; case 14: n0=exists(n0); break; case 15: n0=(long)av[++i]; if (i==ac) { ierror(av[i-1],500); return 20; } break; case 16: printf("%s",n0); break; case 17: n0=(long)get_var(LEVEL_SET,n0); break; case 18: printf("In Commands Out\n"); for (temp=rpn; temp->str; temp++) printf(" %d %-10s%d\n", temp->parsin,temp->str,temp->parsout); break; case 19: n0=(long)strlen(n0); break; case 20: n0=(long)strcmp(n0,n1); break; case 21: n0=*((char *)(n0+n1)); break; case 22: set_var(LEVEL_SET,n1,n0); break; case 23: n1=n0; break; case 24: t=n0; n0=n1; n1=t; break; case 25: break; case 26: n0=atol(n0); break; default: n0=myatol(av[i]); if (Errno) ierror(av[i],500); break; } stack[sp]=n0; stack[sp+1]=n1; sp += rpn[j].parsout; } if (!ifflag) for (i=0;i<sp;i++) printf("stack[%d]: %ld\n", i, stack[i]); return (sp>0 ? (int)stack[sp-1] : 0); } do_path() { union { long *lp; long ll; } l; BPTR lock; char buf[256]; puts("Current dir"); l.lp = (long *) Mycli->cli_CommandDir; while (l.ll) { l.ll <<= 2; PathName(l.lp[1], buf, 256L); puts(buf); l.ll = *l.lp; } puts("C:"); return 0; } do_pri() { long t, pri; t=myatol(av[1]); if (Errno) return 20; if (t<1 || t>20) { ierror(av[1],500); return 20; } pri=myatol(av[2]); if (Errno) return 20; if (pri<-128 || t>127) { ierror(av[2],500); return 20; } Forbid(); SetTaskPri(FindCLI(t),pri); return 0; } SHAR_EOF cat << \SHAR_EOF > execom.c /* * EXECOM.C * * Matthew Dillon, 10 August 1986 * Finally re-written. * * Version 2.07M by Steve Drew 10-Sep-87 * * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88 * */ extern char *v_histnum, *v_except; #define F_EXACT 0 #define F_ABBR 1 #define ST_COND 0x01 #define ST_NORED 0x02 #define ST_NOEXP 0x04 #define ST_AV 0x08 /* delimit args within a variable */ 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_diskchange(), do_stack(), do_fault(), do_path(), do_pri(); extern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany(); extern int do_open(), do_close(), do_fileslist(), do_htype(); extern int do_run(), do_number(), do_assign(), do_join(); extern int do_quit(), do_set_var(), do_unset_var(); extern int do_echo(), do_source(), do_mv(), do_addbuffers(); extern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history(); extern int do_mem(), do_cat(), do_dir(), do_info(), 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(), do_relabel(); extern int do_copy(), date(), do_protect(), do_ps(); extern int do_forever(), do_abortline(), do_strings(), do_touch(); extern int do_window(), do_search(), do_filenote(); char *push_cpy(); static struct COMMAND Command[] = { do_run, 0, ST_AV, 0, "\001", /* may call do_source */ do_set_var, 0, 0, LEVEL_ALIAS, "alias", /* uses avline */ do_abortline, 0, 0, 0, "abortline", do_addbuffers, 2, 0, 0, "addbuffers", do_aset, 1, 0, 0, "aset", do_assign, 0, 0, 0, "assign", do_cat, 0, 0, 0, "cat", do_cd, 0, 0, 0, "cd", do_close, 0, 0, 0, "close", do_copy, 1, 0, 0, "copy", do_copy, 1, 0, 0, "cp", date, 0, 0, 0, "date", do_rm, 0, 0, 0, "delete", do_dir, 0, ST_NOEXP, 0, "dir", do_diskchange, 1, 0, 0, "diskchange", do_inc, 1, 0, -1, "dec", do_echo, 0, 0, 0, "echo", /* uses avline */ do_if, 0, ST_COND, 1, "else", do_if, 0, ST_COND, 2, "endif", do_fault, 1, 0, 0, "fault", do_filenote, 2, 0, 0, "filenote", do_fileslist, 0, 0, 0, "flist", do_foreach, 3, ST_NORED, 0, "foreach", do_forever, 1, ST_NORED, 0, "forever", do_goto, 1, 0, 0, "goto", do_help, 0, 0, 0, "help", do_history, 0, 0, 0, "history", do_howmany, 0, 0, 0, "howmany", do_htype, 1, 0, 0, "htype", do_if, 1, ST_COND|ST_NORED,0, "if", do_inc, 1, 0, 1, "inc", do_info, 0, 0, 0, "info", do_join, 2, 0, 1, "join", do_input, 1, 0, 0, "input", do_label, 1, ST_COND, 0, "label", do_dir, 0, ST_NOEXP, 0, "ls", do_mkdir, 0, 0, 0, "md", do_mem , 0, 0, 0, "mem", do_mkdir, 0, 0, 0, "mkdir", do_mv, 2, 0, 0, "mv", do_open, 3, 0, 0, "open", do_path, 0, 0, 0, "path", do_pri, 2, 0, 0, "pri", do_protect, 2, 0, 0, "protect", do_ps, 0, 0, 0, "ps", do_pwd, 0, 0, 0, "pwd", do_quit, 0, ST_NORED, 0, "quit", do_truerun, 1, ST_NORED, 1, "rback", do_mv, 2, 0, 0, "rename", do_relabel, 2, 0, 0, "relabel", do_resident, 0, 0, 0, "resident", do_return, 0, 0, 0, "return", do_rm, 0, 0, 0, "rm", do_rpn, 0, ST_NOEXP|ST_NORED,0, "rpn", do_truerun, 1, ST_NORED, 0, "run", do_search, 2, 0, 0, "search", do_set_var, 0, ST_AV, LEVEL_SET, "set", do_sleep, 0, 0, 0, "sleep", do_source, 0, ST_NORED|ST_AV, 0, "source", /* uses avline */ do_stack, 0, 0, 0, "stack", do_strhead, 3, 0, 0, "strhead", do_strings, 1, 0, 0, "strings", do_strtail, 3, 0, 0, "strtail", do_touch, 0, 0, 0, "touch", do_cat, 0, 0, 0, "type", do_unset_var, 0, 0, LEVEL_ALIAS, "unalias", do_unset_var, 0, 0, LEVEL_SET , "unset", do_ver, 0, 0, 0, "version", do_window, 0, ST_NOEXP, 0, "window", '\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; 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); preformat(base, scr); return (fcomm(scr, 1) ? -1 : 1); } isalphanum(c) register char c; { return ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') ); } 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) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d); } extern BPTR extOpen(); /* * 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[1] == '$') { if (istr = get_var (LEVEL_SET, str + 2)) 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) { if (cmd_stat(command) & ST_COND) goto skipgood; } if (disable || forward_goto) { 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 cstat = cmd_stat(command); ptr = exarg(&nextstr); inc = 1; arg = ""; cont = (elast == 0x80); switch (*ptr) { case '<': redir = -2; case '>': if (cstat & (ST_NORED | ST_COND)) { /* don't extract */ redir = 0; /* <> stuff if its */ arg = ptr; /* external cmd. */ break; } ++redir; arg = ptr + 1; if (*arg == '>') { redir = 2; /* append >> */ ++arg; } cont = 1; break; case '$': /* restore args if from set command or pend_alias */ if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) { if (cstat & ST_COND) { char *tp; tp = push_cpy(arg); arg = tp; } else { char *pe, sv, *index(); while (pe = index(arg,0xA0)) { sv = *pe; *pe = '\0'; av[ac++] = push_cpy(arg); *pe = sv; av[ac] = '\0'; arg = pe+1; } } } else arg = ptr; break; case '*': case '?': if ((cstat & 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)+strlen(av[ac])); strcpy(av[ac], old); strcat(av[ac], arg); } else { av[ac] = push_cpy(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++] = push_cpy(*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; char save_elast; char *compile_av(); register char *avline; unsigned char delim = ' '; save_elast = elast; if (pend_alias || (cmd_stat(command) & ST_AV)) delim = 0xA0; avline = compile_av(av,((pend_alias) ? 1 : 0), ac , delim); 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 = Myprocess->pr_CIS; long oldcout = Myprocess->pr_COS; char *Cin_buf; struct FileHandle *ci; long oldbuf; fflush(stdout); ccno = find_command (command); if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) { if (Cin_name) { if ((Cin = (long)extOpen(Cin_name,1005L)) == 0L) { ierror (NULL, 504); err = 1; Cin_name = '\0'; } else { Myprocess->pr_CIS = _devtab[stdin->_unit].fd = Cin; ci = (struct FileHandle *)(((long)Cin)<<2); Cin_buf = (char *)AllocMem(202L, MEMF_PUBLIC); oldbuf = ci->fh_Buf; if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */ ci->fh_Buf = (long)Cin_buf>>2; } } if (Cout_name) { if (Cout_append && (Cout =(long)extOpen(Cout_name, 1005L)) ) { Seek(Cout, 0L, 1L); } else { Cout = (long)extOpen(Cout_name,1006L); } if (Cout == NULL) { err = 1; ierror (NULL, 504); Cout_name = '\0'; Cout_append = 0; } else { Myprocess->pr_COS = _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 (E_stack == 0 && Lastresult != err) { Lastresult = err; seterr(); } if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) { if (Cin_name) { fflush(stdin); clearerr(stdin); ci->fh_Buf = oldbuf; extClose(Cin); FreeMem(Cin_buf, 202L); } if (Cout_name) { fflush(stdout); clearerr(stdout); stdout->_flags &= ~_DIRTY; /* because of nil: device */ extClose(Cout); Cout_append = 0; } } 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(6 + bytes + 2); /* may need extra 2 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); } cmd_stat(str) char *str; { return(Command[find_command(str)].stat); } find_command(str) char *str; { register unsigned 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); } char *push_cpy(s) char *s; { return strcpy(mpush(strlen(s)), s); } SHAR_EOF # End of shell archive exit 0 -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.