From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Mon, 8 Jan 1996 09:31:37 -0500 From: G. David Butler gdb@dbSystems.com Subject: Setting up lp for PC Topicbox-Message-UUID: 3a00bde6-eac8-11e9-9e20-41e7f4b1d025 Message-ID: <19960108143137.pXC8H5ZMlO03DeoYjenrirkcWe4dSyYolsZlP_Nw6BM@z> This is how I added a postscript printer on serial port eia1 on a PC cpu server named cpu1. To drive a printer on the parallel port, a different approach is required since tcpostio requires feedback from the printer and the parallel interface is one way. Basically a lptsrv needs to be written that opens /dev/lpt1data write only and emulates the responses from tcpostio. A simpler approach would be to change the daemon side alltogether so it doesn't chat with the printer. Since I have a file server that does *NOT* have a WORM, I have all the cpus and terminals share the /sys/lib/lp directory and use the queue and tmp directories there. (In other words, no bootes "other" file system.) After these changes, one can print from the cpu console and any terminal or cpu window. I would like to have some feedback to the code in eiasrv.c. Did I do all the "proper" Plan 9 things? Enjoy. David Butler gdb@dbSystems.com ================================================== add to /sys/lib/lp/devices: (line broken for readability) ps Office cpu1 /srv/eia1 512 post+nohead generic generic generic generic tcppost FIFO ================================================== /sys/lib/lp/bin/lpsend.rc (/sys/src/cmd/lp/lpsend.rc): diff -e lpsend.rc.cdrom lpsend.rc 24,32c #if (test -e /net/dk/clone || import helix /net/dk) { # dialstring=`{ndb/query sys $1 dk} # network=dk # if (! ~ $dialstring '') { # if(lpsend $dialstring $network printer) exit '' # } # rv=$rv^', dk failed' #} #if not rv=$rv^', no dk' . 5c if (test -e /net/tcp/clone || import cpu1 /net/tcp) { . ================================================== /rc/bin/lp (/sys/src/cmd/lp/lp.rc): diff -e lp.rc.cdrom lp.rc 17,21c #if (! test -r /srv/bootes) srv -m bootes #if (! mount -c /srv/bootes /n/bootesother other || ! bind -a /n/bootesother/lp /sys/lib/lp) { # echo 'could not properly setup LPSPOOL' >[1=2] # exit 'LPSPOOL setup' #} . ================================================== /386/bin/aux/lpdaemon (/sys/src/cmd/lp/lpdaemon.c): diff -e lpdaemon.c.cdrom lpdaemon.c 423a ACK(); . 153c return(fd); . 151d 146c close(fd); if((fd=open(tmpf, 2)) < 0) { . 141c if((fd=creat(tmpf, 0666)) < 0) { . 137,138c char tmpf[100]; int fd; . 92a #else fputs(s1, fp); #endif . 91a #ifndef PLAN9 . 90a #else vfprintf(fp, s1, ap); #endif . 89a #ifndef PLAN9 . 79a #endif . 77a #ifndef PLAN9 . ================================================== /386/bin/aux/tcpostio (/sys/src/cmd/postscript/tcpostio.l): diff -e tcpostio.l.cdrom tcpostio.l 412c fprint(2, ". %5.2f%% sent, %.100s\n", bytes_sent*100.0/bytes_to_send, statusbuf); . 283c blocksize = atoi(av); . 197c byte statusbuf[PRBUFSIZ]; . 177c if (write(printerfd, "\004", 1) != 1) { . 162c if (write(printerfd, "\004", 1) != 1) { . 149c if (write(printerfd, "\024", 1) != 1) { . 123,124c if (*(ke = find(ks, ":")) == '\0') { return(PR_UNKNOWN); } kl = ke - ks; . 120a return(statuslist[i].val); . 117,118c break; . 103c vl = ve - vs; . 91,92c if (*(ke = find(ks, ":")) == '\0') { return(PR_UNKNOWN); } kl = ke - ks; . 59c { nil, PR_UNKNOWN } . ================================================== /386/bin/aux/eiasrv (/sys/src/cmd/aux/eiasrv.c): cat eiasrv.c /* * Copyright (c) 1996 G. David Butler * All Rights Reserved. * * Unrestricted use of this source is granted as long as * the above copyright remains. */ #include #include #define PRBUFSIZ 8192 /* from /sys/src/cmd/postscript/tcpostio/tcpostio.h */ char Srvfilename[256]; int Childpid; /* remove the /srv entry and kill the child at exit */ void cleanup(void) { remove(Srvfilename); postnote(PNPROC, Childpid, "kill"); } /* on interrupt, if in the child writing to pipe, OK */ /* else, cleanup and exit */ int notehandler(void *, char *note) { static char *pipenote = "sys: write on closed pipe"; if (strncmp(note, pipenote, sizeof(pipenote) - 1) == 0) { return 1; } cleanup(); return 0; } void main(int argc, char *argv[]) { int blocksize; /* see tcpostio.l about this */ int baud; /* rate of the serial device */ int outputfd; /* fd to serial device */ int inputfd; /* fd from pipe on /srv */ int pipefd[2]; char buf[PRBUFSIZ]; blocksize = PRBUFSIZ; baud = 9600; /* default rate */ ARGBEGIN { case 'B': blocksize = atoi(ARGF()); break; case 'b': baud = atoi(ARGF()); break; default: fprint(2, "%s: badflag('%c')\n", argv0, ARGC()); break; } ARGEND if (argc != 1 || baud == 0) { fprint(2, "Usage: %s [-B blocksize] [-b baud] device\n", argv0); exits("fatal"); } if (blocksize < 1 || blocksize > PRBUFSIZ) { blocksize = PRBUFSIZ; } if ((outputfd = open(*argv, ORDWR)) < 0) { fprint(2, "%s: open of (%s) failed: %r\n", argv0, *argv); exits("fatal"); } /* set the port up correctly for I/O */ sprint(Srvfilename, "%sctl", *argv); if ((inputfd = open(Srvfilename, OWRITE)) < 0) { fprint(2, "%s: open of (%s) failed: %r\n", argv0, Srvfilename); exits("fatal"); } sprint(buf, "b%d", baud); if (write(inputfd, buf, strlen(buf)) < 0 || write(inputfd, "d1", 2) < 0 || write(inputfd, "r1", 2) < 0 || write(inputfd, "m1", 2) < 0 || write(inputfd, "pn", 2) < 0 || write(inputfd, "s1", 2) < 0 || write(inputfd, "l8", 2) < 0) { fprint(2, "%s: write to (%s) failed: %r\n", argv0, Srvfilename); exits("fatal"); } close(inputfd); /* this is the name of our "named pipe" */ sprint(Srvfilename, "/srv%s", strrchr(*argv, '/')); if ((inputfd = create(Srvfilename, OWRITE, 0666)) < 0) { fprint(2, "%s: create of (%s) failed: %r\n", argv0, Srvfilename); exits("fatal"); } atexit(cleanup); if (pipe(pipefd) < 0) { fprint(2, "%s: pipe failed: %r\n", argv0); exits("fatal"); } sprint(buf, "%d", pipefd[0]); if (write (inputfd, buf, strlen(buf)) < 0) { fprint(2, "%s: write to (%s) failed: %r\n", argv0, Srvfilename); exits("fatal"); } close(inputfd); close(pipefd[0]); inputfd = pipefd[1]; atnotify(notehandler, 1); /* the parent and child can share */ if (Childpid = rfork(RFPROC)) { while ((pipefd[0] = read(inputfd, buf, blocksize)) >= 0) { pipefd[1] = 0; while (pipefd[1] < pipefd[0]) { if ((baud = write(outputfd, buf, pipefd[0])) < 0) { fprint(2, "%s: parent write failed: %r\n", argv0); exits("fatal"); } pipefd[1] += baud; } } if (pipefd[0] < 0) { fprint(2, "%s: parent read failed: %r\n", argv0); exits("fatal"); } else { exits(""); } } else { while ((pipefd[0] = read(outputfd, buf, blocksize)) >= 0) { pipefd[1] = 0; while (pipefd[1] < pipefd[0]) { if ((baud = write(inputfd, buf, pipefd[0])) < 0) { buf[0] = '\0'; errstr(buf); if (strcmp(buf, "interrupted") == 0) { pipefd[1] = pipefd[0]; continue; } else { fprint(2, "%s: child write failed: %s\n", argv0, buf); exits("fatal"); } } pipefd[1] += baud; } } if (pipefd[0] < 0) { fprint(2, "%s: child read failed: %r\n", argv0); exits("fatal"); } else { exits(""); } } } ================================================== /sys/src/cmd/aux/mkfile: diff -e mkfile.cdrom mkfile 10a eiasrv\ . ================================================== /rc/bin/cpurc: add a line to your cpu server bootup like: aux/eiasrv -b 38400 /dev/eia1 &