[comp.sources.amiga] v91i004: CShell 4.02A - alternative command interface, Part02/03

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (02/07/91)

Submitted-by: Cesare.Dieni@p1.f602.n332.z2.fidonet.org (Cesare Dieni)
Posting-number: Volume 91, Issue 004
Archive-name: shells/cshell-4.02a/part02

#!/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 2 (of 3)."
# Contents:  src/comm1.c src/comm3.c src/execom.c
# Wrapped by tadguy@ab20 on Wed Feb  6 19:54:19 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/comm1.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/comm1.c'\"
else
echo shar: Extracting \"'src/comm1.c'\" \(16572 characters\)
sed "s/^X//" >'src/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 *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
X#define DIR_SHORT 0x01
X#define DIR_FILES 0x02
X#define DIR_DIRS  0x04
X#define DIR_NOCOL 0x08
X#define DIR_NAMES 0x10
X
Xextern int has_wild;
X
X/*
X	Parse the options specified in sw[]
X	Setting a bit in global variable options
X	for each one found
X*/
X
Xget_opt(sw,count)
Xchar *sw;
Xint *count;
X{
Xregister char *c,*s;
Xunsigned int l,i = 0;
X
Xoptions=0;
Xwhile((++i < ac) && (av[i][0] == '-')) {
X	for (c = av[i]+1; *c ; c++) {
X		for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
X		if (*s) options |= (1 << l);
X		}
X	}
X*count = i;
X}
X
Xdo_sleep()
X{
Xregister int i;
X
Xif (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i-=2) Delay(100L);
Xreturn 0;
X}
X
Xdo_protect()
X{
Xregister long mask=0xf;
Xregister char *s, *p;
Xstatic char flags[]="DEWRAPSH";
Xregister unsigned short i;
X
Xfor (s=av[--ac]; *s; s++)
X	if (p=index(flags, toupper(*s))) mask^=(1 << (p-flags));
X	else ierror(av[ac],500);
Xfor (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]);
Xreturn 0;
X}
X
Xdo_filenote()
X{
Xchar *note=av[--ac];
Xregister unsigned int i;
X
Xfor (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
Xreturn 0;
X}
X
Xdo_cat()
X{
XFILE *fopen(), *fi;
Xregister unsigned int lctr;
Xunsigned int i;
Xchar buf[256];
X
Xget_opt("n",&i);
Xif (i>=ac) {
X	if (has_wild) { printf("No files matching\n"); return 20; }
X	lctr=0;
X	while (gets(buf) && !dobreak()) {
X		if (options) printf("%4d ",++lctr);
X		puts(buf);
X		}
X	}
Xfor (; i<ac; i++)
X	if (fi = fopen (av[i], "r")) {
X		lctr=0;
X		while (fgets(buf,256,fi) && !dobreak()) {
X			if (options) printf("%4d ",++lctr);
X			printf("%s",buf);
X			}
X		fclose (fi);
X		}
X	else pError(av[i]);
Xreturn 0;
X}
X
Xdo_info()
X{
XBPTR lock;
Xstruct InfoData *info;
Xlong size, free, percent;
Xchar *p, buf[130], *state;
Xstruct DirectoryEntry *de_head=NULL, *de;
X
Xinfo=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
XAddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
XMyprocess->pr_WindowPtr = (APTR)(-1);
Xprintf ("Unit  Size  Bytes  Used Blk/By-Free Full Errs  Status    Name\n");
Xfor (de=de_head; de; de=de->de_Next) {
X	printf("%-5s",de->de_Name);
X	if (lock=Lock(de->de_Name,ACCESS_READ)) {
X	    if (Info(lock, info)) {
X		if(info->id_NumBlocks)
X			percent=(info->id_NumBlocksUsed * 100)/info->id_NumBlocks;
X		else
X			percent=0;
X		PathName(lock, buf, 128L);
X		if (p=index(buf,':')) *p = '\0';
X		size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024;
X		free = (((info->id_NumBlocks-info->id_NumBlocksUsed))*
X			   info->id_BytesPerBlock)/ 1024;
X		switch(info->id_DiskState) {
X			case ID_WRITE_PROTECTED: state="Read Only "; break;
X			case ID_VALIDATED:	 state="Read/Write"; break;
X			case ID_VALIDATING:	 state="Validating"; break;
X			}
X		printf("%4ld%c%6ld%7ld%7ld%4ld%c%4ld%%%4ld  %s %s\n",
X			(size>1024) ? ((size+512) >> 10) : size,
X			(size>1024) ? 'M' : 'K',
X			info->id_BytesPerBlock,
X			info->id_NumBlocksUsed,
X			info->id_NumBlocks-info->id_NumBlocksUsed,
X			(free>1024) ? ((free+512) >> 10) : free,
X			(free>1024) ? 'M' : 'K',
X			(info->id_NumBlocksUsed * 100)/info->id_NumBlocks,
X			info->id_NumSoftErrors,
X			state,
X			buf);
X		}
X	    else pError (de->de_Name);
X	    UnLock(lock);
X	    }
X	else puts("  No disk present");
X	}
XFreeDAList(&de_head);
XMyprocess->pr_WindowPtr = NULL;
XFreeMem(info,(long)sizeof(struct InfoData));
Xreturn 0;
X}
X
X/* things shared with display_file */
X
XBPTR lastlock;
Xint filecount, col;
Xlong bytes, blocks;
X
X/*
X * the args passed to do_dir will never be expanded
X */
Xdo_dir()
X{
Xint i, c, eac;
Xchar **eav;
X
Xcol = filecount = 0;
Xbytes = blocks = 0L;
Xlastlock=NULL;
X
Xget_opt("sfdcn",&i);
X
Xif (ac == i) { ++ac; av[i]=""; }
Xif (!(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS);
X
Xfor (; i<ac && !CHECKBREAK(); ++i)
X	if (eav = expand(av[i], &eac)) {
X		QuickSort(eav, eac);
X		for(c=0; c<eac && !CHECKBREAK(); ++c)
X			if (options & DIR_NAMES)
X				puts(eav[c]);
X			else
X				display_file(eav[c]);
X		free_expand (eav);
X		}
Xif (col) printf("\n");
Xif (filecount>1) {
X	blocks += filecount; /* account for dir blocks */
X	printf(" %ld Blocks, %ld Bytes used in %d files\n",
X		blocks, bytes, filecount);
X	}
Xif (lastlock) UnLock(lastlock);
Xreturn 0;
X}
X
Xdisplay_file(filestr)
Xchar *filestr;
X{
Xlong atol();
Xint isadir,slen;
Xchar sc, *fi, *base, buf[130];
XBPTR thislock;
X
Xbase=BaseName(filestr);
Xsc = *base;
X*base = '\0';
Xthislock=Lock(filestr,SHARED_LOCK);
X/* if (thislock==NULL) return; */
Xif (lastlock==NULL || CompareLock(thislock,lastlock)) {
X	if (col) printf("\n");
X	col = 0;
X	PathName(thislock, buf, 128L);
X	printf("Directory of %s\n", buf);
X	if (lastlock) UnLock(lastlock);
X	lastlock=thislock;
X	}
Xelse UnLock(thislock);
X*base = sc;
Xslen = strlen(base);
Xfi = base + slen + 1;
Xisadir = (fi[12] =='D');
X
Xif (!(((options & DIR_FILES) && !isadir) ||
X	((options & DIR_DIRS) &&  isadir)))
X		return;
Xif (isadir && !(options & DIR_NOCOL)) printf ("\23333m");
Xif (options & DIR_SHORT) {
X	if (col==3 && slen>18) { printf("\n"); col = 0; }
X	if (slen>18) { printf(" %-37s",base); col+= 2; }
X		else { printf(" %-18s",base); col++; }
X	if (col > 3) { printf("\n"); col=0; }
X	}
Xelse printf("   %-24s %s",base ,fi);
Xif (isadir && !(options & DIR_NOCOL)) printf("\2330m");
Xfi[16] = fi[21] = '\0';
Xbytes  += atol(fi+10);
Xblocks += atol(fi+17);
Xfilecount++;
X}
X
Xdo_quit()
X{
Xif (Src_stack) {
X	Quit = 1;
X	return(do_return());
X	}
Xmain_exit(0);
X}
X
Xdo_echo()
X{
Xint i;
X
Xget_opt("n",&i);
Xfor ( ; i<ac; i++) {
X	printf("%s", av[i]);
X	if (i != ac-1) printf(" ");
X	}
Xif (!options) printf("\n");
Xreturn 0;
X}
X
X/* gets a line from file, joining two lines if the first ends in '\' */
X
Xchar *myfgets(buf, buflen, file)
Xchar *buf;
XFILE *file;
X{
Xchar *bufptr=buf, *limit=buf+buflen;
X
Xdo {
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=='\\');
Xreturn buf;
X}
X
Xdo_source(str)
Xchar *str;
X{
Xregister FILE *fi;
Xchar buf[256];
Xint len;
X
Xif (Src_stack == MAXSRC) {
X	ierror(NULL,217);
X	return -1;
X	}
Xif ((fi = fopen (av[1], "r")) == 0) { pError(av[1]); return -1;	}
Xset_var(LEVEL_SET, v_passed, next_word(next_word(str)));
X++H_stack;
XSrc_pos[Src_stack] = 0;
XSrc_base[Src_stack] = (long)fi;
X++Src_stack;
Xwhile (myfgets (buf, 256, fi) && !dobreak()) {
X	len = strlen(buf);
X	buf[len-1] = '\0';
X	Src_pos[Src_stack - 1] += len;
X	if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
X	exec_command (buf);
X	}
X--H_stack;
X--Src_stack;
Xif (forward_goto) ierror(NULL,501);
Xforward_goto = 0;
Xunset_level(LEVEL_LABEL + Src_stack);
Xunset_var(LEVEL_SET, v_gotofwd);
Xunset_var(LEVEL_SET, v_passed);
Xfclose (fi);
Xreturn 0;
X}
X
X/*
X * set process cwd name and $_cwd, if str != NULL also print it.
X */
Xdo_pwd(str)
Xchar *str;
X{
Xchar pwd[130];
X
XPathName(Myprocess->pr_CurrentDir, pwd, 128L);
Xif (str) puts(pwd);
Xset_var(LEVEL_SET, v_cwd, pwd);
X/* put the current dir name in our CLI task structure */
XCtoBStr(pwd, Mycli->cli_SetName, 128L);
Xreturn 0;
X}
X
X/*
X * CD
X *
X * CD(str, 0)      -do CD operation.
X *
X */
X
Xdo_cd(str)
Xchar *str;
X{
XBPTR oldlock, filelock;
X
Xstr=next_word(str);
Xif (!strcmp("..",str)) str="/";
Xfilelock=Lock(str,ACCESS_READ);
Xif (filelock==NULL) { pError(str); return 20; }
Xif (!isdir(str)) { UnLock(filelock); ierror(str,212); return 20; }
Xif (oldlock=CurrentDir(filelock)) UnLock(oldlock);
Xdo_pwd(NULL);
Xreturn 0;
X}
X
Xdo_mkdir()
X{
Xregister unsigned int i;
XBPTR lock;
X
Xfor (i=1; i<ac; ++i) {
X	if (exists(av[i])) ierror(av[i],203);
X	else if (lock=CreateDir(av[i])) UnLock (lock);
X	else pError(av[i]);
X	}
Xreturn 0;
X}
X
Xdo_mv()
X{
Xchar *dest, buf[256];
Xint dirflag;
Xregister unsigned int i;
X
Xdirflag=isdir(dest=av[--ac]);
Xif (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
Xfor (i=1; i<ac; ++i) {
X	strcpy(buf, dest);
X	if (dirflag) TackOn(buf, BaseName(av[i]));
X	if (Rename(av[i], buf)==0)
X		{ pError(av[i]); return -1; }
X	}
Xreturn 0;
X}
X
Xint dirstoo;
X
Xall_args(args, action, dirsflag)
Xchar *args;
Xint (*action)();
X{
Xunsigned int i;
X
Xget_opt(args, &i);
Xdirstoo=dirsflag;
Xfor (; i<ac && !dobreak(); ++i)
X	if (isdir(av[i])) {
X		if (options & 1) recurse(av[i], action);
X			else if (dirstoo) (*action)(av[i]);
X		}
X	else (*action)(av[i]);
Xreturn 0;
X}
X
Xchar *searchstring;
X
Xsearch_file(s)
Xchar *s;
X{
XFILE *fopen(), *fi;
Xregister char *p;
Xregister unsigned int
X	nocasedep, lctr, len, excl=((options & 16) !=0 ), yesno;
Xchar buf[256], lowbuf[256], searchit[256], first;
X
Xif (strcmp("STDIN",s)) fi=fopen(s,"r"); else fi=stdin;
Xif (fi==NULL) { pError(s); return; }
Xnocasedep=!(options & 2);
Xlctr=0;
Xif (!(options & 32)) printf("Examining %s...\n",s);
Xstrcpy(searchit,searchstring);
Xif (options & 4) strcat(searchit,"\n");
Xlen=strlen(searchit);
Xif (nocasedep) strupr(searchit);
Xfirst=*searchit;
Xwhile (fgets(buf,256,fi) && !dobreak()) {
X	lctr++;
X	if (options & 4) yesno=compare_ok(searchit, buf, options & 2);
X	else {
X		if (nocasedep) {
X			strcpy(lowbuf,buf);
X			strupr(lowbuf);
X			p=lowbuf;
X			}
X		else p=buf;
X		while ((p=index(p,first)) && strncmp(p++,searchit,len)) ;
X		yesno= (p!=NULL);
X		}
X	if (yesno ^ excl) {
X			/* default: print line numbers */
X		if (!(options & 8)) printf("%4d ",lctr);
X		printf("%s",buf);
X		}
X	}
Xif (fi!=stdin) fclose (fi);
X}
X
Xdo_search()
X{
Xsearchstring=av[--ac];
Xall_args("rcwneq", search_file, 0);
Xreturn 0;
X}
X
Xrm_file(file)
Xchar *file;
X{
Xif (has_wild) printf(" %s...",file);
Xif (options & 2) SetProtection(file,0L);
Xif (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n");
X}
X
Xdo_rm()
X{
Xall_args("rp", rm_file, 1);
Xreturn 0;
X}
X
Xrecurse(name, action)
Xchar *name;
Xint (*action)();
X{
Xregister BPTR lock, cwd;
Xregister FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
Xchar *namecopy=malloc(256);
X
Xif (name[0] =='\0') return;
Xnamecopy[0]=0;
Xif (lock=Lock(name,ACCESS_READ)) {
X    cwd =CurrentDir(lock);
X    if (Examine(lock, fib))
X	while (ExNext(lock, fib) && !CHECKBREAK()) {
X	    if (*namecopy) { (*action)(namecopy); namecopy[0]=0; }
X	    if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
X		else strcpy(namecopy,fib->fib_FileName);
X	    }
X    if (*namecopy) (*action)(namecopy);
X    UnLock(CurrentDir(cwd));
X    if (dirstoo) (*action)(name);
X    }
Xelse pError(name);
Xfree(namecopy);
XFreeMem(fib, (long)sizeof(FIB));
X}
X
Xdo_history()
X{
Xregister struct HIST *hist;
Xint i = H_tail_base;
Xint len = (av[1]) ? strlen(av[1]) : 0;
X
Xfor (hist = H_tail; hist && !dobreak(); hist = hist->prev)
X	if (len == 0 || !strncmp(av[1], hist->line, len))
X		printf("%3d %s\n", i++, hist->line);
Xreturn 0;
X}
X
Xdo_mem()
X{
Xlong cfree, ffree;
Xextern long AvailMem();
X
XForbid();
Xcfree = AvailMem (MEMF_CHIP);
Xffree = AvailMem (MEMF_FAST);
XPermit();
Xif (ffree) printf ("FAST memory: %ld\nCHIP memory: %ld\n", ffree, cfree);
Xprintf("Total  Free: %ld\n", cfree+ffree);
Xreturn 0;
X}
X
Xdo_forline()
X{
Xchar vname[33], buf[256];
Xregister unsigned short lctr;
XFILE *f;
Xchar *cstr;
X
Xstrcpy(vname,av[1]);
Xf=fopen(av[2],"r");
Xif (f==NULL) pError(av[2]);
Xlctr=0;
X++H_stack;
Xcstr = compile_av (av, 3, ac, ' ', 0);
Xwhile (fgets(buf,256,f) && !dobreak()) {
X	buf[strlen(buf)-1]='\0';	/* remove CR */
X	lctr++;
X	set_var(LEVEL_SET, vname, buf);
X	sprintf(buf,"%d",lctr);
X	set_var(LEVEL_SET, v_linenum, buf);
X	exec_command(cstr);
X	}
Xfclose(f);
X--H_stack;
Xfree (cstr);
Xunset_var (LEVEL_SET, vname);
Xunset_var (LEVEL_SET, v_linenum);
Xreturn 0;
X}
X
Xdo_fornum()
X{
Xchar vname[33], buf[16];
Xint n1, n2, step, i, verbose;
Xchar *cstr;
X
Xget_opt("vs",&i);
Xverbose=(options & 1);
Xstrcpy(vname,av[i++]);
Xn1=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
Xn2=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
Xif (options & 2) {
X	step=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
X	}
Xelse
X	step=1;
X++H_stack;
Xcstr = compile_av (av, i, ac, ' ', 0);
Xfor (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;
Xfree (cstr);
Xunset_var (LEVEL_SET, vname);
Xreturn 0;
X}
X
X/*
X * foreach var_name  ( str str str str... str ) commands
X * spacing is important (unfortunately)
X *
X * ac=0    1 2 3 4 5 6 7
X * foreach i ( a b c ) echo $i
X * foreach i ( *.c ) "echo -n "file ->";echo $i"
X */
X
Xdo_foreach()
X{
Xregister int cstart, cend;
Xregister char *cstr;
Xchar **fav;
Xchar vname[33];
Xint i, verbose;
X
Xget_opt("v",&i);
Xverbose=(options & 1);
Xstrcpy(vname, av[i++]);
Xif (*av[i] == '(') i++;
Xcstart = i;
Xwhile (i<ac && *av[i] != ')') i++;
Xif (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
X++H_stack;
Xcend = i;
X
Xfav = (char **)malloc(sizeof(char *) * (ac));
Xcstr = compile_av (av, cend + 1, ac, ' ', 0);
X
Xfor (i = cstart; i < cend; ++i) fav[i] = av[i];
X
Xfor (i = cstart; i<cend && !CHECKBREAK(); ++i) {
X	set_var (LEVEL_SET, vname, fav[i]);
X	if (verbose) fprintf(stderr, "foreach: %s\n", fav[i]);
X	exec_command(cstr);
X	}
X--H_stack;
Xfree (fav);
Xfree (cstr);
Xunset_var (LEVEL_SET, vname);
Xreturn 0;
X}
X
Xdo_forever(str)
Xchar *str;
X{
Xint rcode = 0;
Xchar *ptr = next_word(str);
X
X++H_stack;
Xfor (;;) {
X	if (CHECKBREAK()) { rcode = 20; break; }
X	if (exec_command (ptr) < 0) {
X		str = get_var(LEVEL_SET, v_lasterr);
X		rcode = (str) ? atoi(str) : 20;
X		break;
X		}
X	}
X--H_stack;
Xreturn rcode;
X}
X
Xdo_exec(str)
Xchar *str;
X{
Xreturn exec_command(next_word(str));
X}
X
Xextern struct Window *w;
Xextern struct IntuitionBase *IntuitionBase;
X
Xdo_window()
X{
Xlong x, y, maxwidth, maxheight, arg[5];
Xunsigned int i;
Xstruct Screen *screen;
Xstruct Window *window;
X
Xget_opt("slfbaq", &i);
Xif (options & 1)
X	SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height));
Xif (options & 2) {
X	x=-w->LeftEdge;
X	y=-w->TopEdge;
X	MoveWindow(w,x,y);
X	x=IntuitionBase->ActiveScreen->Width -w->Width;
X	y=IntuitionBase->ActiveScreen->Height-w->Height;
X	SizeWindow(w,x,y);
X	}
Xif (options & 4) WindowToFront(w);
Xif (options & 8) WindowToBack(w);
Xif (options & 16) ActivateWindow(w);
Xif(ac >= 5) {
X	for(i=1; i<5; i++) {
X		arg[i] = myatoi(av[i],0,1023); if (atoierr) return 20;
X		}
X	maxwidth = w->WScreen->Width;
X	maxheight= w->WScreen->Height;
X	if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) {
X		ierror(NULL, 500);
X		return 20;
X		}
X	x = -w->LeftEdge;
X	y = -w->TopEdge;
X	MoveWindow(w, x, y);
X	x = arg[3] - w->Width;
X	y = arg[4] - w->Height;
X	SizeWindow(w, x, y);
X	x = arg[1];
X	y = arg[2];
X	MoveWindow(w, x, y);
X	}
Xif(options & 32) {
X	for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) {
X	    printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
X			screen->Title,
X			screen->LeftEdge,
X			screen->TopEdge,
X			screen->Width,
X			screen->Height
X			);
X		for (window=screen->FirstWindow; window; window=window->NextWindow) {
X		printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
X			window->Title,
X			window->LeftEdge,
X			window->TopEdge,
X			window->Width,
X			window->Height
X			);
X		}
X	    }
X	return 0;
X	}
XDelay(25L); /* pause 1/2 sec. before trying to print */
Xprintf("\014");
Xreturn 0;
X}
X
Xsetsystemtime(ds)
Xstruct DateStamp *ds;
X{
Xstruct timerequest tr;
Xlong secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
X
Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) {
X	fprintf(stderr,"Clock error: can't open timer device\n");
X	return;
X	}
Xtr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
Xtr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
Xtr.tr_node.io_Message.mn_Node.ln_Name = NULL;
Xtr.tr_node.io_Message.mn_ReplyPort = NULL;
Xtr.tr_node.io_Command = TR_SETSYSTIME;
Xtr.tr_time.tv_secs = secs;
Xtr.tr_time.tv_micro = 0L;
Xif (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n");
XCloseDevice (&tr);
X}
X
Xchar tday[10];
X
Xchar *dates(dss)
Xstruct DateStamp *dss;
X{
Xstatic char timestr[40];
Xchar tdate[10], ttime[10];
Xstruct DateTime dt;
Xstruct DateStamp *myds=&(dt.dat_Stamp);
X
Xdt.dat_Format=FORMAT_DOS;
Xdt.dat_StrDay=tday;
Xdt.dat_StrDate=tdate;
Xdt.dat_StrTime=ttime;
Xdt.dat_Flags=NULL;
Xmyds->ds_Days=dss->ds_Days;
Xmyds->ds_Minute=dss->ds_Minute;
Xmyds->ds_Tick=dss->ds_Tick;
XStamptoStr(&dt);
Xsprintf(timestr,"%s %s\n",tdate,ttime);
Xtimestr[18]='\n';
Xtimestr[19]='\0';	/* protection against bad timestamped files */
Xreturn timestr;
X}
X
Xdo_date()
X{
Xstruct DateStamp dss;
Xregister unsigned short i;
Xstruct DateTime dt;
X
Xdt.dat_Format=FORMAT_DOS;
Xif (ac==1) {
X	DateStamp(&dss);
X	printf("%s %s",tday,dates(&dss));
X	}
Xelse {
X	DateStamp(& (dt.dat_Stamp));
X	for (i=1; i<ac; i++) {
X		dt.dat_StrDate=NULL;
X		dt.dat_StrTime=NULL;
X		dt.dat_Flags=DTF_FUTURE;
X		if (index(av[i],':')) dt.dat_StrTime=av[i];
X			else dt.dat_StrDate=av[i];
X		if (StrtoStamp(&dt)) ierror(av[i],500);
X		}
X	setsystemtime( & (dt.dat_Stamp) );
X	}
Xreturn 0;
X}
END_OF_FILE
if test 16572 -ne `wc -c <'src/comm1.c'`; then
    echo shar: \"'src/comm1.c'\" unpacked with wrong size!
