use syslog().
[unix-history] / usr / src / usr.sbin / lpr / lpd / recvjob.c
CommitLineData
5f84f8f0
SL
1#ifndef lint
2static char sccsid[] = "@(#)recvjob.c 4.6 (Berkeley) %G%";
3#endif
4
e3127271
RC
5/*
6 * Receive printer jobs from the network, queue them and
7 * start the printer daemon.
8 */
9
10#include "lp.h"
11
54266d1f
RC
12static char tfname[40]; /* tmp copy of cf before linking */
13static char *dfname; /* data files */
e3127271
RC
14
15recvjob()
16{
88f026f7 17 struct stat stb;
e3127271
RC
18 char *bp = pbuf;
19 int status;
20
e3127271
RC
21 /*
22 * Perform lookup for printer name or abbreviation
23 */
24 if ((status = pgetent(line, printer)) < 0)
25 fatal("cannot open printer description file");
26 else if (status == 0)
27 fatal("unknown printer");
28 if ((LF = pgetstr("lf", &bp)) == NULL)
29 LF = DEFLOGF;
30 if ((SD = pgetstr("sd", &bp)) == NULL)
31 SD = DEFSPOOL;
88f026f7
RC
32 if ((LO = pgetstr("lo", &bp)) == NULL)
33 LO = DEFLOCK;
e3127271
RC
34
35 (void) close(2);
adec4d9e 36 (void) open(LF, O_WRONLY|O_APPEND);
e3127271
RC
37 if (chdir(SD) < 0)
38 fatal("cannot chdir to %s", SD);
88f026f7
RC
39 if (stat(LO, &stb) == 0 && (stb.st_mode & 010)) {
40 /* queue is disabled */
41 putchar('\1'); /* return error code */
42 exit(1);
43 }
e3127271
RC
44
45 if (readjob())
46 printjob();
47}
48
49char *sp = "";
50#define ack() (void) write(1, sp, 1);
51
52/*
53 * Read printer jobs sent by lpd and copy them to the spooling directory.
54 * Return the number of jobs successfully transfered.
55 */
54266d1f 56static
e3127271
RC
57readjob(printer)
58 char *printer;
59{
60 register int size, nfiles;
61 register char *cp;
62
63 ack();
64 nfiles = 0;
65 for (;;) {
66 /*
67 * Read a command to tell us what to do
68 */
69 cp = line;
70 do {
71 if ((size = read(1, cp, 1)) != 1) {
72 if (size < 0)
73 fatal("Lost connection");
74 return(nfiles);
75 }
76 } while (*cp++ != '\n');
77 *--cp = '\0';
78 cp = line;
79 switch (*cp++) {
80 case '\1': /* cleanup because data sent was bad */
81 cleanup();
82 continue;
83
84 case '\2': /* read cf file */
85 size = 0;
86 while (*cp >= '0' && *cp <= '9')
87 size = size * 10 + (*cp++ - '0');
88 if (*cp++ != ' ')
89 break;
90 strcpy(tfname, cp);
91 tfname[0] = 't';
92 if (!readfile(tfname, size)) {
93 cleanup();
94 continue;
95 }
96 if (link(tfname, cp) < 0)
97 fatal("cannot rename %s", tfname);
98 (void) unlink(tfname);
99 tfname[0] = '\0';
100 nfiles++;
101 continue;
102
103 case '\3': /* read df file */
104 size = 0;
105 while (*cp >= '0' && *cp <= '9')
106 size = size * 10 + (*cp++ - '0');
107 if (*cp++ != ' ')
108 break;
109 (void) readfile(dfname = cp, size);
110 continue;
111 }
112 fatal("protocol screwup");
113 }
114}
115
116/*
117 * Read files send by lpd and copy them to the spooling directory.
118 */
54266d1f 119static
e3127271
RC
120readfile(file, size)
121 char *file;
122 int size;
123{
124 register char *cp;
125 char buf[BUFSIZ];
126 register int i, j, amt;
127 int fd, err;
128
adec4d9e 129 fd = open(file, O_WRONLY|O_CREAT, FILMOD);
e3127271
RC
130 if (fd < 0)
131 fatal("cannot create %s", file);
132 ack();
133 err = 0;
134 for (i = 0; i < size; i += BUFSIZ) {
135 amt = BUFSIZ;
136 cp = buf;
137 if (i + amt > size)
138 amt = size - i;
139 do {
140 j = read(1, cp, amt);
141 if (j <= 0)
142 fatal("Lost connection");
143 amt -= j;
144 cp += j;
145 } while (amt > 0);
146 amt = BUFSIZ;
147 if (i + amt > size)
148 amt = size - i;
c6d1c018 149 if (write(fd, buf, amt) != amt) {
e3127271 150 err++;
c6d1c018
RC
151 break;
152 }
e3127271
RC
153 }
154 (void) close(fd);
155 if (err)
156 fatal("%s: write error", file);
157 if (noresponse()) { /* file sent had bad data in it */
158 (void) unlink(file);
159 return(0);
160 }
161 ack();
162 return(1);
163}
164
165static
166noresponse()
167{
168 char resp;
169
170 if (read(1, &resp, 1) != 1)
171 fatal("Lost connection");
172 if (resp == '\0')
173 return(0);
174 return(1);
175}
176
177/*
178 * Remove all the files associated with the current job being transfered.
179 */
180static
181cleanup()
182{
183 register int i;
184
185 if (tfname[0])
186 (void) unlink(tfname);
187 if (dfname)
188 do {
189 do
190 (void) unlink(dfname);
191 while (dfname[i]-- != 'A');
192 dfname[i] = 'z';
193 } while (dfname[i-2]-- != 'd');
194}
195
196static
197fatal(msg, a1)
198 char *msg;
199{
200 cleanup();
201 log(msg, a1);
202 putchar('\1'); /* return error code */
203 exit(1);
204}