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