Blame


1 262ecfed 2005-08-31 devnull #include <u.h>
2 b87296ce 2005-08-31 devnull #define NOPLAN9DEFINES
3 262ecfed 2005-08-31 devnull #include <sys/types.h>
4 262ecfed 2005-08-31 devnull #include <unistd.h>
5 262ecfed 2005-08-31 devnull #include <stdlib.h>
6 262ecfed 2005-08-31 devnull #include <sys/wait.h>
7 262ecfed 2005-08-31 devnull #include <fcntl.h>
8 262ecfed 2005-08-31 devnull #include <stdlib.h>
9 262ecfed 2005-08-31 devnull #include <stdio.h>
10 262ecfed 2005-08-31 devnull #include <signal.h>
11 262ecfed 2005-08-31 devnull #include <errno.h>
12 262ecfed 2005-08-31 devnull #include <time.h>
13 262ecfed 2005-08-31 devnull #include <string.h>
14 262ecfed 2005-08-31 devnull #include <stdarg.h>
15 262ecfed 2005-08-31 devnull #include <libc.h>
16 262ecfed 2005-08-31 devnull
17 b87296ce 2005-08-31 devnull #define LP unsharp("#9/bin/lp")
18 262ecfed 2005-08-31 devnull #define TMPDIR "/var/tmp"
19 262ecfed 2005-08-31 devnull #define LPDAEMONLOG unsharp("#9/lp/log/lpdaemonl")
20 262ecfed 2005-08-31 devnull
21 262ecfed 2005-08-31 devnull #define ARGSIZ 4096
22 262ecfed 2005-08-31 devnull #define NAMELEN 30
23 262ecfed 2005-08-31 devnull
24 262ecfed 2005-08-31 devnull unsigned char argvstr[ARGSIZ]; /* arguments after parsing */
25 262ecfed 2005-08-31 devnull unsigned char *argvals[ARGSIZ/2+1]; /* pointers to arguments after parsing */
26 262ecfed 2005-08-31 devnull int ascnt = 0, argcnt = 0; /* number of arguments parsed */
27 262ecfed 2005-08-31 devnull /* for 'stuff' gleened from lpr cntrl file */
28 262ecfed 2005-08-31 devnull struct jobinfo {
29 262ecfed 2005-08-31 devnull char user[NAMELEN+1];
30 262ecfed 2005-08-31 devnull char host[NAMELEN+1];
31 262ecfed 2005-08-31 devnull } *getjobinfo();
32 262ecfed 2005-08-31 devnull
33 262ecfed 2005-08-31 devnull #define MIN(a,b) ((a<b)?a:b)
34 262ecfed 2005-08-31 devnull
35 262ecfed 2005-08-31 devnull #define CPYFIELD(src, dst) { while (*(src)!=' ' && *(src)!='\t' && *(src)!='\r' && *(src)!='\n' && *(src)!='\0') *(dst)++ = *(src)++; }
36 262ecfed 2005-08-31 devnull
37 262ecfed 2005-08-31 devnull #define ACK() write(1, "", 1)
38 262ecfed 2005-08-31 devnull #define NAK() write(1, "\001", 1)
39 262ecfed 2005-08-31 devnull
40 262ecfed 2005-08-31 devnull #define LNBFSZ 4096
41 262ecfed 2005-08-31 devnull unsigned char lnbuf[LNBFSZ];
42 262ecfed 2005-08-31 devnull
43 262ecfed 2005-08-31 devnull #define RDSIZE 512
44 262ecfed 2005-08-31 devnull unsigned char jobbuf[RDSIZE];
45 262ecfed 2005-08-31 devnull
46 262ecfed 2005-08-31 devnull int datafd[400], cntrlfd = -1;
47 262ecfed 2005-08-31 devnull
48 262ecfed 2005-08-31 devnull int dbgstate = 0;
49 262ecfed 2005-08-31 devnull char *dbgstrings[] = {
50 262ecfed 2005-08-31 devnull "",
51 262ecfed 2005-08-31 devnull "sendack1",
52 262ecfed 2005-08-31 devnull "send",
53 262ecfed 2005-08-31 devnull "rcvack",
54 262ecfed 2005-08-31 devnull "sendack2",
55 262ecfed 2005-08-31 devnull "done"
56 262ecfed 2005-08-31 devnull };
57 262ecfed 2005-08-31 devnull
58 262ecfed 2005-08-31 devnull void
59 262ecfed 2005-08-31 devnull error(char *s1, ...)
60 262ecfed 2005-08-31 devnull {
61 262ecfed 2005-08-31 devnull FILE *fp;
62 262ecfed 2005-08-31 devnull long thetime;
63 262ecfed 2005-08-31 devnull char *chartime;
64 262ecfed 2005-08-31 devnull va_list ap;
65 262ecfed 2005-08-31 devnull char *args[8];
66 262ecfed 2005-08-31 devnull int argno = 0;
67 262ecfed 2005-08-31 devnull
68 262ecfed 2005-08-31 devnull if((fp=fopen(LPDAEMONLOG, "a"))==NULL) {
69 262ecfed 2005-08-31 devnull fprintf(stderr, "cannot open %s in append mode\n", LPDAEMONLOG);
70 262ecfed 2005-08-31 devnull return;
71 262ecfed 2005-08-31 devnull }
72 262ecfed 2005-08-31 devnull time(&thetime);
73 262ecfed 2005-08-31 devnull chartime = ctime(&thetime);
74 262ecfed 2005-08-31 devnull fprintf(fp, "%.15s [%5.5d] ", &(chartime[4]), getpid());
75 262ecfed 2005-08-31 devnull va_start(ap, s1);
76 262ecfed 2005-08-31 devnull while((args[argno++] = va_arg(ap, char*)) && argno<8);
77 262ecfed 2005-08-31 devnull va_end(ap);
78 262ecfed 2005-08-31 devnull fprintf(fp, s1, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
79 262ecfed 2005-08-31 devnull fflush(fp);
80 262ecfed 2005-08-31 devnull fclose(fp);
81 262ecfed 2005-08-31 devnull return;
82 262ecfed 2005-08-31 devnull }
83 262ecfed 2005-08-31 devnull
84 262ecfed 2005-08-31 devnull void
85 262ecfed 2005-08-31 devnull forklp(int inputfd)
86 262ecfed 2005-08-31 devnull {
87 262ecfed 2005-08-31 devnull int i, cpid;
88 262ecfed 2005-08-31 devnull unsigned char *bp, *cp;
89 262ecfed 2005-08-31 devnull unsigned char logent[LNBFSZ];
90 262ecfed 2005-08-31 devnull
91 262ecfed 2005-08-31 devnull /* log this call to lp */
92 262ecfed 2005-08-31 devnull cp = logent;
93 262ecfed 2005-08-31 devnull for (i=1; i<argcnt; i++) {
94 262ecfed 2005-08-31 devnull bp = argvals[i];
95 262ecfed 2005-08-31 devnull if (cp+strlen((const char *)bp)+1 < logent+LNBFSZ-1) {
96 262ecfed 2005-08-31 devnull CPYFIELD(bp, cp);
97 262ecfed 2005-08-31 devnull *cp++ = ' ';
98 262ecfed 2005-08-31 devnull }
99 262ecfed 2005-08-31 devnull }
100 262ecfed 2005-08-31 devnull *--cp = '\n';
101 262ecfed 2005-08-31 devnull *++cp = '\0';
102 b87296ce 2005-08-31 devnull error((char *)logent);
103 262ecfed 2005-08-31 devnull switch((cpid=fork())){
104 262ecfed 2005-08-31 devnull case -1:
105 262ecfed 2005-08-31 devnull error("fork error\n");
106 262ecfed 2005-08-31 devnull exit(2);
107 262ecfed 2005-08-31 devnull case 0:
108 262ecfed 2005-08-31 devnull if (inputfd != 0)
109 262ecfed 2005-08-31 devnull dup2(inputfd, 0);
110 262ecfed 2005-08-31 devnull dup2(1, 2);
111 262ecfed 2005-08-31 devnull lseek(0, 0L, 0);
112 b87296ce 2005-08-31 devnull execvp(LP, (char **)argvals);
113 262ecfed 2005-08-31 devnull error("exec failed\n");
114 262ecfed 2005-08-31 devnull exit(3);
115 262ecfed 2005-08-31 devnull default:
116 b87296ce 2005-08-31 devnull while((i=wait((int *)0)) != cpid){
117 b87296ce 2005-08-31 devnull if(i == -1 && errno == ECHILD)
118 b87296ce 2005-08-31 devnull break;
119 b87296ce 2005-08-31 devnull printf("%d %d\n", i, errno);
120 b87296ce 2005-08-31 devnull fflush(stdout);
121 b87296ce 2005-08-31 devnull }
122 b87296ce 2005-08-31 devnull error("wait got %d\n", cpid);
123 262ecfed 2005-08-31 devnull }
124 262ecfed 2005-08-31 devnull }
125 262ecfed 2005-08-31 devnull
126 262ecfed 2005-08-31 devnull int
127 262ecfed 2005-08-31 devnull tempfile(void)
128 262ecfed 2005-08-31 devnull {
129 b87296ce 2005-08-31 devnull static int tindx = 0;
130 262ecfed 2005-08-31 devnull char tmpf[sizeof(TMPDIR)+64];
131 262ecfed 2005-08-31 devnull int crtfd, tmpfd;
132 262ecfed 2005-08-31 devnull
133 262ecfed 2005-08-31 devnull sprintf(tmpf, "%s/lp%d.%d", TMPDIR, getpid(), tindx++);
134 262ecfed 2005-08-31 devnull if((crtfd=creat(tmpf, 0666)) < 0) {
135 262ecfed 2005-08-31 devnull error("cannot create temp file %s\n", tmpf);
136 262ecfed 2005-08-31 devnull NAK();
137 262ecfed 2005-08-31 devnull exit(3);
138 262ecfed 2005-08-31 devnull }
139 262ecfed 2005-08-31 devnull if((tmpfd=open(tmpf, 2)) < 0) {
140 262ecfed 2005-08-31 devnull error("cannot open temp file %s\n", tmpf);
141 262ecfed 2005-08-31 devnull NAK();
142 262ecfed 2005-08-31 devnull exit(3);
143 262ecfed 2005-08-31 devnull }
144 262ecfed 2005-08-31 devnull close(crtfd);
145 b87296ce 2005-08-31 devnull /* unlink(tmpf); /* comment out for debugging */
146 262ecfed 2005-08-31 devnull return(tmpfd);
147 262ecfed 2005-08-31 devnull }
148 262ecfed 2005-08-31 devnull
149 262ecfed 2005-08-31 devnull int
150 262ecfed 2005-08-31 devnull readfile(int outfd, int bsize)
151 262ecfed 2005-08-31 devnull {
152 262ecfed 2005-08-31 devnull int rv;
153 262ecfed 2005-08-31 devnull
154 262ecfed 2005-08-31 devnull dbgstate = 1;
155 262ecfed 2005-08-31 devnull alarm(60);
156 262ecfed 2005-08-31 devnull ACK();
157 262ecfed 2005-08-31 devnull dbgstate = 2;
158 262ecfed 2005-08-31 devnull for(; bsize > 0; bsize -= rv) {
159 262ecfed 2005-08-31 devnull alarm(60);
160 262ecfed 2005-08-31 devnull if((rv=read(0, jobbuf, MIN(bsize,RDSIZE))) < 0) {
161 262ecfed 2005-08-31 devnull error("error reading input, %d unread\n", bsize);
162 262ecfed 2005-08-31 devnull exit(4);
163 262ecfed 2005-08-31 devnull } else if (rv == 0) {
164 262ecfed 2005-08-31 devnull error("connection closed prematurely\n");
165 262ecfed 2005-08-31 devnull exit(4);
166 262ecfed 2005-08-31 devnull } else if((write(outfd, jobbuf, rv)) != rv) {
167 262ecfed 2005-08-31 devnull error("error writing temp file, %d unread\n", bsize);
168 262ecfed 2005-08-31 devnull exit(5);
169 262ecfed 2005-08-31 devnull }
170 262ecfed 2005-08-31 devnull }
171 262ecfed 2005-08-31 devnull dbgstate = 3;
172 262ecfed 2005-08-31 devnull alarm(60);
173 262ecfed 2005-08-31 devnull if (((rv=read(0, jobbuf, 1))==1) && (*jobbuf=='\0')) {
174 262ecfed 2005-08-31 devnull alarm(60);
175 262ecfed 2005-08-31 devnull ACK();
176 262ecfed 2005-08-31 devnull dbgstate = 4;
177 262ecfed 2005-08-31 devnull alarm(0);
178 262ecfed 2005-08-31 devnull return(outfd);
179 262ecfed 2005-08-31 devnull }
180 262ecfed 2005-08-31 devnull alarm(0);
181 262ecfed 2005-08-31 devnull error("received bad status <%d> from sender\n", *jobbuf);
182 262ecfed 2005-08-31 devnull error("rv=%d\n", rv);
183 262ecfed 2005-08-31 devnull NAK();
184 262ecfed 2005-08-31 devnull return(-1);
185 262ecfed 2005-08-31 devnull }
186 262ecfed 2005-08-31 devnull
187 262ecfed 2005-08-31 devnull /* reads a line from the input into lnbuf
188 262ecfed 2005-08-31 devnull * if there is no error, it returns
189 262ecfed 2005-08-31 devnull * the number of characters in the buffer
190 262ecfed 2005-08-31 devnull * if there is an error and there where characters
191 262ecfed 2005-08-31 devnull * read, it returns the negative value of the
192 262ecfed 2005-08-31 devnull * number of characters read
193 262ecfed 2005-08-31 devnull * if there is an error and no characters were read,
194 262ecfed 2005-08-31 devnull * it returns the negative value of 1 greater than
195 262ecfed 2005-08-31 devnull * the size of the line buffer
196 262ecfed 2005-08-31 devnull */
197 262ecfed 2005-08-31 devnull int
198 262ecfed 2005-08-31 devnull readline(int inpfd)
199 262ecfed 2005-08-31 devnull {
200 262ecfed 2005-08-31 devnull unsigned char *ap;
201 262ecfed 2005-08-31 devnull int i, rv;
202 262ecfed 2005-08-31 devnull
203 262ecfed 2005-08-31 devnull ap = lnbuf;
204 262ecfed 2005-08-31 devnull lnbuf[0] = '\0';
205 262ecfed 2005-08-31 devnull i = 0;
206 262ecfed 2005-08-31 devnull alarm(60);
207 262ecfed 2005-08-31 devnull do {
208 262ecfed 2005-08-31 devnull rv = read(inpfd, ap, 1);
209 262ecfed 2005-08-31 devnull } while (rv==1 && ++i && *ap != '\n' && ap++ && (i < LNBFSZ - 2));
210 262ecfed 2005-08-31 devnull alarm(0);
211 262ecfed 2005-08-31 devnull if (i != 0 && *ap != '\n') {
212 262ecfed 2005-08-31 devnull *++ap = '\n';
213 262ecfed 2005-08-31 devnull i++;
214 262ecfed 2005-08-31 devnull }
215 262ecfed 2005-08-31 devnull *++ap = '\0';
216 262ecfed 2005-08-31 devnull if (rv < 0) {
217 262ecfed 2005-08-31 devnull error("read error; lost connection\n");
218 262ecfed 2005-08-31 devnull if (i==0) i = -(LNBFSZ+1);
219 262ecfed 2005-08-31 devnull else i = -i;
220 262ecfed 2005-08-31 devnull }
221 262ecfed 2005-08-31 devnull return(i);
222 262ecfed 2005-08-31 devnull }
223 262ecfed 2005-08-31 devnull
224 262ecfed 2005-08-31 devnull int
225 262ecfed 2005-08-31 devnull getfiles(void)
226 262ecfed 2005-08-31 devnull {
227 262ecfed 2005-08-31 devnull unsigned char *ap;
228 262ecfed 2005-08-31 devnull int filecnt, bsize, rv;
229 262ecfed 2005-08-31 devnull
230 262ecfed 2005-08-31 devnull filecnt = 0;
231 262ecfed 2005-08-31 devnull /* get a line, hopefully containing a ctrl char, size, and name */
232 262ecfed 2005-08-31 devnull for(;;) {
233 262ecfed 2005-08-31 devnull ap = lnbuf;
234 262ecfed 2005-08-31 devnull if ((rv=readline(0)) < 0) NAK();
235 262ecfed 2005-08-31 devnull if (rv <= 0) {
236 262ecfed 2005-08-31 devnull return(filecnt);
237 262ecfed 2005-08-31 devnull }
238 262ecfed 2005-08-31 devnull switch(*ap++) {
239 262ecfed 2005-08-31 devnull case '\1': /* cleanup - data sent was bad (whatever that means) */
240 262ecfed 2005-08-31 devnull break;
241 262ecfed 2005-08-31 devnull case '\2': /* read control file */
242 b87296ce 2005-08-31 devnull bsize = atoi((const char *)ap);
243 262ecfed 2005-08-31 devnull cntrlfd = tempfile();
244 262ecfed 2005-08-31 devnull if (readfile(cntrlfd, bsize) < 0) {
245 262ecfed 2005-08-31 devnull close(cntrlfd);
246 262ecfed 2005-08-31 devnull NAK();
247 262ecfed 2005-08-31 devnull return(0);
248 262ecfed 2005-08-31 devnull }
249 262ecfed 2005-08-31 devnull break;
250 262ecfed 2005-08-31 devnull case '\3': /* read data file */
251 b87296ce 2005-08-31 devnull bsize = atoi((const char *)ap);
252 262ecfed 2005-08-31 devnull datafd[filecnt] = tempfile();
253 262ecfed 2005-08-31 devnull if (readfile(datafd[filecnt], bsize) < 0) {
254 262ecfed 2005-08-31 devnull close(datafd[filecnt]);
255 262ecfed 2005-08-31 devnull NAK();
256 262ecfed 2005-08-31 devnull return(0);
257 262ecfed 2005-08-31 devnull }
258 262ecfed 2005-08-31 devnull filecnt++;
259 262ecfed 2005-08-31 devnull break;
260 262ecfed 2005-08-31 devnull default:
261 262ecfed 2005-08-31 devnull error("protocol error <%d>\n", *(ap-1));
262 262ecfed 2005-08-31 devnull NAK();
263 262ecfed 2005-08-31 devnull }
264 262ecfed 2005-08-31 devnull }
265 262ecfed 2005-08-31 devnull return(filecnt);
266 262ecfed 2005-08-31 devnull }
267 262ecfed 2005-08-31 devnull
268 262ecfed 2005-08-31 devnull struct jobinfo *
269 262ecfed 2005-08-31 devnull getjobinfo(int fd)
270 262ecfed 2005-08-31 devnull {
271 262ecfed 2005-08-31 devnull unsigned char *ap;
272 262ecfed 2005-08-31 devnull int rv;
273 262ecfed 2005-08-31 devnull static struct jobinfo info;
274 262ecfed 2005-08-31 devnull
275 262ecfed 2005-08-31 devnull if (fd < 0) error("getjobinfo: bad file descriptor\n");
276 262ecfed 2005-08-31 devnull if (lseek(fd, 0L, 0) < 0) {
277 262ecfed 2005-08-31 devnull error("error seeking in temp file\n");
278 262ecfed 2005-08-31 devnull exit(7);
279 262ecfed 2005-08-31 devnull }
280 262ecfed 2005-08-31 devnull /* the following strings should be < NAMELEN or else they will not
281 262ecfed 2005-08-31 devnull * be null terminated.
282 262ecfed 2005-08-31 devnull */
283 262ecfed 2005-08-31 devnull strncpy(info.user, "daemon", NAMELEN);
284 262ecfed 2005-08-31 devnull strncpy(info.host, "nowhere", NAMELEN);
285 262ecfed 2005-08-31 devnull /* there may be a space after the name and host. It will be filtered out
286 262ecfed 2005-08-31 devnull * by CPYFIELD.
287 262ecfed 2005-08-31 devnull */
288 262ecfed 2005-08-31 devnull while ((rv=readline(fd)) > 0) {
289 262ecfed 2005-08-31 devnull ap = lnbuf;
290 262ecfed 2005-08-31 devnull ap[rv-1] = '\0'; /* remove newline from string */
291 262ecfed 2005-08-31 devnull switch (*ap) {
292 262ecfed 2005-08-31 devnull case 'H':
293 262ecfed 2005-08-31 devnull if (ap[1] == '\0')
294 262ecfed 2005-08-31 devnull strncpy(info.host, "unknown", NAMELEN);
295 262ecfed 2005-08-31 devnull else
296 262ecfed 2005-08-31 devnull strncpy(info.host, (const char *)&ap[1], NAMELEN);
297 262ecfed 2005-08-31 devnull info.host[strlen(info.host)] = '\0';
298 262ecfed 2005-08-31 devnull break;
299 262ecfed 2005-08-31 devnull case 'P':
300 262ecfed 2005-08-31 devnull if (ap[1] == '\0')
301 262ecfed 2005-08-31 devnull strncpy(info.user, "unknown", NAMELEN);
302 262ecfed 2005-08-31 devnull else
303 262ecfed 2005-08-31 devnull strncpy(info.user, (const char *)&ap[1], NAMELEN);
304 262ecfed 2005-08-31 devnull info.user[strlen(info.user)] = '\0';
305 262ecfed 2005-08-31 devnull break;
306 262ecfed 2005-08-31 devnull }
307 262ecfed 2005-08-31 devnull }
308 262ecfed 2005-08-31 devnull return(&info);
309 262ecfed 2005-08-31 devnull }
310 262ecfed 2005-08-31 devnull
311 262ecfed 2005-08-31 devnull void
312 262ecfed 2005-08-31 devnull alarmhandler(int sig) {
313 262ecfed 2005-08-31 devnull signal(sig, alarmhandler);
314 262ecfed 2005-08-31 devnull error("alarm at %d - %s\n", dbgstate, dbgstrings[dbgstate]);
315 262ecfed 2005-08-31 devnull }
316 262ecfed 2005-08-31 devnull
317 262ecfed 2005-08-31 devnull void
318 b87296ce 2005-08-31 devnull nop(int sig)
319 262ecfed 2005-08-31 devnull {
320 b87296ce 2005-08-31 devnull }
321 b87296ce 2005-08-31 devnull
322 b87296ce 2005-08-31 devnull
323 b87296ce 2005-08-31 devnull int
324 b87296ce 2005-08-31 devnull main()
325 b87296ce 2005-08-31 devnull {
326 262ecfed 2005-08-31 devnull unsigned char *ap, *bp, *cp, *savbufpnt;
327 262ecfed 2005-08-31 devnull int i, blen, rv, saveflg, savargcnt;
328 262ecfed 2005-08-31 devnull struct jobinfo *jinfop;
329 262ecfed 2005-08-31 devnull
330 b87296ce 2005-08-31 devnull signal(SIGHUP, SIG_IGN); /* SIGHUP not in lcc */
331 b87296ce 2005-08-31 devnull signal(SIGALRM, alarmhandler); /* SIGALRM not in lcc */
332 b87296ce 2005-08-31 devnull signal(SIGCHLD, nop); /* so that wait will get us something */
333 262ecfed 2005-08-31 devnull cp = argvstr;
334 262ecfed 2005-08-31 devnull /* setup argv[0] for exec */
335 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
336 262ecfed 2005-08-31 devnull for (bp = (unsigned char *)LP, i = 0; (*bp != '\0') && (i < ARGSIZ-1); *cp++ = *bp++, i++);
337 262ecfed 2005-08-31 devnull *cp++ = '\0';
338 262ecfed 2005-08-31 devnull /* get the first line sent and parse it as arguments for lp */
339 262ecfed 2005-08-31 devnull if ((rv=readline(0)) < 0)
340 262ecfed 2005-08-31 devnull exit(1);
341 262ecfed 2005-08-31 devnull bp = lnbuf;
342 262ecfed 2005-08-31 devnull /* setup the remaining arguments */
343 262ecfed 2005-08-31 devnull /* check for BSD style request */
344 262ecfed 2005-08-31 devnull /* ^A, ^B, ^C, ^D, ^E (for BSD lpr) */
345 262ecfed 2005-08-31 devnull switch (*bp) {
346 262ecfed 2005-08-31 devnull case '\001':
347 262ecfed 2005-08-31 devnull case '\003':
348 262ecfed 2005-08-31 devnull case '\004':
349 262ecfed 2005-08-31 devnull bp++; /* drop the ctrl character from the input */
350 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
351 262ecfed 2005-08-31 devnull *cp++ = '-'; *cp++ = 'q'; *cp++ = '\0'; /* -q */
352 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
353 262ecfed 2005-08-31 devnull *cp++ = '-'; *cp++ = 'd'; /* -d */
354 262ecfed 2005-08-31 devnull CPYFIELD(bp, cp); /* printer */
355 262ecfed 2005-08-31 devnull *cp++ = '\0';
356 262ecfed 2005-08-31 devnull break;
357 262ecfed 2005-08-31 devnull case '\002':
358 262ecfed 2005-08-31 devnull bp++; /* drop the ctrl character from the input */
359 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
360 262ecfed 2005-08-31 devnull *cp++ = '-'; *cp++ = 'd'; /* -d */
361 262ecfed 2005-08-31 devnull CPYFIELD(bp, cp); /* printer */
362 262ecfed 2005-08-31 devnull *cp++ = '\0';
363 262ecfed 2005-08-31 devnull ACK();
364 262ecfed 2005-08-31 devnull savargcnt = argcnt;
365 262ecfed 2005-08-31 devnull savbufpnt = cp;
366 262ecfed 2005-08-31 devnull while ((rv=getfiles())) {
367 262ecfed 2005-08-31 devnull jinfop = getjobinfo(cntrlfd);
368 262ecfed 2005-08-31 devnull close(cntrlfd);
369 262ecfed 2005-08-31 devnull argcnt = savargcnt;
370 262ecfed 2005-08-31 devnull cp = savbufpnt;
371 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
372 262ecfed 2005-08-31 devnull *cp++ = '-'; *cp++ = 'M'; /* -M */
373 262ecfed 2005-08-31 devnull bp = (unsigned char *)jinfop->host;
374 262ecfed 2005-08-31 devnull CPYFIELD(bp, cp); /* host name */
375 262ecfed 2005-08-31 devnull *cp++ = '\0';
376 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
377 262ecfed 2005-08-31 devnull *cp++ = '-'; *cp++ = 'u'; /* -u */
378 262ecfed 2005-08-31 devnull bp = (unsigned char *)jinfop->user;
379 262ecfed 2005-08-31 devnull CPYFIELD(bp, cp); /* user name */
380 262ecfed 2005-08-31 devnull *cp++ = '\0';
381 262ecfed 2005-08-31 devnull for(i=0;i<rv;i++)
382 262ecfed 2005-08-31 devnull forklp(datafd[i]);
383 262ecfed 2005-08-31 devnull }
384 262ecfed 2005-08-31 devnull exit(0);
385 262ecfed 2005-08-31 devnull case '\005':
386 262ecfed 2005-08-31 devnull bp++; /* drop the ctrl character from the input */
387 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
388 262ecfed 2005-08-31 devnull *cp++ = '-'; *cp++ = 'k'; *cp++ = '\0'; /* -k */
389 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
390 262ecfed 2005-08-31 devnull *cp++ = '-'; *cp++ = 'd'; /* -d */
391 262ecfed 2005-08-31 devnull CPYFIELD(bp, cp); /* printer */
392 262ecfed 2005-08-31 devnull *cp++ = '\0';
393 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
394 262ecfed 2005-08-31 devnull *cp++ = '-'; ap = cp; *cp++ = 'u'; /* -u */
395 262ecfed 2005-08-31 devnull CPYFIELD(bp, cp); /* username */
396 262ecfed 2005-08-31 devnull
397 262ecfed 2005-08-31 devnull /* deal with bug in lprng where the username is not supplied
398 262ecfed 2005-08-31 devnull */
399 262ecfed 2005-08-31 devnull if (ap == (cp-1)) {
400 262ecfed 2005-08-31 devnull ap = (unsigned char *)"none";
401 262ecfed 2005-08-31 devnull CPYFIELD(ap, cp);
402 262ecfed 2005-08-31 devnull }
403 262ecfed 2005-08-31 devnull
404 262ecfed 2005-08-31 devnull *cp++ = '\0';
405 262ecfed 2005-08-31 devnull datafd[0] = tempfile();
406 262ecfed 2005-08-31 devnull blen = strlen((const char *)bp);
407 262ecfed 2005-08-31 devnull if (write(datafd[0], bp, blen) != blen) {
408 262ecfed 2005-08-31 devnull error("write error\n");
409 262ecfed 2005-08-31 devnull exit(6);
410 262ecfed 2005-08-31 devnull }
411 262ecfed 2005-08-31 devnull if (write(datafd[0], "\n", 1) != 1) {
412 262ecfed 2005-08-31 devnull error("write error\n");
413 262ecfed 2005-08-31 devnull exit(6);
414 262ecfed 2005-08-31 devnull }
415 262ecfed 2005-08-31 devnull break;
416 262ecfed 2005-08-31 devnull default:
417 262ecfed 2005-08-31 devnull /* otherwise get my lp arguments */
418 262ecfed 2005-08-31 devnull do {
419 262ecfed 2005-08-31 devnull /* move to next non-white space */
420 262ecfed 2005-08-31 devnull while (*bp==' '||*bp=='\t')
421 262ecfed 2005-08-31 devnull ++bp;
422 262ecfed 2005-08-31 devnull if (*bp=='\n') continue;
423 262ecfed 2005-08-31 devnull /* only accept arguments beginning with -
424 262ecfed 2005-08-31 devnull * this is done to prevent the printing of
425 262ecfed 2005-08-31 devnull * local files from the destination host
426 262ecfed 2005-08-31 devnull */
427 262ecfed 2005-08-31 devnull if (*bp=='-') {
428 262ecfed 2005-08-31 devnull argvals[argcnt++] = cp;
429 262ecfed 2005-08-31 devnull saveflg = 1;
430 262ecfed 2005-08-31 devnull } else
431 262ecfed 2005-08-31 devnull saveflg = 0;
432 262ecfed 2005-08-31 devnull /* move to next white space copying text to argument buffer */
433 262ecfed 2005-08-31 devnull while (*bp!=' ' && *bp!='\t' && *bp!='\n'
434 262ecfed 2005-08-31 devnull && *bp!='\0') {
435 262ecfed 2005-08-31 devnull *cp = *bp++;
436 262ecfed 2005-08-31 devnull cp += saveflg;
437 262ecfed 2005-08-31 devnull }
438 262ecfed 2005-08-31 devnull *cp = '\0';
439 262ecfed 2005-08-31 devnull cp += saveflg;
440 262ecfed 2005-08-31 devnull } while (*bp!='\n' && *bp!='\0');
441 262ecfed 2005-08-31 devnull if (readline(0) < 0) exit(7);
442 262ecfed 2005-08-31 devnull datafd[0] = tempfile();
443 b87296ce 2005-08-31 devnull if(readfile(datafd[0], atoi((const char *)lnbuf)) < 0) {
444 262ecfed 2005-08-31 devnull error("readfile failed\n");
445 262ecfed 2005-08-31 devnull exit(8);
446 262ecfed 2005-08-31 devnull }
447 262ecfed 2005-08-31 devnull }
448 262ecfed 2005-08-31 devnull forklp(datafd[0]);
449 262ecfed 2005-08-31 devnull exit(0);
450 262ecfed 2005-08-31 devnull }