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