Commit | Line | Data |
---|---|---|
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 | ||
9 | char tfname[40]; /* tmp copy of cf before linking */ | |
10 | char *dfname; /* data files */ | |
11 | ||
12 | recvjob() | |
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 | ||
40 | char *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 | */ | |
47 | readjob(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 | */ | |
109 | readfile(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 | ||
152 | static | |
153 | noresponse() | |
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 | */ | |
167 | static | |
168 | cleanup() | |
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 | ||
183 | static | |
184 | fatal(msg, a1) | |
185 | char *msg; | |
186 | { | |
187 | cleanup(); | |
188 | log(msg, a1); | |
189 | putchar('\1'); /* return error code */ | |
190 | exit(1); | |
191 | } |