1 /*-
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)mysys.c 8.1 (Berkeley) 06/06/93";
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
chgenv()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
mysys(s)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
system(s)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
getargs(s,v)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