/* shell.c contains the routines to allow exec calls. If there were a * small command interpreter somewhere, we could do a real spawn. * If you compile this to run from a shell, undefine GEMLOAD. Since * shells eat memory, you can't give as much back to the OS. If you * will be using this from GEM, give back 256K and you'll be able to * run just about any program from within the editor. */ #include "shell.h" #ifdef GEMLOAD unsigned long _STKSIZ = -262144; /* give back 256K to the OS */ #else unsigned long _STKSIZ = -147456; /* give back 144K to the OS */ #endif char cline[MAXINPUT * 2]; /* holds the command line and other things */ char pnam[MAXINPUT+1]; /* program name */ char source[MAXINPUT+1]; /* name of file for aliasing */ char path[MAXPATH+1]; /* current path string */ int delete = TRUE; /* on/off for above */ int dolink = 0; /* link a program */ int temdrv; int curdrv; ALITAB *aheadp = NULL; /* alias header */ shell(f, n) register int f, n; { extern char *alias(), *index(), *rindex(); register char *ptr; if ((f=mlreply("!: ",cline,MAXINPUT))!=TRUE) return(f); if ((ptr=index(cline,' '))!=(char *)NULL) { *ptr = '\0'; strcpy(pnam,cline); strcpy(&cline[1],++ptr); } else { strcpy(pnam,cline); strcpy(&cline[1]," "); } if (pnam[0] == '~') parsefn(pnam); if (alias(source,pnam)!=(char *)NULL) strcpy(pnam,source); /* check for file type (prg) and append if not there */ if ((ptr=rindex(pnam,'\\'))!=(char *)NULL) /* don't be fooled */ { /* by \foo.dir\bar */ if (!index(ptr,'.')) strcat(ptr,".prg"); } else if (rindex(pnam,'.')==(char *)NULL) strcat(pnam,".prg"); if (cline[1] == '~') parsefn(&cline[1]); while((ptr=index(&cline[1], '~'))!=(char *)NULL) if (!parsefn(ptr)) break; cline[0] = (char)strlen(&cline[1]); ttclose(); /* reset terminal characteristics */ ttputc(0x1b); ttputc('E'); Setexc(2,buserr); /* use default exception handlers */ Setexc(3,adderr); f = (int)Pexec(0,pnam,cline,0L); Setexc(2,&errexit); /* reset local handlers */ Setexc(3,&errexit); mtwrite("[Type a ]"); ttgetc(); ttopen(); /* turn on uemail screen */ if (f == FALSE && n == HUGE) /* called from term */ ; else { sgarbf = TRUE; /* force full redraw */ upmode(); /* set colors */ update(); /* fix screen */ } mlwrite("Return from %s = %d",pnam,f); return(TRUE); } /* read in the cc.ini file if it's on the default drive. Called once at * editor startup and later by command. Bound to CTRL-C. */ commfil(f,n) register int f,n; { FILE *fopen(); register FILE *fp; char *fgets(),*index(); char *ptr; static char line[MAXINPUT+1]; /* for the call from main */ if (f == FALSE && n == HUGE) { if ((fp=fopen("cc.ini","r")) == NULL) { Dgetpath(path,0); mlwrite("Cannot open %s\\cc.ini",path); return(FALSE); } } else { if ((f=mlreply("Command file: ",line,MAXINPUT))!=TRUE) return(f); if (line[0] == '~') parsefn(line); if ((fp=fopen(line, "r"))==NULL) { mlwrite("Cannot open %s",line); return(FALSE); } } while (fgets(line,MAXINPUT,fp)) { /* kill trailing whitespace */ if ((ptr=index(line,'\n'))!=(char *)NULL) *ptr = '\0'; if ((ptr=index(line,' '))!=(char *)NULL) *ptr = '\0'; if ((ptr=index(line,'\t'))!=(char *)NULL) *ptr = '\0'; /* terminate alias and get address of path */ if ((ptr=index(line,'='))!=(char *)NULL) *ptr = '\0'; else /* improper line */ continue; ++ptr; /* now equals &path[0] */ /* test two cases that aren't easy in a switch */ if (strcmp(line,"F10")==NULL) { bindkey((SPEC|'D'),ptr); continue; } if (strcmp(line,"NENTER")==NULL) { bindkey((SPEC|'r'),ptr); continue; } f = strlen(line); n = strlen(ptr); /* bind function keys */ if (line[0] == 'F' && f == 2) { switch(line[1]) { case '1': bindkey((SPEC|';'),ptr); break; case '2': bindkey((SPEC|'<'),ptr); break; case '3': bindkey((SPEC|'='),ptr); break; case '4': bindkey((SPEC|'>'),ptr); break; case '5': bindkey((SPEC|'?'),ptr); break; case '6': bindkey((SPEC|'@'),ptr); break; case '7': bindkey((SPEC|'A'),ptr); break; case '8': bindkey((SPEC|'B'),ptr); break; case '9': bindkey((SPEC|'C'),ptr); break; default: break; } } /* or maybe a number pad key */ else if (line[0] == 'N' && f == 2) { switch(line[1]) { case '(': bindkey((SPEC|'c'),ptr); break; case ')': bindkey((SPEC|'d'),ptr); break; case '/': bindkey((SPEC|'e'),ptr); break; case '*': bindkey((SPEC|'f'),ptr); break; case '7': bindkey((SPEC|'g'),ptr); break; case '8': bindkey((SPEC|'h'),ptr); break; case '9': bindkey((SPEC|'i'),ptr); break; case '-': bindkey((SPEC|'J'),ptr); break; case '4': bindkey((SPEC|'j'),ptr); break; case '5': bindkey((SPEC|'k'),ptr); break; case '6': bindkey((SPEC|'l'),ptr); break; case '+': bindkey((SPEC|'N'),ptr); break; case '1': bindkey((SPEC|'m'),ptr); break; case '2': bindkey((SPEC|'n'),ptr); break; case '3': bindkey((SPEC|'o'),ptr); break; case '.': bindkey((SPEC|'q'),ptr); break; default: break; } } /* search for a match */ /* check possible alias definitions */ else if (insalias(line,ptr)==FALSE) { fclose(fp); return(FALSE); } else if (feof(fp)) break; } fclose(fp); return(TRUE); } insalias(al,pa) register char *al; register char *pa; { register int f, n; register ALITAB *apt; register int found; found = FALSE; if (aheadp == NULL) { if ((aheadp=(ALITAB *)malloc(sizeof(ALITAB)))==NULL) { mlwrite("Cannot allocate %d bytes",sizeof(ALITAB)); return(FALSE); } if ((aheadp->alias=malloc(5))==NULL) { mlwrite("Alias alloc failure"); return(FALSE); } if ((aheadp->value=malloc(11))==NULL) { mlwrite("Alias alloc failure"); return(FALSE); } strcpy(aheadp->alias,"home"); strcpy(aheadp->value,"c:\\uemail\\"); aheadp->a_forw = NULL; } n = strlen(pa); f = strlen(al); apt = aheadp; while (apt) { if (strcmp(apt->alias,al)==NULL) { free(apt->value); if((apt->value=malloc(n+1))==NULL) { mlwrite("Alias alloc failure %s",pa); return(FALSE); } strcpy(apt->value,pa); found == TRUE; } if (apt->a_forw) apt=apt->a_forw; else break; } if (found) return(TRUE); /* not already bound */ if ((apt->a_forw=(ALITAB *)malloc(sizeof(ALITAB)))== NULL) { mlwrite("Cannot allocate %d bytes",sizeof(ALITAB)); return(FALSE); } apt=apt->a_forw; apt->a_forw=NULL; if ((apt->alias=malloc(f+1))==NULL) { mlwrite("Alias alloc failure %s",al); return(FALSE); } if ((apt->value=malloc(n+1))==NULL) { mlwrite("Alias alloc failure %s",pa); return(FALSE); } strcpy(apt->alias,al); strcpy(apt->value,pa); return(TRUE); }