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