|
|
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.