fixed `fc' and `fs' when 0177777 is needed.
[unix-history] / usr / src / usr.sbin / lpr / lpd / recvjob.c
CommitLineData
c6d1c018 1/* recvjob.c 4.5 83/06/17 */
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;
c6d1c018 146 if (write(fd, buf, amt) != amt) {
e3127271 147 err++;
c6d1c018
RC
148 break;
149 }
e3127271
RC
150 }
151 (void) close(fd);
152 if (err)
153 fatal("%s: write error", file);
154 if (noresponse()) { /* file sent had bad data in it */
155 (void) unlink(file);
156 return(0);
157 }
158 ack();
159 return(1);
160}
161
162static
163noresponse()
164{
165 char resp;
166
167 if (read(1, &resp, 1) != 1)
168 fatal("Lost connection");
169 if (resp == '\0')
170 return(0);
171 return(1);
172}
173
174/*
175 * Remove all the files associated with the current job being transfered.
176 */
177static
178cleanup()
179{
180 register int i;
181
182 if (tfname[0])
183 (void) unlink(tfname);
184 if (dfname)
185 do {
186 do
187 (void) unlink(dfname);
188 while (dfname[i]-- != 'A');
189 dfname[i] = 'z';
190 } while (dfname[i-2]-- != 'd');
191}
192
193static
194fatal(msg, a1)
195 char *msg;
196{
197 cleanup();
198 log(msg, a1);
199 putchar('\1'); /* return error code */
200 exit(1);
201}