Commit | Line | Data |
---|---|---|
7fd877f3 BJ |
1 | /* Copyright (c) 1979 Regents of the University of California */ |
2 | #include <signal.h> | |
3 | #include <errno.h> | |
4 | ||
5 | #define BUFSIZ 512 | |
6 | ||
7 | int inpipe[2], outpipe[2]; | |
8 | ||
9 | int dribfil; | |
10 | int inpid, outpid, cmdpid; | |
11 | int badpipe(); | |
12 | char *nargv[3] = { "/bin/csh", "-i", 0 }; | |
13 | ||
14 | main(argc, argv) | |
15 | char *argv[]; | |
16 | { | |
17 | int status; | |
18 | ||
19 | argc--, argv++; | |
20 | if (argc < 0) | |
21 | error("Usage: dribble [ dribble.out [ command ] ] ..."); | |
22 | if (pipe(outpipe) < 0) { | |
23 | piperr: | |
24 | perror("pipe"); | |
25 | exit(1); | |
26 | } | |
27 | dribfil = creat(argc == 0 ? "dribble.out" : argv[0], 0644); | |
28 | if (dribfil < 0) { | |
29 | perror(argc == 0 ? "dribble.out" : argv[0]); | |
30 | exit(1); | |
31 | } | |
32 | if (argc <= 1) { | |
33 | argv = nargv - 1; | |
34 | argc = 3; | |
35 | if (getenv("SHELL")) | |
36 | argv[1] = getenv("SHELL"); | |
37 | else | |
38 | argv[1] = "/bin/sh"; | |
39 | } | |
40 | inpid = getpid(); | |
41 | outpid = fork(); | |
42 | if (outpid < 0) | |
43 | error("No more processes"); | |
44 | if (outpid == 0) { | |
45 | signal(SIGINT, SIG_IGN); | |
46 | close(0); | |
47 | close(2); | |
48 | close(outpipe[1]); | |
49 | outloop(); | |
50 | /* no return */ | |
51 | } | |
52 | signal(SIGTRAP, SIG_IGN); | |
53 | if (pipe(inpipe) < 0) | |
54 | goto piperr; | |
55 | cmdpid = fork(); | |
56 | if (cmdpid < 0) { | |
57 | kill(outpid, SIGKILL); | |
58 | error("No more processes"); | |
59 | } | |
60 | if (cmdpid == 0) { | |
61 | close(0); | |
62 | dup(inpipe[0]); | |
63 | close(1); | |
64 | dup(outpipe[1]); | |
65 | close(inpipe[0]); | |
66 | close(inpipe[1]); | |
67 | close(outpipe[0]); | |
68 | close(outpipe[1]); | |
69 | close(2); | |
70 | dup(1); | |
71 | argv[argc] = 0; | |
72 | argv++; | |
73 | doexec(argv[0], &argv[0]); | |
74 | /* no return */ | |
75 | } | |
76 | signal(SIGPIPE, badpipe); | |
77 | close(inpipe[0]); | |
78 | close(outpipe[0]); | |
79 | input(); | |
80 | } | |
81 | ||
82 | outloop() | |
83 | { | |
84 | int cnt; | |
85 | char linebuf[BUFSIZ]; | |
86 | int bufcnt; | |
87 | extern int errno; | |
88 | ||
89 | bufcnt = 0; | |
90 | for (;;) { | |
91 | errno = 0; | |
92 | bufcnt = read(outpipe[0], linebuf, BUFSIZ); | |
93 | if (bufcnt == 0) | |
94 | break; | |
95 | if (bufcnt > 0) { | |
96 | linebuf[bufcnt] = 0; | |
97 | write(dribfil, linebuf, bufcnt); | |
98 | write(1, linebuf, bufcnt); | |
99 | } | |
100 | } | |
101 | kill(inpid, SIGPIPE); | |
102 | exit(0); | |
103 | } | |
104 | ||
105 | input() | |
106 | { | |
107 | register int i; | |
108 | char linebuf[BUFSIZ]; | |
109 | int bufcnt; | |
110 | ||
111 | signal(SIGINT, SIG_IGN); | |
112 | for (;;) { | |
113 | do { | |
114 | bufcnt = read(0, linebuf, BUFSIZ); | |
115 | if (bufcnt == 0) { | |
116 | linebuf[0] = 4; | |
117 | linebuf[1] = '\n'; | |
118 | linebuf[2] = 0; | |
119 | write(inpipe[1], linebuf, 3); | |
120 | continue; | |
121 | } | |
122 | if (bufcnt == 3 && linebuf[0] == 'E' && | |
123 | linebuf[1] == 'O' && linebuf[2] == 'F') { | |
124 | bufcnt = 4; | |
125 | linebuf[3] = '\n'; | |
126 | write(1, "\n", 1); | |
127 | write(dribfil, linebuf, bufcnt); | |
128 | bufcnt = 0; | |
129 | break; | |
130 | } | |
131 | if (bufcnt > 0) { | |
132 | write(dribfil, linebuf, bufcnt); | |
133 | write(inpipe[1], linebuf, bufcnt); | |
134 | } | |
135 | } while (bufcnt > 0); | |
136 | if (bufcnt == 0) { | |
137 | int status; | |
138 | ||
139 | close(inpipe[1]); | |
140 | do | |
141 | i = wait(&status); | |
142 | while (i > 0 && i != cmdpid); | |
143 | exit(1); | |
144 | } | |
145 | } | |
146 | } | |
147 | ||
148 | error(cp, a1, a2, a3, a4) | |
149 | char *cp; | |
150 | { | |
151 | ||
152 | close(1); | |
153 | open("/dev/tty", 1); | |
154 | printf(cp, a1, a2, a3, a4); | |
155 | putchar('\n'); | |
156 | exit(1); | |
157 | } | |
158 | ||
159 | badpipe() | |
160 | { | |
161 | ||
162 | kill(cmdpid, SIGKILL); | |
163 | kill(outpid, SIGKILL); | |
164 | exit(1); | |
165 | } | |
166 | ||
167 | doexec(cmd, args) | |
168 | char *cmd; | |
169 | char *args[]; | |
170 | { | |
171 | char cmdbuf[120]; | |
172 | ||
173 | strcpy(cmdbuf, ""); | |
174 | strcat(cmdbuf, cmd); | |
175 | execv(cmdbuf, args); | |
176 | strcpy(cmdbuf, "/usr/new/"); | |
177 | strcat(cmdbuf, cmd); | |
178 | execv(cmdbuf, args); | |
179 | strcpy(cmdbuf, "/bin/"); | |
180 | strcat(cmdbuf, cmd); | |
181 | execv(cmdbuf, args); | |
182 | strcpy(cmdbuf, "/usr/bin/"); | |
183 | strcat(cmdbuf, cmd); | |
184 | execv(cmdbuf, args); | |
185 | error("%s: Cannot find", cmd); | |
186 | } |