Blame


1 262ecfed 2005-08-31 devnull #ifdef plan9
2 262ecfed 2005-08-31 devnull
3 262ecfed 2005-08-31 devnull #include <u.h>
4 262ecfed 2005-08-31 devnull #include <libc.h>
5 262ecfed 2005-08-31 devnull #define stderr 2
6 262ecfed 2005-08-31 devnull
7 262ecfed 2005-08-31 devnull #define RDNETIMEOUT 60000
8 262ecfed 2005-08-31 devnull #define WRNETIMEOUT 60000
9 262ecfed 2005-08-31 devnull
10 262ecfed 2005-08-31 devnull #else
11 262ecfed 2005-08-31 devnull
12 262ecfed 2005-08-31 devnull /* not for plan 9 */
13 262ecfed 2005-08-31 devnull #include <stdio.h>
14 262ecfed 2005-08-31 devnull #include <errno.h>
15 262ecfed 2005-08-31 devnull #include <time.h>
16 262ecfed 2005-08-31 devnull #include <fcntl.h>
17 262ecfed 2005-08-31 devnull #include <signal.h>
18 262ecfed 2005-08-31 devnull
19 262ecfed 2005-08-31 devnull #define create creat
20 262ecfed 2005-08-31 devnull #define seek lseek
21 262ecfed 2005-08-31 devnull #define fprint fprintf
22 262ecfed 2005-08-31 devnull #define sprint sprintf
23 262ecfed 2005-08-31 devnull #define exits exit
24 262ecfed 2005-08-31 devnull
25 262ecfed 2005-08-31 devnull #define ORDWR O_RDWR
26 262ecfed 2005-08-31 devnull #define OTRUNC O_TRUNC
27 262ecfed 2005-08-31 devnull #define ORCLOSE 0
28 262ecfed 2005-08-31 devnull
29 262ecfed 2005-08-31 devnull #define RDNETIMEOUT 60
30 262ecfed 2005-08-31 devnull #define WRNETIMEOUT 60
31 262ecfed 2005-08-31 devnull
32 262ecfed 2005-08-31 devnull #endif
33 262ecfed 2005-08-31 devnull
34 262ecfed 2005-08-31 devnull #define MIN(a,b) ((a<b)?a:b)
35 262ecfed 2005-08-31 devnull
36 262ecfed 2005-08-31 devnull #define ACK(a) write(a, "", 1)
37 262ecfed 2005-08-31 devnull #define NAK(a) write(a, "\001", 1)
38 262ecfed 2005-08-31 devnull
39 262ecfed 2005-08-31 devnull #define LPDAEMONLOG "/tmp/lpdaemonl"
40 262ecfed 2005-08-31 devnull
41 262ecfed 2005-08-31 devnull #define LNBFSZ 4096
42 262ecfed 2005-08-31 devnull char lnbuf[LNBFSZ];
43 262ecfed 2005-08-31 devnull int dbgstate = 0;
44 262ecfed 2005-08-31 devnull char *dbgstrings[] = {
45 262ecfed 2005-08-31 devnull "",
46 262ecfed 2005-08-31 devnull "rcvack1",
47 262ecfed 2005-08-31 devnull "send",
48 262ecfed 2005-08-31 devnull "rcvack2",
49 262ecfed 2005-08-31 devnull "response",
50 262ecfed 2005-08-31 devnull "done"
51 262ecfed 2005-08-31 devnull };
52 262ecfed 2005-08-31 devnull
53 262ecfed 2005-08-31 devnull #ifdef plan9
54 262ecfed 2005-08-31 devnull
55 262ecfed 2005-08-31 devnull void
56 262ecfed 2005-08-31 devnull error(int level, char *s1, ...)
57 262ecfed 2005-08-31 devnull {
58 262ecfed 2005-08-31 devnull va_list ap;
59 262ecfed 2005-08-31 devnull long thetime;
60 262ecfed 2005-08-31 devnull char *chartime;
61 262ecfed 2005-08-31 devnull char *args[8];
62 262ecfed 2005-08-31 devnull int argno = 0;
63 262ecfed 2005-08-31 devnull
64 262ecfed 2005-08-31 devnull if (level == 0) {
65 262ecfed 2005-08-31 devnull time(&thetime);
66 262ecfed 2005-08-31 devnull chartime = ctime(thetime);
67 262ecfed 2005-08-31 devnull fprint(stderr, "%.15s ", &(chartime[4]));
68 262ecfed 2005-08-31 devnull }
69 262ecfed 2005-08-31 devnull va_start(ap, s1);
70 262ecfed 2005-08-31 devnull while(args[argno++] = va_arg(ap, char*));
71 262ecfed 2005-08-31 devnull va_end(ap);
72 262ecfed 2005-08-31 devnull fprint(stderr, s1, *args);
73 262ecfed 2005-08-31 devnull return;
74 262ecfed 2005-08-31 devnull }
75 262ecfed 2005-08-31 devnull
76 262ecfed 2005-08-31 devnull int
77 262ecfed 2005-08-31 devnull alarmhandler(void *foo, char *note) {
78 262ecfed 2005-08-31 devnull USED(foo);
79 262ecfed 2005-08-31 devnull if(strcmp(note, "alarm")==0) {
80 262ecfed 2005-08-31 devnull fprint(stderr, "alarm at %d - %s\n", dbgstate, dbgstrings[dbgstate]);
81 262ecfed 2005-08-31 devnull return(1);
82 262ecfed 2005-08-31 devnull } else return(0);
83 262ecfed 2005-08-31 devnull }
84 262ecfed 2005-08-31 devnull
85 262ecfed 2005-08-31 devnull #else
86 262ecfed 2005-08-31 devnull
87 262ecfed 2005-08-31 devnull void
88 262ecfed 2005-08-31 devnull error(int level, char *s1, ...)
89 262ecfed 2005-08-31 devnull {
90 262ecfed 2005-08-31 devnull time_t thetime;
91 262ecfed 2005-08-31 devnull char *chartime;
92 262ecfed 2005-08-31 devnull
93 262ecfed 2005-08-31 devnull if (level == 0) {
94 262ecfed 2005-08-31 devnull time(&thetime);
95 262ecfed 2005-08-31 devnull chartime = ctime(&thetime);
96 262ecfed 2005-08-31 devnull fprintf(stderr, "%.15s ", &(chartime[4]));
97 262ecfed 2005-08-31 devnull }
98 262ecfed 2005-08-31 devnull fprintf(stderr, s1, (&s1+1));
99 262ecfed 2005-08-31 devnull return;
100 262ecfed 2005-08-31 devnull }
101 262ecfed 2005-08-31 devnull
102 262ecfed 2005-08-31 devnull void
103 262ecfed 2005-08-31 devnull alarmhandler() {
104 262ecfed 2005-08-31 devnull fprintf(stderr, "alarm at %d - %s\n", dbgstate, dbgstrings[dbgstate]);
105 262ecfed 2005-08-31 devnull }
106 262ecfed 2005-08-31 devnull
107 262ecfed 2005-08-31 devnull #endif
108 262ecfed 2005-08-31 devnull
109 262ecfed 2005-08-31 devnull /* get a line from inpfd using nonbuffered input. The line is truncated if it is too
110 262ecfed 2005-08-31 devnull * long for the buffer. The result is left in lnbuf and the number of characters
111 262ecfed 2005-08-31 devnull * read in is returned.
112 262ecfed 2005-08-31 devnull */
113 262ecfed 2005-08-31 devnull int
114 262ecfed 2005-08-31 devnull readline(int inpfd)
115 262ecfed 2005-08-31 devnull {
116 262ecfed 2005-08-31 devnull register char *ap;
117 262ecfed 2005-08-31 devnull register int i;
118 262ecfed 2005-08-31 devnull
119 262ecfed 2005-08-31 devnull ap = lnbuf;
120 262ecfed 2005-08-31 devnull i = 0;
121 262ecfed 2005-08-31 devnull do {
122 262ecfed 2005-08-31 devnull if (read(inpfd, ap, 1) != 1) {
123 262ecfed 2005-08-31 devnull error(0, "read error in readline, fd=%d\n", inpfd);
124 262ecfed 2005-08-31 devnull break;
125 262ecfed 2005-08-31 devnull }
126 262ecfed 2005-08-31 devnull } while ((++i < LNBFSZ - 2) && *ap++ != '\n');
127 262ecfed 2005-08-31 devnull if (i == LNBFSZ - 2) {
128 262ecfed 2005-08-31 devnull *ap = '\n';
129 262ecfed 2005-08-31 devnull i++;
130 262ecfed 2005-08-31 devnull }
131 262ecfed 2005-08-31 devnull *ap = '\0';
132 262ecfed 2005-08-31 devnull return(i);
133 262ecfed 2005-08-31 devnull }
134 262ecfed 2005-08-31 devnull
135 262ecfed 2005-08-31 devnull #define RDSIZE 512
136 262ecfed 2005-08-31 devnull char jobbuf[RDSIZE];
137 262ecfed 2005-08-31 devnull
138 262ecfed 2005-08-31 devnull int
139 262ecfed 2005-08-31 devnull pass(int inpfd, int outfd, int bsize)
140 262ecfed 2005-08-31 devnull {
141 262ecfed 2005-08-31 devnull int bcnt = 0;
142 262ecfed 2005-08-31 devnull int rv = 0;
143 262ecfed 2005-08-31 devnull
144 262ecfed 2005-08-31 devnull for(bcnt=bsize; bcnt > 0; bcnt -= rv) {
145 262ecfed 2005-08-31 devnull alarm(WRNETIMEOUT); /* to break hanging */
146 262ecfed 2005-08-31 devnull if((rv=read(inpfd, jobbuf, MIN(bcnt,RDSIZE))) < 0) {
147 262ecfed 2005-08-31 devnull error(0, "read error during pass, %d remaining\n", bcnt);
148 262ecfed 2005-08-31 devnull break;
149 262ecfed 2005-08-31 devnull } else if((write(outfd, jobbuf, rv)) != rv) {
150 262ecfed 2005-08-31 devnull error(0, "write error during pass, %d remaining\n", bcnt);
151 262ecfed 2005-08-31 devnull break;
152 262ecfed 2005-08-31 devnull }
153 262ecfed 2005-08-31 devnull }
154 262ecfed 2005-08-31 devnull alarm(0);
155 262ecfed 2005-08-31 devnull return(bcnt);
156 262ecfed 2005-08-31 devnull }
157 fa325e9b 2020-01-10 cross
158 262ecfed 2005-08-31 devnull /* get whatever stdin has and put it into the temporary file.
159 262ecfed 2005-08-31 devnull * return the file size.
160 262ecfed 2005-08-31 devnull */
161 262ecfed 2005-08-31 devnull int
162 262ecfed 2005-08-31 devnull prereadfile(int inpfd)
163 262ecfed 2005-08-31 devnull {
164 262ecfed 2005-08-31 devnull int rv, bsize;
165 262ecfed 2005-08-31 devnull
166 262ecfed 2005-08-31 devnull bsize = 0;
167 262ecfed 2005-08-31 devnull do {
168 262ecfed 2005-08-31 devnull if((rv=read(0, jobbuf, RDSIZE))<0) {
169 262ecfed 2005-08-31 devnull error(0, "read error while making temp file\n");
170 262ecfed 2005-08-31 devnull exits("read error while making temp file");
171 262ecfed 2005-08-31 devnull } else if((write(inpfd, jobbuf, rv)) != rv) {
172 262ecfed 2005-08-31 devnull error(0, "write error while making temp file\n");
173 262ecfed 2005-08-31 devnull exits("write error while making temp file");
174 262ecfed 2005-08-31 devnull }
175 262ecfed 2005-08-31 devnull bsize += rv;
176 262ecfed 2005-08-31 devnull } while (rv!=0);
177 262ecfed 2005-08-31 devnull return(bsize);
178 262ecfed 2005-08-31 devnull }
179 262ecfed 2005-08-31 devnull
180 262ecfed 2005-08-31 devnull int
181 262ecfed 2005-08-31 devnull tempfile(void)
182 262ecfed 2005-08-31 devnull {
183 262ecfed 2005-08-31 devnull static int tindx = 0;
184 262ecfed 2005-08-31 devnull char tmpf[20];
185 262ecfed 2005-08-31 devnull int tmpfd;
186 262ecfed 2005-08-31 devnull
187 262ecfed 2005-08-31 devnull sprint(tmpf, "/var/tmp/lp%d.%d", getpid(), tindx++);
188 262ecfed 2005-08-31 devnull if((tmpfd=create(tmpf,
189 262ecfed 2005-08-31 devnull
190 262ecfed 2005-08-31 devnull #ifdef plan9
191 262ecfed 2005-08-31 devnull
192 262ecfed 2005-08-31 devnull ORDWR|OTRUNC,
193 262ecfed 2005-08-31 devnull
194 262ecfed 2005-08-31 devnull #endif
195 262ecfed 2005-08-31 devnull
196 262ecfed 2005-08-31 devnull 0666)) < 0) {
197 262ecfed 2005-08-31 devnull error(0, "cannot create temp file %s\n", tmpf);
198 262ecfed 2005-08-31 devnull exits("cannot create temp file");
199 262ecfed 2005-08-31 devnull }
200 262ecfed 2005-08-31 devnull close(tmpfd);
201 262ecfed 2005-08-31 devnull if((tmpfd=open(tmpf, ORDWR
202 262ecfed 2005-08-31 devnull
203 262ecfed 2005-08-31 devnull #ifdef plan9
204 262ecfed 2005-08-31 devnull
205 262ecfed 2005-08-31 devnull |ORCLOSE|OTRUNC
206 262ecfed 2005-08-31 devnull
207 262ecfed 2005-08-31 devnull #endif
208 262ecfed 2005-08-31 devnull
209 262ecfed 2005-08-31 devnull )) < 0) {
210 262ecfed 2005-08-31 devnull error(0, "cannot open temp file %s\n", tmpf);
211 262ecfed 2005-08-31 devnull exits("cannot open temp file");
212 262ecfed 2005-08-31 devnull }
213 262ecfed 2005-08-31 devnull return(tmpfd);
214 262ecfed 2005-08-31 devnull }
215 262ecfed 2005-08-31 devnull
216 262ecfed 2005-08-31 devnull int
217 262ecfed 2005-08-31 devnull recvACK(int netfd)
218 262ecfed 2005-08-31 devnull {
219 262ecfed 2005-08-31 devnull int rv;
220 262ecfed 2005-08-31 devnull
221 262ecfed 2005-08-31 devnull *jobbuf = '\0';
222 262ecfed 2005-08-31 devnull alarm(RDNETIMEOUT);
223 262ecfed 2005-08-31 devnull if (read(netfd, jobbuf, 1)!=1 || *jobbuf!='\0') {
224 262ecfed 2005-08-31 devnull error(0, "failed to receive ACK, ");
225 262ecfed 2005-08-31 devnull if (*jobbuf == '\0')
226 262ecfed 2005-08-31 devnull error(1, "read failed\n");
227 262ecfed 2005-08-31 devnull else
228 262ecfed 2005-08-31 devnull error(1, "received <0x%x> instead\n", *jobbuf);
229 262ecfed 2005-08-31 devnull rv = 0;
230 262ecfed 2005-08-31 devnull } else rv = 1;
231 262ecfed 2005-08-31 devnull alarm(0);
232 262ecfed 2005-08-31 devnull return(rv);
233 262ecfed 2005-08-31 devnull }
234 262ecfed 2005-08-31 devnull
235 262ecfed 2005-08-31 devnull void
236 262ecfed 2005-08-31 devnull main(int argc, char *argv[])
237 262ecfed 2005-08-31 devnull {
238 262ecfed 2005-08-31 devnull char *devdir;
239 262ecfed 2005-08-31 devnull int i, rv, netfd, bsize;
240 262ecfed 2005-08-31 devnull int datafd;
241 262ecfed 2005-08-31 devnull
242 262ecfed 2005-08-31 devnull #ifndef plan9
243 262ecfed 2005-08-31 devnull
244 262ecfed 2005-08-31 devnull void (*oldhandler)();
245 262ecfed 2005-08-31 devnull
246 262ecfed 2005-08-31 devnull #endif
247 262ecfed 2005-08-31 devnull
248 262ecfed 2005-08-31 devnull devdir = nil;
249 262ecfed 2005-08-31 devnull /* make connection */
250 262ecfed 2005-08-31 devnull if (argc != 2) {
251 262ecfed 2005-08-31 devnull fprint(stderr, "usage: %s network!destination!service\n", argv[0]);
252 262ecfed 2005-08-31 devnull exits("incorrect number of arguments");
253 262ecfed 2005-08-31 devnull }
254 262ecfed 2005-08-31 devnull
255 262ecfed 2005-08-31 devnull /* read options line from stdin into lnbuf */
256 262ecfed 2005-08-31 devnull i = readline(0);
257 262ecfed 2005-08-31 devnull
258 262ecfed 2005-08-31 devnull /* read stdin into tempfile to get size */
259 262ecfed 2005-08-31 devnull datafd = tempfile();
260 262ecfed 2005-08-31 devnull bsize = prereadfile(datafd);
261 262ecfed 2005-08-31 devnull
262 262ecfed 2005-08-31 devnull /* network connection is opened after data is in to avoid timeout */
263 262ecfed 2005-08-31 devnull if ((netfd=dial(argv[1], 0, 0, 0)) < 0) {
264 262ecfed 2005-08-31 devnull fprint(stderr, "dialing %s\n", devdir);
265 262ecfed 2005-08-31 devnull perror("dial");
266 262ecfed 2005-08-31 devnull exits("can't dial");
267 262ecfed 2005-08-31 devnull }
268 262ecfed 2005-08-31 devnull
269 262ecfed 2005-08-31 devnull /* write out the options we read above */
270 262ecfed 2005-08-31 devnull if (write(netfd, lnbuf, i) != i) {
271 262ecfed 2005-08-31 devnull error(0, "write error while sending options\n");
272 262ecfed 2005-08-31 devnull exits("write error while sending options");
273 262ecfed 2005-08-31 devnull }
274 262ecfed 2005-08-31 devnull
275 262ecfed 2005-08-31 devnull /* send the size of the file to be sent */
276 262ecfed 2005-08-31 devnull sprint(lnbuf, "%d\n", bsize);
277 262ecfed 2005-08-31 devnull i = strlen(lnbuf);
278 262ecfed 2005-08-31 devnull if ((rv=write(netfd, lnbuf, i)) != i) {
279 262ecfed 2005-08-31 devnull perror("write error while sending size");
280 262ecfed 2005-08-31 devnull error(0, "write returned %d\n", rv);
281 262ecfed 2005-08-31 devnull exits("write error while sending size");
282 262ecfed 2005-08-31 devnull }
283 262ecfed 2005-08-31 devnull
284 262ecfed 2005-08-31 devnull if (seek(datafd, 0L, 0) < 0) {
285 262ecfed 2005-08-31 devnull error(0, "error seeking temp file\n");
286 262ecfed 2005-08-31 devnull exits("seek error");
287 262ecfed 2005-08-31 devnull }
288 262ecfed 2005-08-31 devnull /* mirror performance in readfile() in lpdaemon */
289 262ecfed 2005-08-31 devnull
290 262ecfed 2005-08-31 devnull #ifdef plan9
291 262ecfed 2005-08-31 devnull
292 262ecfed 2005-08-31 devnull atnotify(alarmhandler, 1);
293 262ecfed 2005-08-31 devnull
294 262ecfed 2005-08-31 devnull #else
295 262ecfed 2005-08-31 devnull
296 262ecfed 2005-08-31 devnull oldhandler = signal(SIGALRM, alarmhandler);
297 262ecfed 2005-08-31 devnull
298 262ecfed 2005-08-31 devnull #endif
299 262ecfed 2005-08-31 devnull
300 262ecfed 2005-08-31 devnull dbgstate = 1;
301 262ecfed 2005-08-31 devnull if(!recvACK(netfd)) {
302 262ecfed 2005-08-31 devnull error(0, "failed to receive ACK before sending data\n");
303 262ecfed 2005-08-31 devnull exits("recv ack1 failed");
304 262ecfed 2005-08-31 devnull }
305 262ecfed 2005-08-31 devnull dbgstate = 2;
306 262ecfed 2005-08-31 devnull if ((i=pass(datafd, netfd, bsize)) != 0) {
307 262ecfed 2005-08-31 devnull NAK(netfd);
308 262ecfed 2005-08-31 devnull error(0, "failed to send %d bytes\n", i);
309 262ecfed 2005-08-31 devnull exits("send data failed");
310 262ecfed 2005-08-31 devnull }
311 262ecfed 2005-08-31 devnull ACK(netfd);
312 262ecfed 2005-08-31 devnull dbgstate = 3;
313 262ecfed 2005-08-31 devnull if(!recvACK(netfd)) {
314 262ecfed 2005-08-31 devnull error(0, "failed to receive ACK after sending data\n");
315 262ecfed 2005-08-31 devnull exits("recv ack2 failed");
316 262ecfed 2005-08-31 devnull }
317 262ecfed 2005-08-31 devnull
318 262ecfed 2005-08-31 devnull /* get response, as from lp -q */
319 262ecfed 2005-08-31 devnull dbgstate = 4;
320 262ecfed 2005-08-31 devnull while((rv=read(netfd, jobbuf, RDSIZE)) > 0) {
321 262ecfed 2005-08-31 devnull if((write(1, jobbuf, rv)) != rv) {
322 262ecfed 2005-08-31 devnull error(0, "write error while sending to stdout\n");
323 262ecfed 2005-08-31 devnull exits("write error while sending to stdout");
324 262ecfed 2005-08-31 devnull }
325 262ecfed 2005-08-31 devnull }
326 262ecfed 2005-08-31 devnull dbgstate = 5;
327 262ecfed 2005-08-31 devnull
328 262ecfed 2005-08-31 devnull #ifdef plan9
329 262ecfed 2005-08-31 devnull
330 262ecfed 2005-08-31 devnull atnotify(alarmhandler, 0);
331 262ecfed 2005-08-31 devnull /* close down network connections and go away */
332 262ecfed 2005-08-31 devnull exits("");
333 262ecfed 2005-08-31 devnull
334 262ecfed 2005-08-31 devnull #else
335 262ecfed 2005-08-31 devnull
336 262ecfed 2005-08-31 devnull signal(SIGALRM, oldhandler);
337 262ecfed 2005-08-31 devnull exit(0);
338 262ecfed 2005-08-31 devnull
339 262ecfed 2005-08-31 devnull #endif
340 262ecfed 2005-08-31 devnull
341 262ecfed 2005-08-31 devnull }