|
|
1.1 ! root 1: #include <fio.h> ! 2: #include <errno.h> ! 3: #include <time.h> ! 4: #include <ipc.h> ! 5: ! 6: #define MIN(a,b) ((a<b)?a:b) ! 7: ! 8: #define ACK(a) write(a, "", 1) ! 9: #define NAK(a) write(a, "\001", 1) ! 10: ! 11: #define LPDAEMONLOG "/tmp/lpdaemonl" ! 12: ! 13: #define LNBFSZ 4096 ! 14: char lnbuf[LNBFSZ]; ! 15: ! 16: void ! 17: error(char *s1, ...) ! 18: { ! 19: time_t thetime; ! 20: char *chartime; ! 21: ! 22: time(&thetime); ! 23: chartime = ctime(&thetime); ! 24: fprint(2, "%.15s ", &(chartime[4])); ! 25: fprint(2, s1, (&s1+1)); ! 26: return; ! 27: } ! 28: ! 29: /* get a line from inpfd using nonbuffered input. The line is truncated if it is too ! 30: * long for the buffer. The result is left in lnbuf and the number of characters ! 31: * read in is returned. ! 32: */ ! 33: int ! 34: readline(int inpfd) ! 35: { ! 36: register char *ap; ! 37: register int i; ! 38: ! 39: ap = lnbuf; ! 40: i = 0; ! 41: do { ! 42: if (read(inpfd, ap, 1) != 1) { ! 43: error("read error\n"); ! 44: break; ! 45: } ! 46: } while ((++i < LNBFSZ - 2) && *ap++ != '\n'); ! 47: if (i == LNBFSZ - 2) { ! 48: *ap = '\n'; ! 49: i++; ! 50: } ! 51: *ap = '\0'; ! 52: return(i); ! 53: } ! 54: ! 55: #define RDSIZE 512 ! 56: char jobbuf[RDSIZE]; ! 57: ! 58: int ! 59: pass(int inpfd, int outfd, int bsize) ! 60: { ! 61: int rv; ! 62: for(; bsize > 0; bsize -= rv) ! 63: if((rv=read(inpfd, jobbuf, MIN(bsize,RDSIZE))) < 0) { ! 64: error("read error\n"); ! 65: return(bsize); ! 66: } else if((write(outfd, jobbuf, rv)) != rv) { ! 67: error("write error\n"); ! 68: return(bsize); ! 69: } ! 70: return(bsize); ! 71: } ! 72: ! 73: void ! 74: recvdata(int inpfd, int outfd) ! 75: { ! 76: int i; ! 77: ! 78: while ((readline(inpfd),i = atoi(lnbuf)) != 0) { ! 79: if (pass(inpfd, outfd, i) != 0) { ! 80: error("failed to receive response\n"); ! 81: exit(6); ! 82: } ! 83: } ! 84: return; ! 85: } ! 86: ! 87: /* get whatever stdin has and put it into the temporary file. ! 88: * return the file size. ! 89: */ ! 90: int ! 91: prereadfile(int inpfd) ! 92: { ! 93: int rv, bsize; ! 94: ! 95: bsize = 0; ! 96: do { ! 97: if((rv=read(0, jobbuf, RDSIZE))<0) { ! 98: error("read error\n"); ! 99: exit(4); ! 100: } else if((write(inpfd, jobbuf, rv)) != rv) { ! 101: error("write error\n"); ! 102: exit(5); ! 103: } ! 104: bsize += rv; ! 105: } while (rv!=0); ! 106: return(bsize); ! 107: } ! 108: ! 109: int ! 110: tmpfile(void) ! 111: { ! 112: static tindx = 0; ! 113: char tmpf[20]; ! 114: int crtfd, tmpfd; ! 115: ! 116: sprint(tmpf, "/tmp/lp%d.%d", getpid(), tindx++); ! 117: if((crtfd=creat(tmpf, 0666)) < 0) { ! 118: error("cannot create temp file %s\n", tmpf); ! 119: exit(3); ! 120: } ! 121: if((tmpfd=open(tmpf, 2)) < 0) { ! 122: error("cannot open temp file %s\n", tmpf); ! 123: exit(3); ! 124: } ! 125: close(crtfd); ! 126: unlink(tmpf); ! 127: return(tmpfd); ! 128: } ! 129: ! 130: int ! 131: recvACK(int netfd) ! 132: { ! 133: if (read(netfd, jobbuf, 1)!=1 || *jobbuf!='\0') { ! 134: error("failed to receive ACK\n"); ! 135: if (*jobbuf == '\0') ! 136: error("read failed\n"); ! 137: else ! 138: error("received <0x%x> instead\n", *jobbuf); ! 139: return(0); ! 140: } ! 141: return(1); ! 142: } ! 143: ! 144: main(int argc, char *argv[]) ! 145: { ! 146: char *ap, *cp; ! 147: int i, rv, netfd, bsize, datafd; ! 148: ! 149: /* make connection */ ! 150: if (argc != 4) { ! 151: fprint(2, "usage: %s destination network service\n", argv[0]); ! 152: exit(1); ! 153: } ! 154: if ((netfd = ipcopen((cp = ipcpath(argv[1], argv[2], argv[3])), "heavy tcphup hup")) < 0){ ! 155: fprint(2, "ipcopen(%s):%s\n", cp, errstr); ! 156: exit(2); ! 157: } ! 158: ! 159: /* read options line from stdin and send it */ ! 160: ap = lnbuf; ! 161: i = readline(0); ! 162: if (write(netfd, lnbuf, i) != i) { ! 163: error("write error\n"); ! 164: exit(1); ! 165: } ! 166: ! 167: /* read stdin into tmpfile to get size */ ! 168: datafd = tmpfile(); ! 169: bsize = prereadfile(datafd); ! 170: ! 171: i = sprint(lnbuf, "%d\n", bsize); ! 172: if (write(netfd, lnbuf, i) != i) { ! 173: error("write error\n"); ! 174: exit(1); ! 175: } ! 176: ! 177: if (lseek(datafd, 0L, 0) < 0) { ! 178: error("error seeking temp file\n"); ! 179: exit(4); ! 180: } ! 181: /* mirror performance in readfile() in lpdaemon */ ! 182: recvACK(netfd); ! 183: if (pass(datafd, netfd, bsize) != 0) { ! 184: NAK(netfd); ! 185: error("failed to send data\n"); ! 186: exit(5); ! 187: } ! 188: ACK(netfd); ! 189: recvACK(netfd); ! 190: ! 191: /* get response, as from lp -q */ ! 192: while((rv=read(netfd, jobbuf, RDSIZE)) > 0) { ! 193: if((write(1, jobbuf, rv)) != rv) { ! 194: error("write error\n"); ! 195: exit(6); ! 196: } ! 197: } ! 198: /* close down network connections and go away */ ! 199: exit(0); ! 200: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.