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