amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (03/04/91)
Submitted-by: <umueller@iiic.ethz.ch> Posting-number: Volume 91, Issue 030 Archive-name: shells/cshell-5.00/part04 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 6)." # Contents: comm1.c execom.c # Wrapped by tadguy@ab20 on Sun Mar 3 16:56:00 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'comm1.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'comm1.c'\" else echo shar: Extracting \"'comm1.c'\" \(30286 characters\) sed "s/^X//" >'comm1.c' <<'END_OF_FILE' X/* X * COMM1.C X * X * Matthew Dillon, August 1986 X * X * Version 2.07M by Steve Drew 10-Sep-87 X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90 X * Version 5.00L by Urban Mueller 17-Feb-91 X * X */ X X#include "shell.h" X X/* comm1.c */ Xstatic void display_file(char *filestr); Xstatic char *myfgets(char *buf, int buflen, struct __stdio *file); Xstatic int search_file(char *s); Xstatic int quicksearch(char *name, int nocasedep, char *pattern); Xstatic int rm_file(char *file); Xstatic void setsystemtime(struct DateStamp *ds); Xstatic int found( char *lstart, int lnum, int loffs, char *name, char left ); Xstatic void recurse(char *name, int (*action)(char *)); Xstatic void recurse2( char *name, void (*action)(FIB *)); X Xextern int has_wild; X Xint Xdo_sleep( void ) X{ X int i; X X if (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i--) Delay(50); X return 0; X} X Xint Xdo_protect( void ) X{ X static char flags[]="DEWRAPSH"; X char *s, *p; X long setmask=0, clrmask=0xFF, mask; X int i, mode=0, stat; X struct DPTR *dp; X X for (s=strupr(av[--ac]); *s; s++) { X if (*s=='=') { mode=0; continue; } X if (*s=='+') { mode=1; clrmask=FIBF_ARCHIVE; continue; } X if (*s=='-') { mode=2; clrmask=FIBF_ARCHIVE; continue; } X X if (p=index(flags, *s)) { X if( mode==0 ) setmask|= 1<<(p-flags), clrmask=0xFF; X if( mode==1 ) setmask|= 1<<(p-flags); X if( mode==2 ) clrmask|= 1<<(p-flags); X } else X ierror(av[ac],500); X } X X for (i=1; i<ac; i++) { X if( (dp=dopen(av[i],&stat))) { X mask = dp->fib->fib_Protection ^ 0x0F; X mask&=~clrmask; X mask|= setmask; X dclose(dp); X if( !SetProtection( av[i], mask ^ 0x0F)) X pError(av[i]); X } else X pError(av[i]); X } X return 0; X} X Xint Xdo_filenote( void ) X{ X struct DPTR *dp; X char *note; X int i, stat; X X if( options&1 ) { X for( i=1; i<ac && !dobreak(); i++ ) X if( dp=dopen( av[i], &stat )) { X printf( "%-12s %s\n", av[i],dp->fib->fib_Comment ); X dclose( dp ); X } X } else { X note=av[--ac]; X for (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]); X } X return 0; X} X Xint Xdo_cat( void ) X{ X FILE *fi; X int lctr, i; X char buf[256]; X X prepscroll(0); X if (ac<=1) { X if (has_wild) { printf("No files matching\n"); return 20; } X lctr=0; X while (fgets(buf,256,stdin) && X !dobreak()) { X if (options) printf("%4d ",++lctr); X quickscroll(); X fputs(buf,stdout); X } X } else { X for (i=1; i<ac; i++) X if (fi = fopen (av[i], "r")) { X lctr=0; X while (fgets(buf,256,fi) && !dobreak()) { X if (options&1) printf("%4d ",++lctr); X quickscroll(); X printf("%s",buf); X } X fclose (fi); X } else X pError(av[i]); X } X return 0; X} X X Xvoid Xget_drives(char *buf) X{ X struct DirectoryEntry *de_head=NULL, *de; X X buf[0]=0; X AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY ); X for(de=de_head; de; de=de->de_Next) { X if( buf[0] ) X strcat( buf, "\240" ); X strcat( buf, de->de_Name ); X } X FreeDAList(de_head); X} X Xstatic char infobuf[100]; Xstatic char namebuf[12]; X Xchar * Xdrive_name( char *name ) X{ X struct DirectoryEntry *de_head=NULL, *de; X struct MsgPort *proc=DeviceProc( name ); X X strcpy( namebuf, name ); X AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY ); X for(de=de_head; de; de=de->de_Next) X if( DeviceProc( de->de_Name) == proc ) X strcpy( namebuf, de->de_Name ); X FreeDAList(de_head); X X return namebuf; X} X Xint Xdo_info( void ) X{ X struct DirectoryEntry *de_head=NULL, *de; X int i; X X puts("Unit Size Bytes Used Blk/Byt-Free Full Errs Status Name"); X Myprocess->pr_WindowPtr = (APTR)(-1); X X if( ac==1 ) { X AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY ); X for(de=de_head; de; de=de->de_Next) X oneinfo( de->de_Name, 0); X FreeDAList(de_head); X } else { X for( i=1; i<ac; i++ ) X oneinfo( drive_name( av[i] ), 0 ); X } X X Myprocess->pr_WindowPtr = (APTR) o_noreq; X return 0; X} X Xchar * Xoneinfo( char *name, int mode ) X{ X BPTR lock; X struct InfoData *info; X long size, free, freebl, blocks; X char *p, buf[130], *state=" "; X char *fmt="%s\240%s\240%d\240%d\240%d\240%s\240%d%%\240%d\240%s\240%s"; X X infobuf[0]=0; X if( !name ) name=""; X strcpy(infobuf,"0"); X info=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC); X if (lock=Lock(name,ACCESS_READ)) { X if (Info(lock, info)) { X PathName(lock, buf, 128L); X if (p=index(buf,':')) *p = '\0'; X size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock); X freebl= (info->id_NumBlocks-info->id_NumBlocksUsed); X free = freebl * info->id_BytesPerBlock; 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 blocks=info->id_NumBlocks; X if( mode==0 ) fmt="%-7s%5s%6d%7d%7d %5s%4d%%%4d %s %s\n"; X sprintf(infobuf,fmt, X name, X itok( size ), X info->id_BytesPerBlock, X info->id_NumBlocksUsed, X freebl, X itok( free ), X (blocks) ? (info->id_NumBlocksUsed * 100)/blocks : 0, X info->id_NumSoftErrors, X state, X buf); X if( mode==2 ) sprintf( infobuf, "%d", free ); X if( mode==3 ) sprintf( infobuf, "%d", freebl ); X if( mode==4 ) sprintf( infobuf, "%s", itok( free )); X if( mode==5 ) sprintf( infobuf, "%s:", buf ); X } else X pError (name); X UnLock(lock); X } else { X if ( mode==1 ) sprintf( infobuf, "%s\240No disk present", name ); X else if( mode==0 ) sprintf( infobuf, "%-7s No disk present\n",name); X else if( mode==5 ) sprintf( infobuf, "" ); X else sprintf( infobuf, "0" ); X } X if( mode==0 ) printf( "%s",infobuf); X FreeMem(info,sizeof(struct InfoData)); X return infobuf; X} X X X/* things shared with display_file */ X X#define DIR_SHORT 0x1 X#define DIR_FILES 0x2 X#define DIR_DIRS 0x4 X#define DIR_NOCOL 0x8 X#define DIR_NAMES 0x10 X#define DIR_HIDE 0x20 X#define DIR_LEN 0x40 X#define DIR_TIME 0x80 X#define DIR_BACK 0x100 X#define DIR_UNIQ 0x200 X#define DIR_IDENT 0x400 X#define DIR_CLASS 0x800 X#define DIR_QUIET 0x1000 X#define DIR_AGE 0x2000 X#define DIR_VIEW 0x4000 X#define DIR_NOTE 0x8000 X Xstatic BPTR lastlock; Xstatic int filecount, col, wwidth; Xstatic long bytes, blocks; X X/* the args passed to do_dir will never be expanded */ X Xextern expand_err; Xextern int w_width; X X Xstatic struct DateStamp Stamp; X Xint Xdo_dir( void ) X{ X int i=1, c, eac, reverse, nump=ac, retcode=0; X char **eav, **av1, **av2, inter=interactive(); X int (*func)(), ac1, ac2; X X if( options&DIR_CLASS ) options|=DIR_IDENT; X if( ac == i) ++nump, av[i]=""; X if( !(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS); X if( options&DIR_UNIQ) { X if( ac-i!=2 ) { show_usage(NULL); return 20; } X i=0, nump=3; X } X X if( options&DIR_AGE ) X DateStamp( &Stamp ); X X col = filecount = bytes = blocks = 0L; X lastlock=NULL; X X wwidth=77; X if( inter ) printf( "\033[?7l" ), wwidth=w_width; /* end of line wrap off */ X X prepscroll(0); X for( ; i<nump && !CHECKBREAK(); ++i ) { X if( options&DIR_UNIQ ) { X switch( i ) { X case 0: av1=expand( av[ac-2], &ac1 ); X av2=expand( av[ac-1], &ac2 ); X eav=without( av1, ac1, av2, ac2, &eac, 1 ); X break; X case 1: printf("\nCommon files\n"); X eav=and( av1, ac1, av2, ac2, &eac, 1 ); X break; X case 2: printf("\n"); X eav=without( av2, ac2, av1, ac1, &eac, 1 ); X break; X } X col = filecount = bytes = blocks = 0L; X lastlock=NULL; X } else if (!(eav = expand(av[i], &eac)) && expand_err) { X pError(av[i]); X retcode=5; X continue; X } X X reverse= ( options&DIR_BACK ) ? 1 : 0; X func=cmp; X if( options & DIR_TIME) func=datecmp; X if( options & DIR_LEN ) func=sizecmp; X if( options & DIR_CLASS)func=classcmp; X DirQuickSort(eav, eac, func, reverse); X for(c=0; c<eac && !CHECKBREAK(); ++c) { X if( options & DIR_HIDE ) { X char *b=BaseName(eav[c]); X int l=strlen(b)-5; X struct file_info *info = X (struct file_info *)(eav[c]-sizeof(struct file_info)); X if(*b=='.'|| (l>=0 && !strcmp(b+l,".info"))||(info->flags&128)) X continue; X } X if (options & DIR_NAMES) X puts(eav[c]); X else X display_file(eav[c]); X } X X if (col) { quickscroll(); printf("\n"); col=0; } X if (options&DIR_UNIQ || (filecount>1 && i==nump-1)) { X blocks += filecount; /* account for dir blocks */ X quickscroll(); X printf(" %ld Blocks, %s Bytes used in %d files\n", X blocks, itoa(bytes), filecount); X } X if( options&DIR_UNIQ ) X free(eav); X else X free_expand (eav); X if (lastlock) UnLock(lastlock), lastlock=0; X } X if (lastlock) UnLock(lastlock), lastlock=0; X X if( options&DIR_UNIQ ) X free_expand( av1 ), free_expand( av2 ); X X if( inter ) printf( "\033[?7h" ); /* end of line wrap off */ X X return retcode; X} X X Xstatic void Xdisplay_file( char *filestr ) X{ X int isadir,slen; X char sc, *base, buf[130]; X struct file_info *info; X BPTR thislock; X X base=BaseName(filestr); X sc = *base; X *base = '\0'; X thislock=Lock(filestr,SHARED_LOCK); X /* if (thislock==NULL) return; */ X if (lastlock==NULL || CompareLock(thislock,lastlock)) { X /* struct InfoData *id=AllocMem( sizeof(struct InfoData), 0); */ X if (col) { quickscroll(); printf("\n"); col=0; } X quickscroll(); X PathName(thislock, buf, 128L); X /* Info( thislock, id ); */ X printf("Directory of %s\n", buf ); X /*itok((id->id_NumBlocks-id->id_NumBlocksUsed)*id->id_BytesPerBlock));*/ X /* FreeMem( id, sizeof(struct InfoData)); */ X if (lastlock) UnLock(lastlock); X lastlock=thislock; X } else X UnLock(thislock); X X *base = sc; X if((slen = strlen(base)+1) & 1 ) ++slen; X info = (struct file_info *)(filestr - sizeof(struct file_info)); X isadir = info->size<0; X X if (!(((options & DIR_FILES) && !isadir) || X ((options & DIR_DIRS) && isadir))) X return; X if (isadir && !(options & DIR_NOCOL)) printf (o_hilite); X if (options & DIR_SHORT) { X slen= (slen>18) ? 37 : 18; X if (col && col+slen>=wwidth ) X { quickscroll(); printf("\n"); col = 0; } X printf(" %-*s",slen,base); X col+= ++slen; X } else { X quickscroll(); X printf(" %-24s %s \n",base,formatfile(info)); X } X if (isadir && !(options & DIR_NOCOL)) X printf(o_lolite); X if(info->size>0) X bytes += info->size; X blocks += info->blocks; X filecount++; 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 NNNNNNN NNNN DD-MMM-YY HH:MM:SS\n'\0' X * 1111111111222222222233333333334 4 4 X * 01234567890123456789012345678901234567890 1 2 X */ X Xstatic char linebuf[140]; Xstatic long dlen, dblocks; X Xstatic void Xcount( FIB *fib ) X{ X dlen+=fib->fib_Size; X dblocks+=fib->fib_NumBlocks+1; X} X Xchar * Xformatfile( struct file_info *info) X{ X char *str=linebuf, *class, *t; X int i, stat; X X if( options & DIR_NOTE ) { X struct DPTR *dp; X if( dp=dopen( (char *)(info+1), &stat )) { X strcpy( str, dp->fib->fib_Comment ); X dclose( dp ); X } X return linebuf; X } X X *str++= info->flags & 1<<30 ? 'c' : '-'; X for (i=7; i>=0; i--) X *str++ = ((info->flags & (1L<<i)) ? "hspa----" : "----rwed")[7-i]; X if (info->size >= 0) X sprintf(str,options&DIR_QUIET?" %7ld ":" %7ld %4ld ", X info->size, info->blocks); X else X strcpy(str,options&DIR_QUIET?" <Dir> ":" <Dir> "); X str+=strlen(str); X if( options&DIR_VIEW && info->size<0 ) { X dlen=dblocks=0; X recurse2( (char *)(info+1),count); X sprintf( str, "%10s",itoa(dlen)); X info->size=dlen; info->blocks=dblocks; X } else if( options&DIR_IDENT ) { X if( *info->class!=1 ) X strcpy(str,info->class); X else if( class=getclass((char *)(info+1))) X if( t=index(strncpy(str,class,40),0xA0) ) X *t=0; X } else if( options&DIR_AGE) { X long mins=0; X if( Stamp.ds_Days!=0 ) { X mins =Stamp.ds_Days*1440 + Stamp.ds_Minute; X mins-=info->date.ds_Days*1440 + info->date.ds_Minute; X } X if( mins>=0 ) X sprintf(str,"%4d %02d:%02d",mins/1440,mins/60%60,mins%40); X else X sprintf(str,"Future"); X } else if( !(options&DIR_VIEW) ) X strcat(str,dates(&info->date)); X return linebuf; X} X X Xint Xdo_quit( void ) X{ X if (Src_stack) { X Quit = 1; X return(do_return()); X } X main_exit(0); X return 0; X} X Xint Xdo_echo( void ) X{ X char *args=compile_av(av,1,ac,' ',0); X fprintf( (options&2)?stderr:stdout, (options&1)?"%s":"%s\n",args ); X free(args); X return 0; X} X X Xstatic int Xbreakcheckd(void) X{ X int ret=!o_nobreak && SetSignal(0L,0L) & SIGBREAKF_CTRL_D; X SetSignal(0L, SIGBREAKF_CTRL_D); X if( ret ) X fprintf(stderr,"^D\n"); X return ret; X} X X/* gets a line from file, joining two lines if the first ends in '\' */ X Xstatic char * Xmyfgets(char *buf, int buflen, FILE *file) X{ X char *bufptr=buf, *limit=buf+buflen; X X do { X if (fgets(bufptr, limit-bufptr, file)==NULL) { X if (bufptr != buf) X fprintf(stderr,"Source: file ends in '\\'\n"); X return NULL; X } X bufptr = bufptr+strlen(bufptr)-2; X } while (*bufptr=='\\'); X return buf; X} X Xint Xdo_source( char *str ) X{ X FILE *fi; X char *buf; X int len; X X if (Src_stack == MAXSRC) { X ierror(NULL,217); X return -1; X } X if ((fi = fopen (av[1], "r")) == 0) X { pError(av[1]); return -1; } X buf=malloc(512); X set_var(LEVEL_SET, v_passed, next_word(next_word(str))); X ++H_stack; X Src_pos[Src_stack] = 0; X Src_base[Src_stack] = fi; X Src_if[Src_stack]=If_stack; X ++Src_stack; X while (myfgets (buf, 512, fi) && !dobreak() && !breakcheckd()) { X len = strlen(buf); X if(buf[len-1]=='\n') 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; X if( If_stack>Src_if[Src_stack] ) X If_stack=Src_if[Src_stack], disable=If_stack && If_base[If_stack-1]; X X if (forward_goto) ierror(NULL,501); X forward_goto = 0; X unset_level(LEVEL_SOURCE + Src_stack); X unset_var(LEVEL_SET, v_gotofwd); X unset_var(LEVEL_SET, v_passed); X free(buf); X fclose (fi); X return 0; X} X X/* set process cwd name and $_cwd, if str != NULL also print it. */ X Xint Xdo_pwd( char *str ) X{ X char pwd[130]; X X PathName(Myprocess->pr_CurrentDir, pwd, 128L); X if (str) puts(pwd); X set_var(LEVEL_SET, v_cwd, pwd); X /* put the current dir name in our CLI task structure */ X CtoBStr(pwd, Mycli->cli_SetName, 128L); X return 0; X} X X/* X * CD X * X * CD(str, 0) -do CD operation. X * X */ X Xextern int qcd_flag; X Xstatic char lastqcd[80]; Xstatic lastoffs; X Xint Xdo_cd( char *str ) X{ X BPTR oldlock, filelock; X FILE *file; X char buf[100], *old; X int i=1, repeat; X X if( options & 1 ) { X if( !(file=fopen( o_csh_qcd, "w" ))) X { fprintf(stderr,"Can't open output\n"); return 20; } X for( ; i<ac && !breakcheck(); i++ ) { X fprintf(file,"%s\n",av[i]); X strcpy(buf,av[i]); X appendslash( buf ); X expand_all( buf, file ); X } X fclose(file); X return 0; X } X X str= ( has_wild && ac>=2 ) ? av[1] : next_word(str); X if (!strcmp("..",str)) str="/"; X X if( !*str ) { X printf("%s\n", get_var( LEVEL_SET, v_cwd )); X return 0; X } X X if (filelock=Lock(str,ACCESS_READ)) { X lastqcd[0]=0; X if (!isdir(str)) { UnLock(filelock); ierror(str,212); return 20; } X } else { X repeat= !strncmp( lastqcd, str, 79 ); X strncpy( lastqcd, str, 79); X X if( !quick_cd( buf, av[i], repeat) ) X { fprintf(stderr,"Object not found %s\n",str); return 20; } X if (!(filelock=Lock(buf,ACCESS_READ))) X { pError(buf); return 20; } X } X if (oldlock=CurrentDir(filelock)) UnLock(oldlock); X if( !(old=get_var(LEVEL_SET, v_cwd)) ) X old=""; X set_var(LEVEL_SET, v_lcd, old); X do_pwd(NULL); X X return 0; X} X Xchar * Xquick_cd( char *buf, char *name, int repeat ) X{ X qcd_flag=repeat ? 2 : 1; X strcpy(buf,name); X if( quicksearch( o_csh_qcd, 1, buf)!=2 ) X return NULL; X return buf; X} X X Xint Xdo_mkdir( void ) X{ X int i; X BPTR lock; X X for (i=1; i<ac; ++i) { X if (exists(av[i])) X ierror(av[i],203); X else if (lock=CreateDir(av[i])) X UnLock (lock); X else X pError(av[i]); X } X return 0; X} X Xint Xdo_mv( void ) X{ X char *dest, buf[256]; X int dirflag, i; X X dirflag=isdir(dest=av[--ac]); X if (ac>3 && !dirflag) { ierror(dest, 507); return (-1); } X for (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 else X clear_archive_bit( buf ); X } X return 0; X} X Xstatic int dirstoo; X Xint Xall_args( int (*action)(char *str), int dirsflag ) X{ X int i; X X dirstoo=dirsflag; X for ( i=1; 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 } else X (*action)(av[i]); X return 0; X} X Xchar *searchstring; Xchar docr; X X#define SEARCH_REC 1 X#define SEARCH_CASE 2 X#define SEARCH_WILD 4 X#define SEARCH_NUM 8 X#define SEARCH_EXCL 16 X#define SEARCH_QUIET 32 X#define SEARCH_VERB 64 X#define SEARCH_BIN 128 X#define SEARCH_FILE 256 X#define SEARCH_ABORT 512 X#define SEARCH_LEFT 1024 X#define SEARCH_ONLY 2048 X Xstatic int abort_search; Xstatic char lowbuf[256], file_name, file_cr; X Xstatic int Xsearch_file( char *s ) X{ X FILE *fopen(), *fi; X char *p, *q; X int nocasedep, lctr, len, excl=((options & 16) !=0 ), yesno; X char buf[256], searchit[120], first, left; X X if( abort_search ) X return 0; X X nocasedep=!(options & SEARCH_CASE); X lctr= docr= file_name= file_cr= 0; X if (!(options & (SEARCH_QUIET|SEARCH_FILE))) X if( options & SEARCH_VERB ) X printf("Examining %s...\n",s); X else X printf("\015Examining %s... ",s), docr=1; X X strcpy(searchit,searchstring); X if (options & SEARCH_WILD) strcat(searchit,"\n"); X len=strlen(searchit); X if (nocasedep) strupr(searchit); X first=*searchit; X X if( strcmp("STDIN",s) && !(options&SEARCH_WILD) && !excl || X options&SEARCH_BIN ) X if( quicksearch(s,nocasedep,searchit) ) X return 0; X X if( options&SEARCH_BIN ) X { fprintf(stderr,"Out of memory\n"); return 20; } X X fi = strcmp("STDIN",s) ? fopen(s,"r") : stdin; X if (fi==NULL) { pError(s); return 20; } X X prepscroll(0); X X while (fgets(buf,256,fi) && !dobreak()) { X lctr++; left=1; X if (options & SEARCH_WILD) X yesno=compare_ok(searchit, buf, options&SEARCH_CASE); X else { X if (nocasedep) { X strcpy(lowbuf,buf); X strupr(lowbuf); X p=lowbuf; X } else X p=buf; X q=p; X while ((p=index(p,first)) && strncmp(p++,searchit,len)) ; X yesno= (p!=NULL); X left = --p - q; X } X if( yesno ^ excl ) X if(!(options&SEARCH_ONLY)|| !isalphanum(p[-1])&&!isalphanum(p[len])) X if( found(buf, lctr, 0, s, left ) ) X break; X } X if (fi!=stdin) fclose (fi); X if( file_cr ) printf("\n"); X return 0; X} X Xint qcd_flag, qcd_offs; X Xstatic int Xquicksearch( char *name, int nocasedep, char *pattern ) X{ X int i, ptrn=strlen(pattern); X char ut[256], *buffer, *lend; X char *uptab=ut, *get, c, *lpos, *lstart; X int len, lnum, qcd=qcd_flag, repeat=(qcd==2 && qcd_offs!=0); X int sofar, got; X BPTR fh; X X#ifdef AZTEC_C X while(0) while(0) c=c=0, uptab=uptab=ut, get=get=NULL; X#endif X X qcd_flag=0; X if( !(fh=Open(name,MODE_OLDFILE))) { X i=(long)IoErr(), docr=0; X printf("\n"); X ierror(name,i); X return 1; X } X len=filesize( name ); X if( !(buffer=(void *)malloc(len+2))) { Close(fh); return 0; } X sofar=0; X do { X got=Read( fh, (char *)buffer+sofar, 60000); X sofar+=got; X } while( got==60000 ); X Close( fh); X if( sofar != len ) { pError(pattern); return 1; } X X if( nocasedep ) X strupr( pattern ); X X if( !qcd ) X prepscroll(0); X X for( i=0; i<256; i++ ) uptab[i]=i; X if( nocasedep ) for( i='a'; i<='z'; i++ ) uptab[i]=i-'a'+'A'; Xretry: X c=*pattern, buffer[len]=c, buffer[len+1]=c; X get= (qcd==2) ? buffer+qcd_offs : buffer; X if( qcd==1 ) qcd_offs=0; X X lpos=lstart=buffer, lnum=1; X for( ;; ) { X do ; while( uptab[*get++]!=c ); X if( --get>=buffer + len ) X break; X for( i=1; i<ptrn; i++ ) X if( uptab[get[i]]!=pattern[i] ) X break; X if( i==ptrn ) { X for( ;lpos<get; lpos++ ) X if( *lpos=='\n' ) X lstart=lpos+1, lnum++; X for( lend=lstart+1; *lend!='\n'; lend++ ) ; X if( qcd ) { X if( get[-1]==':' || get[-1]=='/' || X lpos==lstart && lend[-1]==':' ) { X char *tmp; X for( tmp=get+ptrn; *tmp&& *tmp!='\n'&& *tmp!='/'; tmp++ ); X if( *tmp!='/' ) { X *lend=0; X strncpy(pattern,lstart,79); X qcd_offs=lend-buffer; X free( buffer ); X return 2; X } X } else X lend=lpos+1; X } else { X *lend=0; X if(!(options&SEARCH_ONLY) || X !isalphanum(lpos[-1])&&!isalphanum(lpos[ptrn])) X if(found(lstart, lnum, get-buffer, name, lpos==lstart )) X break; X *lend='\n'; X } X get=lend+1; X } else X get++; X } X if( repeat ) { repeat=0; qcd_offs=0; goto retry; } X if( file_cr ) { printf("\n"); quickscroll(); } X free( buffer ); X return 1; X} X Xstatic int Xfound( char *lstart, int lnum, int loffs, char *name, char left ) X{ X int fileabort=0; X X if ( docr ) X { quickscroll(); printf("\n"); docr=0; } X X if( (options&SEARCH_LEFT) && !left) X return 0; X X if( options&SEARCH_FILE ) { X file_cr=1; X if( !file_name ) X printf("%s",name), file_name=1; X if( options&SEARCH_NUM ) X fileabort=1; X else X printf(" %d",lnum); X } else if( options & SEARCH_BIN ) { X if (!(options & SEARCH_NUM)) X printf("Byte offset %d\n",loffs); X else X printf("%d\n",loffs); X quickscroll(); X } else { X if (!(options & SEARCH_NUM)) X printf("%4d ",lnum); X printf((lstart[strlen(lstart)-1]=='\n')?"%s":"%s\n",lstart); X quickscroll(); X } X abort_search= options&SEARCH_ABORT; X return dobreak() || fileabort || abort_search; X} X X Xint Xdo_search( void ) X{ X if( Cout_name ) options |= SEARCH_VERB; X abort_search=0; X searchstring=av[--ac]; X all_args(search_file, 0); X if(docr) printf("\n"),docr=0; X return 0; X} X Xstatic int Xrm_file(char *file) X{ X if ( file[strlen(file)-1]=='/' ) file[strlen(file)-1]=0; X if (has_wild) printf(" %s...",file); X if (options & 2) SetProtection(file,0L); X if (!DeleteFile(file)) X { pError (file); return 20; } X else if (has_wild) X printf("Deleted\n"); X return 0; X} X Xint Xdo_rm( void ) X{ X all_args( rm_file, 1); X return 0; X} X Xstatic void Xrecurse(char *name, int (*action)(char *)) X{ X BPTR lock, cwd; X FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC); X char *namecopy=malloc(256); X X if (name[0] =='\0') return; X namecopy[0]=0; X if (lock=Lock(name,ACCESS_READ)) { X cwd =CurrentDir(lock); X if (Examine(lock, fib)) X while (ExNext(lock, fib) && !CHECKBREAK()) { X if (*namecopy) X { (*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 } else X pError(name); X free(namecopy); X FreeMem(fib, (long)sizeof(FIB)); X} X Xstatic void Xrecurse2( char *name, void (*action)(FIB *)) X{ X BPTR lock, cwd; X FIB *fib=(FIB *)AllocMem(sizeof(FIB),MEMF_PUBLIC); X X if (lock=Lock(name,ACCESS_READ)) { X cwd =CurrentDir(lock); X if (Examine(lock, fib)) X while (ExNext(lock, fib) && !CHECKBREAK()) { X (*action)(fib); X if (fib->fib_DirEntryType>=0) X recurse2(fib->fib_FileName,action); X } X UnLock(CurrentDir(cwd)); X } X X FreeMem(fib, sizeof(FIB)); X} X X Xint Xdo_history( void ) X{ X struct HIST *hist; X int i = H_tail_base; X int len = (av[1]) ? strlen(av[1]) : 0; X X for (hist = H_tail; hist && !dobreak(); hist = hist->prev, i++) X if (len == 0 || !strncmp(av[1], hist->line, len)) X printf("%3d %s\n", i, hist->line); X return 0; X} X Xint Xdo_mem( void ) X{ X static long clast, flast; X long cfree, ffree; X char *desc="Free"; X X Forbid(); X cfree = AvailMem (MEMF_CHIP); X ffree = AvailMem (MEMF_FAST); X Permit(); X if( options&8 ) { X clast=cfree, flast=ffree; X return 0; X } X if( options&16 ) X cfree=clast-cfree, ffree=flast-ffree, desc="Used"; X if( options&4 ) { X if ( options & 1 ) printf("%ld\n",cfree); X else if( options & 2 ) printf("%ld\n",ffree); X else printf("%ld\n",cfree+ffree); X } else { X if ( options & 1 ) printf("Free CHIP memory %s\n",itoa(cfree)); X else if( options & 2 ) printf("Free FAST memory %s\n",itoa(ffree)); X else { X if(ffree) { X printf("FAST memory: %s\n",itoa(ffree)); X printf("CHIP memory: %s\n",itoa(cfree)); X } X printf("Total %s: %s\n",desc,itoa(cfree+ffree)); X } X } X return 0; X} X Xint Xdo_forline( void ) X{ X char vname[33], buf[256], *cstr; X int lctr; X FILE *f; X X strcpy(vname,av[1]); X f=fopen(av[2],"r"); X if (f==NULL) pError(av[2]); X lctr=0; X ++H_stack; X cstr = compile_av (av, 3, ac, ' ', 0); X while (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, v_linenum, buf); X exec_command(cstr); X } X fclose(f); X --H_stack; X free (cstr); X unset_var (LEVEL_SET, vname); X unset_var (LEVEL_SET, v_linenum); X return 0; X} X Xint Xdo_fornum( void ) X{ X char vname[33], buf[16]; X int n1, n2, step, i=1, verbose; X char *cstr; X X verbose=(options & 1); X strcpy(vname,av[i++]); X n1=myatoi(av[i++],-32767,32767); if (atoierr) return 20; X n2=myatoi(av[i++],-32767,32767); if (atoierr) return 20; X if (options & 2) { X step=myatoi(av[i++],-32767,32767); if (atoierr) return 20; X } else X step=1; X ++H_stack; X cstr = compile_av (av, i, ac, ' ', 0); X for (i=n1; (step>=0 ? i<=n2 : i>=n2) && !CHECKBREAK(); i+=step) { X if (verbose) fprintf(stderr, "fornum: %d\n", i); X sprintf(buf,"%d",i); X set_var (LEVEL_SET, vname, buf); X exec_command(cstr); X } X --H_stack; X free (cstr); X unset_var (LEVEL_SET, vname); X return 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 Xint Xdo_foreach( void ) X{ X int cstart, cend; X char *cstr, **fav, vname[33]; X int i=1, verbose; X X verbose=(options & 1); X strcpy(vname, av[i++]); X if (*av[i] == '(') i++; X cstart = i; X while (i<ac && *av[i] != ')') i++; X if (i > ac) { fprintf(stderr,"')' expected\n"); return 20; } X ++H_stack; X cend = i; X X fav = (char **)malloc(sizeof(char *) * (ac)); X cstr = compile_av (av, cend + 1, ac, ' ', 0); X X for (i = cstart; i < cend; ++i) fav[i] = av[i]; X X for (i = cstart; i<cend && !CHECKBREAK(); ++i) { X set_var (LEVEL_SET, vname, fav[i]); X if (verbose) fprintf(stderr, "foreach: %s\n", fav[i]); X exec_command(cstr); X } X --H_stack; X free (fav); X free (cstr); X unset_var (LEVEL_SET, vname); X return 0; X} X Xint Xdo_forever( char *str ) X{ X int rcode = 0; X char *ptr = next_word( str ); X X ++H_stack; X for (;;) { 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; X return rcode; X} X Xextern struct IntuitionBase *IntuitionBase; X Xint Xdo_window( void ) X{ X long x=-1, y=-1, w=-1, h=-1, maxwidth, maxheight, arg[5]; X int i; X X if(options & 32) { X struct Screen *scrn; X struct Window *window; X char buf[80]; X buf[40]=0; X for (scrn=IntuitionBase->FirstScreen; scrn; scrn=scrn->NextScreen) { X buf[0]=0; X if( scrn->Title ) X strncpy(buf,scrn->Title,40); X printf("\nScreen \"%s\" (%d,%d,%dx%d):\n", X buf, X scrn->LeftEdge, X scrn->TopEdge, X scrn->Width, X scrn->Height X ); X for (window=scrn->FirstWindow; window; window=window->NextWindow) { X buf[0]=0; X if( window->Title ) X strncpy(buf,window->Title,40); X printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n", X buf, X window->LeftEdge, X window->TopEdge, X window->Width, X window->Height X ); X } X } X return 0; X } X X if( o_nowindow || !Win ) X return 20; X X maxwidth = Win->WScreen->Width; X maxheight= Win->WScreen->Height; X if( options&1 ) X x=Win->LeftEdge,y=Win->TopEdge,w=Win->MinWidth,h=Win->MinHeight; X if( options&2 ) x=y=0, w=maxwidth, h=maxheight; X if( options&4 ) WindowToFront(Win); X if( options&8 ) WindowToBack(Win); X if( options&16) ActivateWindow(Win); X if( ac >= 5) { X for(i=1; i<5; i++) { X arg[i] = myatoi(av[i],0,1023); if (atoierr) return 20; X } X x=arg[1]; y=arg[2]; w=arg[3]; h=arg[4]; X } X if( w!=-1 ) { X int i; X if ( x+w>maxwidth || y+h>maxheight ) { X ierror(NULL, 500); X return 20; X } X if( w<Win->MinWidth ) w=Win->MinWidth; X if( h<Win->MinHeight ) h=Win->MinHeight; X if( Win->LeftEdge!=0 || Win->TopEdge!=0 ) X MoveWindow(Win, -Win->LeftEdge, -Win->TopEdge ); X if( Win->Width!=w || Win->Height!=h ) X SizeWindow(Win, w-Win->Width , h-Win->Height ); X if( x || y ) X MoveWindow(Win, x, y ); X for( i=0; i<7; i++ ) { X if( Win->LeftEdge==x && Win->TopEdge==y && X Win->Width ==w && Win->Height ==h ) X break; X Delay(5); X } X } else X Delay(30); /* pause 1/2 sec. before trying to print */ X X printf("\014"); X return 0; X} X X Xstatic void Xsetsystemtime(struct DateStamp *ds) X{ X struct timerequest tr; X long secs= ds->ds_Days*86400+ds->ds_Minute*60+ds->ds_Tick/TICKS_PER_SECOND; X X if (OpenDevice(TIMERNAME, UNIT_VBLANK,(struct IORequest *)&tr, 0L)) { X fprintf(stderr,"Clock error: can't open timer device\n"); X return; X } X X tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE; X tr.tr_node.io_Message.mn_Node.ln_Pri = 0L; X tr.tr_node.io_Message.mn_Node.ln_Name = NULL; X tr.tr_node.io_Message.mn_ReplyPort = NULL; X tr.tr_node.io_Command = TR_SETSYSTIME; X tr.tr_time.tv_secs = secs; X tr.tr_time.tv_micro = 0L; X if (DoIO ((struct IORequest *)&tr)) X fprintf(stderr,"Clock error: can't talk to timer device\n"); X CloseDevice ((struct IORequest *)&tr); X} X Xchar tday[10]; X Xchar * Xdates( struct DateStamp *dss ) X{ X static char timestr[40]; X char tdate[10], ttime[10]; X struct DateTime dt; X struct DateStamp *myds=&(dt.dat_Stamp); X X dt.dat_Format=FORMAT_DOS; X dt.dat_StrDay=tday; X dt.dat_StrDate=tdate; X dt.dat_StrTime=ttime; X dt.dat_Flags=NULL; X myds->ds_Days=dss->ds_Days; X myds->ds_Minute=dss->ds_Minute; X myds->ds_Tick=dss->ds_Tick; X StamptoStr(&dt); X sprintf(timestr,"%s %s\n",tdate,ttime); X timestr[18]=0; /* protection against bad timestamped files */ X return timestr; X} X Xint Xdo_date( void ) X{ X static long stopwatch; X struct DateStamp dss; X struct DateTime dt; X long time; X int i=1; X X dt.dat_Format=FORMAT_DOS; X if (ac==1) { X DateStamp(&dss); X time=dss.ds_Minute*6000+2*dss.ds_Tick; /* 2 = 100/TickPerSec */ X if( options & 1 ) X stopwatch=time; X else if( options&2 ) X printf( "%d.%02d\n",(time-stopwatch)/100,(time-stopwatch)%100); X else X printf("%s %s\n",tday,dates(&dss)); X } else { X DateStamp(&dt.dat_Stamp); X for ( ; 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 } X return 0; X} END_OF_FILE if test 30286 -ne `wc -c <'comm1.c'`; then echo shar: \"'comm1.c'\" unpacked with wrong size! fi # end of 'comm1.c' fi if test -f 'execom.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'execom.c'\" else echo shar: Extracting \"'execom.c'\" \(30651 characters\) sed "s/^X//" >'execom.c' <<'END_OF_FILE' 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 * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90 X * Version 5.00L by Urban Mueller 17-Feb-91 X * X */ X X#include "shell.h" X X/* execom.c */ Xstatic void preformat(char *s, char *d); Xstatic void backtrans(char *str); Xstatic int fcomm(char *str); Xstatic char *exarg(char **ptr); Xstatic void mpush_base(void); Xstatic char *mpush(int bytes); Xstatic void mpop_tobase(void); Xstatic char *format_insert_string(char *str, char *from); Xstatic int cmd_stat(char *str); Xstatic int find_command(char *str); Xstatic char *push_cpy(char *s); Xstatic void exec_every(void); Xstatic void show_usage(char *str); Xstatic void get_opt(char **av, int *ac, int ccno); Xstatic int checkav( int n ); X X Xint has_wild = 0; /* set if any arg has wild card */ Xchar *LastCommand; X Xstruct COMMAND { X int (*func)(); X short minargs; X short stat; X int val; X char *name; X char *options; X char *usage; X}; X Xextern int do_basename(), do_tackon(); Xextern int do_fltupper(), do_fltlower(), do_linecnt(); 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(), do_aget(); 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(), do_date(), do_protect(), do_ps(); Xextern int do_forever(), do_abortline(), do_strings(), do_touch(); Xextern int do_window(), do_search(), do_filenote(), do_rxrec(), do_rxsend(); Xextern int do_ascii(), do_whereis(), do_sort(), do_qcd(), do_usage(); Xextern int do_uniq(), do_man(), do_head(), do_tee(), do_menu(), do_readfile(); Xextern int do_rxreturn(), do_split(), do_which(), do_class(); Xextern int do_action(), do_keymap(); 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#define ST_FUNC 0x10 X X#define COND ST_COND X#define NORED ST_NORED X#define NOEXP ST_NOEXP X#define AV ST_AV X#define FUNC ST_FUNC X X#define ALIAS LEVEL_ALIAS X#define SET LEVEL_SET X XBPTR OldCin; X Xstruct COMMAND Command[] = { X do_run, 0, AV, 0, "\001", NULL, NULL, /* may call do_source, do_cd */ X do_abortline, 0, 0, 0, "abortline", NULL, "", X do_action, 2, 0, 9, "action", "av", "action file [args]", X do_addbuffers,2, 0, 0, "addbuffers", NULL, "{drive bufs}", X do_set_var, 0, 0, ALIAS, "alias", NULL, "[name [string] ]",/* uses avline */ X do_ascii, 0, 0, 0, "ascii", "oh", "-oh [string]", X do_aset, 1, 0, 0, "aset", NULL, "name value", X do_assign, 0, 0, 0, "assign", "ln", ",logical,-ln {logical physical}", X do_basename, 2, FUNC, 0, "basename", NULL, "var path", X do_cat, 0, 0, 0, "cat", "n", "-n [file file...]", X do_cd, 0, 0, 0, "cd", "g", "[path],-g path...path", X do_class, 0, AV, 0, "class", "n", "-n name {type=param} \"actions\" {action=command}", X do_close, 0, 0, 0, "close", NULL, "filenumber", X do_copy, 1, 0, 0, "copy", "rudpf","-rudpf file file,-ud file...file dir,-ud dir...dir dir", X do_copy, 1, 0, 0, "cp", "rudpf","-rudpf file file,-ud file...file dir,-ud dir...dir dir", X do_date, 0, 0, 0, "date", "sr", "-sr [date/time]", X do_inc, 1, 0, -1, "dec", NULL, "varname [step]", X do_rm, 0, 0, 0, "delete", "rp", "-pr file...file", X do_dir, 0,NOEXP, 0, "dir", "sfdcnhltbuikqavo","-abcdfhiklnoqstuv [path...path]", X do_diskchange,1, 0, 0, "diskchange", NULL, "drive", X do_echo, 0, AV, 0, "echo", "ne", "-ne string", X do_if, 0, COND, 1, "else", NULL, "", X do_if, 0, COND, 2, "endif", NULL, "", X do_exec, 1, 0, 0, "exec", NULL, "command", X do_fault, 1, 0, 0, "fault", NULL, "error", X do_filenote, 1, 0, 0, "filenote", "s", "file...file note,-s file...file", X do_fileslist, 0, 0, 0, "flist", NULL, "", X do_fltlower, 0, 0, 0, "fltlower", NULL, "<in >out", X do_fltupper, 0, 0, 0, "fltupper", NULL, "<in >out", X do_foreach, 3,NORED, 0, "foreach", "v", "-v varname ( string ) command", X do_forever, 1,NORED, 0, "forever", NULL, "command", X do_forline, 3,NORED, 0, "forline", NULL, "var filename command", X do_fornum, 4,NORED, 0, "fornum", "vs", "-vs var n1 n2 command", X do_getenv, 1, FUNC, 0, "getenv", NULL, "shellvar envvar", X do_goto, 1, 0, 0, "goto", NULL, "label", X do_head, 1, 0, 0, "head", NULL, "filename [num]", X do_help, 0, 0, 0, "help", NULL, "", X do_history, 0, 0, 0, "history", NULL, "[partial_string]", X do_howmany, 0, 0, 0, "howmany", NULL, "", X do_htype, 1, 0, 0, "htype", "r", "-r file...file", X do_if, 1,COND|NORED,0, "if", "rftmdvn","-n arg cond arg,-n arg,-nf file,-nd dir -nm,-nt file...file,-nr rpn_expr,-v varname", X do_inc, 1, 0, 1, "inc", NULL, "varname [step]", X do_info, 0, 0, 0, "info", NULL, "[drive...drive]", X do_input, 1, 0, 0, "input", "sr", "-rs var...var", X do_join, 2, 0, 1, "join", "r", "-r file...file", X do_keymap, 1, 0, 0, "keymap", "n", "-n number {key=function}", X do_label, 1, COND, 0, "label", NULL, "name", X do_linecnt, 0, 0, 0, "linecnt", NULL, "<in >out", X do_dir, 0,NOEXP, 0, "ls", "sfdcnhltbuikqav","-abcdfhiklnqstuv [path...path]", X do_man, 0, 0, 0, "man", NULL, "command...command", X do_mkdir, 0, 0, 0, "md", NULL, "name...name", X do_mem, 0, 0, 0, "mem", "cfqsr","-cfqsr", X do_menu, 0, 0, 0, "menu", "n", "-n [title item...item]", X do_mkdir, 0, 0, 0, "mkdir", NULL, "name...name", X do_mv, 2, 0, 0, "mv", NULL, "from to,from...from todir", X do_open, 3, 0, 0, "open", NULL, "file mode number", X do_path, 0, 0, 0, "path", "r", "-r [dir...dir]", X do_pri, 2, 0, 0, "pri", NULL, "clinumber pri,0 pri", X do_protect, 2, 0, 0, "protect", NULL, "file...file flags", X do_ps, 0, 0, 0, "ps", "le", "-el [commandname...commandname]", X do_pwd, 0, 0, 0, "pwd", NULL, "", X do_qsort, 0, 0, 0, "qsort", NULL, "<in >out", X do_quit, 0,NORED, 0, "quit", NULL, "", X do_truerun, 1,NORED, 1, "rback", NULL, "command", X do_mv, 2, 0, 0, "rename", NULL, "from to,from...from todir", X do_readfile, 1, 0, 0, "readfile", NULL, "varname [filename]", X do_relabel, 2, 0, 0, "relabel", NULL, "drive name", X do_resident, 0, 0, 0, "resident", "ard",",-ard file...file", X do_return, 0, 0, 0, "return", NULL, "[n]", X do_rm, 0, 0, 0, "rm", "rp", "-rp file...file", X do_rpn, 0,NOEXP, 0, "rpn", NULL, "expression", X do_rxrec, 0, 0, 0, "rxrec", NULL, "[portname]", X do_rxsend, 2, 0, 0, "rxsend", "rl", "-lc portname string", X do_truerun, 1,NORED, 0, "run", NULL, "command", X do_search, 2, 0, 0, "search", "rcwneqvbfalo","-abceflnoqrvw file...file string", X do_set_var, 0, AV, SET, "set", NULL, "[name [string] ]", X do_setenv, 2, 0, 0, "setenv", NULL, "var value", X do_sleep, 0, 0, 0, "sleep", NULL, "timeout", X do_split, 1, 0, 0, "split", NULL, "srcvar dstvar...dstvar", X do_source, 1,NORED|AV, 0, "source", NULL, "file", /* uses avline */ X do_stack, 0, 0, 0, "stack", NULL, "[bytes]", X do_strhead, 3, FUNC, 0, "strhead", NULL, "varname breakchar string", X do_strings, 1, 0, 0, "strings", "r", "-r file...file minlength", X do_strleft, 3, FUNC, 0, "strleft", NULL, "varname string n", X do_strlen, 2, FUNC, 0, "strlen", NULL, "varname string", X do_strmid, 3, FUNC, 0, "strmid", NULL, "varname string n1 [n2]", X do_strright, 3, FUNC, 0, "strright", NULL, "varname string n", X do_strtail, 3, FUNC, 0, "strtail", NULL, "varname breakchar string", X do_tackon, 3, FUNC, 0, "tackon", NULL, "var pathname filename", X do_head, 1, 0, 1, "tail", NULL, "filename [num]", X do_tee, 0, 0, 0, "tee", NULL, "<in >out", X do_touch, 0, 0, 0, "touch", NULL, "file...file", X do_truncate, 0, 0, 0, "truncate", NULL, "<in >out", X do_cat, 0, 0, 0, "type", NULL, "-n [file...file]", X do_unset_var, 0, 0, ALIAS, "unalias", NULL, "name...name", X do_uniq, 0, 0, 0, "uniq", NULL, "<in >out", X do_unset_var, 0, 0, SET, "unset", NULL, "name...name", X do_usage, 0, 0, 0, "usage", NULL, "[command...command]", X do_ver, 0, 0, 0, "version", NULL, "", X do_waitport, 1, 0, 0, "waitforport",NULL, "portname [seconds]", X do_whereis, 1,NOEXP, 0, "whereis", "r", "-r file [path...path]", X do_window, 0,NOEXP, 0, "window", "slfbaq","-slfbaq", X NULL, 0, 0, 0, NULL, NULL, NULL, X}; X X X/* do_which, 1, 0, 0, "which", NULL, "command", */ X Xstatic char elast; /* last end delimeter */ Xchar Cin_ispipe, Cout_ispipe; X X#ifdef isalphanum Xchar isalph[256]; X#endif X Xint Xexec_command( char *base ) X{ X char *scr; X char buf[32]; X X if (!H_stack && S_histlen>1) { X add_history(base); X sprintf(buf, "%d", H_tail_base + H_len); X set_var(LEVEL_SET, v_histnum, buf); X } X scr = malloc((strlen(base) << 2) + 2); X preformat(base, scr); X return (fcomm(scr) ? -1 : 1); X} X X#ifndef isalphanum Xisalphanum( char c ) X{ X return ( X (c >= 'a' && c <= 'z') || X (c >= 'A' && c <= 'Z') || X (c >= '0' && c <= '9') || X (c == '_') X ); X} X#endif X X#define HOT_GAP 0x80 X#define HOT_BLANK 0x81 X#define HOT_STAR 0x82 X#define HOT_QUES 0x83 X#define HOT_EXCL 0x84 X#define HOT_SEMI 0x85 X#define HOT_PIPE 0x86 X#define HOT_DOLLAR 0x87 X#define HOT_IN 0x88 X#define HOT_OUT 0x89 X#define HOT_BSLASH 0x8a X#define HOT_APOSTR 0x8b X#define HOT_USAGE 0x8c X#define HOT_SBLANK 0xA0 X X Xstatic void Xpreformat( char *s, char *d ) X{ X int qm, i; X X qm = 0; X while (*s == ' ' || *s == 9) ++s; X if (*s == '\\' ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; } X else if (*s == '~' ) { *d++=HOT_APOSTR; s++; } X X while (*s) { X if (qm ) { X while( *s && *s != '\"' && *s != '\\') X *d++ = *s++; X if( !*s ) break; X } X switch (*s) { X case ' ': X case 9: X *d++ = HOT_BLANK; X while (*s == ' ' || *s == 9) ++s; X if (*s == '~' ) { *d++=HOT_APOSTR; s++; } X else if (*s == 0 || *s == '|' || *s == ';') --d; X break; X case '*': X *d++ = HOT_GAP; X *d++ = HOT_STAR; X ++s; X break; X case '?': X *d++ = HOT_GAP; X *d++ = HOT_QUES; X ++s; X break; X case '!': X *d++ = HOT_EXCL; X ++s; X break; X case '#': X *d++ = '\0'; X while (*s) ++s; X break; X case ';': X case '|': X *d++= (*s++==';') ? HOT_SEMI : HOT_PIPE; X while (*s == ' ' || *s == 9) ++s; X if (*s == '\\' ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; } X break; X case '\\': X if( (i=*++s-'0')>=0 && i<=7 ) { X if( *++s>='0' && *s<='7' ) { X i= 8*i + *s++-'0'; X if( *s>='0' && *s<='7' ) X i= 8*i + *s++-'0'; X } X *d++ = i; X } else { X *d++ = *s; X if (*s) ++s; X } X break; X case '\"': X qm = 1 - qm; X ++s; X break; X case '^': X *d++ = *++s & 0x1F; X if (*s) ++s; X break; X case '<': X *d++ = HOT_IN; X ++s; X break; X case '>': X *d++ = HOT_OUT; X ++s; X break; X case '$': /* search end of var name and place false space */ X *d++ = HOT_GAP; X *d++ = HOT_DOLLAR; X ++s; X while (isalphanum(*s)) *d++ = *s++; X *d++ = HOT_GAP; X break; X default: X *d++ = *s++; X break; X } X } X *d++=0; X *d=0; X if (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d); X} X Xstatic void Xbacktrans( char *str ) X{ X while( *str ) { X while( *(signed char *)str>0 ) str++; X if( !*str ) break; X switch( *str) { X case HOT_GAP : *str++=0; break; X case HOT_BLANK : *str++=' '; break; X case HOT_STAR : *str++='*'; break; X case HOT_QUES : *str++='?'; break; X case HOT_EXCL : *str++='!'; break; X case HOT_SEMI : *str++=';'; break; X case HOT_PIPE : *str++='|'; break; X case HOT_DOLLAR: *str++='$'; break; X case HOT_IN : *str++='<'; break; X case HOT_OUT : *str++='>'; break; X case HOT_BSLASH: *str++='\\'; break; X case HOT_APOSTR: *str++='~'; break; X default : str++; break; X } X } X} X X Xvoid * Xmymalloc( int len ) X{ X return malloc(len); 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 Xint Xfcomm( char *str ) X{ X static int alias_count; X int p_alias_count; X char *istr, *nextstr, *command; X char *pend_alias; X int err; X X ++alias_count; X Xentry: X p_alias_count = 0; X pend_alias = NULL; X err=0; X has_wild = 0; 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 istr = NULL; X if ( *str == HOT_BSLASH ) X memmove( str, str+1, strlen(str)); X else X istr = get_var (LEVEL_ALIAS, str); /* only if not \command */ X X if (istr) { X p_alias_count++; X if (*istr == '%' || *istr=='*') { X pend_alias = istr; X } else { X str = format_insert_string(str, istr ); X goto step1; X } X } X X if (*str == HOT_EXCL) { X char *p, c; /* fix to allow !cmd1;!cmd2 */ X for(p = str; *p && *p != HOT_SEMI ; ++p); X c = *p; X *p = '\0'; X istr = get_history(str,1); X *p = c; X replace_head(istr); X str = format_insert_string(str, istr ); X goto step1; X } 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 X if (disable || forward_goto) { X while (elast && elast != HOT_SEMI && elast != HOT_PIPE) X exarg(&nextstr); X goto done0; X } Xskipgood: X { X char *arg, *ptr; X short redir; X short doexpand; X short cont; X short inc; X X ac = 1; X av[0] = command; X backtrans( av[0] ); Xstep5: /* ac = nextac */ X if (!elast || elast == HOT_SEMI || elast == HOT_PIPE) X goto stepdone; X X av[ac] = NULL; 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 HOT_IN: X redir = -2; X case HOT_OUT: X if (cstat & (ST_NORED | ST_COND)) { /* 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 == HOT_OUT) { X redir = 2; /* append >> */ X ++arg; X } X cont = 1; X break; X case HOT_DOLLAR: X /* restore args if from set command or pend_alias */ X if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) { X char *pe, sv; X while (pe = index(arg,0xA0)) { X sv = *pe; X *pe = '\0'; X checkav(1); X av[ac++] = push_cpy(arg); X *pe = sv; X av[ac] = NULL; X arg = pe+1; X } X } else X arg = ptr; X break; X case HOT_APOSTR: X if ((arg = get_var(LEVEL_SET, v_lcd)) != NULL) { X if( ptr[1] ) { X strcpy(Buf,arg); X appendslash(Buf); X strcat(Buf,ptr+1); X arg=Buf; X } X } else X arg = ptr; X break; X X case HOT_STAR: X case HOT_QUES: X if((cstat & ST_NOEXP) == 0 && !(pend_alias && *istr=='*')) X if(ac==1&&(av[1]==NULL||!*av[1])&& *ptr==HOT_QUES&& !ptr[1]) X ; X else 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 if (av[ac]) { X 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 backtrans( av[ac] ); 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( checkav( eac ) ) { 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 } else if( av[ac][0]==')' ) { X int i; X char *pe, sv; X for( i=ac-1; i>0; i-- ) X if( *av[i]=='@' ) X break; X if( i>0 && av[i][strlen(av[i])-1]=='(' ) { X extern int exec_fn_err; X char *exec_function(); X char *avi=av[i], *last=av[ac]; X av[i]=v_value; av[ac]=NULL; X arg=exec_function( avi+1, av+i, ac-i ); X av[i]=avi; av[ac]=last; X inc=0; X if( exec_fn_err<0 ) X ac++; X else if( exec_fn_err>0 || !arg ) X ac=i, av[ac++]=""; X else { X ac=i; X while (pe = index(arg,0xA0)) { X sv = *pe; X *pe = '\0'; X checkav( 2 ); X av[ac++] = push_cpy(arg); X *pe = sv; X arg= pe+1; X } X av[ac] = mpush(strlen(arg)+strlen(last+1)+4); X strcpy(av[ac],arg); X strcat(av[ac++], last+1 ); X } X } X } X X X /* process redirection */ X X if (redir && !err) { X 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 == HOT_BLANK) X goto step5; X } Xstepdone: X av[ac] = NULL; X X /* process pipes via files */ X X if (elast == HOT_PIPE && !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 int i; X char save_elast; X char *avline; X char delim = ' '; X char *larg=av[ac-1]; X X if( *larg && larg[strlen(larg)-1]=='&' ) { X memmove( av+1, av, (ac-1)*sizeof(*av)); X command=av[0]="rback"; X if( strlen(larg)>1 ) X larg[strlen(larg)-1]=0, ac++; 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, 0); X X if (pend_alias) { /* special % alias */ X char *ptr, *scr, *varname, *val=avline, *gap; X ptr=pend_alias; X do { /* set all args */ X for ( varname= ++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr); X if( *ptr=='%' && (gap=index(val,0xA0 )) ) *gap=0; X set_var( LEVEL_SET, varname, val ); X val= gap ? gap+1 : ""; X } while( *ptr=='%' ); X free (avline); X X scr = malloc((strlen(ptr) << 2) + 2); X preformat (ptr, scr); X fcomm (scr); X ptr=pend_alias; X do { /* unset all args */ X for ( varname=++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr); X unset_var( LEVEL_SET, varname ); X } while( *ptr=='%' ); X unset_var (LEVEL_SET, pend_alias + 1); X } else { /* normal command */ X int ccno; X BPTR oldcin = Myprocess->pr_CIS; X BPTR oldcout = Myprocess->pr_COS; X char *Cin_buf; X struct FileHandle *ci; X long oldbuf; X X OldCin=oldcin; X fflush(stdout); X LastCommand=command; 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)) == 0) { X ierror (NULL, 504); X err = 1; X Cin_name = NULL; X } else { X Myprocess->pr_CIS = DEVTAB(stdin) = Cin; X ci = (struct FileHandle *)(((long)Cin)<<2); X Cin_buf = 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 = NULL; X Cout_append = 0; X } else { X Myprocess->pr_COS = DEVTAB(stdout) = Cout; X } X } X } X if (ac < Command[ccno].minargs + 1) { X show_usage( NULL ); X err = -1; X } else if (!err) { X int (*func)(char*,int)=Command[ccno].func; X get_opt( av, &ac, ccno ); X i=0; X if( ccno>0 && ac>1 && !strcmp(av[1],"?") ) X show_usage(avline); X else X i = (*func)(avline, Command[ccno].val); X fflush(stderr); 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 ci->fh_Buf = oldbuf; X fflush(stdin); X clearerr(stdin); X#ifdef AZTEC_C X stdin->_bp=stdin->_bend; X#else X stdin->_rcnt=stdin->_wcnt; X#endif X extClose(Cin); X FreeMem(Cin_buf, 202L); X } X if (Cout_name) { X fflush(stdout); X clearerr(stdout); X#ifdef AZTEC_C X stdout->_flags &= ~_IODIRTY; /* because of nil: device */ X#endif X extClose(Cout); X Cout_append = 0; X } X } X Myprocess->pr_CIS = DEVTAB(stdin) = oldcin; X Myprocess->pr_COS = DEVTAB(stdout) = 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 = NULL; X } X Cout_name = NULL; 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 *exc; X if (err && E_stack == 0) { X exc = get_var(LEVEL_SET, v_except); X if (err >= ((exc)?atoi(exc):1)) { X if (exc) { X ++H_stack, ++E_stack; X a0tospace(exc); X exec_command(exc); X --E_stack, --H_stack; X } else { X Exec_abortline = 1; X } X } X } X if (elast != 0 && Exec_abortline == 0) { X memmove( str, nextstr, strlen(nextstr)+1 ); X goto entry; X } 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 free(str); X --alias_count; X return err; /* TRUE = error occured */ X} X X Xstatic char * Xexarg(ptr) Xchar **ptr; X{ X char *end, *start; X X start = end = *ptr; X while ( *(signed char *)end>0 || *end && *end != 0x80 && X *end != HOT_SEMI && *end != HOT_PIPE && *end != HOT_BLANK) X ++end; X elast = *end; X *end = '\0'; X *ptr = end + 1; X return start; X} X Xstatic char **Mlist; X Xstatic void 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 Xstatic char * 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 Xstatic void Xmpop_tobase() X{ X 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 Xstatic char * Xformat_insert_string(char *str, char *from) X{ X char *new1, *new2; X char *strskip; X int len; X X for (strskip = str; *(signed char *)strskip>0 || X *strskip && *strskip != HOT_BLANK X && *strskip != HOT_SEMI && *strskip != HOT_PIPE X && *strskip != 0x80; ++strskip); X len = strlen(from); X new1 = malloc((len << 2) + 2); X preformat(from, new1); X len = strlen(new1) + strlen(strskip); X new2 = malloc(len+2); X strcpy(new2, new1); X strcat(new2, strskip); X new2[len+1] = 0; X free (new1); X free (str); X return new2; X} X Xstatic int Xcmd_stat( char *str ) X{ X return (int)Command[find_command(str)].stat; X} X Xchar * Xfind_internal( char *str ) X{ X return(Command[find_command(str)].name); X} X Xstatic int Xfind_command( char *str ) X{ X int i, len = strlen(str); X struct COMMAND *com; X char c=*str; X X for( com=Command, i=0; com->func; com++, i++ ) X if ( c==*com->name && !strncmp(str, com->name, len)) X return i; X return 0; X} X Xint exec_fn_err; X Xextern struct FUNCTION { X short id, minargs, maxargs; X char *name; X} Function[]; X X Xchar *gotfunc( int i, char **fav, int fac ); X Xchar * Xexec_function( char *str, char **fav, int fac) X{ X int len=strlen(str)-1, i; X X exec_fn_err=0; X for (i = 0; Command[i].func; ++i) X if ( Command[i].stat&ST_FUNC && !strncmp(str,Command[i].name,len)) { X if( fac<Command[i].minargs ) { X exec_fn_err=20; X return NULL; X } else { X int (*func)( void )=Command[i].func; X char **oldav=av; X int oldac=ac; X av=fav-1, ac=fac+1; X exec_fn_err=(*func)(); X av=oldav, ac=oldac; X return get_var( LEVEL_SET, fav[0] ); X } X } X for (i = 0; Function[i].id; ++i) X if ( len==strlen(Function[i].name)&&!strncmp(str,Function[i].name,len)) X return gotfunc( i,fav,fac ); X X exec_fn_err=-1; X return NULL; X} X Xint Xechofunc(void) X{ X int i; X char *str; X X if( !strlen(av[0]) ) return -1; X exec_fn_err=0; X for (i = 0; Function[i].id; ++i) X if ( !strcmp(av[0],Function[i].name)) { X if(str=gotfunc( i,av,ac )) X printf("%s\n",str); X return exec_fn_err; X } X return -1; X} X X Xchar * Xgotfunc( int i, char **fav, int fac ) X{ X fac--; fav++; X if( fac<Function[i].minargs ) { X fprintf( stderr, "Not enough arguments for @%s\n", X Function[i].name ); X exec_fn_err=20; X return NULL; X } else if( fac>Function[i].maxargs ) { X if( ac > Function[i].maxargs ) X fprintf( stderr, "Too many arguments for @%s\n", X Function[i].name ); X exec_fn_err=20; X return NULL; X } else { X exec_fn_err=dofunc( Function[i].id, fav, fac); X return get_var( LEVEL_SET, v_value ); X } X return NULL; X} X X X Xdo_help() X{ X struct COMMAND *com; X int i=0; X X for (com = &Command[1]; com->func; ++com) { X printf ("%-12s", com->name); X if (++i % 6 == 0) printf("\n"); X } X printf("\n\nUse man <command> for more information\n"); X return 0; X} X Xstatic char * Xpush_cpy(s) Xchar *s; X{ X return strcpy(mpush(strlen(s)), s); X} X Xvoid Xexec_every(void) X{ X char *str = get_var(LEVEL_SET, v_every); X X if (str) { X ++H_stack, ++E_stack; X a0tospace( str ); X exec_command(str); X --E_stack, --H_stack; X } X} X Xchar * Xa0tospace( str ) X char *str; X{ X char *get=str, *put=str; X X while( *get ) X if( *get==0xA0 ) X *put++=' ', get++; X else X *put++=*get++; X return str; X} X Xvoid Xshow_usage( str ) X char *str; X{ X int ccno, first=0, err=0; X char *get, *put, buf[300]; X X if( !str ) X str=LastCommand, err=1; X for( put=str; *put && (*put&127)!=32; put++ ) ; X *put=0; X X put=buf; X ccno = find_command (str); X if( get= Command[ccno].usage ) { X do { X put+=sprintf(put, first++?" %s ":"Usage: %s ", X Command[ccno].name ); X if( *get=='-' ) { X *put++='['; *put++='-'; X get++; X while( *get && *get!=' ' && *get!=',' ) X *put++=*get++; X *put++=']'; X } X while( *get && *get!=',' ) X *put++=*get++; X *put++='\n'; X } while( *get++ ); X *put=0; X fprintf( err ? stderr : stdout, "%s", buf ); X } X} X Xint Xexecute( char *str ) X{ X char **tav=av, telast=elast; X int tac=ac; X ULONG toptions=options; X int thas_wild=has_wild; X X if( !str ) return -1; X X ++H_stack; X exec_command(str); X --H_stack; X X av=tav; ac=tac; elast=telast; options=toptions; has_wild=thas_wild; X X return 0; X} X Xdo_exec( char *str ) X{ X return execute( next_word( str ) ); X} X Xint Xinteractive( void ) X{ X return IsInteractive(Output()); X} X Xstatic int Xcheckav( int n ) X{ X char **tmp; X int newac; X X if( ac+n+10>=max_ac ) { X newac=max_ac+n+40; X if( tmp=(char **)malloc(newac*sizeof(char *))) { X memcpy(tmp,av,max_ac*sizeof(char *)); X free(av); X av=tmp; max_ac=newac; X } else X return 1; X } X return 0; X} X X/* Parse the options specified in sw[] X Setting a bit in global variable options X for each one found X*/ X Xstatic void Xget_opt( char **av, int *ac, int ccno ) X{ X char **get=av+1,**put=av+1, *c, *s; X int i=1, l, usage=0, nac; X long oldopts; X X options=0; X if( !ccno ) X return; X X for( ; i<*ac && *av[i]=='-'; i++, get++ ) { X if( !*(c=*get+1) ) X goto stop; X oldopts=options; X for ( ; *c ; c++) { X if( *c<'a' || *c>'z' ) X { options=oldopts; goto stop; } X for( l=0, s=Command[ccno].options; *s && *s != *c; ++s ) X ++l; X if ( *s ) X options |= (1 << l); X else if( !usage ) { X usage=1; X show_usage(NULL); X } X } X } Xstop: X for( nac=1; i<*ac; i++ ) X *put++=*get++, nac++; X *put=NULL; X *ac=nac; X} X X#if 0 XUSHORT Options[160]; X Xint Xdo_options() X{ X for( i=1; i<ac; i+=2 ) { X if( ac-i<=1 ) X { ierror( av[i], 500 ); return 20; } X if( *av[i+1]!='-' ) X { ierror( av[i+1], 500 ); return 20; } X options=0; X parseopts( av[i+1]+1 ); X } X} X#endif END_OF_FILE if test 30651 -ne `wc -c <'execom.c'`; then echo shar: \"'execom.c'\" unpacked with wrong size! fi # end of 'execom.c' fi echo shar: End of archive 4 \(of 6\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>. Mail comments to the moderator at <amiga-request@uunet.uu.net>. Post requests for sources, and general discussion to comp.sys.amiga.misc.