page%swap@Sun.COM (Bob Page) (05/19/89)
Submitted-by: PERUGIA@ICNUCEVM.Bitnet (Cesare Dieni) Posting-number: Volume 89, Issue 149 Archive-name: unix/shell303a.1 New to 3.03A: - New filter commands fltlower, fltupper. - Added configuration file feature: now if you have a file named S:.login, it will be sourced for every Shell you start. - New option dir -c. - New editing feature: shift-left(right) arrow move cursor to previous(next) word. - Bugs fixed: alias command wasn't listed in help; typing a number as a command was interpreted like 'alias'. # This is a shell archive. # Remove anything above and including the cut line. # Then run the rest of the file through 'sh'. # Unpacked files will be owned by you and have default permissions. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: SHell ARchive # Run the following text through 'sh' to create: # comm1.c # comm2.c # comm3.c # execom.c # This is archive 1 of a 2-part kit. # This archive created: Thu May 18 12:17:53 1989 echo "extracting comm1.c" sed 's/^X//' << \SHAR_EOF > comm1.c X/* X * COMM1.C X * X * Matthew Dillon, August 1986 X * X * Version 2.07M by Steve Drew 10-Sep-87 X * X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89 X * X */ X Xextern char *v_passed, *v_gotofwd, *v_cwd, *v_lasterr; X X#define DIR_SHORT 0x01 X#define DIR_FILES 0x02 X#define DIR_DIRS 0x04 X#define DIR_NOCOL 0x08 X Xextern int has_wild; Xchar cwd[256]; X X/* X Parse the options specified in sw[] X Setting a bit in global variable options X for each one found X*/ X Xget_opt(sw,count) Xchar *sw; Xint *count; X{ Xregister char *c,*s; Xunsigned int l,i = 0; X Xoptions=0; Xwhile((++i < ac) && (av[i][0] == '-')) { X for (c = av[i]+1; *c ; c++) { X for(l = 0,s = sw;*s && *s != *c; ++s) ++l; X if (*s) options |= (1 << l); X } X } X*count = i; X} X Xdo_sleep() X{ Xint i; X Xif (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i-=2) Delay(100L); Xreturn 0; X} X Xdo_protect() X{ Xregister long mask=0xf; Xregister char *s, *p, *flags="DEWRAPSH"; Xregister unsigned int i; Xfor (s=av[--ac]; *s; s++) X if (p=index(flags,Toupper(*s))) mask^=(1 << (p-flags)); X else ierror(av[ac],500); Xfor (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]); Xreturn 0; X} X Xdo_filenote() X{ Xchar *note=av[--ac]; Xregister unsigned int i; X Xfor (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]); Xreturn 0; X} X Xdo_cat() X{ XFILE *fopen(), *fi; Xregister unsigned int lctr; Xunsigned int i; Xchar buf[256]; X Xget_opt("n",&i); Xif (i>=ac) { X if (has_wild) { printf("No files matching\n"); return 20; } X lctr=0; X while (gets(buf) && !dobreak()) { X if (options) printf("%4d ",++lctr); X puts(buf); X } X } Xfor (; i<ac; i++) X if (fi = fopen (av[i], "r")) { X lctr=0; X while (fgets(buf,256,fi) && !dobreak()) { X if (options) printf("%4d ",++lctr); X printf("%s",buf); X } X fclose (fi); X } X else pError(av[i]); Xreturn 0; X} X Xdo_info() X{ XBPTR lock; Xstruct InfoData *info; Xunsigned int size, free; Xchar *p,*s,*state; Xstruct DirectoryEntry *de_head=NULL, *de; X Xinfo=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC); XAddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY ); XMyprocess->pr_WindowPtr = (APTR)(-1); Xprintf ("Unit Size Bytes Used Blk/By-Free Full Errs Status Name\n"); Xfor (de=de_head; de; de=de->de_Next) { X printf("%-5s",de->de_Name); X if (lock=Lock(de->de_Name,ACCESS_READ)) { X if (Info(lock, info)) { X s = get_pwd(lock); X if (p=index(s,':')) *p = '\0'; X size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024; X free = (((info->id_NumBlocks-info->id_NumBlocksUsed))* X info->id_BytesPerBlock)/ 1024; X switch(info->id_DiskState) { X case ID_WRITE_PROTECTED: state="Read Only "; break; X case ID_VALIDATED: state="Read/Write"; break; X case ID_VALIDATING: state="Validating"; break; X } X printf("%4d%c%6ld%7ld%7ld%4d%c%4ld%%%4ld %s %s\n", X (size>1024) ? ((size+512) >> 10) : size, X (size>1024) ? 'M' : 'K', X info->id_BytesPerBlock, X info->id_NumBlocksUsed, X info->id_NumBlocks-info->id_NumBlocksUsed, X (free>1024) ? ((free+512) >> 10) : free, X (free>1024) ? 'M' : 'K', X (info->id_NumBlocksUsed * 100)/info->id_NumBlocks, X info->id_NumSoftErrors, X state, X s); X } X else pError (de->de_Name); X UnLock(lock); X } X else puts(" No disk present"); X } XFreeDAList(&de_head); XMyprocess->pr_WindowPtr = NULL; XFreeMem(info,(long)sizeof(struct InfoData)); Xreturn 0; X} X X/* things shared with display_file */ X Xchar lspec[128]; Xint filecount, col; Xlong bytes, blocks; X X/* X * the args passed to do_dir will never be expanded X */ Xdo_dir() X{ X void display_file(); X int i; X X col = filecount = 0; X bytes = blocks = 0L; X *lspec = '\0'; X X get_opt("sfdc",&i); X X if (ac == i) { X ++ac; X av[i] = ""; X } X if (!(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS); X X for (; i < ac && !CHECKBREAK(); ++i) { X char **eav; X int c,eac; X if (!(eav = expand(av[i], &eac))) continue; X QuickSort(eav, eac); X for(c=0;c < eac && !breakcheck();++c) display_file(options,eav[c]); X free_expand (eav); X } X if (col) printf("\n"); X if (filecount > 1) { X blocks += filecount; /* account for dir blocks */ X printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount); X } X return 0; X} X Xvoid Xdisplay_file(options,filestr) Xint options; Xchar *filestr; X{ X long atol(); X int isadir,slen; X char sc; X char *c,*s,*fi; X BPTR lock; X X/* if current dir different from lspec then X look for ':' or '/' if found lock it and get_pwd. X else then use cwd. X*/ X for(s = c = filestr; *c; ++c) if (*c == ':' || *c == '/') s = c; X if (*s == ':') ++s; X sc = *s; X *s = '\0'; X c = filestr; X if (!*c) c = cwd; X if (strcmp (c, &lspec)) { X strcpy(lspec, c); X if (col) printf("\n"); X if (lock=Lock(c,SHARED_LOCK)) { X printf("Directory of %s\n", get_pwd(lock)); X UnLock(lock); X } X col = 0; X } X *s = sc; X if (sc == '/') s++; X slen = strlen(s); X fi = s + slen + 1; X isadir = (fi[12] =='D'); X X if (!(((options & DIR_FILES) && !isadir) || X ((options & DIR_DIRS) && isadir))) X return; X if (isadir && !(options & DIR_NOCOL)) printf ("\23333m"); X if (options & DIR_SHORT) { X if (col==3 && slen>18) { printf("\n"); col = 0; } X if (slen>18) { printf(" %-37s",s); col+= 2; } X else { printf(" %-18s",s); col++; } X if (col > 3) { printf("\n"); col=0; } X } X else printf(" %-24s %s",s ,fi); X if (isadir && !(options & DIR_NOCOL)) printf("\2330m"); X fflush(stdout); X fi[16] = fi[21] = '\0'; X bytes += atol(fi+10); X blocks += atol(fi+17); X filecount++; X return; X} X Xdo_quit() X{ Xif (Src_stack) { X Quit = 1; X return(do_return()); X } Xmain_exit(0); X} X Xdo_echo(str) Xregister char *str; X{ Xchar nl=1; X Xfor (; *str && *str != ' '; ++str); Xif (*str==' ') ++str; Xif (av[1] && !strcmp(av[1],"-n")) { X nl = 0; X str += 2; X if (*str==' ') ++str; X } Xprintf("%s",str); Xif (nl) printf("\n"); Xfflush(stdout); Xreturn 0; X} X X/* gets a line from file, joining two lines if the first ends in '\' */ X Xchar *myfgets(buf, buflen, file) Xchar *buf; XFILE *file; X{ Xchar *bufptr=buf; Xint remain=buflen, n, flag; X Xdo { X if (fgets(bufptr, remain, file)==NULL) { X if (remain != buflen) X fprintf(stderr,"Source: file ends in '\\'\n"); X return NULL; X } X n=strlen(buf); X bufptr += n; X if (flag= (*(bufptr-2)=='\\')) bufptr-=2; X remain -= (n+2); X } while (flag); Xreturn buf; X} X Xdo_source(str) Xchar *str; X{ Xregister FILE *fi; Xchar buf[256]; X Xif (Src_stack == MAXSRC) { X ierror(NULL,217); X return -1; X } Xif ((fi = fopen (av[1], "r")) == 0) { pError(av[1]); return -1; } Xset_var(LEVEL_SET, v_passed, next_word(next_word(str))); X++H_stack; XSrc_pos[Src_stack] = 0; XSrc_base[Src_stack] = (long)fi; X++Src_stack; Xwhile (myfgets (buf, 256, fi) && !dobreak()) { X int len = strlen(buf); X buf[len-1] = '\0'; X Src_pos[Src_stack - 1] += len; X if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf); X exec_command (buf); X } X--H_stack; X--Src_stack; Xif (forward_goto) ierror(NULL,501); Xforward_goto = 0; Xunset_level(LEVEL_LABEL + Src_stack); Xunset_var(LEVEL_SET, v_gotofwd); Xunset_var(LEVEL_SET, v_passed); Xfclose (fi); Xreturn 0; X} X X/* X * return ptr to string that contains full cwd spec. X */ Xchar *get_pwd(flock) XBPTR flock; X{ Xstatic char pwdstr[130]; XPathName(flock, pwdstr, 128L); Xreturn pwdstr; X} X X/* X * set process cwd name and $_cwd, if str != NULL also print it. X */ Xdo_pwd(str) Xchar *str; X{ Xif (Myprocess->pr_CurrentDir == 0) X attempt_cd(":"); /* if we just booted 0 = root lock */ Xstrcpy(cwd,get_pwd(Myprocess->pr_CurrentDir,1)); Xif (str) puts(cwd); Xset_var(LEVEL_SET, v_cwd, cwd); X/* put the current dir name in our CLI task structure */ XCtoBStr(cwd, Mycli->cli_SetName, 128L); X} X X/* X * CD X * X * CD(str, 0) -do CD operation. X * X * standard operation: breakup path by '/'s and process independantly X * x: -reset cwd base X * .. -remove last cwd element X * N -add N or /N to cwd X */ X Xdo_cd(str) Xchar *str; X{ X char sc, *ptr; X int err=0; X X str = next_word(str); X if (*str == '\0') { X puts(cwd); X return(0); X } X str[strlen(str)+1] = '\0'; /* add second \0 on end */ X while (*str) { X for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr); X switch (*ptr) { X case ':': X sc = ptr[1]; X ptr[1] = '\0'; X err = attempt_cd(str); X ptr[1] = sc; X break; X case '\0': X case '/': X *ptr = '\0'; X if (strcmp(str, "..") == 0 || str == ptr) X str = "/"; X if (*str) err = attempt_cd(str); X break; X } X if (err) break; X str = ptr + 1; X } X do_pwd(NULL); /* set $_cwd */ X return err; X} X Xattempt_cd(str) Xchar *str; X{ XBPTR oldlock, filelock; X Xif (filelock=Lock(str, ACCESS_READ)) { X if (isdir(str)) { X if (oldlock=CurrentDir(filelock)) UnLock(oldlock); X return (0); X } X UnLock(filelock); X ierror(str, 212); X } Xelse ierror(str, 205); Xreturn -1; X} X Xdo_mkdir() X{ Xregister unsigned int i; XBPTR lock; X Xfor (i=1; i<ac; ++i) { X if (exists(av[i])) ierror(av[i],203); X else if (lock=CreateDir(av[i])) UnLock (lock); X else pError(av[i]); X } Xreturn 0; X} X Xdo_mv() X{ Xchar *dest, buf[256]; Xint dirflag; Xregister unsigned int i; X Xdirflag=isdir(dest=av[--ac]); Xif (ac>3 && !dirflag) { ierror(dest, 507); return (-1); } Xfor (i=1; i<ac; ++i) { X strcpy(buf, dest); X if (dirflag) TackOn(buf, BaseName(av[i])); X if (Rename(av[i], buf)==0) X { pError(av[i]); return -1; } X } Xreturn 0; X} X Xint dirstoo; X Xall_args(args, action, dirsflag) Xchar *args; Xint (*action)(); X{ Xunsigned int i; X Xget_opt(args, &i); Xdirstoo=dirsflag; Xfor (; i<ac && !dobreak(); ++i) X if (isdir(av[i])) { X if (options & 1) recurse(av[i], action); X else if (dirstoo) (*action)(av[i]); X } X else (*action)(av[i]); Xreturn 0; X} X Xchar *searchstring; X Xsearch_file(s) Xchar *s; X{ XFILE *fopen(), *fi; Xunsigned int lctr, len=strlen(searchstring); Xint yesno; Xchar buf[256], lowbuf[256], first; Xregister char *p, *l, *t; X Xif (!(options & 2)) for (t=searchstring; *t=Toupper(*t); t++); Xfirst=*searchstring; Xif ((fi=fopen(s, "r"))==NULL) { pError(s); return; } Xlctr=0; Xif (!(options & 32)) printf("Examining %s...\n",s); Xwhile (fgets(buf,256,fi) && !dobreak()) { X lctr++; X if (options & 4) yesno=compare_ok(searchstring,buf); X else { X yesno=0; X p=buf; X if (!(options & 2)) { X l=lowbuf; /* p is already =buf */ X while (*l++=Toupper(*p++)); /* lowbuf=upper(buf) */ X p=lowbuf; X } X while (p=index(p,first)) X if (!strncmp(p++,searchstring,len)) { yesno=1; break; } X } X if (yesno ^ ((options & 16)!=0) ) { X /* default: print line numbers */ X if (!(options & 8)) printf("%4d ",lctr); X printf("%s",buf); X } X } Xfclose (fi); X} X Xdo_search() X{ Xsearchstring=av[--ac]; Xall_args("rcwneq", search_file, 0); Xreturn 0; X} X Xrm_file(file) Xchar *file; X{ Xif (has_wild) printf(" %s...",file); Xif (options & 2) SetProtection(file,0L); Xif (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n"); X} X Xdo_rm() X{ Xall_args("rp", rm_file, 1); Xreturn 0; X} X Xrecurse(name, action) Xchar *name; Xint (*action)(); X{ Xregister BPTR lock, cwd; Xregister FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC); Xchar *namecopy=malloc(256); X Xif (name[0] =='\0') return; Xnamecopy[0]=0; Xif (lock=Lock(name,ACCESS_READ)) { X cwd =CurrentDir(lock); X if (Examine(lock, fib)) X while (ExNext(lock, fib) && !CHECKBREAK()) { X if (*namecopy) { (*action)(namecopy); namecopy[0]=0; } X if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action); X else strcpy(namecopy,fib->fib_FileName); X } X if (*namecopy) (*action)(namecopy); X UnLock(CurrentDir(cwd)); X if (dirstoo) (*action)(name); X } Xelse pError(name); Xfree(namecopy); XFreeMem(fib, (long)sizeof(FIB)); X} X Xdo_history() X{ Xregister struct HIST *hist; Xint i = H_tail_base; Xint len = (av[1]) ? strlen(av[1]) : 0; X Xfor (hist = H_tail; hist && !dobreak(); hist = hist->prev) X if (len == 0 || !strncmp(av[1], hist->line, len)) X printf("%3d %s\n", i++, hist->line); Xreturn 0; X} X Xdo_mem() X{ Xlong cfree, ffree; Xextern long AvailMem(); X XForbid(); Xcfree = AvailMem (MEMF_CHIP); Xffree = AvailMem (MEMF_FAST); XPermit(); Xif (ffree) printf ("FAST memory: %ld\nCHIP memory: %ld\n", ffree, cfree); Xprintf("Total Free: %ld\n", cfree+ffree); Xreturn 0; X} X X/* forline i RAM:temp echo line $_linenum: $i */ X Xdo_forline() X{ Xchar vname[33], buf[256]; Xregister unsigned short lctr; XFILE *f; Xchar *cstr; Xstatic char *linenumname="_linenum"; X Xstrcpy(vname,av[1]); Xf=fopen(av[2],"r"); Xif (f==NULL) pError(av[2]); Xlctr=0; X++H_stack; Xcstr = compile_av (av, 3, ac, ' '); Xwhile (fgets(buf,256,f) && !dobreak()) { X buf[strlen(buf)-1]='\0'; /* remove CR */ X lctr++; X set_var(LEVEL_SET, vname, buf); X sprintf(buf,"%d",lctr); X set_var(LEVEL_SET, linenumname, buf); X exec_command(cstr); X } Xfclose(f); X--H_stack; Xfree (cstr); Xunset_var (LEVEL_SET, vname); Xunset_var (LEVEL_SET, linenumname); Xreturn 0; X} X X/* fornum i 1 10 echo $i */ X Xdo_fornum() X{ Xchar vname[33], buf[16]; Xint n1, n2; Xchar *cstr; Xregister int i; X Xstrcpy(vname,av[1]); Xn1=myatoi(av[2],0 ,32767); if (Errno) return 20; Xn2=myatoi(av[3],n1, 32767); if (Errno) return 20; X++H_stack; Xcstr = compile_av (av, 4, ac, ' '); Xfor (i=n1; i<=n2 && !CHECKBREAK(); i++) { X sprintf(buf,"%d",i); X set_var (LEVEL_SET, vname, buf); X exec_command(cstr); X } X--H_stack; Xfree (cstr); Xunset_var (LEVEL_SET, vname); Xreturn 0; X} X X/* X * foreach var_name ( str str str str... str ) commands X * spacing is important (unfortunately) X * X * ac=0 1 2 3 4 5 6 7 X * foreach i ( a b c ) echo $i X * foreach i ( *.c ) "echo -n "file ->";echo $i" X */ X Xdo_foreach() X{ Xregister int cstart, cend; Xregister char *cstr; Xchar **fav; Xchar vname[33]; Xint i; X Xget_opt("v",&i); Xstrcpy(vname, av[i++]); Xif (*av[i] == '(') i++; Xcstart = i; Xwhile (i<ac && *av[i] != ')') i++; Xif (i > ac) { fprintf(stderr,"')' expected\n"); return 20; } X++H_stack; Xcend = i; X Xfav = (char **)malloc(sizeof(char *) * (ac)); Xcstr = compile_av (av, cend + 1, ac, ' '); X Xfor (i = cstart; i < cend; ++i) fav[i] = av[i]; X Xfor (i = cstart; i<cend && !CHECKBREAK(); ++i) { X set_var (LEVEL_SET, vname, fav[i]); X if (options & 1) printf("foreach: %s\n", fav[i]); X exec_command(cstr); X } X--H_stack; Xfree (fav); Xfree (cstr); Xunset_var (LEVEL_SET, vname); Xreturn 0; X} X Xdo_forever(str) Xchar *str; X{ Xint rcode = 0; Xchar *ptr = next_word(str); X X++H_stack; Xfor (;;) { X if (CHECKBREAK()) { rcode = 20; break; } X if (exec_command (ptr) < 0) { X str = get_var(LEVEL_SET, v_lasterr); X rcode = (str) ? atoi(str) : 20; X break; X } X } X--H_stack; Xreturn rcode; X} X Xdo_exec(str) Xchar *str; X{ Xreturn exec_command(next_word(str)); X} X Xextern struct Window *w; Xextern struct IntuitionBase *IntuitionBase; X Xdo_window() X{ Xlong x, y, maxwidth, maxheight, arg[5]; Xunsigned int i; Xstruct Screen *screen; Xstruct Window *window; X Xget_opt("slfbaq", &i); Xif (options & 1) X SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height)); Xif (options & 2) { X x=-w->LeftEdge; X y=-w->TopEdge; X MoveWindow(w,x,y); X x=IntuitionBase->ActiveScreen->Width -w->Width; X y=IntuitionBase->ActiveScreen->Height-w->Height; X SizeWindow(w,x,y); X } Xif (options & 4) WindowToFront(w); Xif (options & 8) WindowToBack(w); Xif (options & 16) ActivateWindow(w); Xif(ac >= 5) { X for(i=1; i<5; i++) { X arg[i] = myatoi(av[i],0,1023); X if (Errno) return 20; X } X maxwidth = w->WScreen->Width; X maxheight= w->WScreen->Height; X if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) { X ierror(NULL, 500); X return 20; X } X x = -w->LeftEdge; X y = -w->TopEdge; X MoveWindow(w, x, y); X x = arg[3] - w->Width; X y = arg[4] - w->Height; X SizeWindow(w, x, y); X x = arg[1]; X y = arg[2]; X MoveWindow(w, x, y); X } Xif(options & 32) { X for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) { X printf("\nScreen \"%s\" (%d,%d,%dx%d):\n", X screen->Title, X screen->LeftEdge, X screen->TopEdge, X screen->Width, X screen->Height X ); X for (window=screen->FirstWindow; window; window=window->NextWindow) { X printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n", X window->Title, X window->LeftEdge, X window->TopEdge, X window->Width, X window->Height X ); X } X } X return 0; X } XDelay(25L); /* pause 1/2 sec. before trying to print */ Xprintf("\014"); Xreturn 0; X} X Xsetsystemtime(ds) Xstruct DateStamp *ds; X{ Xstruct timerequest tr; Xlong secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND; X Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) { X fprintf(stderr,"Clock error: can't open timer device\n"); X return; X } Xtr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE; Xtr.tr_node.io_Message.mn_Node.ln_Pri = 0L; Xtr.tr_node.io_Message.mn_Node.ln_Name = NULL; Xtr.tr_node.io_Message.mn_ReplyPort = NULL; Xtr.tr_node.io_Command = TR_SETSYSTIME; Xtr.tr_time.tv_secs = secs; Xtr.tr_time.tv_micro = 0L; Xif (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n"); XCloseDevice (&tr); X} X Xchar tday[10]; X Xchar *dates(dss) Xstruct DateStamp *dss; X{ Xstatic char timestr[40]; Xchar tdate[10], ttime[10]; Xstruct DateTime dt; Xstruct DateStamp *myds=&(dt.dat_Stamp); X Xdt.dat_Format=FORMAT_DOS; Xdt.dat_StrDay=tday; Xdt.dat_StrDate=tdate; Xdt.dat_StrTime=ttime; Xdt.dat_Flags=NULL; Xmyds->ds_Days=dss->ds_Days; Xmyds->ds_Minute=dss->ds_Minute; Xmyds->ds_Tick=dss->ds_Tick; XStamptoStr(&dt); Xsprintf(timestr,"%s %s\n",tdate,ttime); Xtimestr[18]='\n'; Xtimestr[19]='\0'; /* protection against bad timestamped files */ Xreturn timestr; X} X Xdate() X{ Xstruct DateStamp dss; Xregister unsigned short i; Xstruct DateTime dt; X Xdt.dat_Format=FORMAT_DOS; Xif (ac==1) { X DateStamp(&dss); X printf("%s %s",tday,dates(&dss)); X } Xelse { X DateStamp(& (dt.dat_Stamp)); X for (i=1; i<ac; i++) { X dt.dat_StrDate=NULL; X dt.dat_StrTime=NULL; X dt.dat_Flags=DTF_FUTURE; X if (index(av[i],':')) dt.dat_StrTime=av[i]; X else dt.dat_StrDate=av[i]; X if (StrtoStamp(&dt)) ierror(av[i],500); X } X setsystemtime( & (dt.dat_Stamp) ); X } Xreturn 0; X} SHAR_EOF echo "extracting comm2.c" sed 's/^X//' << \SHAR_EOF > comm2.c X/* X * COMM2.C X * X * (c)1986 Matthew Dillon 9 October 1986 X * X * Version 2.07M by Steve Drew 10-Sep-87 X * X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89 X * X */ X Xextern char *v_gotofwd; X X/* Casting conveniences */ X#define BPTR_TO_C(strtag, var) ((struct strtag *)(BADDR( (ULONG) var))) X#define PROC(task) ((struct Process *)task) X#define CLI(proc) (BPTR_TO_C(CommandLineInterface, proc->pr_CLI)) X X/* Externs */ Xextern int has_wild; /* flag set if any arg has a ? or * */ X X/* globals */ Xint cp_update; Xint cp_date; X Xdo_abortline() X{ XExec_abortline = 1; Xreturn 0; X} X Xdo_return() X{ Xregister int retcode=(ac<2 ? 0 : atoi(av[1])); X Exec_abortline = 1; X if (Src_stack) { X FILE *ptr = (FILE *)Src_base[Src_stack - 1]; X ptr->_bp = ptr->_bend; X ptr->_flags |= _EOF; X/* fseek (Src_base[Src_stack - 1], 0L, 2); */ X return retcode; X } else main_exit(retcode); X} X X/* X * STRHEAD X * X * place a string into a variable removing everything after and including X * the 'break' character X * X * strhead varname breakchar string X * X */ X Xdo_strhead() X{ Xchar *s; Xif (s=index(av[3],*av[2])) *s='\0'; Xset_var (LEVEL_SET, av[1], av[3]); Xreturn 0; X} X Xdo_strtail() X{ Xchar *s; Xif (s=index(av[3],*av[2])) s++; else s=av[3]; Xset_var (LEVEL_SET, av[1], s); Xreturn 0; X} X Xlong dptrtosecs(d) Xstruct DPTR *d; X{ Xregister struct DateStamp *ds=(&d->fib->fib_Date); Xreturn ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND; X} X Xlong timeof(s) Xchar *s; X{ Xstruct DPTR *d; Xint dummy; Xlong n; X Xif ( (d=dopen(s,&dummy))==NULL ) return 0L; Xn=dptrtosecs(d); Xdclose(d); Xreturn n; X} X X/* X * if -f file (exists) or: X * X * if A < B <, >, =, <=, >=, <>, where A and B are either: X * nothing X * a string X * a value (begins w/ number) X */ X Xdo_if(garbage, com) Xchar *garbage; X{ Xint result; Xint i; X Xswitch (com) { X case 0: X if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1; X else { X get_opt("rftmdn",&i); X result=evalif(i); X If_base[If_stack++]=(options & 32 ? result : !result); X } X break; X case 1: X if (If_stack > 1 && If_base[If_stack - 2]) break; X if (If_stack) If_base[If_stack - 1] ^= 1; X break; X case 2: X if (If_stack) --If_stack; X break; X } Xdisable = (If_stack) ? If_base[If_stack - 1] : 0; Xif (If_stack >= MAXIF) { X fprintf(stderr,"If's too deep\n"); X disable = If_stack = 0; X return -1; X } Xif (forward_goto) disable = If_base[If_stack - 1] = 0; Xreturn 0; X} X Xevalif(i) Xregister unsigned int i; X{ Xchar c; Xlong num, t0; Xlong AvailMem(); X Xswitch(options & ~32) { X case 0: X if (ac-i != 3) return (ac>i && *av[i]); X Errno=0; X num=Atol(av[i])-Atol(av[i+2]); X if (Errno) num=strcmp(av[i],av[i+2]); X if (num < 0) c='<'; X else if (num > 0) c='>'; X else if (num == 0) c='='; X return index(av[i+1], c) != NULL; X case 1: X return do_rpn(NULL,i); X case 2: X return exists(av[i]); X case 4: X t0=timeof(av[i++]); X for ( ; i<ac ; i++) X if (t0<=timeof(av[i])) return 1; X return 0; X case 8: X return (AvailMem( (long)MEMF_FAST )!=0); X case 16: X return (isdir(av[i])!=0); X default: X ierror(NULL,500); X return 0; X } X} X Xdo_label() X{ X char aseek[32]; X X if (Src_stack == 0) { X ierror (NULL, 502); X return (-1); X } X X sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack); X set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek); X if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd))) X forward_goto = 0; X return 0; X} X Xdo_goto() X{ X int new; X long pos; X char *lab; X X if (Src_stack == 0) { X ierror (NULL, 502); X } else { X lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]); X if (lab == NULL) { X forward_goto = 1; X set_var (LEVEL_SET, v_gotofwd, av[1]); X return(0); X } else { X pos = atoi(lab); X fseek (Src_base[Src_stack - 1], pos, 0); X Src_pos[Src_stack - 1] = pos; X new = atoi(next_word(lab)); X for (; If_stack < new; ++If_stack) X If_base[If_stack] = 0; X If_stack = new; X } X } X Exec_abortline = 1; X return (0); /* Don't execute rest of this line */ X} X X Xdo_inc(garbage, com) Xchar *garbage; X{ Xchar *var, num[32]; X Xif (ac>2) com *= atoi(av[2]); Xif (var = get_var (LEVEL_SET, av[1])) { X sprintf (num, "%d", atoi(var)+com); X set_var (LEVEL_SET, av[1], num); X } Xreturn 0; X} X Xdo_input() X{ Xchar in[256], *p,*s; Xunsigned int i; X Xfor (i=1; i < ac; ++i) X if (gets(in)) { X for(p = in; *p; p = s) { X s = next_word(p); X if (*s) *(s-1) = 0xA0; X } X set_var (LEVEL_SET, av[i], in); X } Xreturn 0; X} X Xdo_ver() X{ Xputs("Shell V3.03A\n\ X)1986 Matthew Dillon\n\ XManx (M) versions by Steve Drew\n\ XARP (A) versions by Carlo Borreo & Cesare Dieni\n"); Xreturn 0; X} X Xdo_ps() X{ X/* this code fragment based on ps.c command by Dewi Williams */ X Xregister int count; /* loop variable */ Xstruct Task *task; /* EXEC descriptor */ Xchar strbuf[64+1]; /* scratch for btocstr() */ Xchar cmd[40+1]; /* holds cmd name */ Xlong ncli; X Xprintf("Proc Command Name CLI Type Pri. Address Directory\n"); XForbid(); X Xncli=(long)FindCLI(0L); Xfor (count = 1; count <= ncli ; count++) X /* or just assume 20?*/ X if (task = (struct Task *)FindCLI((long)count)) { X if (task==NULL) continue; X /* Sanity check just in case */ X if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue; X /* or complain? */ X BtoCStr(cmd, CLI(PROC(task))->cli_CommandName, 40L); X BtoCStr(strbuf,CLI(PROC(task))->cli_SetName , 64L); X printf("%2d %-20.20s %-11.11s %3d %8lx %s\n", X count, X cmd, X task->tc_Node.ln_Name, X task->tc_Node.ln_Pri, X task, X strbuf); X } XPermit(); Xreturn 0; X} X X/* X * CP [-d] [-u] file file X * CP [-d] [-u] file file file... destdir X * CP [-r][-u][-d] dir dir dir... destdir X */ X Xchar *errstr; /* let's be alittle more informative */ X Xdo_copy() X{ Xregister int recur, ierr; Xregister char *destname; Xregister char destisdir; Xregister FIB *fib; Xint i; X Xerrstr = ""; Xierr = 0; X Xfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); X Xget_opt("rud",&i); Xrecur = (options & 0x01); Xcp_update = (options & 0x02); Xcp_date = (!(options & 0x04)); /* the default is keep orignal file date */ X Xdestname = av[ac - 1]; X Xif (ac < i + 2) { X ierr = 500; X goto done; X } Xdestisdir = isdir(destname); Xif (ac > i + 2 && !destisdir) { X ierr = 507; X goto done; X } X X/* X * copy set: reduce to: X * file to file file to file X * dir to file (NOT ALLOWED) X * file to dir dir to dir X * dir to dir dir to dir X * X */ X Xfor (; i<ac-1 && !dobreak(); ++i) { X short srcisdir = isdir(av[i]); X if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */ X continue; /* getting copied if specified */ X /* from wild expansion */ X if (srcisdir) { X BPTR srcdir, destdir; X if (!destisdir) { X if (exists(destname)) { X ierr = 507; /* disallow dir to file */ X goto done; X } X if (destdir = CreateDir(destname)) UnLock(destdir); X destisdir = 1; X } X if (!(destdir = Lock(destname, ACCESS_READ))) { X ierr = 205; X errstr = destname; X goto done; X } X if (!(srcdir = Lock(av[i], ACCESS_READ))) { X ierr = 205; X errstr = av[i]; X UnLock(destdir); X goto done; X } X ierr = copydir(srcdir, destdir, recur); X UnLock(srcdir); X UnLock(destdir); X if (ierr) break; X } X else { /* FILE to DIR, FILE to FILE */ X BPTR destdir, srcdir, tmp; X char *destfilename; X X srcdir = (BPTR)(Myprocess->pr_CurrentDir); X X if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) { X if (tmp) UnLock(tmp); X ierr = 205; X errstr = av[i]; X goto done; X } X UnLock(tmp); X if (destisdir) { X destdir = Lock(destname, ACCESS_READ); X destfilename = fib->fib_FileName; X } X else { X destdir = srcdir; X destfilename = destname; X } X printf(" %s..",av[i]); X fflush(stdout); X ierr = copyfile(av[i], srcdir, destfilename, destdir); X if (destisdir) UnLock(destdir); X if (ierr) break; X } X } X Xdone: X XFreeMem(fib, (long)sizeof(FIB)); Xif (ierr) { X ierror(errstr, ierr); X return(20); X } Xreturn 0; X} X X Xcopydir(srcdir, destdir, recur) Xregister BPTR srcdir, destdir; X{ X BPTR cwd; X register FIB *srcfib; X register BPTR destlock, srclock; X int ierr; X static int level; X X level++; X ierr = 0; X srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); X if (Examine(srcdir, srcfib)) { X while (ExNext(srcdir, srcfib)) { X if (CHECKBREAK()) X break; X if (srcfib->fib_DirEntryType < 0) { X printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName); X fflush(stdout); X ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir); X if (ierr) X break; X } else { X if (recur) { X cwd = CurrentDir(srcdir); X if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) { X CurrentDir(destdir); X if (!(destlock = Lock(srcfib->fib_FileName))) { X destlock = CreateDir(srcfib->fib_FileName); X printf("%*s%s (Dir)....[Created]\n",(level-1) * 6, X " ",srcfib->fib_FileName); X X /* UnLock and re Lock if newly created X for file_date() to work properly X */ X if (destlock) UnLock(destlock); X destlock = Lock(srcfib->fib_FileName); X } X else X printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName); X if (destlock) { X ierr = copydir(srclock, destlock, recur); X UnLock(destlock); X } else { X ierr = (int)((long)IoErr()); X } X UnLock(srclock); X } else { X ierr = (int)((long)IoErr()); X } X CurrentDir(cwd); X if (ierr) X break; X } X } X } X } else { X ierr = (int)((long)IoErr()); X } X --level; X FreeMem(srcfib, (long)sizeof(FIB)); X return(ierr); X} X X Xcopyfile(srcname, srcdir, destname, destdir) Xchar *srcname, *destname; XBPTR srcdir, destdir; X{ XBPTR cwd; XBPTR f1, f2; Xlong i; Xint stat,ierr; Xchar *buf; Xstruct DPTR *dp, *dps = NULL; X Xif ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL) X { ierr = 103; goto fail; } Xierr = 0; Xcwd = CurrentDir(srcdir); Xif ((f1=Open(srcname, MODE_OLDFILE))==NULL) X { errstr = srcname; ierr = 205; goto fail; } Xdps = dopen(srcname,&stat); XCurrentDir(destdir); Xif (cp_update) X { X dp=dopen(destname, &stat); X if ( dptrtosecs(dp) >= dptrtosecs(dps) && X !strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName)) X { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; } X dclose(dp); X } Xif ((f2=Open(destname, MODE_NEWFILE))==NULL) X { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail; } Xwhile (i = Read(f1, buf, 8192L)) X if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; } XClose(f2); XClose(f1); Xif (!ierr) X { X if (cp_date) file_date(&dps->fib->fib_Date, destname); X printf("..copied\n"); X } Xelse DeleteFile(destname); Xfail: X dclose(dps); X if (buf) FreeMem(buf, 8192L); X CurrentDir(cwd); X return(ierr); X} X Xdo_touch() X{ Xstruct DateStamp ds; Xregister unsigned int i; XDateStamp(&ds); Xfor (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500); Xreturn 0; X} X Xfile_date(date,name) Xstruct DateStamp *date; Xchar *name; X{ Xlong packargs[7]; XUBYTE *ptr; Xstruct MsgPort *task; XBPTR dirlock; Xstruct DPTR *tmp; Xint stat; X Xif (!(task = (struct MsgPort *)DeviceProc(name))) return(1); Xif (tmp = dopen(name, &stat)) { X dirlock = ParentDir(tmp->lock); X ptr=AllocMem(65L,MEMF_PUBLIC); X CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L); X dclose(tmp); X packargs[1]=dirlock; X packargs[2]=(ULONG)ptr >> 2L; X packargs[3]=(long)date; X SendPacket(ACTION_SET_DATE,packargs,task); X UnLock(dirlock); X FreeMem(ptr,65L); X } Xreturn 0; X} X Xdo_addbuffers() X{ Xlong packargs[7]; Xlong n; Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]); X Xif (!task) { ierror(av[1],510); return 20; } Xn=myatoi(av[2],1,32767); if (Errno) return 20; Xpackargs[0]=n; XSendPacket(ACTION_MORE_CACHE,packargs,task); Xreturn 0; X} X Xdo_relabel() X{ Xlong packargs[7]; XUBYTE *ptr; Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]); X Xif (!task) { ierror(av[1],510); return 20; } Xptr=AllocMem(65L,MEMF_PUBLIC); XCtoBStr(av[2],(ULONG)ptr >> 2L,64L); Xpackargs[0]=(ULONG)ptr >> 2L; XSendPacket(ACTION_RENAME_DISK,packargs,task); XFreeMem(ptr,65L); Xchangedisk(task); Xreturn 0; X} X Xdo_diskchange() X{ Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]); X Xif (!task) { ierror(av[1],510); return 20; } Xchangedisk(task); Xreturn 0; X} X Xchangedisk(task) Xstruct MsgPort *task; X{ Xlong packargs[7]; X Xpackargs[0]=1L; XSendPacket(ACTION_INHIBIT,packargs,task); Xpackargs[0]=0L; XSendPacket(ACTION_INHIBIT,packargs,task); X} SHAR_EOF echo "extracting comm3.c" sed 's/^X//' << \SHAR_EOF > comm3.c X/* X * COMM3.C X * X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89 X * X */ X Xdo_assign() { Xswitch(ac) { X case 1: assignlist(); X break; X case 2: doassign(av[1], NULL); X break; X case 3: doassign(av[1], av[2]); X break; X default: ierror(NULL, 500); X break; X } Xreturn 0; X} X Xchar *assign_errors[4]={ X "", X "Name %s is not valid\n", X "Weird error\n", X "Can't cancel %s\n" X }; X Xdoassign(log, phy) Xchar *log, *phy; X{ Xint last=strlen(log) - 1; X Xif (log[last] != ':') fprintf(stderr, "Bad name %s\n", log); Xelse { X log[last] = 0; X fprintf(stderr,assign_errors[Assign(log, phy)],log); X } X} X Xassignlist() X{ Xstruct DirectoryEntry *de_head=NULL, *de; Xchar buf[256]; XBPTR lock; Xint ctr=0; X XAddDADevs(&de_head, DLF_DEVICES | DLF_VOLUMES | DLF_DIRS); Xprintf("Devices:\n"); Xfor (de=de_head; de && de->de_Type==DLX_DEVICE; de=de->de_Next) { X printf("%-8s",de->de_Name); X if (ctr++ == 5) { ctr=0; printf("\n"); } X } Xprintf("\n\nVolumes:\n"); Xfor ( ; X de && (de->de_Type==DLX_VOLUME || de->de_Type==DLX_UNMOUNTED); X de=de->de_Next X ) X printf( "%-16s %s\n", X de->de_Name, X de->de_Type == DLX_VOLUME ? "[Mounted]" : "" X ); Xprintf("\nDirectories:\n"); Xfor (; de && de->de_Type==DLX_ASSIGN; de=de->de_Next) { X if (lock=Lock(de->de_Name, ACCESS_READ)) { X PathName(lock, buf, 256L); X UnLock(lock); X } X else X strcpy(buf,"Unexisting lock"); X printf("%-20s%s\n",de->de_Name,buf); X } XFreeDAList(&de_head); X} X Xdo_join() X{ XBPTR sou, dest; Xchar *buffer; Xunsigned int i; Xlong n; Xchar *namedest=av[--ac]; X Xget_opt("r", &i); Xif (options==0 && exists(namedest)) { ierror(namedest,203); return 20; } Xif ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; } Xif ( (dest=Open(namedest, MODE_NEWFILE)) == NULL ) X { pError(namedest); goto fail1; } Xfor (i=1; i<ac; i++) { X if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]); X else X while( (n=Read(sou, buffer, 8192L)) > 0 ) X if (Write(dest, buffer, n) != n) X { pError(namedest); Close(sou); goto fail2; } X Close(sou); X } Xfail2: X Close(dest); Xfail1: X free(buffer); X return 0; X} X X#define BUFDIM 512L X#define MAXSTR 256 X Xint minstr; X Xstrings_in_file(s) Xchar *s; X{ Xchar c; Xchar readbuf[BUFDIM+1], strbuf[MAXSTR+1]; Xregister unsigned int i, strctr=0; XBPTR fh; Xint out, n; X Xif ( fh=Open(s, MODE_OLDFILE) ) { X fprintf(stderr, "Strings in %s (len>=%d):\n",s,minstr); X while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() ) X for (i=0; i<n; i++) { X c=readbuf[i]; X if (c<0x20 || c>0x7f) { X out=(strctr>=minstr); X if (!out) strctr=0; X } X else { X strbuf[strctr++]=c; X out=(strctr>=BUFDIM); X } X if (out) { X strbuf[strctr]='\0'; X puts(strbuf); X strctr=0; X } X } X Close(fh); X } Xelse pError(s); X} X Xdo_strings() X{ Xminstr=myatoi(av[--ac],1,255); Xall_args("r", strings_in_file, 0); Xreturn 0; X} X XBPTR myfile[MAXMYFILES]; X Xdo_open() X{ Xlong mode; Xunsigned int n; X Xswitch (av[2][0]) { X case 'r': mode=MODE_OLDFILE; break; X case 'w': mode=MODE_NEWFILE; break; X default : ierror(NULL,500); return; X } XErrno=0; Xn=(unsigned int)myatoi(av[3],0,MAXMYFILES); if (Errno) return 20; Xmyfile[n]=Open(av[1],mode); Xreturn (myfile[n]==NULL); X} X Xdo_close() X{ Xregister unsigned int i; Xint n; X Xfor (i=1; i<ac; i++) { X Errno=0; X n=myatoi(av[i],0,MAXMYFILES); if (Errno) return 20; X myclose(n); X } Xreturn 0; X} X Xmyclose(n) X{ Xif (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; } X} X Xdo_fileslist() X{ Xregister unsigned short i; Xint flag=0; X Xprintf("Open files:"); Xfor (i=0; i<MAXMYFILES; i++) X if (myfile[i]) { printf(" %d",i); flag=1; } Xif (!flag) printf(" None!"); Xprintf("\n"); Xreturn 0; X} X XBPTR extOpen(name,mode) Xchar *name; Xlong mode; X{ Xif (name[0]=='.') return myfile[atoi(name+1)]; Xreturn Open(name,mode); X} X XextClose(fh) XBPTR fh; X{ Xregister unsigned short i; X Xfor (i=0; i<MAXMYFILES; i++) X if (myfile[i]==fh) return; XClose(fh); X} X Xdo_resident(avline) Xchar *avline; X{ Xunsigned int i; XBPTR seg; Xstruct ResidentPrgNode *p; X Xget_opt("ar", &i); Xswitch (options) { X case 0: X ObtainSemaphore (& (ArpBase->ResPrgProtection) ); X if (p=ArpBase->ResidentPrgList) { X printf("Name Users\n"); X for (; p; p=p->rpn_Next) X printf("%-16s %-3ld\n",p->rpn_Name,p->rpn_Usage); X } X else printf("No resident program(s)\n"); X ReleaseSemaphore(& (ArpBase->ResPrgProtection) ); X break; X case 1: X for (; i<ac; i++) X if ( (seg=(BPTR)LoadPrg(av[i])) && AddResidentPrg(seg,av[i]) ) X printf("OK! %s is now resident\n", BaseName(av[i])); X else pError(av[i]); X break; X case 2: X for (; i<ac; i++) X if (RemResidentPrg(av[i])) ierror(av[i],202); X else printf("Removed %s\n",av[i]); X break; X default: X ierror(NULL,500); X break; X } Xreturn 0; X} X Xstruct ProcessControlBlock pcb={ X 4000, /* pcb_StackSize */ X 0, /* pcb_Pri */ X }; X/* remaining field are NULL */ X Xdo_truerun(avline, backflag) Xchar *avline; X{ Xchar name[200]; Xchar *FindIt(); X Xif (backflag) { X pcb.pcb_Control=NULL; X pcb.pcb_Input=pcb.p_Output=Open("NIL:",MODE_OLDFILE); X } Xelse { X pcb.pcb_Control=NULL; X pcb.pcb_Input=pcb.p_Output =NULL; X } Xif (FindIt(av[1], "", name)) X ASyncRun(name,next_word(next_word(avline)),&pcb); Xelse X ierror(av[1],205); Xreturn 0; X} X Xint exists(name) Xchar *name; X{ XBPTR lock; X Xif (lock=Lock(name,ACCESS_READ)) { X UnLock(lock); X return 1; X } Xreturn 0; X} X Xdo_aset() X{ XSetenv(av[1],av[2]); Xreturn 0; X} X X#define HTYPELINE 16L X Xhtype_a_file(s) Xchar *s; X{ XBPTR fh; Xlong n, filesize=0; Xchar buf[HTYPELINE+1]; Xregister unsigned int i; X Xif ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; } Xwhile ( (n=Read(fh,buf,HTYPELINE))>0 && !dobreak()) { X printf("%06lx: ",filesize); X filesize+=n; X for (i=0; i<n; i++) { X printf( (i&3) ? "%02x" : " %02x",(int)(unsigned char)buf[i]); X if (buf[i]<=0x20) buf[i]='.'; X } X for ( ; i<HTYPELINE; i++) { X printf( (i&3) ? " " : " "); X buf[i]=' '; X } X buf[i]=0; X printf(" %s\n",buf); X } XClose(fh); Xreturn 0; X} X Xdo_htype() X{ Xall_args("", htype_a_file, 0); Xreturn 0; X} X Xdo_stack() X{ Xlong n; X Xif (ac>1) { X Errno=0; X n=Atol(av[1]); X if (!Errno) Mycli->cli_DefaultStack=(long)(n >> 2L); X } Xelse printf("current stack size is %ld bytes\n", X (long)Mycli->cli_DefaultStack << 2L); Xreturn 0; X} X Xdo_fault() X{ Xstruct PERROR *p; Xregister unsigned int i; Xint n; X Xfor (i=1; i<ac; i++) { X n=myatoi(av[i],0,32767); X if (!Errno) { X for (p=Perror; p->errnum && p->errnum!=n; p++); X if (p->errnum) X printf("Fault %d: %s\n",n,p->errstr); X else X printf("Fault %d not recognized\n",n); X } X } Xreturn 0; X} X Xstruct rpncommand { X char *str; X int parsin, parsout; X }; X Xstruct rpncommand rpn[]={ X "+", 2, 1, X "-", 2, 1, X "*", 2, 1, X "/", 2, 1, X "%", 2, 1, X "&", 2, 1, X "|", 2, 1, X "~", 1, 1, X ">", 2, 1, X "<", 2, 1, X "==", 2, 1, X "!", 1, 1, X "DUP", 1, 2, X "DROP", 1, 0, X "SWAP", 2, 2, X "HELP", 0, 0, X NULL, 0, 1, /* this looks for a number */ X}; X Xdo_rpn(garbage,ifflag) /* ifflag!=0 if called from if */ Xchar *garbage; X{ Xregister long n0, n1; Xlong t; Xunsigned int i, j; Xint sp=0; Xlong stack[100]; Xstruct rpncommand *temp; X Xi=1; Xif (ifflag) get_opt("rn",&i); Xfor (; i<ac; i++) { X for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ; X n0=stack[sp-1]; X n1=stack[sp-2]; X sp -= (rpn[j].parsin); X if (sp<0) { fprintf(stderr, "RPN: Empty stack\n"); return 1; } X switch (j) { X case 0: n0 += n1; break; X case 1: n0 = n1-n0; break; X case 2: n0 *= n1; break; X case 3: n0 = n1/n0; break; X case 4: n0 = n1%n0; break; X case 5: n0 &= n1; break; X case 6: n0 |= n1; break; X case 7: n0 = ~n0; break; X case 8: n0 = (n1 > n0); break; X case 9: n0 = (n1 < n0); break; X case 10: n0 = (n0 == n1); break; X case 11: n0 = !n0; break; X case 12: n1=n0; break; X case 13: t=n0; n0=n1; n1=t; break; X case 14: break; X case 15: printf("In Commands Out\n"); X for (temp=rpn; temp->str; temp++) X printf(" %d %-10s%d\n", X temp->parsin,temp->str,temp->parsout); X break; X default: Errno=0; X n0=Atol(av[i]); X if (Errno) { X fprintf(stderr, "Bad RPN cmd: %s\n",av[i]); X return 20; X } X break; X } X stack[sp]=n0; X stack[sp+1]=n1; X sp += rpn[j].parsout; X } Xif (ifflag) return (int)(stack[sp-1]); /* called from if: return top value */ Xfor (i=sp-1;(int)i>=0;i--) printf("%ld\n", stack[i]); /* else print stack */ Xreturn 0; X} X Xdo_path() X{ Xunion { long *lp; long ll; } l; Xchar buf[256]; X Xputs("Current dir"); Xl.lp = (long *) Mycli->cli_CommandDir; Xwhile (l.ll) { X l.ll <<= 2; X PathName(l.lp[1], buf, 256L); X puts(buf); X l.ll = *l.lp; X } Xputs("C:"); Xreturn 0; X} X Xdo_pri() X{ Xint t, pri; Xstruct Process *proc; X Xt=myatoi(av[1],0,20); if (Errno) return 20; Xpri=myatoi(av[2],-128,127); if (Errno) return 20; XForbid(); Xproc=(t==0 ? Myprocess : FindCLI((long)t)); Xif (proc==NULL) fprintf(stderr, "process not found\n"); X else SetTaskPri(proc, (long)pri); XPermit(); Xreturn 0; X} X Xdo_strleft() X{ Xchar buf[256]; Xint n; X Xstrcpy(buf,av[2]); Xn=myatoi(av[3],1,strlen(buf)); if (Errno) return 20; Xbuf[n]='\0'; Xset_var(LEVEL_SET, av[1], buf); Xreturn 0; X} X Xdo_strright() X{ Xchar buf[256]; Xint n; X Xstrcpy(buf, av[2]); Xn=myatoi(av[3],1,strlen(buf)); if (Errno) return 20; Xset_var(LEVEL_SET, av[1], buf+strlen(buf)-n); Xreturn 0; X} X Xdo_strmid() X{ Xchar buf[256]; Xint n1, n2; X Xstrcpy(buf, av[2]); Xn1=myatoi(av[3],1,strlen(buf))-1; if (Errno) return 20; Xif (ac>4) { X n2=myatoi(av[4],1,strlen(buf)-n1); X if (Errno) return 20; X buf[n1+n2]='\0'; X } Xset_var(LEVEL_SET, av[1], buf+n1); Xreturn 0; X} X Xdo_strlen() X{ Xchar buf[16]; X Xsprintf(buf,"%d",strlen(av[2])); Xset_var(LEVEL_SET, av[1], buf); Xreturn 0; X} X Xmyatoi(s,min,max) Xchar *s; X{ Xlong n; X XErrno=0; Xn=Atol(s); Xif (Errno==ERRBADINT) ierror(s,511); X else if (n<min || n>max) { X Errno=ERRBADINT; X printf("%s not in (%d,%d)\n",s,min,max); X } Xreturn (int)n; X} X Xdo_fltlower() X{ Xchar buf[256], *s; X Xwhile (!CHECKBREAK() && gets(buf)) { X for (s=buf; *s; s++) *s=tolower(*s); X puts(buf); X } Xreturn 0; X} X Xdo_fltupper() X{ Xchar buf[256], *s; X Xwhile (!CHECKBREAK() && gets(buf)) { X for (s=buf; *s; s++) *s=toupper(*s); X puts(buf); X } Xreturn 0; X} SHAR_EOF echo "extracting execom.c" sed 's/^X//' << \SHAR_EOF > execom.c X/* X * EXECOM.C X * X * Matthew Dillon, 10 August 1986 X * Finally re-written. X * X * Version 2.07M by Steve Drew 10-Sep-87 X * X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89 X * X */ X Xextern char *v_histnum, *v_except; X X#define F_EXACT 0 X#define F_ABBR 1 X X#define ST_COND 0x01 X#define ST_NORED 0x02 X#define ST_NOEXP 0x04 X#define ST_AV 0x08 /* delimit args within a variable */ X Xint has_wild = 0; /* set if any arg has wild card */ X Xstruct COMMAND { X int (*func)(); X short minargs; X short stat; X int val; X char *name; X}; X Xextern char *format_insert_string(); Xextern char *mpush(), *exarg(); X Xextern int do_fltupper(), do_fltlower(); Xextern int do_strleft(), do_strright(), do_strmid(), do_strlen(); Xextern int do_fornum(), do_forline(), do_exec(); Xextern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri(); Xextern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany(); Xextern int do_open(), do_close(), do_fileslist(), do_htype(); Xextern int do_run(), do_number(), do_assign(), do_join(); Xextern int do_quit(), do_set_var(), do_unset_var(); Xextern int do_echo(), do_source(), do_mv(), do_addbuffers(); Xextern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history(); Xextern int do_mem(), do_cat(), do_dir(), do_info(), do_inc(); Xextern int do_foreach(), do_return(), do_if(), do_label(), do_goto(); Xextern int do_input(), do_ver(), do_sleep(), do_help(); Xextern int do_strhead(), do_strtail(), do_relabel(); Xextern int do_copy(), date(), do_protect(), do_ps(); Xextern int do_forever(), do_abortline(), do_strings(), do_touch(); Xextern int do_window(), do_search(), do_filenote(); Xchar *push_cpy(); X Xstatic struct COMMAND Command[] = { Xdo_run, 0, ST_AV, 0, "\001", /* may call do_source */ Xdo_set_var, 0, 0, LEVEL_ALIAS, "alias", /* uses avline */ Xdo_abortline, 0, 0, 0, "abortline", Xdo_addbuffers, 2, 0, 0, "addbuffers", Xdo_aset, 1, 0, 0, "aset", Xdo_assign, 0, 0, 0, "assign", Xdo_cat, 0, 0, 0, "cat", Xdo_cd, 0, 0, 0, "cd", Xdo_close, 0, 0, 0, "close", Xdo_copy, 1, 0, 0, "copy", Xdo_copy, 1, 0, 0, "cp", Xdate, 0, 0, 0, "date", Xdo_rm, 0, 0, 0, "delete", Xdo_dir, 0, ST_NOEXP, 0, "dir", Xdo_diskchange, 1, 0, 0, "diskchange", Xdo_inc, 1, 0, -1, "dec", Xdo_echo, 0, 0, 0, "echo", /* uses avline */ Xdo_if, 0, ST_COND, 1, "else", Xdo_if, 0, ST_COND, 2, "endif", Xdo_exec, 1, 0, 0, "exec", Xdo_fault, 1, 0, 0, "fault", Xdo_filenote, 2, 0, 0, "filenote", Xdo_fileslist, 0, 0, 0, "flist", Xdo_fltlower, 0, 0, 0, "fltlower", Xdo_fltupper, 0, 0, 0, "fltupper", Xdo_foreach, 3, ST_NORED, 0, "foreach", Xdo_forever, 1, ST_NORED, 0, "forever", Xdo_forline, 3, ST_NORED, 0, "forline", Xdo_fornum, 4, ST_NORED, 0, "fornum", Xdo_goto, 1, 0, 0, "goto", Xdo_help, 0, 0, 0, "help", Xdo_history, 0, 0, 0, "history", Xdo_howmany, 0, 0, 0, "howmany", Xdo_htype, 1, 0, 0, "htype", Xdo_if, 1, ST_COND|ST_NORED,0, "if", Xdo_inc, 1, 0, 1, "inc", Xdo_info, 0, 0, 0, "info", Xdo_join, 2, 0, 1, "join", Xdo_input, 1, 0, 0, "input", Xdo_label, 1, ST_COND, 0, "label", Xdo_dir, 0, ST_NOEXP, 0, "ls", Xdo_mkdir, 0, 0, 0, "md", Xdo_mem, 0, 0, 0, "mem", Xdo_mkdir, 0, 0, 0, "mkdir", Xdo_mv, 2, 0, 0, "mv", Xdo_open, 3, 0, 0, "open", Xdo_path, 0, 0, 0, "path", Xdo_pri, 2, 0, 0, "pri", Xdo_protect, 2, 0, 0, "protect", Xdo_ps, 0, 0, 0, "ps", Xdo_pwd, 0, 0, 0, "pwd", Xdo_quit, 0, ST_NORED, 0, "quit", Xdo_truerun, 1, ST_NORED, 1, "rback", Xdo_mv, 2, 0, 0, "rename", Xdo_relabel, 2, 0, 0, "relabel", Xdo_resident, 0, 0, 0, "resident", Xdo_return, 0, 0, 0, "return", Xdo_rm, 0, 0, 0, "rm", Xdo_rpn, 0, ST_NOEXP|ST_NORED,0, "rpn", Xdo_truerun, 1, ST_NORED, 0, "run", Xdo_search, 2, 0, 0, "search", Xdo_set_var, 0, ST_AV, LEVEL_SET, "set", Xdo_sleep, 0, 0, 0, "sleep", Xdo_source, 0, ST_NORED|ST_AV, 0, "source", /* uses avline */ Xdo_stack, 0, 0, 0, "stack", Xdo_strhead, 3, 0, 0, "strhead", Xdo_strings, 1, 0, 0, "strings", Xdo_strleft, 3, 0, 0, "strleft", Xdo_strlen, 2, 0, 0, "strlen", Xdo_strmid, 3, 0, 0, "strmid", Xdo_strright, 3, 0, 0, "strright", Xdo_strtail, 3, 0, 0, "strtail", Xdo_touch, 0, 0, 0, "touch", Xdo_cat, 0, 0, 0, "type", Xdo_unset_var, 0, 0, LEVEL_ALIAS, "unalias", Xdo_unset_var, 0, 0, LEVEL_SET , "unset", Xdo_ver, 0, 0, 0, "version", Xdo_window, 0, ST_NOEXP, 0, "window", X'\0', 0, 0, 0, NULL X}; X Xstatic unsigned char elast; /* last end delimeter */ Xstatic char Cin_ispipe, Cout_ispipe; X Xexec_command(base) Xchar *base; X{ Xregister char *scr; Xchar buf[32]; X Xif (!H_stack) { X add_history(base); X sprintf(buf, "%d", H_tail_base + H_len); X set_var(LEVEL_SET, v_histnum, buf); X } Xscr = malloc((strlen(base) << 2) + 2); Xpreformat(base, scr); Xreturn (fcomm(scr, 1) ? -1 : 1); X} X Xisalphanum(c) Xregister char c; X{ Xreturn ( X (c >= '0' && c <= '9') || X (c >= 'a' && c <= 'z') || X (c >= 'A' && c <= 'Z') || X (c == '_') X ); X} X Xpreformat(s, d) Xregister char *s, *d; X{ Xregister int si, di, qm; X Xsi = di = qm = 0; Xwhile (s[si] == ' ' || s[si] == 9) ++si; Xwhile (s[si]) { X if (qm && s[si] != '\"' && s[si] != '\\') { X d[di++] = s[si++] | 0x80; X continue; X } X switch (s[si]) { X case ' ': X case 9: X d[di++] = ' '; X while (s[si] == ' ' || s[si] == 9) ++si; X if (s[si] == 0 || s[si] == '|' || s[si] == ';') --di; X break; X case '*': X case '?': X d[di++] = 0x80; X case '!': X d[di++] = s[si++]; X break; X case '#': X d[di++] = '\0'; X while (s[si]) ++si; X break; X case ';': X case '|': X d[di++] = s[si++]; X while (s[si] == ' ' || s[si] == 9) ++si; X break; X case '\\': X d[di++] = s[++si] | 0x80; X if (s[si]) ++si; X break; X case '\"': X qm = 1 - qm; X ++si; X break; X case '^': X d[di++] = s[++si] & 0x1F; X if (s[si]) ++si; X break; X case '$': /* search end of var name and place false space */ X d[di++] = 0x80; X d[di++] = s[si++]; X while (isalphanum(s[si])) d[di++] = s[si++]; X d[di++] = 0x80; X break; X default: X d[di++] = s[si++]; X break; X } X } Xd[di++]=0; Xd[di]=0; Xif (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d); X} X Xextern BPTR extOpen(); X X/* X * process formatted string. ' ' is the delimeter. X * X * 0: check '\0': no more, stop, done. X * 1: check $. if so, extract, format, insert X * 2: check alias. if so, extract, format, insert. goto 1 X * 3: check history or substitution, extract, format, insert. goto 1 X * X * 4: assume first element now internal or disk based command. X * X * 5: extract each ' ' or 0x80 delimited argument and process, placing X * in av[] list (except 0x80 args appended). check in order: X * X * '$' insert string straight X * '>' setup stdout X * '>>' setup stdout flag for append X * '<' setup stdin X * '*' or '?' do directory search and insert as separate args. X * X * ';' 0 '|' end of command. if '|' setup stdout X * -execute command, fix stdin and out (|) sets X * up stdin for next guy. X */ X X Xfcomm(str, freeok) Xregister char *str; X{ X static int alias_count; X int p_alias_count = 0; X char *istr; X char *nextstr; X char *command; X char *pend_alias = NULL; X char err = 0; X has_wild = 0; X X ++alias_count; X X mpush_base(); X if (*str == 0) X goto done1; Xstep1: X if (alias_count == MAXALIAS || ++p_alias_count == MAXALIAS) { X fprintf(stderr,"Alias Loop\n"); X err = 20; X goto done1; X } X/* X if (str[1] == '$') { X if (istr = get_var (LEVEL_SET, str + 2)) X str = format_insert_string(str, istr, &freeok); X } X*/ X istr = NULL; X if (*(unsigned char *)str < 0x80) X istr = get_var (LEVEL_ALIAS, str); /* only if not \command */ X *str &= 0x7F; /* remove \ teltail */ X if (istr) { X if (*istr == '%') { X pend_alias = istr; X } else { X str = format_insert_string(str, istr, &freeok); X goto step1; X } X } X if (*str == '!') { X char *p, c; /* fix to allow !cmd1;!cmd2 */ X for(p = str; *p && *p != ';' ; ++p); X c = *p; X *p = '\0'; X istr = get_history(str); X *p = c; X replace_head(istr); X str = format_insert_string(str, istr, &freeok); X goto step1; X } X nextstr = str; X command = exarg(&nextstr); X if (*command == 0) X goto done0; X if (pend_alias == 0) { X if (cmd_stat(command) & ST_COND) X goto skipgood; X } X if (disable || forward_goto) { X while (elast && elast != ';' && elast != '|') X exarg(&nextstr); X goto done0; X } Xskipgood: X { X register char *arg, *ptr, *scr; X short redir; X short doexpand; X short cont; X short inc; X X ac = 1; X av[0] = command; Xstep5: /* ac = nextac */ X if (!elast || elast == ';' || elast == '|') X goto stepdone; X X av[ac] = '\0'; X cont = 1; X doexpand = redir = inc = 0; X X while (cont && elast) { X int cstat = cmd_stat(command); X X ptr = exarg(&nextstr); X inc = 1; X arg = ""; X cont = (elast == 0x80); X switch (*ptr) { X case '<': X redir = -2; X case '>': X if (cstat & (ST_NORED | ST_COND)) { X /* don't extract */ X redir = 0; /* <> stuff if its */ X arg = ptr; /* external cmd. */ X break; X } X ++redir; X arg = ptr + 1; X if (*arg == '>') { X redir = 2; /* append >> */ X ++arg; X } X cont = 1; X break; X case '$': X /* restore args if from set command or pend_alias */ X if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) { X if (cstat & ST_COND) { X char *tp; X tp = push_cpy(arg); X arg = tp; X } X else { X char *pe, sv; X while (pe = index(arg,0xA0)) { X sv = *pe; X *pe = '\0'; X av[ac++] = push_cpy(arg); X *pe = sv; X av[ac] = '\0'; X arg = pe+1; X } X } X } X else X arg = ptr; X break; X case '*': X case '?': X if ((cstat & ST_NOEXP) == 0) X doexpand = 1; X arg = ptr; X break; X default: X arg = ptr; X break; X } X X /* Append arg to av[ac] */ X X for (scr = arg; *scr; ++scr) X *scr &= 0x7F; X if (av[ac]) { X register char *old = av[ac]; X av[ac] = mpush(strlen(arg)+strlen(av[ac])); X strcpy(av[ac], old); X strcat(av[ac], arg); X } else { X av[ac] = push_cpy(arg); X } X if (elast != 0x80) X break; X } X X /* process expansion */ X X if (doexpand) { X char **eav, **ebase; X int eac; X has_wild = 1; X eav = ebase = expand(av[ac], &eac); X inc = 0; X if (eav) { X if (ac + eac + 2 > MAXAV) { X ierror (NULL, 506); X err = 1; X } else { X QuickSort(eav, eac); X for (; eac; --eac, ++eav) X av[ac++] = push_cpy(*eav); X } X free_expand (ebase); X } X } X X /* process redirection */ X X if (redir && !err) { X register char *file = (doexpand) ? av[--ac] : av[ac]; X X if (redir < 0) X Cin_name = file; X else { X Cout_name = file; X Cout_append = (redir == 2); X } X inc = 0; X } X X /* check elast for space */ X X if (inc) { X ++ac; X if (ac + 2 > MAXAV) { X ierror (NULL, 506); X err = 1; /* error condition */ X elast = 0; /* don't process any more arguemnts */ X } X } X if (elast == ' ') X goto step5; X } Xstepdone: X av[ac] = '\0'; X X /* process pipes via files */ X X if (elast == '|' && !err) { X static int which; /* 0 or 1 in case of multiple pipes */ X which = 1 - which; X Cout_name = (which) ? Pipe1 : Pipe2; X Cout_ispipe = 1; X } X X X if (err) X goto done0; X X { X register int i; X char save_elast; X char *compile_av(); X register char *avline; X unsigned char delim = ' '; X X save_elast = elast; X if (pend_alias || (cmd_stat(command) & ST_AV)) X delim = 0xA0; X avline = compile_av(av,((pend_alias) ? 1 : 0), ac , delim); X X X if (pend_alias) { /* special % alias */ X register char *ptr, *scr; X for (ptr = pend_alias; *ptr && *ptr != ' '; ++ptr); X set_var (LEVEL_SET, pend_alias + 1, avline); X free (avline); X X scr = malloc((strlen(ptr) << 2) + 2); X preformat (ptr, scr); X fcomm (scr, 1); X unset_var (LEVEL_SET, pend_alias + 1); X } else { /* normal command */ X register int ccno; X long oldcin = Myprocess->pr_CIS; X long oldcout = Myprocess->pr_COS; X char *Cin_buf; X struct FileHandle *ci; X long oldbuf; X X fflush(stdout); X ccno = find_command (command); X if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) { X if (Cin_name) { X if ((Cin = (long)extOpen(Cin_name,1005L)) == 0L) { X ierror (NULL, 504); X err = 1; X Cin_name = '\0'; X } else { X Myprocess->pr_CIS = _devtab[stdin->_unit].fd = Cin; X ci = (struct FileHandle *)(((long)Cin)<<2); X Cin_buf = (char *)AllocMem(202L, MEMF_PUBLIC); X oldbuf = ci->fh_Buf; X if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */ X ci->fh_Buf = (long)Cin_buf>>2; X } X } X if (Cout_name) { X if (Cout_append && (Cout =(long)extOpen(Cout_name, 1005L)) ) { X Seek(Cout, 0L, 1L); X } else { X Cout = (long)extOpen(Cout_name,1006L); X } X if (Cout == NULL) { X err = 1; X ierror (NULL, 504); X Cout_name = '\0'; X Cout_append = 0; X } else { X Myprocess->pr_COS = _devtab[stdout->_unit].fd = Cout; X } X } X } X if (ac < Command[ccno].minargs + 1) { X ierror (NULL, 500); X err = -1; X } else if (!err) { X i = (*Command[ccno].func)(avline, Command[ccno].val); X if (i < 0) X i = 20; X err = i; X } X free (avline); X if (E_stack == 0 && Lastresult != err) { X Lastresult = err; X seterr(); X } X if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) { X if (Cin_name) { X fflush(stdin); X clearerr(stdin); X ci->fh_Buf = oldbuf; X extClose(Cin); X FreeMem(Cin_buf, 202L); X } X if (Cout_name) { X fflush(stdout); X clearerr(stdout); X stdout->_flags &= ~_DIRTY; /* because of nil: device */ X extClose(Cout); X Cout_append = 0; X } X } X Myprocess->pr_CIS = _devtab[stdin->_unit].fd = oldcin; X Myprocess->pr_COS = _devtab[stdout->_unit].fd = oldcout; X } X X if (Cin_ispipe && Cin_name) X DeleteFile(Cin_name); X if (Cout_ispipe) { X Cin_name = Cout_name; /* ok to assign.. static name */ X Cin_ispipe = 1; X } else { X Cin_name = '\0'; X } X Cout_name = '\0'; X Cout_ispipe = 0; X elast = save_elast; X } X mpop_tobase(); /* free arguments */ X mpush_base(); /* push dummy base */ X Xdone0: X { X char *str; X if (err && E_stack == 0) { X str = get_var(LEVEL_SET, v_except); X if (err >= ((str)?atoi(str):1)) { X if (str) { X ++H_stack; X ++E_stack; X exec_command(str); X --E_stack; X --H_stack; X } else { X Exec_abortline = 1; X } X } X } X if (elast != 0 && Exec_abortline == 0) X err = fcomm(nextstr, 0); X Exec_abortline = 0; X if (Cin_name) X DeleteFile(Cin_name); X Cin_name = NULL; X Cin_ispipe = 0; X } Xdone1: X mpop_tobase(); X if (freeok) X free(str); X --alias_count; X return ((int)err); /* TRUE = error occured */ X} X X Xchar * Xexarg(ptr) Xunsigned char **ptr; X{ X register unsigned char *end; X register unsigned char *start; X X start = end = *ptr; X while (*end && *end != 0x80 && *end != ';' && *end != '|' && *end != ' ') X ++end; X elast = *end; X *end = '\0'; X *ptr = end + 1; X return ((char *)start); X} X Xstatic char **Mlist; X Xmpush_base() X{ X char *str; X X str = malloc(5); X *(char ***)str = Mlist; X str[4] = 0; X Mlist = (char **)str; X} X Xchar * Xmpush(bytes) X{ X char *str; X X str = malloc(6 + bytes + 2); /* may need extra 2 bytes in do_run() */ X *(char ***)str = Mlist; X str[4] = 1; X Mlist = (char **)str; X return (str + 5); X} X Xmpop_tobase() X{ X register char *next; X while (Mlist) { X next = *Mlist; X if (((char *)Mlist)[4] == 0) { X free (Mlist); X Mlist = (char **)next; X break; X } X free (Mlist); X Mlist = (char **)next; X } X} X X X/* X * Insert 'from' string in front of 'str' while deleting the X * first entry in 'str'. if freeok is set, then 'str' will be X * free'd X */ X Xchar *format_insert_string(str, from, freeok) Xchar *str; Xchar *from; Xint *freeok; X{ Xregister char *new1, *new2; Xregister unsigned char *strskip; Xint len; X Xfor (strskip = (unsigned char *)str; X *strskip && *strskip != ' ' X && *strskip != ';' && *strskip != '|' X && *strskip != 0x80; ++strskip); Xlen = strlen(from); Xnew1 = malloc((len << 2) + 2); Xpreformat(from, new1); Xlen = strlen(new1) + strlen(strskip); Xnew2 = malloc(len+2); Xstrcpy(new2, new1); Xstrcat(new2, strskip); Xnew2[len+1] = 0; Xfree (new1); Xif (*freeok) free (str); X*freeok = 1; Xreturn new2; X} X Xcmd_stat(str) Xchar *str; X{ Xreturn(Command[find_command(str)].stat); X} X Xfind_command(str) Xchar *str; X{ Xregister unsigned short i; Xint len = strlen(str); X Xfor (i = 0; Command[i].func; ++i) X if ( ! strncmp(str, Command[i].name, len)) return (int)i; Xreturn 0; X} X Xdo_help() X{ Xregister struct COMMAND *com; Xint i=0; X Xfor (com = &Command[1]; com->func; ++com) { X printf ("%-12s", com->name); X if (++i % 6 == 0) printf("\n"); X } Xprintf("\n"); Xreturn 0; X} X Xchar *push_cpy(s) Xchar *s; X{ Xreturn strcpy(mpush(strlen(s)), s); X} SHAR_EOF echo "End of archive 1 (of 2)" # if you want to concatenate archives, remove anything after this line exit