BSD 2 development
[unix-history] / src / dribble.c
/* Copyright (c) 1979 Regents of the University of California */
#include <signal.h>
#include <errno.h>
#define BUFSIZ 512
int inpipe[2], outpipe[2];
int dribfil;
int inpid, outpid, cmdpid;
int badpipe();
char *nargv[3] = { "/bin/csh", "-i", 0 };
main(argc, argv)
char *argv[];
{
int status;
argc--, argv++;
if (argc < 0)
error("Usage: dribble [ dribble.out [ command ] ] ...");
if (pipe(outpipe) < 0) {
piperr:
perror("pipe");
exit(1);
}
dribfil = creat(argc == 0 ? "dribble.out" : argv[0], 0644);
if (dribfil < 0) {
perror(argc == 0 ? "dribble.out" : argv[0]);
exit(1);
}
if (argc <= 1) {
argv = nargv - 1;
argc = 3;
if (getenv("SHELL"))
argv[1] = getenv("SHELL");
else
argv[1] = "/bin/sh";
}
inpid = getpid();
outpid = fork();
if (outpid < 0)
error("No more processes");
if (outpid == 0) {
signal(SIGINT, SIG_IGN);
close(0);
close(2);
close(outpipe[1]);
outloop();
/* no return */
}
signal(SIGTRAP, SIG_IGN);
if (pipe(inpipe) < 0)
goto piperr;
cmdpid = fork();
if (cmdpid < 0) {
kill(outpid, SIGKILL);
error("No more processes");
}
if (cmdpid == 0) {
close(0);
dup(inpipe[0]);
close(1);
dup(outpipe[1]);
close(inpipe[0]);
close(inpipe[1]);
close(outpipe[0]);
close(outpipe[1]);
close(2);
dup(1);
argv[argc] = 0;
argv++;
doexec(argv[0], &argv[0]);
/* no return */
}
signal(SIGPIPE, badpipe);
close(inpipe[0]);
close(outpipe[0]);
input();
}
outloop()
{
int cnt;
char linebuf[BUFSIZ];
int bufcnt;
extern int errno;
bufcnt = 0;
for (;;) {
errno = 0;
bufcnt = read(outpipe[0], linebuf, BUFSIZ);
if (bufcnt == 0)
break;
if (bufcnt > 0) {
linebuf[bufcnt] = 0;
write(dribfil, linebuf, bufcnt);
write(1, linebuf, bufcnt);
}
}
kill(inpid, SIGPIPE);
exit(0);
}
input()
{
register int i;
char linebuf[BUFSIZ];
int bufcnt;
signal(SIGINT, SIG_IGN);
for (;;) {
do {
bufcnt = read(0, linebuf, BUFSIZ);
if (bufcnt == 0) {
linebuf[0] = 4;
linebuf[1] = '\n';
linebuf[2] = 0;
write(inpipe[1], linebuf, 3);
continue;
}
if (bufcnt == 3 && linebuf[0] == 'E' &&
linebuf[1] == 'O' && linebuf[2] == 'F') {
bufcnt = 4;
linebuf[3] = '\n';
write(1, "\n", 1);
write(dribfil, linebuf, bufcnt);
bufcnt = 0;
break;
}
if (bufcnt > 0) {
write(dribfil, linebuf, bufcnt);
write(inpipe[1], linebuf, bufcnt);
}
} while (bufcnt > 0);
if (bufcnt == 0) {
int status;
close(inpipe[1]);
do
i = wait(&status);
while (i > 0 && i != cmdpid);
exit(1);
}
}
}
error(cp, a1, a2, a3, a4)
char *cp;
{
close(1);
open("/dev/tty", 1);
printf(cp, a1, a2, a3, a4);
putchar('\n');
exit(1);
}
badpipe()
{
kill(cmdpid, SIGKILL);
kill(outpid, SIGKILL);
exit(1);
}
doexec(cmd, args)
char *cmd;
char *args[];
{
char cmdbuf[120];
strcpy(cmdbuf, "");
strcat(cmdbuf, cmd);
execv(cmdbuf, args);
strcpy(cmdbuf, "/usr/new/");
strcat(cmdbuf, cmd);
execv(cmdbuf, args);
strcpy(cmdbuf, "/bin/");
strcat(cmdbuf, cmd);
execv(cmdbuf, args);
strcpy(cmdbuf, "/usr/bin/");
strcat(cmdbuf, cmd);
execv(cmdbuf, args);
error("%s: Cannot find", cmd);
}