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.