fi
# end of 'src/comm1.c'
fi
if test -f 'src/comm3.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/comm3.c'\"
else
echo shar: Extracting \"'src/comm3.c'\" \(13753 characters\)
sed "s/^X//" >'src/comm3.c' <<'END_OF_FILE'
X/*
X * COMM3.C
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
Xdo_tee()
X{
Xchar buf[256];
X
Xwhile (gets(buf)) {
X	puts(buf);
X	fprintf(stderr, "%s\n", buf);
X	}
X}
X
Xdo_head(garbage, com)
Xchar *garbage;
X{
Xint i, n;
XFILE *f;
Xchar buf[256];
X
Xif (ac>2) {
X	n=(int)(long)Atol(av[2]);
X	if (IoErr()) {
X		ierror(av[2],511);
X		return 20;
X		}
X	}
Xelse n=10;
Xf=fopen(av[1], "r");
Xif (f==NULL) {
X	pError(av[1]);
X	return 20;
X	}
Xif (com) {	/* tail specific part */
X	i=0;
X	while (fgets(buf, 256, f) && ! dobreak()) i++;
X	rewind(f);
X	if (n>i) n=i;
X	i=i-n;
X	while (i-- && fgets(buf, 256, f) && ! dobreak()) ;
X	}
Xfor (i=1; i<=n && fgets(buf, 256, f) && ! dobreak(); i++)
X	printf("%s", buf);
Xfclose(f);
Xreturn 0;
X}
X
Xman(f, s)
XFILE *f;
Xchar *s;
X{
Xchar buf[256], entry[256];
Xint len=sprintf(entry, "    %s", s);
X
Xrewind(f);
Xdo	/* look for required argument */
X	if (fgets(buf, 256, f) == NULL) {
X		fprintf(stderr, "Help not found for %s\n", s);
X		return;
X		}
Xwhile ( Strncmp(entry, buf, len) );
Xdo {	/* display help */
X	printf("%s", buf);
X	if (fgets(buf, 256, f) == NULL) return;
X	}
Xwhile ( ( ! isalphanum(*buf) ) && strncmp(buf, "    ", 4) );
X}
X
Xdo_man()
X{
XFILE *f;
Xregister unsigned int i = 1;
X
Xf=fopen("DOC:Shell.doc", "r");
Xif (f==NULL) {
X	fprintf(stderr, "You must assign directory DOC:, and copy Shell.doc there\n");
X	return 20;
X	}
Xfor (i=1; i<ac; i++) man(f, av[i]);
Xif (ac==1) man(f, "MAN");
Xfclose(f);
Xreturn 0;
X}
X
Xdo_assign()
X{
Xswitch(ac) {
X	case 1:  assignlist();
X		 break;
X	case 2:  doassign(av[1], NULL);
X		 break;
X	case 3:  doassign(av[1], av[2]);
X		 break;
X	default: ierror(NULL, 500);
X		 break;
X	}
Xreturn 0;
X}
X
Xchar *assign_errors[4]={
X	"",
X	"Name %s is not valid\n",
X	"Weird error\n",
X	"Can't cancel %s\n"
X	};
X
Xdoassign(log, phy)
Xchar *log, *phy;
X{
Xint last=strlen(log) - 1;
X
Xif (log[last] != ':') fprintf(stderr, "Bad name %s\n", log);
Xelse {
X	log[last] = 0;
X	fprintf(stderr,assign_errors[Assign(log, phy)],phy);
X	}
X}
X
Xassignlist()
X{
Xstruct DirectoryEntry *de_head=NULL, *de;
Xchar buf[256];
XBPTR lock;
Xint ctr=0;
X
XAddDADevs(&de_head, DLF_DEVICES | DLF_VOLUMES | DLF_DIRS);
Xprintf("Devices:\n");
Xfor (de=de_head; de && de->de_Type==DLX_DEVICE; de=de->de_Next) {
X	printf("%-8s",de->de_Name);
X	if (ctr++ == 5) { ctr=0; printf("\n"); }
X	}
Xprintf("\n\nVolumes:\n");
Xfor (	;
X	de && (de->de_Type==DLX_VOLUME || de->de_Type==DLX_UNMOUNTED);
X	de=de->de_Next
X	)
X	printf( "%-16s %s\n",
X		de->de_Name,
X		de->de_Type == DLX_VOLUME ? "[Mounted]" : ""
X		);
Xprintf("\nDirectories:\n");
Xfor (; de && de->de_Type==DLX_ASSIGN; de=de->de_Next) {
X	if (lock=Lock(de->de_Name, ACCESS_READ)) {
X		PathName(lock, buf, 256L);
X		UnLock(lock);
X		}
X	else
X		strcpy(buf,"Unexisting lock");
X	printf("%-20s%s\n",de->de_Name,buf);
X	}
XFreeDAList(&de_head);
X}
X
Xdo_join()
X{
XBPTR sou, dest;
Xchar *buffer;
Xunsigned int i;
Xlong n;
Xchar *namedest=av[--ac];
X
Xget_opt("r", &i);
Xif (options==0 && exists(namedest)) { ierror(namedest,203); return 20; }
Xif ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; }
Xif ( (dest=Open(namedest, MODE_NEWFILE)) == NULL )
X	{ pError(namedest); goto fail1; }
Xfor (i=1; i<ac; i++) {
X	if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]);
X	else
X		while( (n=Read(sou, buffer, 8192L)) > 0 )
X			if (Write(dest, buffer, n) != n)
X				{ pError(namedest); Close(sou); goto fail2; }
X	Close(sou);
X	}
Xfail2:
X	Close(dest);
Xfail1:
X	free(buffer);
X	return 0;
X}
X
X#define BUFDIM 512L
X#define MAXSTR 256
X
Xint minstr;
X
Xstrings_in_file(s)
Xchar *s;
X{
Xchar c;
Xchar readbuf[BUFDIM+1], strbuf[MAXSTR+1];
Xregister unsigned int i, strctr=0;
XBPTR fh;
Xint out, n;
X
Xif ( fh=Open(s, MODE_OLDFILE) ) {
X	fprintf(stderr, "Strings in %s (len>=%d):\n",s,minstr);
X	while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() )
X	    for (i=0; i<n; i++) {
X		c=readbuf[i];
X		if (c<0x20 || c>0x7f) {
X			out=(strctr>=minstr);
X			if (!out) strctr=0;
X			}
X		else {
X			strbuf[strctr++]=c;
X			out=(strctr>=BUFDIM);
X			}
X		if (out) {
X			strbuf[strctr]='\0';
X			puts(strbuf);
X			strctr=0;
X			}
X		}
X	Close(fh);
X	}
Xelse pError(s);
X}
X
Xdo_strings()
X{
Xminstr=myatoi(av[--ac],1,255);
Xall_args("r", strings_in_file, 0);
Xreturn 0;
X}
X
XBPTR myfile[MAXMYFILES];
X
Xdo_open()
X{
Xlong mode;
Xunsigned int n;
X
Xswitch (toupper(av[2][0])) {
X	case 'R': mode=MODE_OLDFILE; break;
X	case 'W': mode=MODE_NEWFILE; break;
X	default : ierror(NULL,500); return;
X	}
Xn=(unsigned int)myatoi(av[3],0,MAXMYFILES-1); if (atoierr) return 20;
Xif (myfile[n]) myclose(n);
Xmyfile[n]=Open(av[1],mode);
Xreturn (myfile[n]==NULL);
X}
X
Xdo_close()
X{
Xregister unsigned int i;
Xint n;
X
Xif (ac==1)
X	for (i=1; i<MAXMYFILES; i++)
X		myclose(i);
Xfor (i=1; i<ac; i++) {
X	n=myatoi(av[i],0,MAXMYFILES-1); if (atoierr) return 20;
X	myclose(n);
X	}
Xreturn 0;
X}
X
Xmyclose(n)
X{
Xif (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; }
X}
X
Xdo_fileslist()
X{
Xregister unsigned short i;
Xint flag=0;
X
Xprintf("Open files:");
Xfor (i=0; i<MAXMYFILES; i++)
X	if (myfile[i]) { printf(" %d",i); flag=1; }
Xif (!flag) printf(" None!");
Xprintf("\n");
Xreturn 0;
X}
X
XBPTR extOpen(name,mode)
Xchar *name;
Xlong mode;
X{
Xif (name[0]=='.') return myfile[atoi(name+1)];
Xreturn Open(name,mode);
X}
X
XextClose(fh)
XBPTR fh;
X{
Xregister unsigned short i;
X
Xfor (i=0; i<MAXMYFILES; i++)
X	if (myfile[i]==fh) return;
XClose(fh);
X}
X
Xdo_basename()
X{
Xset_var(LEVEL_SET, av[1], BaseName(av[2]));
Xreturn 0;
X}
X
Xdo_tackon()
X{
Xchar buf[256];
X
Xstrcpy(buf, av[2]);
XTackOn(buf, av[3]);
Xset_var(LEVEL_SET, av[1], buf);
Xreturn 0;
X}
X
Xdo_resident()
X{
Xunsigned int i;
Xregister struct ResidentProgramNode *p;
Xchar buf[256];
X
Xget_opt("ard", &i);
Xif (options==0 && ac>1) options=1;
Xswitch (options) {
X    case 0:
X	ObtainSemaphore (& (ArpBase->ResPrgProtection) );
X	if (p=ArpBase->ResidentPrgList) {
X		printf("Name             Users Access\n");
X		for (; p; p=p->rpn_Next)
X			printf("%-17s%5d%6d\n",
X				p->rpn_Name, p->rpn_Usage, p->rpn_AccessCnt);
X		}
X	else printf("No resident program(s)\n");
X	ReleaseSemaphore(& (ArpBase->ResPrgProtection) );
X	break;
X    case 1:
X	for (; i<ac; i++)
X		if (loadres(av[i]))
X			printf("OK! %s is now resident\n", BaseName(av[i]));
X		else pError(av[i]);
X	break;
X    case 2:
X	for (; i<ac; i++)
X		if (RemResidentPrg(av[i])) ierror(av[i],202);
X		else printf("Removed %s\n",av[i]);
X	break;
X    case 4:
X	for (; i<ac; i++) {
X		sprintf(buf,"res_%s",av[i]);
X		Setenv(buf,"1");
X		}
X	break;
X    default:
X	ierror(NULL,500);
X	break;
X    }
Xreturn 0;
X}
X
Xint loadres(s)
Xchar *s;
X{
XBPTR seg;
X
Xif (seg=(BPTR)LoadPrg(s)) AddResidentPrg(seg,BaseName(s));
Xreturn (seg != NULL);
X}
X
Xstruct ProcessControlBlock pcb={
X	4000,		/* pcb_StackSize	*/
X	0,		/* pcb_Pri		*/
X	};
X/* remaining field are NULL */
X	
Xdo_truerun(avline, backflag)
Xchar *avline;
X{
Xchar name[200];
Xchar *FindIt();
X
Xif (backflag) {
X	pcb.pcb_Control=NULL;
X	pcb.pcb_Input=pcb.pcb_Output=Open("NIL:",MODE_OLDFILE);
X	}
Xelse {
X	pcb.pcb_Control=NULL;
X	pcb.pcb_Input=pcb.pcb_Output =NULL;
X	}
Xif (FindIt(av[1], "", name))
X	ASyncRun(name,next_word(next_word(avline)),&pcb);
Xelse
X	ierror(av[1],205);
Xreturn 0;
X}
X
Xint exists(name)
Xchar *name;
X{
XBPTR lock;
X
Xif (lock=Lock(name,ACCESS_READ)) {
X	UnLock(lock);
X	return 1;
X	}
Xreturn 0;
X}
X
Xdo_aset()
X{
XSetenv(av[1],av[2]);
Xreturn 0;
X}
X
X#define HTYPELINE 16L
X
Xhtype_a_file(s)
Xchar *s;
X{
XBPTR fh;
Xlong n, filesize=0;
Xchar buf[HTYPELINE+1];
Xregister unsigned short i;
X
Xif ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; }
Xwhile ( (n=Read(fh,buf,HTYPELINE))>0 && !dobreak()) {
X	printf("%06lx: ",filesize);
X	filesize+=n;
X	for (i=0; i<n; i++) {
X		printf( (i&3) ? "%02x" : " %02x",(int)(unsigned char)buf[i]);
X		if (buf[i]<0x20) buf[i]='.';
X		}
X	for ( ; i<HTYPELINE; i++) {
X		printf( (i&3) ? "  " : "   ");
X		buf[i]=' ';
X		}
X	buf[i]=0;
X	printf("    %s\n",buf);
X	}
XClose(fh);
Xreturn 0;
X}
X
Xdo_htype()
X{
Xall_args("", htype_a_file, 0);
Xreturn 0;
X}
X
Xdo_stack()
X{
Xlong n;
X
Xif (ac>1) {
X	n=Atol(av[1]);
X	if (!IoErr()) Mycli->cli_DefaultStack=(long)(n >> 2L);
X	}
Xelse printf("current stack size is %ld bytes\n",
X				(long)Mycli->cli_DefaultStack << 2L);
Xreturn 0;
X}
X
Xdo_fault()
X{
Xstruct PERROR *p;
Xregister unsigned int i;
Xint n;
X
Xfor (i=1; i<ac; i++) {
X	n=myatoi(av[i],0,32767);
X	if (!atoierr) {
X		for (p=Perror; p->errnum && p->errnum!=n; p++);
X		if (p->errnum)
X			printf("Fault %d: %s\n",n,p->errstr);
X		else
X			printf("Fault %d not recognized\n",n);
X		}
X	}
Xreturn 0;
X}
X
Xstruct rpncommand {
X	char *str;
X	int parsin, parsout;
X	};
X
Xstruct rpncommand rpn[]={
X	"+",	2,	1,
X	"-",	2,	1,
X	"*",	2,	1,
X	"/",	2,	1,
X	"%",	2,	1,
X	"&",	2,	1,
X	"|",	2,	1,
X	"~",	1,	1,
X	">",	2,	1,
X	"<",	2,	1,
X	"==",	2,	1,
X	"!",	1,	1,
X	"DUP",	1,	2,
X	"DROP",	1,	0,
X	"SWAP",	2,	2,
X	"HELP",	0,	0,
X	NULL,	0,	1,	/* this looks for a number */
X};
X
Xdo_rpn(garbage,ifflag) /* ifflag!=0 if called from if */
Xchar *garbage;
X{
Xregister long n0, n1;
Xlong t;
Xunsigned int i, j;
Xint sp=0;
Xlong stack[100];
Xstruct rpncommand *temp;
X
Xi=1;
Xif (ifflag) get_opt("rn",&i);
Xfor (; i<ac; i++) {
X	for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ;
X	n0=stack[sp-1];
X	n1=stack[sp-2];
X	sp -= (rpn[j].parsin);
X	if (sp<0) { fprintf(stderr, "RPN: Empty stack\n"); return 1; }
X	switch (j) {
X	  case 0:	n0 += n1;		break;
X	  case 1:	n0 = n1-n0;		break;
X	  case 2:	n0 *= n1;		break;
X	  case 3:	n0 = n1/n0;		break;
X	  case 4:	n0 = n1%n0;		break;
X	  case 5:	n0 &= n1;		break;
X	  case 6:	n0 |= n1;		break;
X	  case 7:	n0 =  ~n0;		break;
X	  case 8:	n0 = (n1 > n0);		break;
X	  case 9:	n0 = (n1 < n0);		break;
X	  case 10:	n0 = (n0 == n1);	break;
X	  case 11:	n0 = !n0;		break;
X	  case 12:	n1=n0;			break;
X	  case 13:	t=n0; n0=n1; n1=t;	break;
X	  case 14:				break;
X	  case 15:	printf("In Commands Out\n");
X			for (temp=rpn; temp->str; temp++)
X			    printf(" %d %-10s%d\n",
X				temp->parsin,temp->str,temp->parsout);
X			break;
X	  default:	n0=Atol(av[i]);
X			if (IoErr()) {
X				fprintf(stderr, "Bad RPN cmd: %s\n",av[i]);
X				return 20;
X				}
X			break;
X	  }
X	stack[sp]=n0;
X	stack[sp+1]=n1;
X	sp += rpn[j].parsout;
X	}
Xif (ifflag) return (int)(stack[sp-1]);	/* called from if: return top value */
Xfor (i=sp-1;(int)i>=0;i--) printf("%ld\n", stack[i]); /* else print stack */
Xreturn 0;
X}
X
Xdo_path()
X{
Xunion {	long *lp; long ll; } l;
Xchar buf[256];
X
Xputs("Current dir");
Xl.lp = (long *) Mycli->cli_CommandDir;
Xwhile (l.ll) {
X	l.ll <<= 2;
X	PathName(l.lp[1], buf, 256L);
X	puts(buf);
X	l.ll = *l.lp;
X	}
Xputs("C:");
Xreturn 0;
X}
X
Xdo_pri()
X{
Xint t, pri;
Xstruct Process *proc;
X
Xt=(int)(long)FindCLI(0L);
Xt=myatoi(av[1],0,t); if (atoierr) return 20;
Xpri=myatoi(av[2],-128,127); if (atoierr) return 20;
XForbid();
Xproc=(t==0 ? Myprocess : FindCLI((long)t));
Xif (proc==NULL) fprintf(stderr, "process not found\n");
X	else SetTaskPri(proc, (long)pri);
XPermit();
Xreturn 0;
X}
X
Xdo_strleft()
X{
Xchar buf[256];
Xint n;
X
Xstrcpy(buf,av[2]);
Xn=myatoi(av[3],1,strlen(buf)); if (atoierr) return 20;
Xbuf[n]='\0';
Xset_var(LEVEL_SET, av[1], buf);
Xreturn 0;
X}
X
Xdo_strright()
X{
Xchar buf[256];
Xint n;
X
Xstrcpy(buf, av[2]);
Xn=myatoi(av[3],1,strlen(buf)); if (atoierr) return 20;
Xset_var(LEVEL_SET, av[1], buf+strlen(buf)-n);
Xreturn 0;
X}
X
Xdo_strmid()
X{
Xchar buf[256];
Xint n1, n2;
X
Xstrcpy(buf, av[2]);
Xn1=myatoi(av[3],1,strlen(buf))-1; if (atoierr) return 20;
Xif (ac>4) {
X	n2=myatoi(av[4],1,strlen(buf)-n1); if (atoierr) return 20;
X	buf[n1+n2]='\0';
X	}
Xset_var(LEVEL_SET, av[1], buf+n1);
Xreturn 0;
X}
X
Xdo_strlen()
X{
Xchar buf[16];
X
Xsprintf(buf,"%d",strlen(av[2]));
Xset_var(LEVEL_SET, av[1], buf);
Xreturn 0;
X}
X
Xint atoierr;
X
Xmyatoi(s,min,max)
Xchar *s;
X{
Xint n;
X
Xn=(int)(long)Atol(s);
Xif (atoierr=IoErr())
X	ierror(s,511);
X	else if (n<min || n>max) {
X		atoierr=1;
X		fprintf(stderr, "%s(%d) not in (%d,%d)\n",s,n,min,max);
X		}
Xreturn n;
X}
X
Xdo_fltlower()
X{
Xchar buf[256];
Xchar *strlwr();
X
Xwhile (!CHECKBREAK() && gets(buf)) puts(strlwr(buf));
Xreturn 0;
X}
X
Xdo_fltupper()
X{
Xchar buf[256];
Xchar *strupr();
X
Xwhile (!CHECKBREAK() && gets(buf)) puts(strupr(buf));
Xreturn 0;
X}
X
Xdo_uniq()
X{
Xint firstline=1;
Xchar buf[256], oldbuf[256];
X
Xwhile (!CHECKBREAK() && gets(buf)) {
X	if ( firstline || strcmp(buf, oldbuf)) {
X		strcpy(oldbuf, buf);
X		puts(buf);
X		}
X	firstline=0;
X	}
Xreturn 0;
X}
X
X#define RXFB_RESULT  17
X
Xstatic struct rexxmsg {
X	struct Message cm_Node;
X	LONG   RFU1;
X	LONG   RFU2;
X	LONG   rm_Action;
X	LONG   rm_Result1;
X	LONG   rm_Result2;
X	char   *cm_Args[16];
X	LONG   RFU7;
X	LONG   RFU8;
X	LONG   RFU9;
X	LONG   RFU10;
X	LONG   RFU11;
X	LONG   RFU12;
X} mymsg;
X
Xdo_rxsend()
X{
Xint i=1, resflag;
Xchar *result;
Xstruct MsgPort *port, *reply;
Xlong len;
X
Xget_opt("r", &i);
Xresflag=options;
Xif (!(port = FindPort(av[i++]))) { fprintf(stderr, "No port %s!\n", av[--i]); return 20; }
Xmymsg.cm_Node.mn_Node.ln_Type = NT_MESSAGE;
Xmymsg.cm_Node.mn_Length = sizeof(struct rexxmsg);
Xmymsg.rm_Action = (resflag ? 1L << RXFB_RESULT : 0);
Xif (!(reply = CreatePort(NULL, 0L))) {
X	fprintf(stderr, "No reply port\n");
X	return 20;
X	}
Xmymsg.cm_Node.mn_ReplyPort = reply;
X
Xfor ( ; i<ac; i++) {
X	mymsg.cm_Args[0] = av[i];
X	mymsg.rm_Result2 = 0;	/* clear out the last result. */
X	PutMsg(port, &mymsg.cm_Node);
X	WaitPort(reply);
X
X	if (resflag) {
X		result=(char *)mymsg.rm_Result2;
X		len=*( (long *)(result-4) );
X		if (len<0 || len>256)
X			fprintf(stderr, "Risultato troppo lungo\n");
X		else
X			printf("%s\n", result);
X		FreeMem(result, len);
X		}
X	}
X
Xif (reply) DeletePort(reply);
Xreturn 0;
X}
X
Xdo_rxrec()
X{
Xstruct MsgPort *port;
Xstruct rexxmsg *msg;
Xchar *portname, *str;
X
Xif (ac > 1)
X	portname=av[1];
Xelse
X	portname="rexx_csh";
X
Xport=CreatePort(portname, 0L);
Xif (port==NULL) {
X	fprintf(stderr, "Can't have MsgPort %s\n", portname);
X	return 20;
X	}
Xfor (;;) {
X	WaitPort(port);
X	while (msg=(struct rexxmsg *)GetMsg(port)) {
X		if ( ! Strcmp(msg->cm_Args[0], "bye")) {
X			ReplyMsg((struct Message *)msg);
X			DeletePort(port);
X			return 0;
X			}
X		exec_command(msg->cm_Args[0]);
X		if (msg->rm_Action & (1L << RXFB_RESULT)) {
X			str = get_var(LEVEL_SET, v_lasterr);
X			msg->rm_Result2=(str) ? atoi(str) : 20;
X			}
X		ReplyMsg((struct Message *)msg);
X		}
X	}
X}
END_OF_FILE
if test 13753 -ne `wc -c <'src/comm3.c'`; then
    echo shar: \"'src/comm3.c'\" unpacked with wrong size!
