|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)recvjob.c 4.6 (Berkeley) 7/17/83";
3: #endif
4:
5: /*
6: * Receive printer jobs from the network, queue them and
7: * start the printer daemon.
8: */
9:
10: #include "lp.h"
11:
12: static char tfname[40]; /* tmp copy of cf before linking */
13: static char *dfname; /* data files */
14:
15: recvjob()
16: {
17: struct stat stb;
18: char *bp = pbuf;
19: int status;
20:
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;
32: if ((LO = pgetstr("lo", &bp)) == NULL)
33: LO = DEFLOCK;
34:
35: (void) close(2);
36: (void) open(LF, O_WRONLY|O_APPEND);
37: if (chdir(SD) < 0)
38: fatal("cannot chdir to %s", SD);
39: if (stat(LO, &stb) == 0 && (stb.st_mode & 010)) {
40: /* queue is disabled */
41: putchar('\1'); /* return error code */
42: exit(1);
43: }
44:
45: if (readjob())
46: printjob();
47: }
48:
49: char *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: */
56: static
57: readjob(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: */
119: static
120: readfile(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:
129: fd = open(file, O_WRONLY|O_CREAT, FILMOD);
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;
149: if (write(fd, buf, amt) != amt) {
150: err++;
151: break;
152: }
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:
165: static
166: noresponse()
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: */
180: static
181: cleanup()
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:
196: static
197: fatal(msg, a1)
198: char *msg;
199: {
200: cleanup();
201: log(msg, a1);
202: putchar('\1'); /* return error code */
203: exit(1);
204: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.