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