1 /*- 2 * Copyright (c) 1986 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.proprietary.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)mysys.c 4.9 (Berkeley) 04/17/91"; 10 #endif /* not lint */ 11 12 #include <sys/signal.h> 13 #include "stdio.h" 14 #include "pathnames.h" 15 16 #define EASY 1 17 #define MEDIUM 2 18 #define HARD 3 19 #define EMAX 256 20 21 char *envp[EMAX+1]; 22 23 /* 24 * This routine edits the PATH environment variable so that 25 * special commands that learners may need will be found. 26 * EXINIT is modified so that the editor will always prompt, 27 * will not print \r's, and will be usable with open mode. 28 */ 29 30 chgenv() 31 { 32 register char **p; 33 register int i; 34 extern char **environ; 35 extern char *direct; 36 char path[BUFSIZ], exinit[BUFSIZ]; 37 char *malloc(); 38 39 sprintf(path, "%s/bin:", direct); 40 sprintf(exinit, "EXINIT=set prompt noopt open window=23"); 41 #if BSD4_2 42 system("stty old"); 43 for (p=environ,i=3; *p != 0 && i < EMAX; p++,i++) { 44 #else 45 for (p=environ,i=2; *p != 0 && i < EMAX; p++,i++) { 46 #endif 47 envp[i] = *p; 48 if (**p != 'P' && **p != 'E') 49 continue; 50 if (strncmp(*p, "PATH=", 5) == 0) 51 sprintf(path, "PATH=%s/bin:%s", direct, &envp[i--][5]); 52 else if (strncmp(*p, "EXINIT=", 7) == 0) 53 sprintf(exinit, "%s|set prompt noopt open window=23", envp[i--]); 54 #if BSD4_2 55 else if (strncmp(*p, "PS1=", 4) == 0) 56 i--; 57 } 58 envp[2] = malloc(7); 59 strcpy(envp[2], "PS1=% "); 60 #else 61 } 62 #endif 63 envp[0] = malloc(strlen(path) + 1); 64 strcpy(envp[0], path); 65 envp[1] = malloc(strlen(exinit) + 1); 66 strcpy(envp[1], exinit); 67 envp[i] = 0; 68 environ = envp; 69 } 70 71 mysys(s) 72 char *s; 73 { 74 /* like "system" but rips off "mv", etc.*/ 75 /* also tries to guess if can get away with exec cmd */ 76 /* instead of sh cmd */ 77 char p[300]; 78 char *np[40]; 79 register char *t; 80 int nv, type, stat; 81 82 type = EASY; /* we hope */ 83 for (t = s; *t && type != HARD; t++) { 84 switch (*t) { 85 case '*': 86 case '[': 87 case '?': 88 case '>': 89 case '<': 90 case '$': 91 case '\'': 92 case '"': 93 case '`': 94 case '{': 95 case '~': 96 type = MEDIUM; 97 break; 98 case '|': 99 case ';': 100 case '&': 101 type = HARD; 102 break; 103 } 104 } 105 switch (type) { 106 case HARD: 107 return(system(s)); 108 case MEDIUM: 109 strcpy(p, "exec "); 110 strcat(p, s); 111 return(system(p)); 112 case EASY: 113 strcpy(p,s); 114 nv = getargs(p, np); 115 t=np[0]; 116 if ((strcmp(t, "mv") == 0)|| 117 (strcmp(t, "cp") == 0)|| 118 (strcmp(t, "rm") == 0)|| 119 (strcmp(t, "ls") == 0) ) { 120 if (fork() == 0) { 121 char b[100]; 122 signal(SIGINT, SIG_DFL); 123 np[nv] = 0; 124 execvp(t, np); 125 perror(t); 126 fprintf(stderr, "Mysys: execv failed on %s\n", np); 127 exit(1); 128 } 129 wait(&stat); 130 return(stat); 131 } 132 return(system(s)); 133 } 134 } 135 136 /* 137 * system(): 138 * same as library version, except that resets 139 * default handling of signals in child, so that 140 * user gets the behavior he expects. 141 */ 142 143 system(s) 144 char *s; 145 { 146 register int pid, w; 147 sig_t istat, qstat; 148 int status; 149 150 istat = signal(SIGINT, SIG_IGN); 151 qstat = signal(SIGQUIT, SIG_IGN); 152 if ((pid = fork()) == 0) { 153 signal(SIGINT, SIG_DFL); 154 signal(SIGQUIT, SIG_DFL); 155 execl(_PATH_CSHELL, "csh", "-cf", s, 0); 156 _exit(127); 157 } 158 while ((w = wait(&status)) != pid && w != -1) 159 ; 160 if (w == -1) 161 status = -1; 162 (void)signal(SIGINT, istat); 163 (void)signal(SIGQUIT, qstat); 164 return(status); 165 } 166 167 getargs(s, v) 168 char *s, **v; 169 { 170 int i; 171 172 i = 0; 173 for (;;) { 174 v[i++]=s; 175 while (*s != 0 && *s!=' '&& *s != '\t') 176 s++; 177 if (*s == 0) 178 break; 179 *s++ =0; 180 while (*s == ' ' || *s == '\t') 181 s++; 182 if (*s == 0) 183 break; 184 } 185 return(i); 186 } 187