page%swap@Sun.COM (Bob Page) (05/19/89)
Submitted-by: PERUGIA@ICNUCEVM.Bitnet (Cesare Dieni) Posting-number: Volume 89, Issue 150 Archive-name: unix/shell303a.2 # 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: # globals.c # main.c # makefile # rawconsole.c # run.c # set.c # shell.h # shellfunctions.h # sub.c # This is archive 2 of a 2-part kit. # This archive created: Thu May 18 12:17:54 1989 echo "extracting globals.c" sed 's/^X//' << \SHAR_EOF > globals.c X X/* X * GLOBALS.C X * X * (c)1986 Matthew Dillon 9 October 1986 X * X * Version 2.07M by Steve Drew 10-Sep-87 X * X * Most global variables. X * X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89 X * X */ X Xchar *v_titlebar="_titlebar"; /* Window title */ Xchar *v_prompt ="_prompt"; /* your prompt (ascii command) */ Xchar *v_hist ="_history"; /* set history depth (value) */ Xchar *v_histnum ="_histnum"; /* set history numbering var */ Xchar *v_debug ="_debug"; /* set debug mode */ Xchar *v_verbose ="_verbose"; /* set verbose for source files */ Xchar *v_stat ="_maxerr"; /* worst return value to date */ Xchar *v_lasterr ="_lasterr"; /* return value from last comm. */ Xchar *v_cwd ="_cwd"; /* current directory */ Xchar *v_except ="_except"; /* "nnn;command" */ Xchar *v_passed ="_passed"; /* passed arguments to source file */ Xchar *v_path ="_path"; /* search path for external commands */ Xchar *v_gotofwd ="_gtf"; /* set name for fwd goto name */ X Xstruct HIST *H_head, *H_tail; /* HISTORY lists */ X Xstruct PERROR Perror[]= { /* error code->string */ X 103, "Insufficient free storage", X 105, "Task table full", X 120, "Argument line invalid or too long", X 121, "File is not an object module", X 122, "Invalid resident library during load", X 201, "No default directory", X 202, "Object in use", X 203, "Object already exists", X 204, "Directory not found", X 205, "Object not found", X 206, "Bad stream name", X 207, "Object too large", X 209, "Action not known", X 210, "Invalid stream component name", X 211, "Invalid object lock", X 212, "Object not of required type", X 213, "Disk not validated", X 214, "Disk write protected", X 215, "Rename across devices", X 216, "Directory not empty", X 217, "Too many levels", X 218, "Device not mounted", X 219, "Seek error", X 220, "Comment too long", X 221, "Disk full", X 222, "File delete protected", X 223, "File write protected", X 224, "File read protected", X 225, "Not a DOS disk", X 226, "No disk", X X /* custom error messages */ X X 500, "Bad arguments", X 501, "Label not found", X 502, "Must be within source file", X 503, "Syntax Error", X 504, "Redirection error", X 505, "Pipe error", X 506, "Too many arguments", X 507, "Destination not a directory", X 508, "Cannot mv a filesystem", X 509, "Error in command name", X 510, "Bad drive name", X 511, "Illegal number", X 0, NULL X}; X Xchar *av[MAXAV]; /* Internal argument list */ Xlong Src_base[MAXSRC]; /* file pointers for source files */ Xlong Src_pos[MAXSRC]; /* seek position storage for same */ Xchar If_base[MAXIF]; /* If/Else stack for conditionals */ Xint H_len, H_tail_base; /* History associated stuff */ Xint H_stack; /* AddHistory disable stack */ Xint E_stack; /* Exception disable stack */ Xint Src_stack, If_stack; /* Stack Indexes */ Xint forward_goto; /* Flag for searching for foward lables */ Xint ac; /* Internal argc */ Xint debug; /* Debug mode */ Xint disable; /* Disable com. execution (conditionals)*/ Xint Verbose; /* Verbose mode for source files */ Xint Lastresult; /* Last return code */ Xint Exec_abortline; /* flag to abort rest of line */ Xint Quit; /* Quit flag */ Xlong Cout, Cin; /* Current input and output file handles*/ Xlong Cout_append; /* append flag for Cout */ Xchar *Cin_name, *Cout_name; /* redirection input/output name or NULL*/ Xchar *Pipe1, *Pipe2; /* the two pipe temp. files */ Xstruct Process *Myprocess; Xstruct CommandLineInterface *Mycli; Xint S_histlen = 20; /* Max # history entries */ Xunsigned int options; SHAR_EOF echo "extracting main.c" sed 's/^X//' << \SHAR_EOF > main.c X/* X * MAIN.C X * X * Matthew Dillon, 24 Feb 1986 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 Xchar *shellctr="CshCounter"; X Xextern char *v_titlebar, *v_prompt, *v_hist, *v_lasterr, *v_path; X Xint aux; /* for use with aux: driver */ Xchar *oldtitle; Xchar trueprompt[100]; Xchar Inline[260]; Xstruct IntuitionBase *IntuitionBase; Xstruct Window *w; Xstruct ArpBase *ArpBase; X Xmain(argc, argv) Xregister char *argv[]; X{ X#if RAW_CONSOLE X char *rawgets(); X#endif X Xregister unsigned int i; Xextern int Enable_Abort; Xchar buf[10]; X XArpBase=(struct ArpBase *)OpenLibrary("arp.library",34L); Xif (ArpBase==NULL) { printf("No arp library\n"); exit(0); } X XForbid(); Xi=Errno=0; Xif (Getenv(shellctr,buf,10L)) { X i=(int)(long)Atol(buf); X if (Errno) i=0; X } Xsprintf(buf,"%d",i+1); XSetenv(shellctr,buf); XPermit(); X XIntuitionBase=(struct IntuitionBase *)ArpBase->IntuiBase; X Xinit(); X Xsprintf(buf,"%ld",Myprocess->pr_TaskNum); Xset_var(LEVEL_SET, "_clinumber", buf); X Xoldtitle=(char *)(w->Title); X Xset_var(LEVEL_SET, v_titlebar, "CShell V3.03A"); Xset_var(LEVEL_SET, v_prompt, X (IsInteractive(Input())) ? "\23337m%p> \2330m" : ""); Xset_var(LEVEL_SET, v_hist, "20"); Xset_var(LEVEL_SET, v_lasterr, "0"); Xset_var(LEVEL_SET, v_path, "RAM:,RAM:c/,df0:c/,df1:c/,sys:system/"); Xset_var(LEVEL_SET, "_insert", "1"); Xset_var(LEVEL_SET, "f1", "cdir df0:\15"); Xset_var(LEVEL_SET, "F1", "cdir df1:\15"); Xset_var(LEVEL_SET, "f3", "cdir RAM:\15"); Xset_var(LEVEL_SET, "F3", "cdir vd0:\15"); Xset_var(LEVEL_SET, "f4", "cd df0:\15"); Xset_var(LEVEL_SET, "F4", "cd df1:\15"); Xset_var(LEVEL_SET, "f5", "cls; ls\15"); Xset_var(LEVEL_SET, "F5", "cdir "); Xset_var(LEVEL_SET, "f6", "lc\15"); Xset_var(LEVEL_SET, "f7", "info\15"); Xset_var(LEVEL_SET, "F7", "assign \15"); Xset_var(LEVEL_SET, "f8", "window -lf\15"); Xset_var(LEVEL_SET, "F8", "window -sb\15"); Xset_var(LEVEL_SET, "f10", "cls\15"); Xset_var(LEVEL_SET, "F10", "exit\15"); Xset_var(LEVEL_ALIAS, "cls", "echo -n ^l"); Xset_var(LEVEL_ALIAS, "lc", "ls -s"); Xset_var(LEVEL_ALIAS, "kr", "rm -r RAM:* >NIL:"); Xset_var(LEVEL_ALIAS, "cdir", "%q cd $q; cls; dir"); Xset_var(LEVEL_ALIAS, "exit", "endcli;quit"); Xset_var(LEVEL_ALIAS, "lp", "cat >PRT:"); Xseterr(); Xdo_pwd(NULL); /* set $_cwd */ XEnable_Abort = 0; X Xif (exists(av[1] = "S:.login")) { X strcpy(Inline, "source S:.login"); X do_source (Inline); X } X Xfor (i = 1; i < argc; ++i) { X if (!strcmp(argv[i],"-c")) { X Inline[0] = ' '; X Inline[1] = '\0'; X while (++i < argc) X { strcat(Inline,argv[i]); strcat(Inline," "); } X exec_command(Inline); X main_exit(Lastresult); X } X if (!strcmp(argv[i],"-a")) { aux = 1; continue; } X sprintf (Inline, "source %s",argv[i]); X av[1] = argv[i]; X do_source (Inline); X } Xfor (;;) { X if (breakcheck()) X while (WaitForChar(Input(), 100L) || stdin->_bp < stdin->_bend) X gets(Inline); X clearerr(stdin); /* prevent acidental quit */ X#if RAW_CONSOLE X if (Quit || !rawgets(Inline, disable ? "_ " : trueprompt)) main_exit(0); X#else X printf("%s", disable ? "_ " : trueprompt); X fflush(stdout); X if (Quit || !gets(Inline)) main_exit(0); X#endif X breakreset(); X if (*Inline) exec_command(Inline); X } X} X Xmain_exit(n) X{ Xregister unsigned short i; Xchar buf[10]; X XGetenv(shellctr,buf,10L); Xi=(int)Atol(buf); Xsprintf(buf,"%d",i-1); XSetenv(shellctr,buf); XSetWindowTitles(w,oldtitle,-1L); Xfor (i=1; i<MAXMYFILES; i++) myclose(i); XArpExit(0L,0L); /* Intuition need not to be closed */ X} X Xinit() X{ Xstatic char pipe1[32], pipe2[32]; Xstruct Window *getwindow(); X Xstdin->_flags |= 0x80; /* make sure we're set as a tty */ Xstdout->_flags |= 0x80; /* in case of redirection in .login */ XClose(_devtab[2].fd); X_devtab[2].mode |= O_STDIO; X_devtab[2].fd = _devtab[1].fd; /* set stderr to Output() otherwise */ X /* don't work with aux driver */ XMyprocess = (struct Process *)FindTask(0L); XMycli=(struct CommandLineInterface *)((long)Myprocess->pr_CLI << 2); Xw=getwindow(); XPipe1 = pipe1; XPipe2 = pipe2; Xsprintf(pipe1, "ram:pipe1_%ld", Myprocess); Xsprintf(pipe2, "ram:pipe2_%ld", Myprocess); X} X Xbreakcheck() X{ Xreturn (int)(SetSignal(0L,0L) & SIGBREAKF_CTRL_C); X} X Xbreakreset() X{ XSetSignal(0L, SIGBREAKF_CTRL_C); X} X Xdobreak() X{ Xif (breakcheck()) { printf("^C\n"); return(1); } Xreturn(0); X} X X/* this routine causes manx to use this Chk_Abort() rather than it's own */ X/* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */ X/* is zero). Since we want to check for our own ^C's */ X XChk_Abort() X{ Xreturn(0); X} X X_wb_parse() X{ X} X Xdo_howmany() X{ Xchar buf[10]; X XGetenv(shellctr, buf, 10L); Xprintf("Shell(s) running: %s\n",buf); X} X Xstruct Window *getwindow() X{ Xstruct InfoData *infodata; Xstruct Window *win; Xlong args[8]; X Xinfodata=AllocMem((long)sizeof(struct InfoData),MEMF_CLEAR | MEMF_PUBLIC); Xargs[0]=(long)infodata >> 2; XSendPacket(ACTION_DISK_INFO,args,Myprocess->pr_ConsoleTask); Xwin=(struct Window *)infodata->id_VolumeNode; XFreeMem(infodata,(long)sizeof(struct InfoData)); Xreturn win; X} SHAR_EOF echo "extracting makefile" sed 's/^X//' << \SHAR_EOF > makefile X###################################################################### X# X# Makefile to build Shell 3.02A X# by Carlo Borreo & Cesare Dieni 20-Dec-88 X# X###################################################################### X XOBJS = run.o main.o comm1.o comm2.o comm3.o execom.o set.o sub.o \ X globals.o rawconsole.o X XINCL = shell.h X XShell : Shell.syms $(OBJS) X ln +q -m -o Shell $(OBJS) -la -lc X XShell.syms : $(INCL) X cc +HShell.syms shell.h X Xrawconsole.o : rawconsole.c $(INCL) X cc +IShell.syms rawconsole.c X Xrun.o : run.c $(INCL) X cc +IShell.syms run.c X Xmain.o : main.c $(INCL) X cc +IShell.syms main.c X Xcomm1.o : comm1.c $(INCL) X cc +IShell.syms comm1.c X Xcomm2.o : comm2.c $(INCL) X cc +IShell.syms comm2.c X Xcomm3.o : comm3.c $(INCL) X cc +IShell.syms comm3.c X Xset.o : set.c $(INCL) X cc +IShell.syms set.c X Xsub.o : sub.c $(INCL) X cc +IShell.syms sub.c X Xglobals.o : globals.c $(INCL) X cc +IShell.syms globals.c X Xexecom.o : execom.c $(INCL) X cc +IShell.syms execom.c SHAR_EOF echo "extracting rawconsole.c" sed 's/^X//' << \SHAR_EOF > rawconsole.c X/* X * RawConsole.c X * X * Shell 2.07M 17-Jun-87 X * console handling, command line editing support for Shell X * using new console packets from 1.2. X * Written by Steve Drew. (c) 14-Oct-86. X * 16-Dec-86 Slight mods to rawgets() for Disktrashing. X * X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89 X * X */ X X#if RAW_CONSOLE X Xchar *tyahdptr; X Xmyget() X{ Xif (*tyahdptr) return *tyahdptr++; Xreturn getchar(); X} X Xextern int aux; /* for use with aux: */ X X#define SETRAW setrawcon(-1L); X#define SETCON setrawcon(0L); X Xint width; X Xnewwidth() X{ Xextern struct Window *w; X Xwidth=(w->Width- (w->BorderLeft + w->BorderRight)) / w->RPort->TxWidth; X} X Xchar *rawgets(line,prompt) Xchar *line, *prompt; X{ Xchar *get_var(); Xchar *gets(); Xregister int n, pl; Xregister int max, i; Xunsigned char c1,c2,c3; Xchar fkeys[5]; Xchar *s; Xchar *ps; Xchar typeahd[256]; Xint fkey, savn; Xint insert = 1; Xint recall = -1; Xstruct HIST *hist; X Xnewwidth(); X Xif (aux) { X printf("%s",prompt); X fflush(stdout); X } Xif (!IsInteractive(Input()) || aux ) return(gets(line)); Xif (WaitForChar((long)Input(), 100L) || /* don't switch to 1L ...*/ X stdin->_bp < stdin->_bend) { /* else causes read err's*/ X gets(line); X return(line); X } XSETRAW; Xprintf("\015%s\2336n",prompt); Xsavn = pl = n = 0; Xtyahdptr = typeahd; Xwhile((typeahd[n]=getchar()) != 'R') { X if ((unsigned char)typeahd[n] == 155) savn = n; X n++; X } X /* typeahd now contains possible type a head chars X followed by <CSI> cursor position report. X */ Xtypeahd[savn] = '\0'; Xif (typeahd[n-2] != ';') pl = (typeahd[n-2] - 48) * 10; Xpl += typeahd[n-1] - 49; Xps = line + pl; Xline[max = i = pl] = '\0'; X Xif (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0; X Xwhile( (c1 = myget()) != 255) { X switch(c1) { X case 155: X c2 = myget(); X switch(c2) { X case 'A': /* up arrow */ X n = ++recall; X case 'B': /* down arrow */ X line[pl] = '\0'; X if (recall >= 0 || c2 == 'A') { X if (c2 == 'B') n = --recall; X if (recall >= 0) { X for(hist = H_head; hist && n--; X hist = hist->next); X if (hist) strcpy(&line[pl],hist->line); X else recall = H_len; X } X } X if (i != pl) X printf("\233%dD",i); X printf("\015\233J%s%s",prompt,ps); X i = max = strlen(ps) + pl; X break; X case 'C': /* right arrow*/ X if (i < max) { X i++; X printf("\233C"); X } X break; X case 'D': /* left arrow */ X if (i > pl) { X i--; X printf("\233D"); X } X break; X case 'T': /* shift-up */ X n = recall = H_len-1; X case 'S': /* shift-down */ X line[pl] = '\0'; X if (c2 == 'S') { X n = recall = 0; X if (H_head) strcpy(&line[pl], H_head->line); X } X else if (H_tail) strcpy(&line[pl], H_tail->line); X printf("\015\233J%s%s", prompt, ps); X i = max = strlen(ps) + pl; X break; X case ' ': /* shift -> <-*/ X c3 = myget(); X switch(c3) { X case('@'): /* shift -> */ X while (ps[i-pl-1] == ' ' && i<max) { X i++; X printf("\233C"); X } X while (ps[i-pl-1] != ' ' && i<max) { X i++; X printf("\233C"); X } X break; X case('A'): /* shift <- */ X while (ps[i-pl-1] == ' ' && i>pl) { X i--; X printf("\233D"); X } X while (ps[i-pl-1] != ' ' && i>pl) { X i--; X printf("\233D"); X } X break; X default: X break; X } X break; X default: X c3 = myget(); X if (c3 == '~') { X fkey = c2; X fkeys[0] = 'f'; X if (c2 == '?') { X strcpy(ps,"help"); X goto done; X } X } X else if (myget() != '~') { /* window was resized */ X while(myget() != '|'); X newwidth(); X break; X } X else { X fkey = c3; X fkeys[0] = 'F'; X } X sprintf(fkeys+1,"%d",fkey - 47); X if (s = get_var(LEVEL_SET, fkeys)) X tyahdptr = strcpy(typeahd,s); X break; X } X break; X case 8: X if (i > pl) { X i--; X printf("\010"); X } X else break; X case 127: X if (i < max) { X int j,t,l = 0; X movmem(&line[i+1],&line[i],max-i); X --max; X printf("\233P"); X j = width - i % width - 1; /* amount to end */ X t = max/width - i/width; /* no of lines */ X for(n = 0; n < t; n++) { X l += j; /* no. of char moved */ X if (j) printf("\233%dC",j); /* goto eol */ X printf("%c\233P",line[width*(i/width+n+1)-1]); X j = width-1; X } X if (t) X printf("\233%dD",l+t); /* get back */ X } X break; X case 18: X n = i/width; X if (n) printf("\233%dF",n); X printf("\015\233J%s%s",prompt,ps); X i = max; X break; X case 27: X break; X case 1: X insert ^= 1; X break; X case 21: X case 24: X case 26: X if (i>pl) printf("\233%dD",i-pl); X i = pl; X if (c1 == 26) break; X case 11: /* ^K */ X printf("\233J"); X max = i; X line[i] = '\0'; X break; X case 28: /* ^\ */ X SETCON; X return(NULL); X case 5: X if (i!=max) printf("\233%dC",max - i); X i = max; X break; X case 10: X case 13: X line[max] = '\0'; Xdone: printf("\233%dC\n",max - i); X X SETCON; X strcpy(line, ps); X return(line); X default: X c1 &= 0x7f; X if (c1 == 9) c1 = 32; X if (c1 > 31 & i < 256) { X if (i < max && insert) { X int j,t,l = 0; X movmem(&line[i], &line[i+1], max - i); X printf("\233@%c",c1); X t = max/width - i/width; X j = width - i % width - 1; X for(n = 0; n < t; n++) { X l += j; X if (j) printf("\233%dC",j); X printf("\233@%c",line[width*(i/width+n+1)]); X j = width-1; X } X if (t) printf("\233%dD",l + t); X ++max; X } X else { X if(i == pl && max == i) printf("\015%s%s",prompt,ps); X putchar(c1); X } X line[i++] = c1; X if (max < i) max = i; X line[max] = '\0'; X } X } X } XSETCON; Xreturn(NULL); X} X Xsetrawcon(flag) /* -1L=RAW:, 0L=CON: */ Xlong flag; X{ Xlong packargs[8]; X Xpackargs[0]=flag; XSendPacket(994L, packargs, Myprocess->pr_ConsoleTask); X} X X#endif SHAR_EOF echo "extracting run.c" sed 's/^X//' << \SHAR_EOF > run.c X X/* X * RUN.C X * X * (c)1986 Matthew Dillon 9 October 1986 X * X * RUN handles running of external commands. 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_path; Xchar *FindIt(); X Xdo_run(str) Xchar *str; X{ Xint i, len, retcode; Xchar buf[200]; /* enough space for 100 char cmd name + path stuff */ Xchar *path; X Xchar *p = av[0]; Xchar **args = av+1; X Xwhile(*p++) *p &= 0x7F; /* allow "com mand" */ X Xwhile(*args) { /* if any arg contains a space then */ X if (index(*args,' ')) { /* surround with quotes, since must */ X i = strlen(*args); /* of specified via "arg u ment" on */ X movmem(*args,(*args)+1,i); /* original command line. */ X args[0][0] = args[0][i+1] = '\"'; /* mpush in execom.c has */ X args[0][i+2] = '\0'; /* allowed for these 2 extra bytes. */ X } X ++args; X } Xif ((len = strlen(av[0])) > 100) { ierror(NULL,509); return -1; } Xif (path = FindIt(av[0],"",buf)) retcode = myfexecv(path, av); Xelse { X Myprocess->pr_WindowPtr = (APTR)(-1); X /* X * manx's fexecv code only allows us 38 X * chars for command name. X */ X if (len > 37) av[0][37] = '\0'; X retcode = myfexecv(av[0], av); X Myprocess->pr_WindowPtr = NULL; X } Xif (retcode < 0) { X char *copy; X if ((path = FindIt(av[0],".sh",buf)) == NULL) { X fprintf(stderr,"Command Not Found %s\n",av[0]); X return -1; X } X av[1] = buf; /* particular to do_source() */ X copy = malloc(strlen(str)+3); X sprintf(copy,"x %s",str); X retcode = do_source(copy); X free(copy); X } Xreturn retcode; X} X Xchar *dofind(cmd, ext, buf) Xchar *cmd, *ext, *buf; X{ Xchar *ptr, *s; X Xsprintf(buf,"%s%s",cmd,ext); Xif (exists(buf)) return buf; Xif (BaseName(buf)==buf) { X s = get_var(LEVEL_SET, v_path); X while (*s) { X for (ptr=buf; *s && *s!=','; ) *ptr++ = *s++; X sprintf(ptr, "%s%s", cmd, ext); X if (exists(buf)) return buf; X if (*s) s++; X } X } Xreturn NULL; X} X Xchar *FindIt(cmd,ext,buf) Xchar *cmd, *ext, *buf; X{ Xchar *response; X XMyprocess->pr_WindowPtr = (APTR)(-1); Xresponse=dofind(cmd,ext,buf); XMyprocess->pr_WindowPtr = NULL; Xreturn response; X} X Xmyfexecv(cmd, argv) Xchar *cmd, **argv; X{ Xlong ret_val; Xstruct FileHandle *fhp; XAPTR sav_ret; Xregister char **ap, *cp, *arg; Xlong len, seg, sav, stksiz; Xchar buf[40]; Xunion { X long *lp; X long ll; X } l, stk; Xlong oldcin, oldcout; Xlong doexec(); Xextern long _savsp; X Xif (seg = LoadPrg(cmd)) goto found; Xl.lp = (long *) Mycli->cli_CommandDir; Xwhile (l.ll) { X l.ll <<= 2; X sav = CurrentDir(l.lp[1]); X seg = LoadPrg(cmd); X CurrentDir(sav); X if (seg) goto found; X l.ll = *l.lp; X } Xsprintf(buf, "c:%s", cmd); Xif (seg = LoadPrg(buf)) goto found; Xreturn -1; X Xfound: X Xstksiz = 4 * Mycli->cli_DefaultStack; Xif ((stk.lp = AllocMem(stksiz+8, 0L)) == 0) { X UnLoadPrg(seg); X return -1; X } Xfor (len=0,ap=argv+1;*ap;ap++) X len += strlen(*ap) + 1; Xif (len==0) len++; Xif ((cp = arg = AllocMem(len, 0L)) == 0) { X UnLoadPrg(seg); X FreeMem(stk.lp, stksiz+8); X return -1; X } X*stk.lp = stksiz + 8; Xstk.ll += stksiz; Xstk.lp[0] = stksiz; Xstk.lp[1] = ((long *)_savsp)[2]; Xsav_ret = Myprocess->pr_ReturnAddr; XMyprocess->pr_ReturnAddr = (APTR) stk.lp; X Xsav = Mycli->cli_Module; XMycli->cli_Module = seg; X Xfor (ap=argv+1;*ap;ap++) { X strcpy(cp, *ap); X if (ap[1]) strcat(cp, " "); X cp += strlen(cp); X } Xif (len==1) arg[1]='\0'; Xarg[len-1] = '\n'; X Xcp = (char *)((long)Mycli->cli_CommandName << 2); Xmovmem(cp, buf, 40); Xstrcpy(cp+1, cmd); Xcp[0] = strlen(cmd); X Xfhp = (struct FileHandle *) (Myprocess->pr_CIS << 2); Xstrncpy(fhp->fh_Buf<<2, arg, (int)(len < 200?len:199)); Xfhp->fh_Pos = 0; Xfhp->fh_End = len < 200?len:199; Xoldcin = Myprocess->pr_CIS; Xoldcout = Myprocess->pr_COS; X Xret_val = doexec(len, stksiz, stksiz+8, len, arg, (seg+1)<<2, stk.ll); X XMyprocess->pr_CIS = oldcin; XMyprocess->pr_COS = oldcout; Xfhp->fh_Pos = fhp->fh_End; XUnLoadPrg(Mycli->cli_Module); XMyprocess->pr_ReturnAddr = sav_ret; XMycli->cli_Module = sav; XFreeMem(arg, len); Xmovmem(buf, cp, 40); Xreturn ret_val; X} X Xstatic long doexec() X{ X#asm X movem.l d3-d7/a2-a5,-(sp) ;save registers X lea savsp(pc),a0 X move.l sp,(a0) ;save our sp X movem.l 8(a5),d0/d2/d3/d4/a0/a4/a7 ;load params X move.l 4(sp),a3 ;get old sp from CLI X movem.l 4(a3),a1/a2/a5/a6 ;get BCPL environment X move.l d0,12(a1) ;set length X move.l a0,d1 ;copy to dreg X lsr.l #2,d1 ;convert to BPTR X move.l d1,8(a1) ;set ptr X move.l a0,d1 ;copy to d1 as well X jsr (a4) ;call new program X movem.l (sp)+,d2/d3 ;get stk siz and old sp X move.l sp,a1 ;save current sp X move.l savsp(pc),sp ;get back our sp X movem.l (sp)+,d3-d7/a2-a5 ;get back registers X move.l d0,-(sp) ;save return code X sub.l d2,a1 ;back up a bit X sub.l #8,a1 ;back up over header X move.l (a1),d0 ;get size to free X move.l 4,a6 ;get ExecBase X jsr -210(a6) ;free the memory X move.l (sp)+,d0 ;get the return code X#endasm X} X X#asm Xsavsp: X dc.l 0 X#endasm SHAR_EOF echo "extracting set.c" sed 's/^X//' << \SHAR_EOF > set.c X X/* X * SET.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_titlebar, *v_verbose, *v_hist, *v_debug, *v_prompt; Xextern struct Window *w; X X#define MAXLEVELS (3 + MAXSRC) X Xstruct MASTER { X struct MASTER *next; X struct MASTER *last; X char *name; X char *text; X}; X Xstatic struct MASTER *Mbase[MAXLEVELS]; X Xchar *set_var(level, name, str) Xregister char *name, *str; X{ X register struct MASTER *base = Mbase[level]; X register struct MASTER *last; X register int len; X X for (len = 0; isalphanum(name[len]); ++len); X while (base != NULL) { X if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) { X Free (base->text); X goto gotit; X } X last = base; X base = base->next; X } X if (base == Mbase[level]) { X base = Mbase[level] = (struct MASTER *)malloc (sizeof(struct MASTER)); X base->last = NULL; X } else { X base = (struct MASTER *)malloc (sizeof(struct MASTER)); X base->last = last; X last->next = base; X } X base->name = malloc (len + 1); X bmov (name, base->name, len); X base->name[len] = 0; X base->next = NULL; Xgotit: X base->text = malloc (strlen(str) + 1); X strcpy (base->text, str); X if (*name=='_') sys_vars(); X return (base->text); X} X Xchar *get_var (level, name) Xregister char *name; X{ X register struct MASTER *base = Mbase[level]; X register unsigned char *scr; X register int len; X X for (scr = (unsigned char *)name; *scr && *scr != 0x80 && *scr != ' ' && *scr != ';' && *scr != '|'; ++scr); X len = scr - name; X X while (base != NULL) { X if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) X return (base->text); X base = base->next; X } X return (NULL); X} X Xunset_level(level) X{ X register struct MASTER *base = Mbase[level]; X X while (base) { X Free (base->name); X Free (base->text); X Free (base); X base = base->next; X } X Mbase[level] = NULL; X} X Xunset_var(level, name) Xchar *name; X{ X register struct MASTER *base = Mbase[level]; X register struct MASTER *last = NULL; X register int len; X X for (len = 0; isalphanum(name[len]); ++len); X while (base) { X if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) { X if (base != Mbase[level]) X last->next = base->next; X else X Mbase[level] = base->next; X if (base->next != NULL) X base->next->last = last; X if (base == Mbase[level]) X Mbase[level] = base->next; X Free (base->name); X Free (base->text); X Free (base); X return (1); X } X last = base; X base = base->next; X } X return (-1); X} X Xdo_unset_var(str, level) Xchar *str; X{ Xregister unsigned int i; X Xfor (i = 1; i < ac; ++i) unset_var (level, av[i]); Xsys_vars(); Xreturn 0; X} X Xdo_set_var(command, level) Xchar *command; X{ Xregister struct MASTER *base = Mbase[level]; Xregister char *str; X Xswitch (ac) { Xcase 1: X while (base && !dobreak()) { X printf ("\2330m%-10s %s\n", base->name, base->text); X base = base->next; X } X break; Xcase 2: X if (str=get_var(level,av[1])) printf ("%-10s %s\n", av[1], str); X break; Xdefault: X set_var (level, av[1], next_word (next_word (command))); X if (*av[1]=='_') sys_vars(); X break; X } Xreturn 0; X} X Xextern char trueprompt[100]; X Xsys_vars() X{ Xregister char *str, *t; X Xif (strcmp(w->Title, str=get_var(LEVEL_SET, v_titlebar))) X SetWindowTitles(w, str, -1L); XS_histlen=(str = get_var(LEVEL_SET, v_hist)) ? atoi(str) : 0; Xdebug =(get_var(LEVEL_SET, v_debug) !=NULL); XVerbose=(get_var(LEVEL_SET, v_verbose)!=NULL); Xif (S_histlen < 2) S_histlen=2; X Xif ( (str=get_var(LEVEL_SET,v_prompt)) ==NULL) str="$ "; Xt=trueprompt; Xwhile (*str) X if (*str=='%' && Toupper(str[1])=='P') { X str+=2; X strcpy(t,get_var(LEVEL_SET,"_cwd")); X t+=strlen(t); X } X else *t++=*str++; Xstrcpy(t,"\2330m"); X} SHAR_EOF echo "extracting shell.h" sed 's/^X//' << \SHAR_EOF > shell.h X X/* X * SHELL.H X * X * (c)1986 Matthew Dillon 9 October 1986 X * X * X * SHELL include file.. contains shell parameters and extern's X * X * Version 2.07M by Steve Drew 10-Sep-87 X * X * Version 3.02A by Carlo Borreo & Cesare Dieni 20-Dec-88 X * X */ X X#define RAW_CONSOLE 1 /* Set to 0 to compile out Cmd Line Editing */ X X#include <stdio.h> X#include <exec/exec.h> X#include <time.h> X#include <libraries/dos.h> X#include <libraries/dosextens.h> X#include <intuition/intuition.h> X#include <intuition/intuitionbase.h> X#include "shellfunctions.h" X#include <fcntl.h> X#include <libraries/arpbase.h> X#include <arpfunctions.h> X Xtypedef struct FileInfoBlock FIB; X X#define bmov movmem X X#define MAXAV 256 /* Max. # arguments */ X#define MAXSRC 5 /* Max. # of source file levels */ X#define MAXIF 10 /* Max. # of if levels */ X#define MAXALIAS 20 /* Max. # of alias levels */ X#define MAXMYFILES 9 /* Max. # of internal files */ X X#define LEVEL_SET 0 /* which variable list to use */ X#define LEVEL_ALIAS 1 X#define LEVEL_LABEL 2 X X /* EXECOM.C defines */ X X#define FL_DOLLAR 0x01 /* One of the following */ X#define FL_BANG 0x02 X#define FL_PERCENT 0x04 X#define FL_QUOTE 0x08 X#define FL_IDOLLAR 0x10 /* Any or all of the following may be set */ X#define FL_EOC 0x20 X#define FL_EOL 0x40 X#define FL_OVERIDE 0x80 X#define FL_WILD 0x100 X#define FL_MASK (FL_DOLLAR|FL_BANG|FL_PERCENT|FL_QUOTE) X X#ifndef NULL X#define NULL 0L X#endif X X#define CHECKBREAK() dobreak() X X#ifndef AZTEC_C Xstruct _dev { X long fd; X short mode; X }; X#endif X Xstruct HIST { X struct HIST *next, *prev; /* doubly linked list */ X char *line; /* line in history */ X}; X Xstruct PERROR { X int errnum; /* Format of global error lookup */ X char *errstr; X}; X Xstruct DPTR { /* Format of directory fetch pointer */ X BPTR lock; /* lock on directory */ X FIB *fib; /* mod'd fib for entry */ X }; X Xextern struct HIST *H_head, *H_tail; Xextern struct PERROR Perror[]; Xextern struct DPTR *dopen(); Xextern char *set_var(), *get_var(), *next_word(); Xextern char *get_history(), *compile_av(), *get_pwd(); Xextern char *malloc(), *strcpy(), *strcat(), *index(); Xextern char **expand(); Xextern char *av[]; Xextern char *Current; Xextern int H_len, H_tail_base, H_stack; Xextern int E_stack; Xextern int Src_stack, If_stack, forward_goto; Xextern int ac; Xextern int debug, Rval, Verbose, disable, Quit; Xextern int Lastresult; Xextern int Exec_abortline; Xextern int S_histlen; Xextern unsigned int options; Xextern long Cin, Cout, Cout_append; Xextern char *Cin_name, *Cout_name; Xextern char Cin_type, Cout_type; /* these variables are in transition */ Xextern char *Pipe1, *Pipe2; X Xextern long Errno; Xextern long Src_base[MAXSRC]; Xextern long Src_pos[MAXSRC]; Xextern char If_base[MAXIF]; Xextern struct Process *Myprocess; Xextern struct CommandLineInterface *Mycli; X Xextern long atol(), Atol(), myatol(); SHAR_EOF echo "extracting shellfunctions.h" sed 's/^X//' << \SHAR_EOF > shellfunctions.h Xtypedef long cList; Xextern int Enable_Abort; X Xlong AbleICR(); Xlong AbortIO(); Xlong ActivateGadget(); Xvoid ActivateWindow(); Xvoid AddAnimOb(); Xvoid AddBob(); Xvoid AddConfigDev(); Xvoid AddDevice(); Xlong AddDosNode(); Xvoid AddFont(); Xvoid AddFreeList(); Xshort AddGadget(); Xunsigned short AddGList(); Xvoid AddHead(); Xstruct Interrupt * AddICRVector(); Xvoid AddIntServer(); Xvoid AddLibrary(); Xlong AddMemList(); Xvoid AddPort(); Xvoid AddResource(); Xvoid AddSemaphore(); Xvoid AddTail(); Xvoid AddTask(); Xvoid AddTime(); Xvoid AddVSprite(); Xlong Alert(); Xvoid * AllocAbs(); Xlong AllocBoardMem(); XcList AllocCList(); Xstruct ConfigDev * AllocConfigDev(); Xstruct MemList * AllocEntry(); Xunsigned long AllocExpansionMem(); Xvoid * AllocMem(); Xlong AllocPotBits(); Xvoid * AllocRaster(); Xchar * AllocRemember(); Xlong AllocSignal(); Xlong AllocTrap(); Xstruct WBObject * AllocWBObject(); Xvoid * Allocate(); Xvoid AlohaWorkbench(); Xvoid AndRectRegion(); Xlong AndRegionRegion(); Xvoid Animate(); Xshort AreaDraw(); Xlong AreaEllipse(); Xvoid AreaEnd(); Xshort AreaMove(); Xvoid AskFont(); Xlong AskSoftStyle(); Xlong AttemptLockLayerRom(); Xlong AttemptSemaphore(); Xshort AutoRequest(); Xlong AvailFonts(); Xlong AvailMem(); Xvoid BeginIO(); Xvoid BeginRefresh(); Xvoid BeginUpdate(); Xvoid BeginLayer(); Xlong BltBitMap(); Xlong BltBitMapRastPort(); Xvoid BltClear(); Xvoid BltMaskBitMapRastPort(); Xvoid BltPattern(); Xvoid BltTemplate(); Xstruct Window * BuildSysRequest(); Xchar * BumpRevision(); Xvoid Cause(); Xvoid CBump(); Xstruct Events * CDInputHandler(); Xvoid ChangeSprite(); Xstruct IORequest * CheckIO(); Xshort ClearDMRequest(); Xvoid ClearEOL(); Xvoid ClearMenuStrip(); Xvoid ClearPointer(); Xvoid ClearRegion(); Xlong ClearRectRegion(); Xvoid ClearScreen(); Xvoid ClipBit(); Xvoid Close(); Xvoid CloseDevice(); Xvoid CloseFont(); Xvoid CloseLibrary(); Xvoid CloseScreen(); Xvoid CloseWindow(); Xshort CloseWorkBench(); Xvoid CMove(); Xshort CmpTime(); Xlong ConcatCList(); Xlong ConfigBoard(); Xlong ConfigChain(); Xlong ConsoleDevice(); Xlong CopperListInit(); XcList CopyCList(); Xvoid CopyMem(); Xvoid CopyMemQuick(); Xvoid CopySBitMap(); Xstruct Layer * CreateBehindLayer(); XBPTR CreateDir(); Xstruct MsgPort * CreatePort(); Xstruct Process * CreateProc(); Xstruct IOStdReq * CreateStdIO(); Xstruct Task * CreateTask(); Xstruct Layer * CreateUpfrontLayer(); XBPTR CurrentDir(); Xvoid CurrentTime(); Xvoid CWait(); Xlong * DateStamp(); Xvoid Deallocate(); Xvoid Debug(); Xvoid Delay(); Xshort DeleteFile(); Xvoid DeleteLayer(); Xvoid DeletePort(); Xvoid DeleteStdIO(); Xvoid DeleteTask(); Xstruct Process * DeviceProc(); Xvoid Disable(); Xvoid DisownBlitter(); Xshort DisplayAlert(); Xvoid DisplayBeep(); Xvoid DisposeRegion(); Xvoid DoCollision(); Xlong DoIO(); Xshort DoubleClick(); Xvoid Draw(); Xvoid DrawBorder(); Xvoid DrawEllipse(); Xvoid DrawGList(); Xvoid DrawImage(); XBPTR DupLock(); Xvoid Enable(); Xvoid EndRefresh(); Xvoid EndRequest(); Xvoid EndUpdate(); Xvoid Enqueue(); Xshort ExNext(); Xshort Examine(); Xshort Execute(); Xvoid Exit(); Xstruct ConfigDev * FindConfigDev(); Xstruct Node * FindName(); Xstruct MsgPort * FindPort(); Xstruct Resident * FindResident(); Xstruct SignalSemaphore * FindSemaphore(); Xstruct Task * FindTask(); Xchar * FindToolType(); Xshort Flood(); Xvoid FlushCList(); Xvoid Forbid(); Xvoid FreeBoardMem(); Xvoid FreeCList(); Xvoid FreeColorMap(); Xvoid FreeConfigDev(); Xvoid FreeCopList(); Xvoid FreeCprList(); Xvoid FreeDiskObject(); Xvoid FreeEntry(); Xvoid FreeExpansionMem(); Xvoid FreeFreeList(); Xvoid FreeGBuffers(); Xvoid FreeMem(); Xvoid FreePotBits(); Xvoid FreeRaster(); Xvoid FreeRemember(); Xvoid FreeSignal(); Xvoid FreeSprite(); Xvoid FreeSysRequest(); Xvoid FreeTrap(); Xvoid FreeVPortCopLists(); Xvoid FreeWBObject(); Xlong GetCC(); Xlong GetCLBuf(); Xshort GetCLChar(); Xshort GetCLWord(); Xstruct ColorMap * GetColorMap(); Xlong GetCurrentBinding(); Xstruct Preferences * GetDefPrefs(); Xstruct DiskObject * GetDiskObject(); Xshort GetGBuffers(); Xlong GetIcon(); Xstruct Message * GetMsg(); Xstruct Preferences * GetPrefs(); Xshort GetRGB4(); Xlong GetScreenData(); Xshort GetSprite(); Xstruct WBObject * GetWBObject(); Xlong IncrCLMark(); Xshort Info(); Xvoid InitArea(); Xvoid InitBitMap(); Xlong InitCLPool(); Xvoid InitCode(); Xvoid InitGMasks(); Xvoid InitGels(); Xvoid InitMasks(); Xvoid InitRastPort(); Xvoid InitRequester(); Xvoid InitResident(); Xvoid InitSemaphore(); Xvoid InitStruct(); Xvoid InitTmpRas(); Xvoid InitVPort(); Xvoid InitView(); XBPTR Input(); Xvoid Insert(); Xstruct Region * InstallClipRegion(); Xlong IntuiTextLength(); Xstruct InputEvent * Intuition(); Xlong IoErr(); Xshort IsInteractive(); Xstruct MenuItem * ItemAddress(); Xvoid LoadRGB4(); Xstruct Segment * LoadSeg(); Xvoid LoadView(); XBPTR Lock(); Xvoid LockLayer(); Xvoid LockLayerInfo(); Xvoid LockLayerRom(); Xvoid LockLayers(); Xstruct DeviceNode * MakeDosNode(); Xlong MakeFunctions(); Xstruct Library * MakeLibrary(); Xvoid MakeScreen(); Xvoid MakeVPort(); Xlong MarkCList(); Xlong MatchToolValue(); Xvoid ModifyIDCMP(); Xvoid ModifyProp(); Xvoid Move(); Xlong MoveLayer(); Xvoid MoveScreen(); Xvoid MoveSprite(); Xvoid MoveWindow(); Xvoid MrgCop(); Xvoid NewList(); Xvoid NewModifyProp(); Xstruct Region * NewRegion(); Xvoid ObtainConfigBinding(); Xvoid ObtainSemaphore(); Xvoid ObtainSemaphoreList(); Xvoid OffGadget(); Xvoid OffMenu(); Xvoid OnGadget(); Xvoid OnMenu(); XBPTR Open(); Xlong OpenDevice(); Xstruct Font * OpenDiskFont(); Xstruct Font * OpenFont(); Xvoid OpenIntuition(); Xstruct Library * OpenLibrary(); Xstruct MiscResource * OpenResource(); Xstruct Screen * OpenScreen(); Xstruct Window * OpenWindow(); Xshort OpenWorkBench(); Xvoid OrRectRegion(); Xlong OrRegionRegion(); XBPTR Output(); Xvoid OwnBlitter(); XBPTR ParentDir(); Xshort PeekCLMark(); Xvoid Permit(); Xvoid PolyDraw(); Xvoid PrintIText(); Xlong PutCLBuf(); Xlong PutCLChar(); Xlong PutCLWord(); Xshort PutDiskObject(); Xlong PutIcon(); Xvoid PutMsg(); Xlong PutWBObject(); Xvoid QBSBlit(); Xvoid QBlit(); Xshort RawKeyConvert(); Xlong Read(); Xchar ReadExpansionByte(); Xlong ReadExpansionRom(); Xshort ReadPixel(); Xvoid RectFill(); Xvoid RefreshGadgets(); Xvoid RefreshGList(); Xvoid RefreshWindowFrame(); Xvoid ReleaseConfigBinding(); Xvoid ReleaseSemaphore(); Xvoid ReleaseSemaphoreList(); Xvoid RemConfigDev(); Xlong RemDevice(); Xvoid RemFont(); Xstruct Node * RemHead(); Xvoid RemIBob(); Xvoid RemICRVector(); Xvoid RemIntServer(); Xlong RemLibrary(); Xunsigned short RemoveGList(); Xvoid RemPort(); Xvoid RemResource(); Xvoid RemSemaphore(); Xstruct Node * RemTail(); Xvoid RemTask(); Xvoid RemVSprite(); Xvoid RemakeDisplay(); Xvoid Remove(); Xunsigned short RemoveGadget(); Xshort Rename(); Xvoid ReplyMsg(); Xvoid ReportMouse(); Xshort Request(); Xvoid RethinkDisplay(); Xvoid ScreenToBack(); Xvoid ScreenToFront(); Xvoid ScrollLayer(); Xvoid ScrollRaster(); Xvoid ScrollVPort(); Xlong Seek(); Xvoid SendIO(); Xvoid SetAPen(); Xvoid SetBPen(); Xvoid SetCollision(); Xshort SetComment(); Xvoid SetCurrentBinding(); Xshort SetDMRequest(); Xvoid SetDRMd(); Xlong SetExcept(); Xlong SetFont(); Xlong SetFunction(); Xlong SetICR(); Xstruct Interrupt * SetIntVector(); Xshort SetMenuStrip(); Xvoid SetPointer(); Xstruct Preferences * SetPrefs(); Xshort SetProtection(); Xvoid SetRast(); Xvoid SetRGB4(); Xvoid SetRGB4CM(); Xlong SetSR(); Xlong SetSignal(); Xlong SetSoftStyle(); Xshort SetTaskPri(); Xvoid SetWindowTitles(); Xvoid ShowTitle(); Xvoid Signal(); Xlong SizeCList(); Xshort SizeLayer(); Xvoid SizeWindow(); Xvoid SortGList(); XcList SplitCList(); XcList SubCList(); Xvoid SubTime(); Xvoid SubLibrary(); Xvoid SumKickData(); Xlong SuperState(); Xvoid SwapBitsRastPortClipRect(); Xvoid SyncSBitMap(); Xlong Text(); Xlong TextLength(); Xlong Translate(); Xlong UnGetCLChar(); Xlong UnGetCLWord(); Xvoid UnLoadSeg(); Xvoid UnLock(); Xshort UnPutCLChar(); Xshort UnPutCLWord(); Xvoid UnlockLayer(); Xvoid UnlockLayerInfo(); Xvoid UnlockLayerRom(); Xvoid UnlockLayers(); Xshort UpfrontLayer(); Xvoid UserState(); Xshort VBeamPos(); Xstruct View * ViewAddress(); Xstruct ViewPort * ViewPortAddress(); Xshort WBenchToBack(); Xshort WBenchToFront(); Xlong Wait(); Xvoid WaitBOVP(); Xvoid WaitBlit(); Xshort WaitForChar(); Xlong WaitIO(); Xstruct Message * WaitPort(); Xvoid WaitTOF(); Xstruct Layer * WhichLayer(); Xshort WindowLimits(); Xvoid WindowToBack(); Xvoid WindowToFront(); Xlong Write(); Xlong WriteExpansionByte(); Xvoid WritePixel(); Xvoid WritePotgo(); Xvoid XorRectRegion(); Xlong XorRegionRegion(); SHAR_EOF echo "extracting sub.c" sed 's/^X//' << \SHAR_EOF > sub.c X X/* X * SUB.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_lasterr, *v_stat; X X#define HM_STR 0 /* various HISTORY retrieval modes */ X#define HM_REL 1 X#define HM_ABS 2 X X/* extern BPTR Clock; */ X Xseterr() X{ Xchar buf[32]; Xint stat; X Xsprintf(buf, "%d", Lastresult); Xset_var(LEVEL_SET, v_lasterr, buf); Xstat = atoi(get_var(LEVEL_SET, v_stat)); Xif (stat < Lastresult) stat = Lastresult; Xsprintf(buf, "%d", stat); Xset_var(LEVEL_SET, v_stat, buf); X} X X Xchar * Xnext_word(str) Xregister char *str; X{ X while (*str && *str != ' ' && *str != 9 && (unsigned char)*str != 0xA0) X ++str; X while (*str && (*str == ' ' || *str == 9 || (unsigned char)*str == 0xA0)) X ++str; X return (str); X} X Xchar * Xcompile_av(av, start, end, delim) Xchar **av; Xunsigned char delim; X{ Xchar *cstr; Xint len; Xregister unsigned int i; X Xlen = 0; Xfor (i = start; i < end; ++i) len += strlen(av[i]) + 1; Xcstr = malloc(len + 1); X*cstr = '\0'; Xfor (i = start; i < end; ++i) { X if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]); X strcat (cstr, av[i]); X if (i + 1 < end) strncat(cstr, &delim, 1); X } Xreturn (cstr); X} X X X/* X * FREE(ptr) --frees without actually freeing, so the data is still good X * immediately after the free. X */ X X XFree(ptr) Xchar *ptr; X{ X static char *old_ptr; X X if (old_ptr) X free (old_ptr); X old_ptr = ptr; X} X X/* X * Add new string to history (H_head, H_tail, H_len, X * S_histlen X */ X Xadd_history(str) Xchar *str; X{ X register struct HIST *hist; X X if (H_head != NULL && strcmp(H_head->line, str) == 0) X return(0); X while (H_len > S_histlen) X del_history(); X hist = (struct HIST *)malloc (sizeof(struct HIST)); X if (H_head == NULL) { X H_head = H_tail = hist; X hist->next = NULL; X } else { X hist->next = H_head; X H_head->prev = hist; X H_head = hist; X } X hist->prev = NULL; X hist->line = malloc (strlen(str) + 1); X strcpy (hist->line, str); X ++H_len; X} X Xdel_history() X{ X if (H_tail) { X --H_len; X ++H_tail_base; X free (H_tail->line); X if (H_tail->prev) { X H_tail = H_tail->prev; X free (H_tail->next); X H_tail->next = NULL; X } else { X free (H_tail); X H_tail = H_head = NULL; X } X } X} X Xchar * Xget_history(ptr) Xchar *ptr; X{ X register struct HIST *hist; X register int len; X int mode = HM_REL; X int num = 1; X char *str; X char *result = NULL; X X if (ptr[1] >= '0' && ptr[1] <= '9') { X mode = HM_ABS; X num = atoi(&ptr[1]); X goto skip; X } X switch (ptr[1]) { X case '!': X break; X case '-': X num += atoi(&ptr[2]); X break; X default: X mode = HM_STR; X str = ptr + 1; X break; X } Xskip: X switch (mode) { X case HM_STR: X len = strlen(str); X for (hist = H_head; hist; hist = hist->next) { X if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') { X result = hist->line; X break; X } X } X break; X case HM_REL: X for (hist = H_head; hist && num--; hist = hist->next); X if (hist) X result = hist->line; X break; X case HM_ABS: X len = H_tail_base; X for (hist = H_tail; hist && len != num; hist = hist->prev, ++len); X if (hist) X result = hist->line; X break; X } X if (result) { X fprintf(stderr,"%s\n",result); X return(result); X } X printf("History failed\n"); X return (""); X} X Xreplace_head(str) Xchar *str; X{ X if (str == NULL) X str = ""; X if (H_head) { X free (H_head->line); X H_head->line = malloc (strlen(str)+1); X strcpy (H_head->line, str); X } X} X X XpError(str) Xchar *str; X{ X int ierr = (long)IoErr(); X ierror(str, ierr); X} X Xierror(str, err) Xregister char *str; X{ X register struct PERROR *per = Perror; X X if (err) { X for (; per->errstr; ++per) { X if (per->errnum == err) { X fprintf (stderr, "%s%s%s\n", X per->errstr, X (str) ? ": " : "", X (str) ? str : ""); X return ((short)err); X } X } X fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : ""); X } X return ((short)err); X} X X/* X * Disk directory routines X * X * dptr = dopen(name, stat) X * struct DPTR *dptr; X * char *name; X * int *stat; X * X * dnext(dptr, name, stat) X * struct DPTR *dptr; X * char **name; X * int *stat; X * X * dclose(dptr) -may be called with NULL without harm X * X * dopen() returns a struct DPTR, or NULL if the given file does not X * exist. stat will be set to 1 if the file is a directory. If the X * name is "", then the current directory is openned. X * X * dnext() returns 1 until there are no more entries. The **name and X * *stat are set. *stat = 1 if the file is a directory. X * X * dclose() closes a directory channel. X * X */ X Xstruct DPTR * Xdopen(name, stat) Xchar *name; Xint *stat; X{ X struct DPTR *dp; X X *stat = 0; X dp = (struct DPTR *)malloc(sizeof(struct DPTR)); X if (*name == '\0') X dp->lock = DupLock(Myprocess->pr_CurrentDir); X else X dp->lock = Lock (name,ACCESS_READ); X if (dp->lock == NULL) { X free (dp); X return (NULL); X } X dp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC); X if (!Examine (dp->lock, dp->fib)) { X pError (name); X dclose (dp); X return (NULL); X } X if (dp->fib->fib_DirEntryType >= 0) X *stat = 1; X return (dp); X} X Xdnext(dp, pname, stat) Xstruct DPTR *dp; Xchar **pname; Xint *stat; X{ X if (dp == NULL) X return (0); X if (ExNext (dp->lock, dp->fib)) { X *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1; X *pname = dp->fib->fib_FileName; X return (1); X } X return (0); X} X X Xdclose(dp) Xstruct DPTR *dp; X{ X if (dp == NULL) X return (1); X if (dp->fib) X FreeMem (dp->fib,(long)sizeof(*dp->fib)); X if (dp->lock) X UnLock (dp->lock); X free (dp); X return (1); X} X X Xisdir(file) Xchar *file; X{ X register struct DPTR *dp; X int stat; X X stat = 0; X if (dp = dopen (file, &stat)) X dclose(dp); X return (stat == 1); X} X X Xfree_expand(av) Xregister char **av; X{ X char **base = av; X X if (av) { X while (*av) { X free (*av); X ++av; X } X free (base); X } X} X X/* X * EXPAND(base,pac) X * base - char * (example: "df0:*.c") X * pac - int * will be set to # of arguments. X * X * 22-May-87 SJD. Heavily modified to allow recursive wild carding and X * simple directory/file lookups. Returns a pointer to X * an array of pointers that contains the full file spec X * eg. 'df0:c/sear*' would result in : 'df0:C/Search' X * X * Now no longer necessary to Examine the files a second time X * in do_dir since expand will return the full file info X * appended to the file name. Set by formatfile(). X * eg. fullfilename'\0'rwed NNNNNN NNNN DD-MMM-YY HH:MM:SS X * X * Caller must call free_expand when done with the array. X * X * base bname = ename = X * ------ ------- ------- X * "*" "" "*" X * "!*.info" "" "*.info" (wild_exclude set) X * "su*d/*" "" "*" (tail set) X * "file.*" "" "file.*" X * "df0:c/*" "df0:c" "*" X * "" "" "*" X * "df0:.../*" "df0:" "*" (recur set) X * "df0:sub/.../*" "df0:sub" "*" (recur set) X * X * ---the above base would be provided by execom.c or do_dir(). X * ---the below base would only be called from do_dir(). X * X * "file.c" "file.c" "" if (dp == 0) fail else get file.c X * "df0:" "df0:" "*" X * "file/file" "file/file" "" (dp == 0) so fail X * "df0:.../" "df0:" "*" (recur set) X * X */ X X Xchar ** Xexpand(base, pac) Xchar *base; Xint *pac; X{ X register char *ptr; X char **eav = (char **)malloc(sizeof(char *) * (2)); X short eleft, eac; X char *name; X char *svfile(); X char *bname, *ename, *tail; X int stat, recur, scr, bl; X register struct DPTR *dp; X X *pac = recur = eleft = eac = 0; X X base = strcpy(malloc(strlen(base)+1), base); X for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr); X X if (!*ptr) /* no wild cards */ X --ptr; X else X for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr); X X if (ptr < base) { X bname = strcpy (malloc(1), ""); X } else { X scr = ptr[1]; X ptr[1] = '\0'; X if (!strcmp(ptr-3,".../")) { X recur = 1; X *(ptr-3) = '\0'; X } X bname = strcpy (malloc(strlen(base)+2), base); X ptr[1] = scr; X } X bl = strlen(bname); X ename = ++ptr; X for (; *ptr && *ptr != '/'; ++ptr); X scr = *ptr; X *ptr = '\0'; X if (scr) ++ptr; X tail = ptr; X X if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) { X free (bname); X free (base); X free (eav); X return (NULL); X } X X if (!stat) { /* eg. 'dir file' */ X char *p,*s; X for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p; X if (s != bname) ++s; X *s ='\0'; X eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib); X goto done; X } X if (!*ename) ename = "*"; /* eg. dir df0: */ X if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */ X bname[bl] = '/'; X bname[++bl] = '\0'; X } X while ((dnext (dp, &name, &stat)) && !breakcheck()) { X int match = compare_ok(ename,name); X if (match && !(!recur && *tail)) { X if (eleft < 2) { X char **scrav = (char **)malloc(sizeof(char *) * (eac + 10)); X movmem (eav, scrav, (eac + 1) << 2); X free (eav); X eav = scrav; X eleft = 10; X } X eav[eac++] = svfile(bname,name,dp->fib); X --eleft; X } X if ((*tail && match) || recur) { X int alt_ac; X char *search, **alt_av, **scrav; X BPTR lock; X X if (!stat) /* expect more dirs, but this not a dir */ X continue; X lock = CurrentDir (dp->lock); X search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5); X strcpy (search, name); X strcat (search, "/"); X if (recur) { X strcat(search, ".../"); X strcat(search, ename); X } X strcat (search, tail); X scrav = alt_av = expand (search, &alt_ac); X /* free(search); */ X CurrentDir (lock); X if (scrav) { X while (*scrav) { X int l; X if (eleft < 2) { X char **scrav = (char **)malloc(sizeof(char *) * (eac + 10)); X movmem (eav, scrav, (eac + 1) << 2); X free (eav); X eav = scrav; X eleft = 10; X } X X l = strlen(*scrav); X scrav[0][l] = ' '; X eav[eac] = malloc(bl+l+45); X strcpy(eav[eac], bname); X strcat(eav[eac], *scrav); X eav[eac][l+bl] = '\0'; X X free (*scrav); X ++scrav; X --eleft, ++eac; X } X free (alt_av); X } X } X } Xdone: X dclose (dp); X *pac = eac; X eav[eac] = NULL; X free (bname); X free (base); X if (eac) { X return (eav); X } X free (eav); X return (NULL); X} X X/* X * Compare a wild card name with a normal name X */ X X#define MAXB 8 X Xcompare_ok(wild, name) Xchar *wild, *name; X{ Xregister char *w = wild; Xregister char *n = name; Xchar *back0[MAXB], *back1[MAXB]; Xint bi=0, queryflag; X Xif (*w=='!') return !compare_ok(wild+1,name); Xif (queryflag=(*w=='&')) w++; Xwhile (*n || *w) { X switch (*w) { X case '*': X if (bi==MAXB) { printf(stderr,"Too many levels of '*'\n"); return 0; } X back0[bi] = w; X back1[bi] = n; X ++bi; X ++w; X continue; Xgoback: X --bi; X while (bi >= 0 && *back1[bi] == '\0') --bi; X if (bi < 0) return 0; X w = back0[bi] + 1; X n = ++back1[bi]; X ++bi; X continue; X case '?': X if (!*n) goto goback; X break; X default: X if (Toupper(*n)!=Toupper(*w)) goto goback; X break; X } X if (*n) ++n; X if (*w) ++w; X } Xif (queryflag) { X char in[256]; X printf("Select \23337m%-16s\2330m [y/n] ? ",name); X gets(in); X return (Toupper(*in)=='Y'); X } Xreturn 1; X} X Xchar *svfile(s1,s2,fib) Xchar *s1,*s2; XFIB *fib; X{ Xchar *p = malloc (strlen(s1)+strlen(s2)+45); Xstrcpy(p, s1); Xstrcat(p, s2); Xformatfile(p,fib); Xreturn p; X} X X/* will have either of these formats: X * X * fullfilename'\0'hsparwed <Dir> DD-MMM-YY HH:MM:SS\n'\0' X * fullfilename'\0'hsparwed NNNNNN NNNN DD-MMM-YY HH:MM:SS\n'\0' X * 1111111111222222222233333333334 4 4 X * 01234567890123456789012345678901234567890 1 2 X */ Xformatfile(str,fib) Xchar *str; XFIB *fib; X{ Xchar *dates(); Xint i; Xwhile(*str++); Xfor (i=7; i>=0; i--) X *str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i]; Xif (fib->fib_DirEntryType < 0) X sprintf(str," %6ld %4ld ", (long)fib->fib_Size, (long)fib->fib_NumBlocks); Xelse strcpy(str," <Dir> "); Xstrcat(str,dates(&fib->fib_Date)); X} X X/* Sort routines */ X Xlong cmp(s1, s2) Xchar **s1, **s2; X{ Xreturn (long)Strcmp(*s1, *s2); X} X XCmp() { X#asm X public _geta4 X movem.l d2-d3/a4/a6,-(sp) X movem.l a0/a1,-(sp) X bsr _geta4 X bsr _cmp X addq.l #8,sp X movem.l (sp)+,d2-d3/a4/a6 X#endasm X} X XQuickSort(av, n) Xchar *av[]; Xint n; X{ XQSort(av, (long)n, 4L, Cmp); X} SHAR_EOF echo "End of archive 2 (of 2)" # if you want to concatenate archives, remove anything after this line exit