summaryrefslogtreecommitdiff
path: root/ucspi-tcp-0.88/recordio.c
diff options
context:
space:
mode:
Diffstat (limited to 'ucspi-tcp-0.88/recordio.c')
-rw-r--r--ucspi-tcp-0.88/recordio.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/ucspi-tcp-0.88/recordio.c b/ucspi-tcp-0.88/recordio.c
new file mode 100644
index 0000000..a3ee03c
--- /dev/null
+++ b/ucspi-tcp-0.88/recordio.c
@@ -0,0 +1,178 @@
+#include "sig.h"
+#include "buffer.h"
+#include "strerr.h"
+#include "str.h"
+#include "byte.h"
+#include "readwrite.h"
+#include "exit.h"
+#include "fmt.h"
+#include "iopause.h"
+#include "pathexec.h"
+
+#define FATAL "recordio: fatal: "
+
+char pid[FMT_ULONG];
+
+char recordbuf[512];
+buffer ssrecord = BUFFER_INIT(write,2,recordbuf,sizeof recordbuf);
+
+void record(char *buf,int len,char *direction) /* 1 <= len <= 256 */
+{
+ int i;
+
+ while (len) {
+ buffer_puts(&ssrecord,pid);
+ buffer_puts(&ssrecord,direction);
+
+ i = byte_chr(buf,len,'\n');
+ buffer_put(&ssrecord,buf,i);
+
+ if (i == len) {
+ buffer_puts(&ssrecord,"+\n");
+ buffer_flush(&ssrecord);
+ return;
+ }
+
+ buffer_puts(&ssrecord," \n");
+ buffer_flush(&ssrecord);
+ buf += i + 1;
+ len -= i + 1;
+ }
+}
+
+int leftstatus = 0;
+char leftbuf[256];
+int leftlen;
+int leftpos;
+
+int rightstatus = 0;
+char rightbuf[256];
+int rightlen;
+int rightpos;
+
+void doit(int fdleft,int fdright) /* copy 0 -> fdleft, copy fdright -> 1 */
+{
+ struct taia stamp;
+ struct taia deadline;
+ iopause_fd x[4];
+ int xlen;
+ iopause_fd *io0;
+ iopause_fd *ioleft;
+ iopause_fd *io1;
+ iopause_fd *ioright;
+ int r;
+
+ for (;;) {
+ xlen = 0;
+
+ io0 = 0;
+ if (leftstatus == 0) {
+ io0 = &x[xlen++];
+ io0->fd = 0;
+ io0->events = IOPAUSE_READ;
+ }
+ ioleft = 0;
+ if (leftstatus == 1) {
+ ioleft = &x[xlen++];
+ ioleft->fd = fdleft;
+ ioleft->events = IOPAUSE_WRITE;
+ }
+
+ ioright = 0;
+ if (rightstatus == 0) {
+ ioright = &x[xlen++];
+ ioright->fd = fdright;
+ ioright->events = IOPAUSE_READ;
+ }
+ io1 = 0;
+ if (rightstatus == 1) {
+ io1 = &x[xlen++];
+ io1->fd = 1;
+ io1->events = IOPAUSE_WRITE;
+ }
+
+ taia_now(&stamp);
+ taia_uint(&deadline,3600);
+ taia_add(&deadline,&stamp,&deadline);
+ iopause(x,xlen,&deadline,&stamp);
+
+ if (io0 && io0->revents) {
+ r = read(0,leftbuf,sizeof leftbuf);
+ if (r <= 0) {
+ leftstatus = -1;
+ close(fdleft);
+ buffer_puts(&ssrecord,pid);
+ buffer_puts(&ssrecord," < [EOF]\n");
+ buffer_flush(&ssrecord);
+ }
+ else {
+ leftstatus = 1; leftpos = 0; leftlen = r;
+ record(leftbuf,r," < ");
+ }
+ }
+
+ if (ioleft && ioleft->revents) {
+ r = write(fdleft,leftbuf + leftpos,leftlen - leftpos);
+ if (r == -1) break;
+ leftpos += r;
+ if (leftpos == leftlen) leftstatus = 0;
+ }
+
+ if (ioright && ioright->revents) {
+ r = read(fdright,rightbuf,sizeof rightbuf);
+ if (r <= 0) {
+ buffer_puts(&ssrecord,pid);
+ buffer_puts(&ssrecord," > [EOF]\n");
+ buffer_flush(&ssrecord);
+ break;
+ }
+ rightstatus = 1; rightpos = 0; rightlen = r;
+ record(rightbuf,r," > ");
+ }
+
+ if (io1 && io1->revents) {
+ r = write(1,rightbuf + rightpos,rightlen - rightpos);
+ if (r == -1) break;
+ rightpos += r;
+ if (rightpos == rightlen) rightstatus = 0;
+ }
+ }
+
+ _exit(0);
+}
+
+main(int argc,char **argv,char **envp)
+{
+ int piin[2];
+ int piout[2];
+
+ pid[fmt_ulong(pid,getpid())] = 0;
+
+ if (argc < 2)
+ strerr_die1x(100,"recordio: usage: recordio program [ arg ... ]");
+
+ if (pipe(piin) == -1)
+ strerr_die2sys(111,FATAL,"unable to create pipe: ");
+ if (pipe(piout) == -1)
+ strerr_die2sys(111,FATAL,"unable to create pipe: ");
+
+ switch(fork()) {
+ case -1:
+ strerr_die2sys(111,FATAL,"unable to fork: ");
+ case 0:
+ sig_ignore(sig_pipe);
+ close(piin[0]);
+ close(piout[1]);
+ doit(piin[1],piout[0]);
+ }
+
+ close(piin[1]);
+ close(piout[0]);
+ if (fd_move(0,piin[0]) == -1)
+ strerr_die2sys(111,FATAL,"unable to move descriptors: ");
+ if (fd_move(1,piout[1]) == -1)
+ strerr_die2sys(111,FATAL,"unable to move descriptors: ");
+
+ pathexec_run(argv[1],argv + 1,envp);
+ strerr_die4sys(111,FATAL,"unable to run ",argv[1],": ");
+}