Commit | Line | Data |
---|---|---|
51d1035a BJ |
1 | /* |
2 | * | |
3 | * 1.1 mike 5/77 - all files copied to spooler space | |
4 | * (see note below) | |
5 | * | |
6 | * 1.2 dlm 26 Sep 1977 | |
7 | * fix for allowing variable indents (-i flag) | |
8 | * | |
9 | * 1.3 dlm/njl 12 Dec 1977 | |
10 | * fix for open pipe when spawning progess (affects lpd) | |
11 | * | |
12 | * 1.4 dlm 24 Feb 1978 | |
13 | * test for data files; add -C option for classification | |
14 | * and change format of $L card; reversed 1.1 on copies | |
15 | * | |
16 | * 1.5 dlm 27 Mar 1978 | |
17 | * add job name and -h option | |
18 | * | |
19 | * 2.0 was 21 Dec 1978 | |
20 | * -h option changed to -J | |
21 | * added -H option to cause header page to be | |
22 | * printed, default is no header page | |
23 | * added -p option to cause files to be printed | |
24 | * using pr | |
25 | * default for classification changed | |
26 | * | |
27 | * 2.1 was 14 Mar 1979 | |
28 | * multiple printer logic changed, | |
29 | * printer number sent to daemon. | |
30 | * | |
31 | * 3.0 sjl 6 May 1980 | |
32 | * Mods for Version 7, plus portability | |
33 | * (in preparation for UNIX/24V) | |
34 | * | |
35 | * 3.1 sjl Oct 28 1980 | |
36 | * Mods for protected spooling area, see note below | |
37 | * | |
38 | * 3.2 sjl Mar 13 1981 | |
39 | * Add N card for file names to help out sq | |
40 | * | |
41 | * 3.3 sjl Mar 27 1981 from decvax!shannon | |
42 | * Mods and cleanup for 4bsd. | |
43 | * Send mail option added. | |
44 | * | |
45 | * 4.0 sjl Mar 28 1981 | |
46 | * Support multiple printers and daemons through termcap-like | |
47 | * data base | |
48 | * | |
49 | * 4.1 sjl Apr 28 1981 | |
50 | * Check for printer being down (mode 0 on device) | |
51 | * | |
52 | * 4.2 was May 1 1981 | |
53 | * Clean up handling of printcap database, add more defaults | |
54 | */ | |
55 | ||
56 | char lpr_id[] = "~|^`lpr.c:\t4.2\t1 May 1981\n"; | |
57 | ||
09d5163a | 58 | /* lpr.c 4.9 83/03/01 */ |
51d1035a BJ |
59 | /* |
60 | * lpr -- off line print | |
fdaeefb7 BJ |
61 | * |
62 | * Allows multiple printers and printers on remote machines by | |
63 | * using information from a printer data base. | |
51d1035a BJ |
64 | */ |
65 | ||
66 | #include <sys/types.h> | |
67 | #include <sys/stat.h> | |
fdaeefb7 | 68 | #include <sys/file.h> |
51d1035a BJ |
69 | #include <signal.h> |
70 | #include <pwd.h> | |
71 | #include <stdio.h> | |
72 | #include <ctype.h> | |
73 | #include "lp.local.h" | |
74 | ||
fdaeefb7 BJ |
75 | char *tfname; /* tmp copy of cf before linking */ |
76 | char *cfname; /* daemon control files, linked from tf's */ | |
77 | char *dfname; /* data files */ | |
51d1035a BJ |
78 | |
79 | int nact; /* number of jobs to act on */ | |
fdaeefb7 | 80 | int tfd; /* control file descriptor */ |
51d1035a | 81 | int mailflg; /* send mail */ |
fdaeefb7 | 82 | int qflag; /* q job, but don't exec daemon */ |
878a0818 | 83 | char format = 'f'; /* format char for printing files */ |
fdaeefb7 | 84 | int rflag; /* remove files upon completion */ |
e95c0734 | 85 | int lflag; /* link flag */ |
51d1035a BJ |
86 | char *person; /* user name */ |
87 | int inchar; /* location to increment char in file names */ | |
88 | int ncopies = 1; /* # of copies to make */ | |
89 | int iflag; /* indentation wanted */ | |
90 | int indent; /* amount to indent */ | |
fdaeefb7 BJ |
91 | char *DN; /* path name to daemon program */ |
92 | char *LP; /* line printer device name */ | |
93 | char *RM; /* remote machine name if no local printer */ | |
94 | char *SD; /* spool directory */ | |
51d1035a | 95 | int MX; /* maximum size in blocks of a print file */ |
fdaeefb7 | 96 | int hdr = 1; /* print header or not (default is yes) */ |
878a0818 | 97 | int userid; /* user id */ |
51d1035a | 98 | char *title; /* pr'ing title */ |
878a0818 RC |
99 | char *fonts[4]; /* troff font names */ |
100 | char *width; /* width for versatec printing */ | |
fdaeefb7 BJ |
101 | char host[32]; /* host name */ |
102 | char *class = host; /* class title on header page */ | |
51d1035a BJ |
103 | char *jobname; /* job name on header page */ |
104 | char *name; /* program name */ | |
51d1035a BJ |
105 | |
106 | char *pgetstr(); | |
51d1035a BJ |
107 | char *malloc(); |
108 | char *getenv(); | |
109 | char *rindex(); | |
110 | ||
fdaeefb7 | 111 | /*ARGSUSED*/ |
51d1035a | 112 | main(argc, argv) |
6f038d7b RC |
113 | int argc; |
114 | char *argv[]; | |
51d1035a | 115 | { |
878a0818 RC |
116 | extern char *getlogin(); |
117 | extern struct passwd *getpwuid(), *getpwnam(); | |
118 | struct passwd *pw; | |
119 | extern char *itoa(); | |
51d1035a | 120 | register char *arg; |
fdaeefb7 BJ |
121 | int i, f, out(); |
122 | char *printer = NULL; | |
123 | struct stat stb; | |
51d1035a BJ |
124 | |
125 | /* | |
126 | * Strategy to maintain protected spooling area: | |
127 | * 1. Spooling area is writable only by daemon and spooling group | |
128 | * 2. lpr runs setuid root and setgrp spooling group; it uses | |
129 | * root to access any file it wants (verifying things before | |
130 | * with an access call) and group id to know how it should | |
131 | * set up ownership of files in spooling area. | |
fdaeefb7 | 132 | * 3. Files in spooling area are owned by daemon and spooling |
51d1035a | 133 | * group, with mode 660. |
fdaeefb7 | 134 | * 4. lpd runs setuid root and setgrp spooling group to |
51d1035a | 135 | * access files and printer. Users can't get to anything |
fdaeefb7 | 136 | * w/o help of lpq and lprm programs. |
51d1035a | 137 | */ |
6f038d7b | 138 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN) |
51d1035a | 139 | signal(SIGHUP, out); |
6f038d7b | 140 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) |
51d1035a | 141 | signal(SIGINT, out); |
6f038d7b | 142 | if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) |
51d1035a | 143 | signal(SIGQUIT, out); |
6f038d7b | 144 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) |
51d1035a | 145 | signal(SIGTERM, out); |
fdaeefb7 BJ |
146 | |
147 | gethostname(host, sizeof (host)); | |
51d1035a BJ |
148 | name = argv[0]; |
149 | ||
fdaeefb7 BJ |
150 | while (argc > 1 && (arg = argv[1])[0] == '-') { |
151 | argc--; | |
152 | argv++; | |
51d1035a BJ |
153 | switch (arg[1]) { |
154 | ||
fdaeefb7 BJ |
155 | case 'P': /* specifiy printer name */ |
156 | printer = &arg[2]; | |
51d1035a BJ |
157 | break; |
158 | ||
159 | case 'C': /* classification spec */ | |
160 | hdr++; | |
161 | if (arg[2]) | |
162 | class = &arg[2]; | |
878a0818 | 163 | else if (argc > 1) { |
51d1035a | 164 | argc--; |
fdaeefb7 | 165 | class = *++argv; |
51d1035a BJ |
166 | } |
167 | break; | |
168 | ||
fdaeefb7 BJ |
169 | case 'J': /* job name */ |
170 | hdr++; | |
171 | if (arg[2]) | |
51d1035a | 172 | jobname = &arg[2]; |
878a0818 | 173 | else if (argc > 1) { |
51d1035a | 174 | argc--; |
fdaeefb7 | 175 | jobname = *++argv; |
51d1035a BJ |
176 | } |
177 | break; | |
178 | ||
fdaeefb7 BJ |
179 | case 'T': /* pr's title line */ |
180 | if (arg[2]) | |
181 | title = &arg[2]; | |
878a0818 | 182 | else if (argc > 1) { |
fdaeefb7 BJ |
183 | argc--; |
184 | title = *++argv; | |
185 | } | |
51d1035a BJ |
186 | break; |
187 | ||
878a0818 RC |
188 | case 'l': /* literal output */ |
189 | case 'p': /* print using ``pr'' */ | |
190 | case 't': /* print troff output */ | |
191 | case 'c': /* print cifplot output */ | |
192 | case 'v': /* print vplot output */ | |
193 | format = arg[1]; | |
194 | break; | |
195 | ||
196 | case '4': /* troff fonts */ | |
197 | case '3': | |
198 | case '2': | |
199 | case '1': | |
200 | if (argc > 1) { | |
201 | argc--; | |
202 | fonts[arg[1] - '1'] = *++argv; | |
203 | format = 't'; | |
204 | } | |
205 | break; | |
206 | ||
207 | case 'w': /* versatec page width */ | |
208 | width = arg+2; | |
51d1035a BJ |
209 | break; |
210 | ||
fdaeefb7 BJ |
211 | case 'r': /* remove file when done */ |
212 | rflag++; | |
51d1035a BJ |
213 | break; |
214 | ||
fdaeefb7 BJ |
215 | case 'm': /* send mail when done */ |
216 | mailflg++; | |
51d1035a BJ |
217 | break; |
218 | ||
fdaeefb7 | 219 | case 'h': /* toggle want of header page */ |
51d1035a BJ |
220 | hdr = !hdr; |
221 | break; | |
222 | ||
878a0818 | 223 | case 's': /* try to link files */ |
e95c0734 | 224 | lflag++; |
fdaeefb7 BJ |
225 | break; |
226 | ||
227 | case 'q': /* just q job */ | |
228 | qflag++; | |
229 | break; | |
230 | ||
231 | case 'i': /* indent output */ | |
232 | iflag++; | |
233 | indent = arg[2] ? atoi(&arg[2]) : 8; | |
234 | break; | |
235 | ||
51d1035a BJ |
236 | default: /* n copies ? */ |
237 | if (isdigit(arg[1])) | |
238 | ncopies = atoi(&arg[1]); | |
239 | } | |
51d1035a | 240 | } |
fdaeefb7 BJ |
241 | if (printer == NULL && (printer = getenv("PRINTER")) == NULL) |
242 | printer = DEFLP; | |
51d1035a | 243 | if (!chkprinter(printer)) { |
fdaeefb7 | 244 | printf("%s: unknown printer\n", name, printer); |
51d1035a BJ |
245 | exit(2); |
246 | } | |
878a0818 RC |
247 | /* |
248 | * Get the identity of the person doing the lpr and initialize the | |
249 | * control file. | |
250 | */ | |
251 | userid = getuid(); | |
252 | if ((person = getlogin()) == NULL) { | |
253 | if ((pw = getpwuid(userid)) == NULL) | |
254 | person = "Unknown User"; | |
255 | else | |
256 | person = pw->pw_name; | |
257 | } else if ((pw = getpwnam(person)) != NULL) | |
258 | userid = pw->pw_uid; /* in case of su */ | |
fdaeefb7 BJ |
259 | mktemps(); |
260 | tfd = nfile(tfname); | |
878a0818 RC |
261 | card('H', host); |
262 | card('P', person); | |
263 | if (hdr) { | |
264 | if (jobname == NULL) { | |
265 | if (argc == 1) | |
266 | jobname = &cfname[inchar-2]; | |
267 | else | |
268 | jobname = argv[1]; | |
269 | } | |
270 | card('J', jobname); | |
271 | card('C', class); | |
272 | card('L', person); | |
51d1035a | 273 | } |
878a0818 RC |
274 | if (iflag) |
275 | card('I', itoa(indent)); | |
276 | if (mailflg) | |
277 | card('M', person); | |
278 | if (format == 't') | |
279 | for (i = 0; i < 4; i++) | |
280 | if (fonts[i] != NULL) | |
281 | card('1'+i, fonts[i]); | |
282 | else if ((format == 'f' || format == 'l' || format == 'p') && width) | |
283 | card('W', width); | |
51d1035a | 284 | |
6f038d7b | 285 | if (argc == 1) |
51d1035a | 286 | copy(0, " "); |
6f038d7b | 287 | else while (--argc) { |
c249bc99 | 288 | if ((i = test(arg = *++argv)) < 0) |
fdaeefb7 BJ |
289 | continue; /* file unreasonable */ |
290 | ||
c249bc99 | 291 | if (i && lflag && linked(arg)) { |
878a0818 | 292 | if (format == 'p') |
fdaeefb7 | 293 | card('T', title ? title : arg); |
878a0818 RC |
294 | for (i = 0; i < ncopies; i++) |
295 | card(format, &dfname[inchar-2]); | |
fdaeefb7 BJ |
296 | card('U', &dfname[inchar-2]); |
297 | card('N', arg); | |
298 | dfname[inchar]++; | |
51d1035a | 299 | nact++; |
c249bc99 | 300 | } else { |
fdaeefb7 BJ |
301 | if ((f = open(arg, 0)) < 0) { |
302 | printf("%s: cannot open %s\n", name, arg); | |
303 | continue; | |
304 | } | |
305 | copy(f, arg); | |
306 | (void) close(f); | |
51d1035a | 307 | } |
fdaeefb7 BJ |
308 | if (rflag) { |
309 | register char *cp; | |
310 | ||
311 | if ((cp = rindex(arg, '/')) == NULL) | |
312 | f = access(".", 2); | |
313 | else { | |
314 | *cp = '\0'; | |
315 | f = access(arg, 2); | |
316 | *cp = '/'; | |
317 | } | |
318 | if (f || unlink(arg)) | |
319 | printf("%s: cannot remove %s\n", name, arg); | |
51d1035a | 320 | } |
51d1035a BJ |
321 | } |
322 | ||
6f038d7b | 323 | if (nact) { |
51d1035a | 324 | tfname[inchar]--; |
fdaeefb7 BJ |
325 | if (link(tfname, cfname) < 0) { |
326 | printf("%s: cannot rename %s\n", name, cfname); | |
51d1035a BJ |
327 | tfname[inchar]++; |
328 | out(); | |
329 | } | |
330 | unlink(tfname); | |
fdaeefb7 | 331 | if (qflag) /* just q things up */ |
51d1035a | 332 | exit(0); |
fdaeefb7 BJ |
333 | if (*LP && stat(LP, &stb) >= 0 && (stb.st_mode & 0777) == 0) { |
334 | printf("jobs queued, but line printer is down.\n"); | |
51d1035a BJ |
335 | exit(0); |
336 | } | |
fdaeefb7 BJ |
337 | execl(DN, arg = rindex(DN, "/") ? arg+1 : DN, printer, 0); |
338 | printf("jobs queued, but cannot start daemon.\n"); | |
339 | exit(0); | |
51d1035a BJ |
340 | } |
341 | out(); | |
fdaeefb7 | 342 | /*NOTREACHED*/ |
51d1035a BJ |
343 | } |
344 | ||
fdaeefb7 BJ |
345 | /* |
346 | * Create the file n and copy from file descriptor f. | |
347 | */ | |
51d1035a | 348 | copy(f, n) |
6f038d7b RC |
349 | int f; |
350 | char n[]; | |
51d1035a | 351 | { |
fdaeefb7 | 352 | register int fd, i, nr, nc; |
51d1035a BJ |
353 | char buf[BUFSIZ]; |
354 | ||
878a0818 | 355 | if (format == 'p') |
fdaeefb7 BJ |
356 | card('T', title ? title : n); |
357 | for (i = 0; i < ncopies; i++) | |
878a0818 | 358 | card(format, &dfname[inchar-2]); |
fdaeefb7 BJ |
359 | card('U', &dfname[inchar-2]); |
360 | card('N', n); | |
361 | fd = nfile(dfname); | |
51d1035a | 362 | nr = nc = 0; |
6f038d7b | 363 | while ((i = read(f, buf, BUFSIZ)) > 0) { |
fdaeefb7 | 364 | if (write(fd, buf, i) != i) { |
51d1035a BJ |
365 | printf("%s: %s: temp file write error\n", name, n); |
366 | break; | |
367 | } | |
368 | nc += i; | |
6f038d7b | 369 | if (nc >= BUFSIZ) { |
51d1035a | 370 | nc -= BUFSIZ; |
6f038d7b | 371 | if (nr++ > MX) { |
51d1035a BJ |
372 | printf("%s: %s: copy file is too large\n", name, n); |
373 | break; | |
374 | } | |
375 | } | |
376 | } | |
fdaeefb7 | 377 | (void) close(fd); |
51d1035a BJ |
378 | nact++; |
379 | } | |
380 | ||
fdaeefb7 BJ |
381 | /* |
382 | * Try and link the file to dfname. Return true if successful. | |
383 | */ | |
384 | linked(file) | |
385 | register char *file; | |
386 | { | |
387 | register char *cp; | |
388 | char buf[BUFSIZ]; | |
389 | ||
390 | if (link(file, dfname) == 0) | |
391 | return(1); | |
392 | if (*file != '/') { | |
393 | if (getwd(buf) == NULL) | |
394 | return(0); | |
395 | while (file[0] == '.') { | |
396 | switch (file[1]) { | |
397 | case '/': | |
398 | file += 2; | |
399 | continue; | |
400 | case '.': | |
401 | if (file[2] == '/') { | |
402 | if ((cp = rindex(buf, '/')) != NULL) | |
403 | *cp = '\0'; | |
404 | file += 3; | |
405 | continue; | |
406 | } | |
407 | } | |
408 | break; | |
409 | } | |
410 | strcat(buf, "/"); | |
411 | strcat(buf, file); | |
412 | file = buf; | |
413 | } | |
414 | return(symlink(file, dfname) == 0); | |
415 | } | |
416 | ||
417 | /* | |
418 | * Put a line into the control file. | |
419 | */ | |
51d1035a | 420 | card(c, p2) |
6f038d7b | 421 | register char c, *p2; |
51d1035a BJ |
422 | { |
423 | char buf[BUFSIZ]; | |
424 | register char *p1 = buf; | |
fdaeefb7 | 425 | register int len = 2; |
51d1035a BJ |
426 | |
427 | *p1++ = c; | |
6f038d7b | 428 | while ((c = *p2++) != '\0') { |
51d1035a | 429 | *p1++ = c; |
fdaeefb7 | 430 | len++; |
51d1035a BJ |
431 | } |
432 | *p1++ = '\n'; | |
fdaeefb7 | 433 | write(tfd, buf, len); |
51d1035a BJ |
434 | } |
435 | ||
fdaeefb7 BJ |
436 | /* |
437 | * Create a new file in the spool directory. | |
438 | */ | |
439 | ||
51d1035a | 440 | nfile(n) |
6f038d7b | 441 | char *n; |
51d1035a BJ |
442 | { |
443 | register f; | |
fdaeefb7 | 444 | int oldumask = umask(0); /* should block signals */ |
51d1035a | 445 | |
6f038d7b RC |
446 | f = creat(n, FILMOD); |
447 | (void) umask(oldumask); | |
448 | if (f < 0) { | |
51d1035a BJ |
449 | printf("%s: cannot create %s\n", name, n); |
450 | out(); | |
451 | } | |
878a0818 | 452 | if (chown(n, userid, -1) < 0) { |
51d1035a BJ |
453 | unlink(n); |
454 | printf("%s: cannot chown %s\n", name, n); | |
455 | out(); | |
456 | } | |
457 | n[inchar]++; | |
fdaeefb7 | 458 | return(f); |
51d1035a BJ |
459 | } |
460 | ||
fdaeefb7 BJ |
461 | /* |
462 | * Cleanup after interrupts and errors. | |
463 | */ | |
51d1035a BJ |
464 | out() |
465 | { | |
466 | register i; | |
467 | ||
468 | signal(SIGHUP, SIG_IGN); | |
469 | signal(SIGINT, SIG_IGN); | |
470 | signal(SIGQUIT, SIG_IGN); | |
471 | signal(SIGTERM, SIG_IGN); | |
472 | i = inchar; | |
473 | if (tfname) | |
6f038d7b | 474 | while (tfname[i] != 'A') { |
51d1035a BJ |
475 | tfname[i]--; |
476 | unlink(tfname); | |
477 | } | |
478 | if (cfname) | |
6f038d7b | 479 | while (cfname[i] != 'A') { |
51d1035a BJ |
480 | cfname[i]--; |
481 | unlink(cfname); | |
482 | } | |
51d1035a | 483 | if (dfname) |
6f038d7b | 484 | while (dfname[i] != 'A') { |
51d1035a BJ |
485 | dfname[i]--; |
486 | unlink(dfname); | |
487 | } | |
488 | exit(); | |
489 | } | |
490 | ||
fdaeefb7 BJ |
491 | /* |
492 | * Test to see if this is a printable file. | |
c249bc99 | 493 | * Return -1 if it is not, 1 if it's publically readable, else 0 |
fdaeefb7 | 494 | */ |
51d1035a | 495 | test(file) |
6f038d7b | 496 | char *file; |
51d1035a | 497 | { |
fdaeefb7 BJ |
498 | struct exec execb; |
499 | struct stat statb; | |
51d1035a BJ |
500 | int fd; |
501 | ||
502 | if (access(file, 4) < 0) { | |
503 | printf("%s: cannot access %s\n", name, file); | |
fdaeefb7 | 504 | return(-1); |
51d1035a | 505 | } |
fdaeefb7 | 506 | if (stat(file, &statb) < 0) { |
51d1035a | 507 | printf("%s: cannot stat %s\n", name, file); |
fdaeefb7 | 508 | return(-1); |
51d1035a | 509 | } |
fdaeefb7 | 510 | if ((statb.st_mode & S_IFMT) == S_IFDIR) { |
51d1035a | 511 | printf("%s: %s is a directory\n", name, file); |
fdaeefb7 | 512 | return(-1); |
51d1035a | 513 | } |
6f038d7b | 514 | if ((fd = open(file, 0)) < 0) { |
51d1035a | 515 | printf("%s: cannot open %s\n", name, file); |
fdaeefb7 | 516 | return(-1); |
51d1035a | 517 | } |
fdaeefb7 BJ |
518 | if (read(fd, &execb, sizeof(execb)) == sizeof(execb)) |
519 | switch(execb.a_magic) { | |
51d1035a BJ |
520 | case A_MAGIC1: |
521 | case A_MAGIC2: | |
522 | case A_MAGIC3: | |
523 | #ifdef A_MAGIC4 | |
524 | case A_MAGIC4: | |
525 | #endif | |
526 | printf("%s: %s is an executable program", name, file); | |
527 | goto error1; | |
528 | ||
529 | case ARMAG: | |
530 | printf("%s: %s is an archive file", name, file); | |
531 | goto error1; | |
532 | } | |
fdaeefb7 BJ |
533 | (void) close(fd); |
534 | if (rflag) { /* check to make sure user can delete this file */ | |
535 | register char *cp = rindex(file, '/'); | |
536 | ||
537 | if (cp == NULL) | |
878a0818 RC |
538 | fd = access(".", 2); |
539 | else { | |
fdaeefb7 | 540 | *cp = '\0'; |
878a0818 | 541 | fd = access(file, 2); |
fdaeefb7 | 542 | *cp = '/'; |
878a0818 RC |
543 | } |
544 | if (fd < 0) { | |
fdaeefb7 BJ |
545 | printf("%s: cannot remove %s\n", name, file); |
546 | return(-1); | |
547 | } | |
fdaeefb7 | 548 | } |
c249bc99 RC |
549 | if (statb.st_mode & 04) |
550 | return(1); | |
fdaeefb7 | 551 | return(0); |
51d1035a | 552 | |
51d1035a BJ |
553 | error1: |
554 | printf(" and is unprintable\n"); | |
fdaeefb7 BJ |
555 | (void) close(fd); |
556 | return(-1); | |
51d1035a BJ |
557 | } |
558 | ||
559 | /* | |
560 | * itoa - integer to string conversion | |
561 | */ | |
562 | char * | |
563 | itoa(i) | |
6f038d7b | 564 | register int i; |
51d1035a BJ |
565 | { |
566 | static char b[10] = "########"; | |
567 | register char *p; | |
568 | ||
569 | p = &b[8]; | |
570 | do | |
571 | *p-- = i%10 + '0'; | |
572 | while (i /= 10); | |
fdaeefb7 | 573 | return(++p); |
51d1035a BJ |
574 | } |
575 | ||
576 | /* | |
577 | * Perform lookup for printer name or abbreviation -- | |
51d1035a BJ |
578 | */ |
579 | chkprinter(s) | |
6f038d7b | 580 | register char *s; |
51d1035a BJ |
581 | { |
582 | static char buf[BUFSIZ/2]; | |
583 | char b[BUFSIZ]; | |
584 | int stat; | |
585 | char *bp = buf; | |
586 | ||
587 | if ((stat = pgetent(b, s)) < 0) { | |
fdaeefb7 | 588 | printf("%s: can't open printer description file\n", name); |
51d1035a BJ |
589 | exit(3); |
590 | } else if (stat == 0) | |
fdaeefb7 | 591 | return(0); |
51d1035a BJ |
592 | if ((DN = pgetstr("dn", &bp)) == NULL) |
593 | DN = DEFDAEMON; | |
594 | if ((LP = pgetstr("lp", &bp)) == NULL) | |
595 | LP = DEFDEVLP; | |
fdaeefb7 BJ |
596 | if ((SD = pgetstr("sd", &bp)) == NULL) |
597 | SD = DEFSPOOL; | |
51d1035a BJ |
598 | if ((MX = pgetnum("mx")) < 0) |
599 | MX = DEFMX; | |
fdaeefb7 BJ |
600 | RM = pgetstr("rm", &bp); |
601 | return(1); | |
602 | } | |
603 | ||
604 | /* | |
605 | * Make the temp files. | |
606 | */ | |
607 | mktemps() | |
608 | { | |
c249bc99 | 609 | register int c, len; |
fdaeefb7 BJ |
610 | int n; |
611 | char buf[BUFSIZ], *mktemp(); | |
c249bc99 | 612 | FILE *fp; |
fdaeefb7 BJ |
613 | |
614 | (void) sprintf(buf, "%s/.seq", SD); | |
c249bc99 | 615 | if ((fp = fopen(buf, "r+")) == NULL) { |
878a0818 RC |
616 | if ((fp = fopen(buf, "w")) == NULL) { |
617 | printf("%s: cannot create %s\n", name, buf); | |
618 | exit(1); | |
619 | } | |
620 | setbuf(fp, buf); | |
621 | n = 0; | |
c249bc99 RC |
622 | } else { |
623 | setbuf(fp, buf); | |
878a0818 | 624 | #ifdef BSD41C |
c249bc99 | 625 | if (flock(fileno(fp), FEXLOCK)) { |
fdaeefb7 BJ |
626 | printf("%s: cannot lock %s\n", name, buf); |
627 | exit(1); | |
628 | } | |
878a0818 | 629 | #endif |
c249bc99 RC |
630 | n = 0; |
631 | while ((c = getc(fp)) >= '0' && c <= '9') | |
632 | n = n * 10 + (c - '0'); | |
fdaeefb7 BJ |
633 | } |
634 | len = strlen(SD) + strlen(host) + 8; | |
635 | tfname = mktemp("tf", n, len); | |
636 | cfname = mktemp("cf", n, len); | |
637 | dfname = mktemp("df", n, len); | |
638 | inchar = strlen(SD) + 3; | |
639 | n = (n + 1) % 1000; | |
c249bc99 RC |
640 | (void) fseek(fp, 0L, 0); |
641 | fprintf(fp, "%d\n", n); | |
642 | (void) fclose(fp); | |
51d1035a BJ |
643 | } |
644 | ||
645 | /* | |
fdaeefb7 | 646 | * Make a temp file name. |
51d1035a BJ |
647 | */ |
648 | char * | |
fdaeefb7 BJ |
649 | mktemp(id, num, len) |
650 | char *id; | |
651 | int num, len; | |
51d1035a BJ |
652 | { |
653 | register char *s; | |
654 | ||
fdaeefb7 BJ |
655 | if ((s = malloc(len)) == NULL) { |
656 | printf("%s: out of memory\n", name); | |
51d1035a BJ |
657 | exit(1); |
658 | } | |
fdaeefb7 BJ |
659 | (void) sprintf(s, "%s/%sA%03d%s", SD, id, num, host); |
660 | return(s); | |
51d1035a | 661 | } |