1219b2ee8SDavid du Colombier #include <stdio.h>
243af371bSDavid du Colombier #include <stdlib.h>
3219b2ee8SDavid du Colombier #include <string.h>
443af371bSDavid du Colombier #include <errno.h>
543af371bSDavid du Colombier #include <fcntl.h>
643af371bSDavid du Colombier #include <signal.h>
77dd7cddfSDavid du Colombier #include <stdarg.h>
843af371bSDavid du Colombier #include <time.h>
943af371bSDavid du Colombier #include <unistd.h>
1043af371bSDavid du Colombier #include <sys/types.h>
1143af371bSDavid du Colombier #include <sys/wait.h>
12bd389b36SDavid du Colombier
13bd389b36SDavid du Colombier /* for Plan 9 */
14219b2ee8SDavid du Colombier #ifdef PLAN9
15bd389b36SDavid du Colombier #define LP "/bin/lp"
16219b2ee8SDavid du Colombier #define TMPDIR "/sys/lib/lp/tmp"
17219b2ee8SDavid du Colombier #define LPDAEMONLOG "/sys/lib/lp/log/lpdaemonl"
18219b2ee8SDavid du Colombier #endif
19bd389b36SDavid du Colombier /* for Tenth Edition systems */
20219b2ee8SDavid du Colombier #ifdef V10
21219b2ee8SDavid du Colombier #define LP "/usr/bin/lp"
22219b2ee8SDavid du Colombier #define TMPDIR "/tmp"
23bd389b36SDavid du Colombier #define LPDAEMONLOG "/tmp/lpdaemonl"
24219b2ee8SDavid du Colombier #endif
25219b2ee8SDavid du Colombier /* for System V or BSD systems */
26219b2ee8SDavid du Colombier #if defined(SYSV) || defined(BSD)
27219b2ee8SDavid du Colombier #define LP "/v/bin/lp"
28219b2ee8SDavid du Colombier #define TMPDIR "/tmp"
29219b2ee8SDavid du Colombier #define LPDAEMONLOG "/tmp/lpdaemonl"
30219b2ee8SDavid du Colombier #endif
31bd389b36SDavid du Colombier
32bd389b36SDavid du Colombier #define ARGSIZ 4096
33219b2ee8SDavid du Colombier #define NAMELEN 30
34bd389b36SDavid du Colombier
3580ee5cbfSDavid du Colombier unsigned char argvstr[ARGSIZ]; /* arguments after parsing */
3680ee5cbfSDavid du Colombier unsigned char *argvals[ARGSIZ/2+1]; /* pointers to arguments after parsing */
37bd389b36SDavid du Colombier int ascnt = 0, argcnt = 0; /* number of arguments parsed */
38219b2ee8SDavid du Colombier /* for 'stuff' gleened from lpr cntrl file */
39219b2ee8SDavid du Colombier struct jobinfo {
40219b2ee8SDavid du Colombier char user[NAMELEN+1];
41219b2ee8SDavid du Colombier char host[NAMELEN+1];
42219b2ee8SDavid du Colombier } *getjobinfo();
43bd389b36SDavid du Colombier
44219b2ee8SDavid du Colombier #define MIN(a,b) ((a<b)?a:b)
45219b2ee8SDavid du Colombier
46219b2ee8SDavid du Colombier #define CPYFIELD(src, dst) { while (*(src)!=' ' && *(src)!='\t' && *(src)!='\r' && *(src)!='\n' && *(src)!='\0') *(dst)++ = *(src)++; }
47219b2ee8SDavid du Colombier
48219b2ee8SDavid du Colombier #define ACK() write(1, "", 1)
49219b2ee8SDavid du Colombier #define NAK() write(1, "\001", 1)
50219b2ee8SDavid du Colombier
51219b2ee8SDavid du Colombier #define LNBFSZ 4096
5280ee5cbfSDavid du Colombier unsigned char lnbuf[LNBFSZ];
53219b2ee8SDavid du Colombier
54219b2ee8SDavid du Colombier #define RDSIZE 512
5580ee5cbfSDavid du Colombier unsigned char jobbuf[RDSIZE];
56219b2ee8SDavid du Colombier
577dd7cddfSDavid du Colombier int datafd[400], cntrlfd = -1;
58219b2ee8SDavid du Colombier
59219b2ee8SDavid du Colombier int dbgstate = 0;
60219b2ee8SDavid du Colombier char *dbgstrings[] = {
61219b2ee8SDavid du Colombier "",
62219b2ee8SDavid du Colombier "sendack1",
63219b2ee8SDavid du Colombier "send",
64219b2ee8SDavid du Colombier "rcvack",
65219b2ee8SDavid du Colombier "sendack2",
66219b2ee8SDavid du Colombier "done"
67219b2ee8SDavid du Colombier };
68bd389b36SDavid du Colombier
69bd389b36SDavid du Colombier void
error(char * s1,...)70219b2ee8SDavid du Colombier error(char *s1, ...)
71bd389b36SDavid du Colombier {
72219b2ee8SDavid du Colombier FILE *fp;
73219b2ee8SDavid du Colombier long thetime;
74219b2ee8SDavid du Colombier char *chartime;
75219b2ee8SDavid du Colombier va_list ap;
76219b2ee8SDavid du Colombier char *args[8];
77219b2ee8SDavid du Colombier int argno = 0;
78bd389b36SDavid du Colombier
79219b2ee8SDavid du Colombier if((fp=fopen(LPDAEMONLOG, "a"))==NULL) {
807dd7cddfSDavid du Colombier fprintf(stderr, "cannot open %s in append mode\n", LPDAEMONLOG);
81219b2ee8SDavid du Colombier return;
82bd389b36SDavid du Colombier }
83219b2ee8SDavid du Colombier time(&thetime);
84219b2ee8SDavid du Colombier chartime = ctime(&thetime);
857dd7cddfSDavid du Colombier fprintf(fp, "%.15s [%5.5d] ", &(chartime[4]), getpid());
86219b2ee8SDavid du Colombier va_start(ap, s1);
8743af371bSDavid du Colombier while((args[argno++] = va_arg(ap, char*)) && argno<8)
8843af371bSDavid du Colombier ;
89219b2ee8SDavid du Colombier va_end(ap);
90219b2ee8SDavid du Colombier fprintf(fp, s1, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
91219b2ee8SDavid du Colombier fclose(fp);
92219b2ee8SDavid du Colombier }
93219b2ee8SDavid du Colombier
94219b2ee8SDavid du Colombier void
forklp(int inputfd)95219b2ee8SDavid du Colombier forklp(int inputfd)
96219b2ee8SDavid du Colombier {
97219b2ee8SDavid du Colombier int i, cpid;
9880ee5cbfSDavid du Colombier unsigned char *bp, *cp;
9980ee5cbfSDavid du Colombier unsigned char logent[LNBFSZ];
100219b2ee8SDavid du Colombier
101219b2ee8SDavid du Colombier /* log this call to lp */
102219b2ee8SDavid du Colombier cp = logent;
103219b2ee8SDavid du Colombier for (i=1; i<argcnt; i++) {
104219b2ee8SDavid du Colombier bp = argvals[i];
10580ee5cbfSDavid du Colombier if (cp+strlen((const char *)bp)+1 < logent+LNBFSZ-1) {
106219b2ee8SDavid du Colombier CPYFIELD(bp, cp);
107219b2ee8SDavid du Colombier *cp++ = ' ';
108219b2ee8SDavid du Colombier }
109219b2ee8SDavid du Colombier }
110219b2ee8SDavid du Colombier *--cp = '\n';
111219b2ee8SDavid du Colombier *++cp = '\0';
11280ee5cbfSDavid du Colombier error((const char *)logent);
113219b2ee8SDavid du Colombier switch((cpid=fork())){
114219b2ee8SDavid du Colombier case -1:
115219b2ee8SDavid du Colombier error("fork error\n");
116219b2ee8SDavid du Colombier exit(2);
117219b2ee8SDavid du Colombier case 0:
118219b2ee8SDavid du Colombier if (inputfd != 0)
119219b2ee8SDavid du Colombier dup2(inputfd, 0);
120219b2ee8SDavid du Colombier dup2(1, 2);
121219b2ee8SDavid du Colombier lseek(0, 0L, 0);
12280ee5cbfSDavid du Colombier execvp(LP, (const char **)argvals);
123219b2ee8SDavid du Colombier error("exec failed\n");
124219b2ee8SDavid du Colombier exit(3);
125219b2ee8SDavid du Colombier default:
12643af371bSDavid du Colombier while(wait((int *)0) != cpid)
12743af371bSDavid du Colombier ;
128219b2ee8SDavid du Colombier }
129219b2ee8SDavid du Colombier }
130219b2ee8SDavid du Colombier
131219b2ee8SDavid du Colombier int
tempfile(void)132219b2ee8SDavid du Colombier tempfile(void)
133219b2ee8SDavid du Colombier {
134219b2ee8SDavid du Colombier static tindx = 0;
1357dd7cddfSDavid du Colombier char tmpf[sizeof(TMPDIR)+64];
136219b2ee8SDavid du Colombier int crtfd, tmpfd;
137219b2ee8SDavid du Colombier
138219b2ee8SDavid du Colombier sprintf(tmpf, "%s/lp%d.%d", TMPDIR, getpid(), tindx++);
139219b2ee8SDavid du Colombier if((crtfd=creat(tmpf, 0666)) < 0) {
140219b2ee8SDavid du Colombier error("cannot create temp file %s\n", tmpf);
141219b2ee8SDavid du Colombier NAK();
142219b2ee8SDavid du Colombier exit(3);
143219b2ee8SDavid du Colombier }
144219b2ee8SDavid du Colombier if((tmpfd=open(tmpf, 2)) < 0) {
145219b2ee8SDavid du Colombier error("cannot open temp file %s\n", tmpf);
146219b2ee8SDavid du Colombier NAK();
147219b2ee8SDavid du Colombier exit(3);
148219b2ee8SDavid du Colombier }
149219b2ee8SDavid du Colombier close(crtfd);
150219b2ee8SDavid du Colombier unlink(tmpf); /* comment out for debugging */
151219b2ee8SDavid du Colombier return(tmpfd);
152219b2ee8SDavid du Colombier }
153219b2ee8SDavid du Colombier
154219b2ee8SDavid du Colombier int
readfile(int outfd,int bsize)155219b2ee8SDavid du Colombier readfile(int outfd, int bsize)
156219b2ee8SDavid du Colombier {
157219b2ee8SDavid du Colombier int rv;
158219b2ee8SDavid du Colombier
159219b2ee8SDavid du Colombier dbgstate = 1;
160219b2ee8SDavid du Colombier alarm(60);
161219b2ee8SDavid du Colombier ACK();
162219b2ee8SDavid du Colombier dbgstate = 2;
163219b2ee8SDavid du Colombier for(; bsize > 0; bsize -= rv) {
164219b2ee8SDavid du Colombier alarm(60);
165219b2ee8SDavid du Colombier if((rv=read(0, jobbuf, MIN(bsize,RDSIZE))) < 0) {
166219b2ee8SDavid du Colombier error("error reading input, %d unread\n", bsize);
167219b2ee8SDavid du Colombier exit(4);
1687dd7cddfSDavid du Colombier } else if (rv == 0) {
1697dd7cddfSDavid du Colombier error("connection closed prematurely\n");
1707dd7cddfSDavid du Colombier exit(4);
171219b2ee8SDavid du Colombier } else if((write(outfd, jobbuf, rv)) != rv) {
172219b2ee8SDavid du Colombier error("error writing temp file, %d unread\n", bsize);
173219b2ee8SDavid du Colombier exit(5);
174219b2ee8SDavid du Colombier }
175219b2ee8SDavid du Colombier }
176219b2ee8SDavid du Colombier dbgstate = 3;
177219b2ee8SDavid du Colombier alarm(60);
178219b2ee8SDavid du Colombier if (((rv=read(0, jobbuf, 1))==1) && (*jobbuf=='\0')) {
179219b2ee8SDavid du Colombier alarm(60);
180219b2ee8SDavid du Colombier ACK();
181219b2ee8SDavid du Colombier dbgstate = 4;
182219b2ee8SDavid du Colombier alarm(0);
183219b2ee8SDavid du Colombier return(outfd);
184219b2ee8SDavid du Colombier }
185219b2ee8SDavid du Colombier alarm(0);
186219b2ee8SDavid du Colombier error("received bad status <%d> from sender\n", *jobbuf);
187219b2ee8SDavid du Colombier error("rv=%d\n", rv);
188219b2ee8SDavid du Colombier NAK();
189219b2ee8SDavid du Colombier return(-1);
190219b2ee8SDavid du Colombier }
191219b2ee8SDavid du Colombier
192219b2ee8SDavid du Colombier /* reads a line from the input into lnbuf
193219b2ee8SDavid du Colombier * if there is no error, it returns
194219b2ee8SDavid du Colombier * the number of characters in the buffer
195219b2ee8SDavid du Colombier * if there is an error and there where characters
196219b2ee8SDavid du Colombier * read, it returns the negative value of the
197219b2ee8SDavid du Colombier * number of characters read
198219b2ee8SDavid du Colombier * if there is an error and no characters were read,
199219b2ee8SDavid du Colombier * it returns the negative value of 1 greater than
200219b2ee8SDavid du Colombier * the size of the line buffer
201219b2ee8SDavid du Colombier */
202219b2ee8SDavid du Colombier int
readline(int inpfd)203219b2ee8SDavid du Colombier readline(int inpfd)
204219b2ee8SDavid du Colombier {
20580ee5cbfSDavid du Colombier unsigned char *ap;
206219b2ee8SDavid du Colombier int i, rv;
207219b2ee8SDavid du Colombier
208219b2ee8SDavid du Colombier ap = lnbuf;
2097dd7cddfSDavid du Colombier lnbuf[0] = '\0';
210219b2ee8SDavid du Colombier i = 0;
2117dd7cddfSDavid du Colombier alarm(60);
212219b2ee8SDavid du Colombier do {
213219b2ee8SDavid du Colombier rv = read(inpfd, ap, 1);
214219b2ee8SDavid du Colombier } while (rv==1 && ++i && *ap != '\n' && ap++ && (i < LNBFSZ - 2));
2157dd7cddfSDavid du Colombier alarm(0);
216219b2ee8SDavid du Colombier if (i != 0 && *ap != '\n') {
217219b2ee8SDavid du Colombier *++ap = '\n';
218219b2ee8SDavid du Colombier i++;
219219b2ee8SDavid du Colombier }
220219b2ee8SDavid du Colombier *++ap = '\0';
221219b2ee8SDavid du Colombier if (rv < 0) {
222219b2ee8SDavid du Colombier error("read error; lost connection\n");
223219b2ee8SDavid du Colombier if (i==0) i = -(LNBFSZ+1);
224219b2ee8SDavid du Colombier else i = -i;
225219b2ee8SDavid du Colombier }
226219b2ee8SDavid du Colombier return(i);
227219b2ee8SDavid du Colombier }
228219b2ee8SDavid du Colombier
229219b2ee8SDavid du Colombier int
getfiles(void)230219b2ee8SDavid du Colombier getfiles(void)
231219b2ee8SDavid du Colombier {
23280ee5cbfSDavid du Colombier unsigned char *ap;
233219b2ee8SDavid du Colombier int filecnt, bsize, rv;
234219b2ee8SDavid du Colombier
235219b2ee8SDavid du Colombier filecnt = 0;
236219b2ee8SDavid du Colombier /* get a line, hopefully containing a ctrl char, size, and name */
237219b2ee8SDavid du Colombier for(;;) {
238219b2ee8SDavid du Colombier ap = lnbuf;
239219b2ee8SDavid du Colombier if ((rv=readline(0)) < 0) NAK();
2407dd7cddfSDavid du Colombier if (rv <= 0) {
2417dd7cddfSDavid du Colombier return(filecnt);
2427dd7cddfSDavid du Colombier }
243219b2ee8SDavid du Colombier switch(*ap++) {
244219b2ee8SDavid du Colombier case '\1': /* cleanup - data sent was bad (whatever that means) */
245219b2ee8SDavid du Colombier break;
246219b2ee8SDavid du Colombier case '\2': /* read control file */
24780ee5cbfSDavid du Colombier bsize = atoi((const char *)ap);
248219b2ee8SDavid du Colombier cntrlfd = tempfile();
249219b2ee8SDavid du Colombier if (readfile(cntrlfd, bsize) < 0) {
250219b2ee8SDavid du Colombier close(cntrlfd);
251219b2ee8SDavid du Colombier NAK();
252219b2ee8SDavid du Colombier return(0);
253219b2ee8SDavid du Colombier }
254219b2ee8SDavid du Colombier break;
255219b2ee8SDavid du Colombier case '\3': /* read data file */
25680ee5cbfSDavid du Colombier bsize = atoi((const char *)ap);
257219b2ee8SDavid du Colombier datafd[filecnt] = tempfile();
258219b2ee8SDavid du Colombier if (readfile(datafd[filecnt], bsize) < 0) {
259219b2ee8SDavid du Colombier close(datafd[filecnt]);
260219b2ee8SDavid du Colombier NAK();
261219b2ee8SDavid du Colombier return(0);
262219b2ee8SDavid du Colombier }
263219b2ee8SDavid du Colombier filecnt++;
264219b2ee8SDavid du Colombier break;
265219b2ee8SDavid du Colombier default:
266219b2ee8SDavid du Colombier error("protocol error <%d>\n", *(ap-1));
267219b2ee8SDavid du Colombier NAK();
268219b2ee8SDavid du Colombier }
269219b2ee8SDavid du Colombier }
270219b2ee8SDavid du Colombier return(filecnt);
271219b2ee8SDavid du Colombier }
272219b2ee8SDavid du Colombier
273219b2ee8SDavid du Colombier struct jobinfo *
getjobinfo(int fd)274219b2ee8SDavid du Colombier getjobinfo(int fd)
275219b2ee8SDavid du Colombier {
27680ee5cbfSDavid du Colombier unsigned char *ap;
277219b2ee8SDavid du Colombier int rv;
278219b2ee8SDavid du Colombier static struct jobinfo info;
279219b2ee8SDavid du Colombier
2807dd7cddfSDavid du Colombier if (fd < 0) error("getjobinfo: bad file descriptor\n");
281219b2ee8SDavid du Colombier if (lseek(fd, 0L, 0) < 0) {
282219b2ee8SDavid du Colombier error("error seeking in temp file\n");
283219b2ee8SDavid du Colombier exit(7);
284219b2ee8SDavid du Colombier }
285219b2ee8SDavid du Colombier /* the following strings should be < NAMELEN or else they will not
286219b2ee8SDavid du Colombier * be null terminated.
287219b2ee8SDavid du Colombier */
288219b2ee8SDavid du Colombier strncpy(info.user, "daemon", NAMELEN);
289219b2ee8SDavid du Colombier strncpy(info.host, "nowhere", NAMELEN);
290219b2ee8SDavid du Colombier /* there may be a space after the name and host. It will be filtered out
291219b2ee8SDavid du Colombier * by CPYFIELD.
292219b2ee8SDavid du Colombier */
293219b2ee8SDavid du Colombier while ((rv=readline(fd)) > 0) {
294219b2ee8SDavid du Colombier ap = lnbuf;
295219b2ee8SDavid du Colombier ap[rv-1] = '\0'; /* remove newline from string */
296219b2ee8SDavid du Colombier switch (*ap) {
297219b2ee8SDavid du Colombier case 'H':
298219b2ee8SDavid du Colombier if (ap[1] == '\0')
299219b2ee8SDavid du Colombier strncpy(info.host, "unknown", NAMELEN);
300219b2ee8SDavid du Colombier else
30180ee5cbfSDavid du Colombier strncpy(info.host, (const char *)&ap[1], NAMELEN);
302*ea9142f7SDavid du Colombier info.host[NAMELEN] = '\0';
303219b2ee8SDavid du Colombier break;
304219b2ee8SDavid du Colombier case 'P':
305219b2ee8SDavid du Colombier if (ap[1] == '\0')
306219b2ee8SDavid du Colombier strncpy(info.user, "unknown", NAMELEN);
307219b2ee8SDavid du Colombier else
30880ee5cbfSDavid du Colombier strncpy(info.user, (const char *)&ap[1], NAMELEN);
309*ea9142f7SDavid du Colombier info.user[NAMELEN] = '\0';
310219b2ee8SDavid du Colombier break;
311219b2ee8SDavid du Colombier }
312219b2ee8SDavid du Colombier }
313219b2ee8SDavid du Colombier return(&info);
314219b2ee8SDavid du Colombier }
315219b2ee8SDavid du Colombier
316219b2ee8SDavid du Colombier void
alarmhandler(int sig)317219b2ee8SDavid du Colombier alarmhandler(int sig) {
318219b2ee8SDavid du Colombier signal(sig, alarmhandler);
319219b2ee8SDavid du Colombier error("alarm at %d - %s\n", dbgstate, dbgstrings[dbgstate]);
320219b2ee8SDavid du Colombier }
321219b2ee8SDavid du Colombier
322027288c8SDavid du Colombier void
main()323219b2ee8SDavid du Colombier main()
324219b2ee8SDavid du Colombier {
32580ee5cbfSDavid du Colombier unsigned char *ap, *bp, *cp, *savbufpnt;
326219b2ee8SDavid du Colombier int i, blen, rv, saveflg, savargcnt;
327219b2ee8SDavid du Colombier struct jobinfo *jinfop;
328219b2ee8SDavid du Colombier
32943af371bSDavid du Colombier signal(SIGHUP, SIG_IGN);
33043af371bSDavid du Colombier signal(SIGALRM, alarmhandler);
331219b2ee8SDavid du Colombier cp = argvstr;
332bd389b36SDavid du Colombier /* setup argv[0] for exec */
333219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
33480ee5cbfSDavid du Colombier for (bp = (unsigned char *)LP, i = 0; (*bp != '\0') && (i < ARGSIZ-1); *cp++ = *bp++, i++);
335219b2ee8SDavid du Colombier *cp++ = '\0';
336219b2ee8SDavid du Colombier /* get the first line sent and parse it as arguments for lp */
337219b2ee8SDavid du Colombier if ((rv=readline(0)) < 0)
338219b2ee8SDavid du Colombier exit(1);
3393ff48bf5SDavid du Colombier bp = lnbuf;
340bd389b36SDavid du Colombier /* setup the remaining arguments */
341219b2ee8SDavid du Colombier /* check for BSD style request */
342219b2ee8SDavid du Colombier /* ^A, ^B, ^C, ^D, ^E (for BSD lpr) */
343219b2ee8SDavid du Colombier switch (*bp) {
344219b2ee8SDavid du Colombier case '\001':
345219b2ee8SDavid du Colombier case '\003':
346219b2ee8SDavid du Colombier case '\004':
347219b2ee8SDavid du Colombier bp++; /* drop the ctrl character from the input */
348219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
349219b2ee8SDavid du Colombier *cp++ = '-'; *cp++ = 'q'; *cp++ = '\0'; /* -q */
350219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
351219b2ee8SDavid du Colombier *cp++ = '-'; *cp++ = 'd'; /* -d */
352219b2ee8SDavid du Colombier CPYFIELD(bp, cp); /* printer */
353219b2ee8SDavid du Colombier *cp++ = '\0';
354219b2ee8SDavid du Colombier break;
355219b2ee8SDavid du Colombier case '\002':
356219b2ee8SDavid du Colombier bp++; /* drop the ctrl character from the input */
357219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
358219b2ee8SDavid du Colombier *cp++ = '-'; *cp++ = 'd'; /* -d */
359219b2ee8SDavid du Colombier CPYFIELD(bp, cp); /* printer */
360219b2ee8SDavid du Colombier *cp++ = '\0';
361219b2ee8SDavid du Colombier ACK();
362219b2ee8SDavid du Colombier savargcnt = argcnt;
363219b2ee8SDavid du Colombier savbufpnt = cp;
364219b2ee8SDavid du Colombier while ((rv=getfiles())) {
365219b2ee8SDavid du Colombier jinfop = getjobinfo(cntrlfd);
366219b2ee8SDavid du Colombier close(cntrlfd);
367219b2ee8SDavid du Colombier argcnt = savargcnt;
368219b2ee8SDavid du Colombier cp = savbufpnt;
369219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
370219b2ee8SDavid du Colombier *cp++ = '-'; *cp++ = 'M'; /* -M */
37180ee5cbfSDavid du Colombier bp = (unsigned char *)jinfop->host;
372219b2ee8SDavid du Colombier CPYFIELD(bp, cp); /* host name */
373219b2ee8SDavid du Colombier *cp++ = '\0';
374219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
375219b2ee8SDavid du Colombier *cp++ = '-'; *cp++ = 'u'; /* -u */
37680ee5cbfSDavid du Colombier bp = (unsigned char *)jinfop->user;
377219b2ee8SDavid du Colombier CPYFIELD(bp, cp); /* user name */
378219b2ee8SDavid du Colombier *cp++ = '\0';
379219b2ee8SDavid du Colombier for(i=0;i<rv;i++)
380219b2ee8SDavid du Colombier forklp(datafd[i]);
381219b2ee8SDavid du Colombier }
382219b2ee8SDavid du Colombier exit(0);
383219b2ee8SDavid du Colombier case '\005':
384219b2ee8SDavid du Colombier bp++; /* drop the ctrl character from the input */
385219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
386219b2ee8SDavid du Colombier *cp++ = '-'; *cp++ = 'k'; *cp++ = '\0'; /* -k */
387219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
388219b2ee8SDavid du Colombier *cp++ = '-'; *cp++ = 'd'; /* -d */
389219b2ee8SDavid du Colombier CPYFIELD(bp, cp); /* printer */
390219b2ee8SDavid du Colombier *cp++ = '\0';
391219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
3923ff48bf5SDavid du Colombier *cp++ = '-'; ap = cp; *cp++ = 'u'; /* -u */
393219b2ee8SDavid du Colombier CPYFIELD(bp, cp); /* username */
3943ff48bf5SDavid du Colombier
3953ff48bf5SDavid du Colombier /* deal with bug in lprng where the username is not supplied
3963ff48bf5SDavid du Colombier */
3973ff48bf5SDavid du Colombier if (ap == (cp-1)) {
3983ff48bf5SDavid du Colombier ap = (unsigned char *)"none";
3993ff48bf5SDavid du Colombier CPYFIELD(ap, cp);
4003ff48bf5SDavid du Colombier }
4013ff48bf5SDavid du Colombier
402219b2ee8SDavid du Colombier *cp++ = '\0';
403219b2ee8SDavid du Colombier datafd[0] = tempfile();
40480ee5cbfSDavid du Colombier blen = strlen((const char *)bp);
405219b2ee8SDavid du Colombier if (write(datafd[0], bp, blen) != blen) {
406219b2ee8SDavid du Colombier error("write error\n");
407219b2ee8SDavid du Colombier exit(6);
408219b2ee8SDavid du Colombier }
409219b2ee8SDavid du Colombier if (write(datafd[0], "\n", 1) != 1) {
410219b2ee8SDavid du Colombier error("write error\n");
411219b2ee8SDavid du Colombier exit(6);
412219b2ee8SDavid du Colombier }
413219b2ee8SDavid du Colombier break;
414219b2ee8SDavid du Colombier default:
415219b2ee8SDavid du Colombier /* otherwise get my lp arguments */
416bd389b36SDavid du Colombier do {
417bd389b36SDavid du Colombier /* move to next non-white space */
418219b2ee8SDavid du Colombier while (*bp==' '||*bp=='\t')
419bd389b36SDavid du Colombier ++bp;
420219b2ee8SDavid du Colombier if (*bp=='\n') continue;
421bd389b36SDavid du Colombier /* only accept arguments beginning with -
422bd389b36SDavid du Colombier * this is done to prevent the printing of
423bd389b36SDavid du Colombier * local files from the destination host
424bd389b36SDavid du Colombier */
425bd389b36SDavid du Colombier if (*bp=='-') {
426219b2ee8SDavid du Colombier argvals[argcnt++] = cp;
427bd389b36SDavid du Colombier saveflg = 1;
428bd389b36SDavid du Colombier } else
429bd389b36SDavid du Colombier saveflg = 0;
430bd389b36SDavid du Colombier /* move to next white space copying text to argument buffer */
431219b2ee8SDavid du Colombier while (*bp!=' ' && *bp!='\t' && *bp!='\n'
432bd389b36SDavid du Colombier && *bp!='\0') {
433219b2ee8SDavid du Colombier *cp = *bp++;
434219b2ee8SDavid du Colombier cp += saveflg;
435bd389b36SDavid du Colombier }
436219b2ee8SDavid du Colombier *cp = '\0';
437219b2ee8SDavid du Colombier cp += saveflg;
4387dd7cddfSDavid du Colombier } while (*bp!='\n' && *bp!='\0');
4397dd7cddfSDavid du Colombier if (readline(0) < 0) exit(7);
440219b2ee8SDavid du Colombier datafd[0] = tempfile();
44180ee5cbfSDavid du Colombier if(readfile(datafd[0], atoi((const char *)lnbuf)) < 0) {
442219b2ee8SDavid du Colombier error("readfile failed\n");
443219b2ee8SDavid du Colombier exit(8);
444bd389b36SDavid du Colombier }
445bd389b36SDavid du Colombier }
446219b2ee8SDavid du Colombier forklp(datafd[0]);
447219b2ee8SDavid du Colombier exit(0);
448bd389b36SDavid du Colombier }
449