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.