fi
# end of 'src/comm3.c'
fi
if test -f 'src/execom.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/execom.c'\"
else
echo shar: Extracting \"'src/execom.c'\" \(16435 characters\)
sed "s/^X//" >'src/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 *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
X#define F_EXACT 0
X#define F_ABBR  1
X
X#define ST_COND   0x01
X#define ST_NORED  0x02
X#define ST_NOEXP  0x04
X#define ST_AV     0x08 /* delimit args within a variable */
X
Xint has_wild = 0;                 /* set if any arg has wild card */
X
Xstruct COMMAND {
X	int (*func)();
X	short minargs;
X	short stat;
X	int val;
X	char *name;
X	};
X
Xextern char *format_insert_string();
Xextern char *mpush(), *exarg();
X
Xextern int do_uniq(), do_man(), do_head(), do_tee();
Xextern int do_basename(), do_tackon();
Xextern int do_fltupper(), do_fltlower();
Xextern int do_strleft(), do_strright(), do_strmid(), do_strlen();
Xextern int do_fornum(), do_forline(), do_exec();
Xextern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri();
Xextern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany();
Xextern int do_open(), do_close(), do_fileslist(), do_htype();
Xextern int do_run(), do_number(), do_assign(), do_join();
Xextern int do_quit(), do_set_var(), do_unset_var();
Xextern int do_echo(), do_source(), do_mv(), do_addbuffers();
Xextern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history();
Xextern int do_mem(), do_cat(), do_dir(), do_info(), do_inc();
Xextern int do_foreach(), do_return(), do_if(), do_label(), do_goto();
Xextern int do_input(), do_ver(), do_sleep(), do_help();
Xextern int do_strhead(), do_strtail(), do_relabel();
Xextern int do_copy(), 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();
Xchar *push_cpy();
X
Xstatic struct COMMAND Command[] = {
Xdo_run,		0, ST_AV,	0,	"\001",   /* may call do_source */
Xdo_abortline,	0, 0,		0,	"abortline",
Xdo_addbuffers,	2, 0,		0,	"addbuffers",
Xdo_set_var,	0, 0, LEVEL_ALIAS,	"alias",  /* uses avline */
Xdo_aset,	1, 0,		0,	"aset",
Xdo_assign,	0, 0,		0,	"assign",
Xdo_basename,	2, 0,		0,	"basename",
Xdo_cat,		0, 0,		0,	"cat",
Xdo_cd,		0, 0,		0,	"cd",
Xdo_close,	0, 0,		0,	"close",
Xdo_copy,	1, 0,		0,	"copy",
Xdo_copy,	1, 0,		0,	"cp",
Xdo_date,	0, 0,		0,	"date",
Xdo_inc,		1, 0,		-1,	"dec",
Xdo_rm,		0, 0,		0,	"delete",
Xdo_dir,		0, ST_NOEXP,	0,	"dir",
Xdo_diskchange,	1, 0,		0,	"diskchange",
Xdo_echo,	0, 0,		0,	"echo", /* uses avline */
Xdo_if,		0, ST_COND,	1,	"else",
Xdo_if,		0, ST_COND,	2,	"endif",
Xdo_exec,	1, 0,		0,	"exec",
Xdo_fault,	1, 0,		0,	"fault",
Xdo_filenote,	2, 0,		0,	"filenote",
Xdo_fileslist,	0, 0,		0,	"flist",
Xdo_fltlower,	0, 0,		0,	"fltlower",
Xdo_fltupper,	0, 0,		0,	"fltupper",
Xdo_foreach,	3, ST_NORED,	0,	"foreach",
Xdo_forever,	1, ST_NORED,	0,	"forever",
Xdo_forline,	3, ST_NORED,	0,	"forline",
Xdo_fornum,	4, ST_NORED,	0,	"fornum",
Xdo_goto,	1, 0,		0,	"goto",
Xdo_head,	1, 0,		0,	"head",
Xdo_help,	0, 0,		0,	"help",
Xdo_history,	0, 0,		0,	"history",
Xdo_howmany,	0, 0,		0,	"howmany",
Xdo_htype,	1, 0,		0,	"htype",
Xdo_if,		1, ST_COND|ST_NORED,0,	"if",
Xdo_inc,		1, 0,		1,	"inc",
Xdo_info,	0, 0,		0,	"info",
Xdo_input,	1, 0,		0,	"input",
Xdo_join,	2, 0,		1,	"join",
Xdo_label,	1, ST_COND,	0,	"label",
Xdo_dir,		0, ST_NOEXP,	0,	"ls",
Xdo_man,		0, 0,		0,	"man",
Xdo_mkdir,	0, 0,		0,	"md",
Xdo_mem,		0, 0,		0,	"mem",
Xdo_mkdir,	0, 0,		0,	"mkdir",
Xdo_mv,		2, 0,		0,	"mv",
Xdo_open,	3, 0,		0,	"open",
Xdo_path,	0, 0,		0,	"path",
Xdo_pri,		2, 0,		0,	"pri",
Xdo_protect,	2, 0,		0,	"protect",
Xdo_ps,		0, 0,		0,	"ps",
Xdo_pwd,		0, 0,		0,	"pwd",
Xdo_quit,	0, ST_NORED,	0,	"quit",
Xdo_truerun,	1, ST_NORED,	1,	"rback",
Xdo_mv,		2, 0,		0,	"rename",
Xdo_relabel,	2, 0,		0,	"relabel",
Xdo_resident,	0, 0,		0,	"resident",
Xdo_return,	0, 0,		0,	"return",
Xdo_rm,		0, 0,		0,	"rm",
Xdo_rpn,		0, ST_NOEXP,	0,	"rpn",
Xdo_rxrec,	0, 0,		0,	"rxrec",
Xdo_rxsend,	2, 0,		0,	"rxsend",
Xdo_truerun,	1, ST_NORED,	0,	"run",
Xdo_search,	2, 0,		0,	"search",
Xdo_set_var,	0, ST_AV, LEVEL_SET,	"set",
Xdo_sleep,	0, 0,		0,	"sleep",
Xdo_source,	0, ST_NORED|ST_AV, 0,	"source", /* uses avline */
Xdo_stack,	0, 0,		0,	"stack",
Xdo_strhead,	3, 0,		0,	"strhead",
Xdo_strings,	1, 0,		0,	"strings",
Xdo_strleft,	3, 0,		0,	"strleft",
Xdo_strlen,	2, 0,		0,	"strlen",
Xdo_strmid,	3, 0,		0,	"strmid",
Xdo_strright,	3, 0,		0,	"strright",
Xdo_strtail,	3, 0,		0,	"strtail",
Xdo_tackon,	3, 0,		0,	"tackon",
Xdo_head,	1, 0,		1,	"tail",
Xdo_tee,		0, 0,		0,	"tee",
Xdo_touch,	0, 0,		0,	"touch",
Xdo_cat,		0, 0,		0,	"type",
Xdo_unset_var,	0, 0, LEVEL_ALIAS,	"unalias",
Xdo_uniq,	0, 0,		0,	"uniq",
Xdo_unset_var,	0, 0, LEVEL_SET  ,	"unset",
Xdo_ver,		0, 0,		0,	"version",
Xdo_window,	0, ST_NOEXP,	0,	"window",
X'\0',		0, 0,		0,	NULL
X};
X
Xstatic unsigned char elast;		/* last end delimeter */
Xstatic char Cin_ispipe, Cout_ispipe;
X
Xexec_command(base)
Xchar *base;
X{
Xregister char *scr;
Xchar buf[32];
X
Xif (!H_stack) {
X	add_history(base);
X	sprintf(buf, "%d", H_tail_base + H_len);
X	set_var(LEVEL_SET, v_histnum, buf);
X	}
Xscr = malloc((strlen(base) << 2) + 2);
Xpreformat(base, scr);
Xreturn (fcomm(scr, 1) ? -1 : 1);
X}
X
Xisalphanum(c)
Xregister char c;
X{
Xreturn (
X	(c >= '0' && c <= '9') ||
X	(c >= 'a' && c <= 'z') ||
X	(c >= 'A' && c <= 'Z') ||
X	(c == '_')
X	);
X}
X
Xpreformat(s, d)
Xregister char *s, *d;
X{
Xregister int si, di, qm;
X
Xsi = di = qm = 0;
Xwhile (s[si] == ' ' || s[si] == 9) ++si;
Xwhile (s[si]) {
X	if (qm && s[si] != '\"' && s[si] != '\\') {
X		d[di++] = s[si++] | 0x80;
X		continue;
X		}
X	switch (s[si]) {
X		case ' ':
X		case 9:
X			d[di++] = ' ';
X			while (s[si] == ' ' || s[si] == 9) ++si;
X			if (s[si] == 0 || s[si] == '|' || s[si] == ';') --di;
X			break;
X		case '*':
X		case '?':
X			d[di++] = 0x80;
X		case '!':
X			d[di++] = s[si++];
X			break;
X		case '#':
X			d[di++] = '\0';
X			while (s[si]) ++si;
X			break;
X		case ';':
X		case '|':
X			d[di++] = s[si++];
X			while (s[si] == ' ' || s[si] == 9) ++si;
X			break;
X		case '\\':
X			d[di++] = s[++si] | 0x80;
X			if (s[si]) ++si;
X			break;
X		case '\"':
X			qm = 1 - qm;
X			++si;
X			break;
X		case '^':
X			d[di++] = s[++si] & 0x1F;
X			if (s[si]) ++si;
X			break;
X		case '$': /* search end of var name and place false space */
X			d[di++] = 0x80;
X			d[di++] = s[si++];
X			while (isalphanum(s[si])) d[di++] = s[si++];
X			d[di++] = 0x80;
X			break;
X		default:
X			d[di++] = s[si++];
X			break;
X		}
X	}
Xd[di++]=0;
Xd[di]=0;
Xif (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
X}
X
Xextern BPTR extOpen();
X
X/*
X * process formatted string.  ' ' is the delimeter.
X *
X *    0: check '\0': no more, stop, done.
X *    1: check $.     if so, extract, format, insert
X *    2: check alias. if so, extract, format, insert. goto 1
X *    3: check history or substitution, extract, format, insert. goto 1
X *
X *    4: assume first element now internal or disk based command.
X *
X *    5: extract each ' ' or 0x80 delimited argument and process, placing
X *       in av[] list (except 0x80 args appended).  check in order:
X *
X *             '$'         insert string straight
X *             '>'         setup stdout
X *             '>>'        setup stdout flag for append
X *             '<'         setup stdin
X *             '*' or '?'  do directory search and insert as separate args.
X *
X *             ';' 0 '|'   end of command.  if '|' setup stdout
X *                          -execute command, fix stdin and out (|) sets
X *                           up stdin for next guy.
X */
X
Xfcomm(str, freeok)
Xregister char *str;
X{
Xstatic int alias_count;
Xint p_alias_count=0, err=0;
Xchar *istr, *nextstr, *command, *pend_alias=NULL, *temp;
X
Xhas_wild = 0;
X++alias_count;
Xmpush_base();
Xif (*str == 0) goto done1;
X
Xstep1:
X
Xif (alias_count == MAXALIAS || ++p_alias_count == MAXALIAS) {
X	fprintf(stderr,"Alias Loop\n");
X	err = 20;
X	goto done1;
X	}
Xistr = NULL;
Xif (*str >= 0) istr=get_var(LEVEL_ALIAS, str);
X	/* only if not \command, i.e. bit 7 not set */
X*str &= 0x7F;
X	/* remove \ teltail */
X
Xif (istr) {
X	if (*istr == '%') pend_alias = istr;
X	else {
X		str = format_insert_string(str, istr, &freeok);
X		goto step1;
X		}
X	}
X
Xif (*str == '!') {
X	char *p, c;
X
X	for (p = str; *p && *p != ';' ; ++p);
X	c = *p;
X	*p = '\0';
X	istr = get_history(str);
X	*p = c;
X	replace_head(istr);
X	str = format_insert_string(str, istr, &freeok);
X	goto step1;
X	}
X
Xnextstr = str;
Xcommand = exarg(&nextstr);
Xif (*command == 0) goto done0;
Xif (
X	(pend_alias || ! (cmd_stat(command) & ST_COND) ) &&
X	(disable || forward_goto)
X	) {
X		while (elast && elast != ';' && elast != '|') exarg(&nextstr);
X		goto done0;
X	}
X
X{
Xregister char *arg, *ptr, *scr;
Xshort redir, doexpand, cont, inc;
X
Xac = 1;
Xav[0] = command;
X
Xstep5:                                          /* ac = nextac */
X
Xif (!elast || elast == ';' || elast == '|') goto stepdone;
X
Xav[ac] = '\0';
Xcont = 1;
Xdoexpand = redir = inc = 0;
X
Xwhile (cont && elast) {
X   int cstat = cmd_stat(command);
X
X   ptr = exarg(&nextstr);
X   inc = 1;
X   arg = "";
X   cont = (elast == 0x80);
X   switch (*ptr) {
X   case '<':
X      redir = -2;
X   case '>':
X      if (cstat & (ST_NORED | ST_COND)) {
X                                                  /* don't extract   */
X          redir = 0;                              /* <> stuff if its */
X          arg = ptr;                              /* external cmd.   */
X          break;
X      }
X      ++redir;
X      arg = ptr + 1;
X      if (*arg == '>') {
X         redir = 2;        /* append >> */
X         ++arg;
X      }
X      cont = 1;
X      break;
X   case '$':
X      /* restore args if from set command or pend_alias */
X      if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) {
X         if (cstat & ST_COND) {
X            char *tp;
X            tp = push_cpy(arg);
X            arg = tp;
X         }
X         else {
X            char *pe, sv;
X            while (pe = index(arg,0xA0)) {
X               sv = *pe;
X               *pe = '\0';
X               av[ac++] = push_cpy(arg);
X               *pe = sv;
X               av[ac] = '\0';
X               arg = pe+1;
X            }
X         }
X      }
X      else arg = ptr;
X      break;
X   case '*':
X   case '?':
X      if ((cstat & ST_NOEXP) == 0) doexpand = 1;
X      arg = ptr;
X      break;
X   default:
X      arg = ptr;
X      break;
X   }
X
X   /* Append arg to av[ac] */
X
X   for (scr = arg; *scr; ++scr) *scr &= 0x7F;
X   if (av[ac]) {
X      register char *old = av[ac];
X      av[ac] = mpush(strlen(arg)+strlen(av[ac]));
X      strcpy(av[ac], old);
X      strcat(av[ac], arg);
X   } else av[ac] = push_cpy(arg);
X   if (elast != 0x80) break;
X}
X
X/* process expansion */
X
Xif (doexpand) {
X	char **eav, **ebase;
X	int eac;
X
X	has_wild = 1;
X	eav = ebase = expand(av[ac], &eac);
X	inc = 0;
X	if (eav) {
X		if (ac + eac + 2 > MAXAV) {
X			ierror (NULL, 506);
X			err = 1;
X			}
X		else {
X			QuickSort(eav, eac);
X			for (; eac; --eac, ++eav) av[ac++] = push_cpy(*eav);
X			}
X		free_expand (ebase);
X		}
X	}
X
X/* process redirection  */
X
Xif (redir && !err) {
X	register char *file = doexpand ? av[--ac] : av[ac];
X
X	if (redir < 0) 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
Xif (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 args */
X		}
X	}
Xif (elast == ' ') goto step5;
X}
X
Xstepdone:
X
Xav[ac] = NULL;
X
X/* process pipes via files */
X
Xif (elast == '|' && !err) {
X	static int which;	/* 0 or 1 in case of multiple pipes */
X
X	which = 1 - which;
X	Cout_name = (which ? Pipe1 : Pipe2);
X	Cout_ispipe = 1;
X	}
X
Xif (err) goto done0;
X
X{
Xchar save_elast;
Xchar *compile_av();
Xregister char *avline;
Xunsigned char delim = ' ';
X
Xsave_elast = elast;
Xif (pend_alias || (cmd_stat(command) & ST_AV)) delim = 0xA0;
Xavline = compile_av(av,((pend_alias) ? 1 : 0), ac, delim, 0);
X
Xif (pend_alias) {	/* special % alias */
X	register char *ptr, *scr;
X
X	for (ptr = pend_alias; *ptr && *ptr != ' '; ++ptr);
X	set_var (LEVEL_SET, pend_alias + 1, avline);
X	free (avline);
X
X	scr = malloc((strlen(ptr) << 2) + 2);
X	preformat (ptr, scr);
X	fcomm (scr, 1);
X	unset_var (LEVEL_SET, pend_alias + 1);
X	}
Xelse {	/* normal command  */
X	register int ccno;
X	long oldcin  = Myprocess->pr_CIS;
X	long oldcout = Myprocess->pr_COS;
X	char *Cin_buf;
X	struct FileHandle *ci;
X	long oldbuf;
X
X	fflush(stdout);
X	ccno = find_command (command);
X	if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
X		if (Cin_name) {
X			if ((Cin = (long)extOpen(Cin_name,1005L)) == 0L) {
X				ierror (NULL, 504);
X				err = 1;
X				Cin_name = '\0';
X				}
X			else {
X				Myprocess->pr_CIS = _devtab[stdin->_unit].fd = Cin;
X				ci = (struct FileHandle *)(((long)Cin)<<2);
X				Cin_buf = (char *)AllocMem(202L, MEMF_PUBLIC);
X				oldbuf = ci->fh_Buf;
X				if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
X					ci->fh_Buf = (long)Cin_buf>>2;
X				}
X			}
X		if (Cout_name) {
X			if (Cout_append && (Cout =(long)extOpen(Cout_name, 1005L)) )
X				Seek(Cout, 0L, 1L);
X			else
X				Cout = (long)extOpen(Cout_name,1006L);
X			if (Cout == NULL) {
X				err = 1;
X				ierror (NULL, 504);
X				Cout_name = '\0';
X				Cout_append = 0;
X				}
X			else Myprocess->pr_COS = _devtab[stdout->_unit].fd = Cout;
X			}
X		}
X	if (ac < Command[ccno].minargs + 1) {
X		ierror (NULL, 500);
X		err = -1;
X		}
X	else if (!err) {
X		err = (*Command[ccno].func)(avline, Command[ccno].val);
X		if (err<0) err=20;
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))) {
X		if (Cin_name) {
X			fflush(stdin);
X			clearerr(stdin);
X			ci->fh_Buf = oldbuf;
X			extClose(Cin);
X			FreeMem(Cin_buf, 202L);
X			}
X		if (Cout_name) {
X			fflush(stdout);
X			clearerr(stdout);
X			stdout->_flags &= ~_DIRTY;	 /* because of nil: device */
X			extClose(Cout);
X			Cout_append = 0;
X			}
X		}
X	Myprocess->pr_CIS =  _devtab[stdin->_unit].fd  = oldcin;
X	Myprocess->pr_COS =  _devtab[stdout->_unit].fd = oldcout;
X	}
X
Xif (Cin_ispipe && Cin_name) DeleteFile(Cin_name);
Xif (Cout_ispipe) {
X	Cin_name = Cout_name;	/* ok to assign.. static name */
X	Cin_ispipe = 1;
X	}
Xelse Cin_name = '\0';
XCout_name = '\0';
XCout_ispipe = 0;
Xelast = save_elast;
X}
X
Xmpop_tobase();	/* free arguments   */
Xmpush_base();	/* push dummy base  */
X
Xdone0:
X
Xif (err && E_stack == 0) {
X	temp = get_var(LEVEL_SET, v_except);
X	if (err >= (temp ? atoi(temp) : 1)) {
X		if (temp) {
X			++H_stack;
X			++E_stack;
X			exec_command(temp);
X			--E_stack;
X			--H_stack;
X			}
X		else Exec_abortline = 1;
X		}
X	}
Xif (elast && ! Exec_abortline) err = fcomm(nextstr, 0);
XExec_abortline = 0;
Xif (Cin_name) DeleteFile(Cin_name);
XCin_name = NULL;
XCin_ispipe = 0;
X
Xdone1:
X
Xmpop_tobase();
Xif (freeok) free(str);
X--alias_count;
Xreturn err;	/* TRUE = error occured */
X}
X
X
Xchar *exarg(ptr)
Xunsigned char **ptr;
X{
Xregister unsigned char *start, *end;
X
Xstart = end = *ptr;
Xwhile(*end && *end!=0x80 && *end!=';' && *end!='|' && *end!=' ') ++end;
Xelast = *end;
X*end = '\0';
X*ptr = end + 1;
Xreturn (char *)start;
X}
X
Xstatic char **Mlist;
X
Xmpush_base()
X{
Xchar *str;
X
Xstr = malloc(5);
X*(char ***)str = Mlist;
Xstr[4] = 0;
XMlist = (char **)str;
X}
X
Xchar *mpush(bytes)
X{
Xchar *str;
X
Xstr = malloc(6 + bytes + 2); /* may need extra 2 bytes in do_run() */
X*(char ***)str = Mlist;
Xstr[4] = 1;
XMlist = (char **)str;
Xreturn (str + 5);
X}
X
Xmpop_tobase()
X{
Xregister char *next;
X
Xwhile (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 * Insert 'from' string in front of 'str' while deleting the
X * first entry in 'str'.  if freeok is set, then 'str' will be
X * free'd
X */
X
Xchar *format_insert_string(str, from, freeok)
Xchar *str;
Xchar *from;
Xint *freeok;
X{
Xregister char *new1, *new2;
Xregister unsigned char *strskip;
Xint len;
X
Xfor (strskip = (unsigned char *)str;
X		*strskip && *strskip != ' ' 
X		&& *strskip != ';' && *strskip != '|'
X		&& *strskip != 0x80; ++strskip);
Xlen = strlen(from);
Xnew1 = malloc((len << 2) + 2);
Xpreformat(from, new1);
Xlen = strlen(new1) + strlen(strskip);
Xnew2 = malloc(len+2);
Xstrcpy(new2, new1);
Xstrcat(new2, strskip);
Xnew2[len+1] = 0;
Xfree (new1);
Xif (*freeok) free (str);
X*freeok = 1;
Xreturn new2;
X}
X
Xcmd_stat(str)
Xchar *str;
X{
Xreturn(Command[find_command(str)].stat);
X}
X
Xfind_command(str)
Xchar *str;
X{
Xregister unsigned short i;
Xint len = strlen(str);
X
Xif (*str<'a' || *str>'z') return 0;
Xfor (i = 0; Command[i].func; ++i)
X	if ( ! strncmp(str, Command[i].name, len)) return (int)i;
Xreturn 0;
X}
X
Xdo_help()
X{
Xregister struct COMMAND *com;
Xint i=0;
X
Xfor (com = &Command[1]; com->func; ++com) {
X	printf ("%-12s", com->name);
X	if (++i % 6 == 0) printf("\n");
X	}
Xprintf("\n");
Xreturn 0;
X}
X
Xchar *push_cpy(s)
Xchar *s;
X{
Xreturn strcpy(mpush(strlen(s)), s);
X}
END_OF_FILE
if test 16435 -ne `wc -c <'src/execom.c'`; then
    echo shar: \"'src/execom.c'\" unpacked with wrong size!
fi
# end of 'src/execom.c'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 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.