BSD 2 development
[unix-history] / src / dribble.c
CommitLineData
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
7int inpipe[2], outpipe[2];
8
9int dribfil;
10int inpid, outpid, cmdpid;
11int badpipe();
12char *nargv[3] = { "/bin/csh", "-i", 0 };
13
14main(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) {
23piperr:
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
82outloop()
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
105input()
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
148error(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
159badpipe()
160{
161
162 kill(cmdpid, SIGKILL);
163 kill(outpid, SIGKILL);
164 exit(1);
165}
166
167doexec(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}