#ifdef MSDOS /* { */ #include "grep_msd.h" #endif /* } */ char sccsID[] = "@(#) csh.c V1.0 Copyright http://berklix.com (pjc) 1987\n"; /* Csh.c - A shell by PJAC */ #include "csh.h" /* * name of shell used to execute shell scripts */ #ifdef MSDOS #define DEF_SHELL "c:/bin/local/csh.exe" #else #define DEF_SHELL "/usr/bin/local/csh" #endif char SHELL[MAX_CWD]; char *in_buf; char *in_bufp; int in_len; int in_ifd; int in_ofd; int in_efd; char *in_savblk; char *Args[MAXARGS]; int Argc = 0; char CWD[MAX_CWD]; char HOME[MAX_CWD]; char *IFS; char *Prompt[2]; char **Real_Environ; int Nenvir; char *Path; char Special[] = "<>|();&\"'`"; char IPipe[MAX_CWD]; /* name of pipe file, delete if exists */ char OPipe[MAX_CWD]; char *dirstack[MAX_DSTACK]; int ndirstack; struct inbuilt incmds[] = { "cd", do_cd, "set", do_set, "history", do_hist, "alias", do_alias, "pwd", do_pwd, "unset", do_unset, "setenv", do_setenv, "unsetenv", do_u_nsetenv, "unalias", do_ualias, #ifdef MSDOS "drive", do_drive, #endif "echo", do_echo, "pushd", do_pushd, "popd", do_popd, "dirs", do_dirs, "exit", do_exit, "printenv", do_prtenv, "rehash", do_rehash, "foreach", do_for, "shift", do_shift, "while", do_while, "break", do_brk, "continue", do_cont, "end", do_end, "source", do_source, "if", do_if, ":", do_colon, "@", do_atsign, #ifdef MSDOS "ctty", do_ctty, #endif 0, 0, }; struct lvars *Lvars; /* * the list of aliases */ struct lvars *Aliases; /* * structure to store parse tree state */ struct cmd *ctree; char **History; int Curcnum; int Hist_siz = -1; char *last_cmd; struct ins in_bufs[MAX_INS], *Cur_ins; jmp_buf env_main; int ctrlcret; int status; int noglob; int igneof; char mustcd = FALSE; /* various flags */ char cflag, eflag, fflag, iflag, nflag, sflag, tflag; char vflag, xflag, XVflag, Pflag; char Lflag; /* flag, set if login shell */ char sh_script; /* set if current command is a shell script */ char in_cshrc; /* set if reading cshrc */ char *scr_name; char hist_expand; char **ARGV ; main(ac, av) char **av; { int result = 0; int state; #ifdef VSL /* { */ extern vsl() ; ARGV = av ; #include "../../include/vsl.h" #endif /* } */ proc_args(ac, av); init(*av); bld_hash(); /* build the command hash tables */ if(!fflag) cshrc(); for(;;){ re_start(); if(scr_name && !in_cshrc){ /* open shell scipt */ char *p; result = set_input(p = scr_name, FALSE); scr_name = 0; if(result != OK){ if(cflag){ puterr("Can't open '"); puterr(p); puterr("'.\n"); } _exit(ERR); } } state = setjmp(env_main); if(state != 0){ switch(state){ case INTERUPT: /* command interupted */ break; case BADPARSE: puterr("Syntax error.\n"); break; case NOMEM: puterr("No mem.\n"); break; case EXPRERR: puterr("Expression error.\n"); break; } pop_in(TRUE); if(Pflag) continue; if(eflag || tflag || sh_script) _exit(ERR); continue; } if(Prompt[0]) put_prompt(Prompt[0]); hist_expand = FALSE; if(readin() == EOF){ if(pop_in(FALSE) == OK) continue; if(in_cshrc){ in_cshrc = FALSE; end_cshrc(); continue; } if(Pflag || igneof) continue; _exit(result); } if(hist_expand){ put_s(in_buf); put_s("\n"); } parse(in_buf, &ctree); if(ctree == 0) continue; if(!in_cshrc && Cur_ins == in_bufs) add_to_hist(); if(vflag && (!in_cshrc || XVflag)){ put_s(in_buf); put_s("\n"); } result = rtree(ctree); status = result; if(Pflag) continue; if(eflag && result) break; if(tflag && !in_cshrc) break; } _exit(result); } proc_args(ac, av) char **av; { char *opts; if(strcmp(av[0], "-") == 0) Lflag = TRUE; /* first process args */ for(ac--, av++ ; *av ; av++, ac--){ if(*(opts = *av) != '-') break; for(;*opts ; opts++) switch(*opts){ case 'c': cflag = TRUE; break; case 'e': eflag = TRUE; break; case 'f': fflag = TRUE; break; case 'i': iflag = TRUE; break; case 'n': nflag = TRUE; break; case 's': sflag = TRUE; break; case 't': tflag = TRUE; break; case 'V': XVflag = TRUE; /* fall through */ case 'v': vflag = TRUE; break; case 'X': XVflag = TRUE; /* fall through */ case 'x': xflag = TRUE; break; case 'P': Pflag = TRUE; break; } } if(cflag && !ac){ if(Pflag) cflag = 0; else _exit(1); } if(ac){ /* got arguments, must be a shell script */ sh_script = TRUE; scr_name = *av; } if(cflag){ if(ac > 1) set_avs("argv", ac-1, av+1); } else if(ac) set_avs("argv", ac, av); } /* * start everything off */ init(av0) char *av0; { char *getenv(); char *p, **xp, **x1p; char *av[2]; dup2(0, 10); /* move stdin and stdout, out of the way */ dup2(1, 11); dup2(2, 12); in_ifd = 10; in_ofd = 11; in_efd = 12; close(0); close(1); close(2); Cur_ins = in_bufs; Cur_ins->i_nleft = 0; Cur_ins->i_fd = in_ifd; /* input is from stdin */ Cur_ins->i_buf = mmalloc(MAXINLINE+1); /* allocate an input buffer */ get_dir(); /* now get path */ if( (p = getenv("PATH")) == NULL) p = INIT_PATH; Path = strsave(p); /* path components are split by ';' */ to_fslash(Path); /* get all strings to be '/'ed */ to_low(Path); if(vflag) set_avl("verbose", (char *)0); if((p = getenv("SHELL")) == NULL){ /* get the shell var */ #ifdef MSDOS p = av0; if(p== 0 || *p == 0) p = DEF_SHELL; #else p = DEF_SHELL; #endif } set_avl("shell", p); set_avl("prompt", INIT_PROMPT); /* set up prompts */ Prompt[1] = strsave(INIT_SPROMPT); /* set up prompts */ if((p = getenv("HOME")) == NULL) /* set up home directory */ p = CWD; set_avl("home", p); if(xflag) set_avl("echo", (char *)0); if((p = getenv("IFS")) == NULL) /* get IFS string */ p = INIT_IFS; IFS = strsave(p); in_buf = mmalloc(MAXINLINE+1); in_len = MAXINLINE; Curcnum = 1; /* * set up environment */ for(xp = environ ; *xp ; xp++, Nenvir++); Real_Environ = (char **)mmalloc(sizeof(char *)*(Nenvir+1)); for(x1p = Real_Environ, xp = environ ; (*x1p++ = *xp++);); } /* * reinitialise all variables */ re_start() { int ctrlctrap(); dup2(in_ifd, 0); dup2(in_ofd, 1); dup2(in_efd, 2); if(mustcd){ mustcd = FALSE; #ifdef MSDOS if(chdir(CWD) < 0){ puterr("Cannot CHDIR back - CWD is now "); get_dir(); puterr(CWD); puterr("\n"); } #endif } if(ctree){ /* junk last command tree */ free_tree(ctree); ctree = 0; if(*IPipe){ /* close and junk any pipes */ unlink(IPipe); *IPipe = 0; } if(*OPipe){ /* close and junk any pipes */ unlink(OPipe); *OPipe = 0; } } if(in_savblk){ free(in_savblk); in_savblk = 0; } signal(SIGINT, ctrlctrap); ctrlcret = INTERUPT; } ctrlctrap() { signal(SIGINT, SIG_IGN); longjmp(env_main, ctrlcret); } /* * Try to execute the cshrc file */ static int cshrc_fd; cshrc() { char lbuf[128]; strcpy(lbuf, HOME); strcat(lbuf, "/cshrc"); cshrc_fd = Cur_ins->i_fd; re_start(); /* get the fd's back */ if(set_input(lbuf, FALSE) == OK) in_cshrc = TRUE; } /* * source a file */ do_source(argc, argv) char **argv; { if(argc < 2) syn_err(); return(set_input(argv[1], TRUE)); } /* * set input to be file - used by shell scripts and cshrc and sourceing */ set_input(file, is_source) char *file; { int fd; if(!is_source && Cur_ins != in_bufs) return(ERR); if(is_source && Cur_ins >= &in_bufs[MAX_INS]){ puterr("No resources for source.\n"); return(ERR); } fd = open(file, 0); if(fd < 0){ if(is_source) puterr("Can't open source file.\n"); return(ERR); } if(is_source){ Cur_ins++; Cur_ins->i_buf = mmalloc(MAXINLINE+1); /* allocate buffer */ } Cur_ins->i_nleft = 0; Cur_ins->i_fd = fd; return(OK); } end_cshrc() { close(Cur_ins->i_fd); Cur_ins->i_fd = cshrc_fd; } /* * pop the input source stack */ pop_in(unstack) { struct forblk *fp; char **xp; if(Cur_ins < &in_bufs[1]) return(ERR); while(Cur_ins >= &in_bufs[1]){ if(fp = Cur_ins->i_fblk){ if(fp->F_name) free(fp->F_name); if(xp = fp->F_argv){ while(*xp) free(*xp++); free( (char *)fp->F_argv); } free( (char *)fp); Cur_ins->i_fblk = 0; } else close(Cur_ins->i_fd); free(Cur_ins->i_buf); Cur_ins--; if(!unstack) break; } return(OK); }