xref: /original-bsd/usr.bin/learn/learn/mysys.c (revision cba8738a)
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