|
|
1.1 root 1: /*
2: * lpr.c
3: * 12/13/90
4: * Submit a listing to the line printer spooler.
5: * This source produces both lpr and (compiled -DLASER) hpr.
6: */
7:
8: #include <stdio.h>
9: #include <pwd.h>
10: #include <signal.h>
11: #include <sys/types.h>
12:
13: #ifdef LASER
14: #define USAGE "Usage: %s [-Bcemnr] [-b banner] [-f fontnum] [file ...]\n"
15: #else
16: #define USAGE "Usage: %s [-Bcmnr] [-b banner] [file ...]\n"
17: #endif
18:
19: /* Schizo is missing so -r doesn't check access privileges */
20: #define NBAN 6 /* Maximum number of banners */
21: #define NFNAME 400 /* Longest filename allowed */
22:
23: char *banners[NBAN];
24: char tfspace[20];
25: char cfname[20];
26: char dfname[20];
27: char *tfname; /* Control file during lpr */
28: char *wd;
29: char *myuname;
30: char *argv0;
31: FILE *cfp; /* Control file stream */
32: #ifdef LASER
33: char spooldir[] = "/usr/spool/hpd";
34: char lpd[] = "/usr/lib/hpd";
35: #else
36: char spooldir[] = "/usr/spool/lpd";
37: char lpd[] = "/usr/lib/lpd";
38: #endif
39: char tmb[] = "too many banners, '%s' ignored";
40:
41: int Bflag; /* Suppress banners */
42: int cflag; /* Generate a copy */
43: int mflag; /* Send notification */
44: int rflag; /* Remove when done */
45: int banno = 4; /* Current banner number */
46: int myuid;
47: #ifdef LASER
48: int eflag; /* Erase existing fonts */
49: int fflag; /* Load new fonts */
50: int fontindex; /* Current font index */
51: #endif
52:
53: extern char *ctime();
54: extern char *getenv();
55: extern char *getlogin();
56: extern char *getwd();
57: extern time_t time();
58:
59: char *absname();
60: void lpr();
61: void lprinit();
62: int rmexit();
63: long unique();
64:
65: main(argc, argv) int argc; char *argv[];
66: {
67: register char *ap;
68: register int i, j;
69:
70: argv0 = argv[0];
71: signal(SIGINT, rmexit);
72: signal(SIGHUP, rmexit);
73: for (i=1; i<argc; i++) {
74: if (*argv[i] != '-')
75: break;
76: for (ap = &argv[i][1]; *ap != '\0'; ap++)
77: switch (*ap) {
78: case 'B':
79: ++Bflag;
80: break;
81:
82: case 'b':
83: if (++i >= argc)
84: lperr("missing banner");
85: if (banno >= NBAN)
86: fprintf(stderr, tmb, argv[i]);
87: else
88: banners[banno++] = argv[i];
89: break;
90:
91: case 'c':
92: cflag = 1;
93: break;
94:
95: #ifdef LASER
96: case 'e':
97: eflag = 1;
98: break;
99:
100: case 'f':
101: Bflag = fflag = 1; /* -f forces -B */
102: if (++i >= argc)
103: lperr("missing font index");
104: else
105: fontindex = atoi(argv[i]);
106: break;
107: #endif
108: case 'm':
109: mflag = 1;
110: break;
111:
112: case 'n':
113: mflag = 0;
114: break;
115:
116: case 'r':
117: cflag = rflag = 1;
118: break;
119:
120: default:
121: usage();
122: }
123: }
124: lprinit(argc, argv);
125: #ifdef LASER
126: if (eflag)
127: fprintf(cfp, "E\n");
128: #endif
129: if (Bflag)
130: fprintf(cfp, "B\n");
131: for (j = i; j < argc; j++)
132: if (banno < NBAN)
133: banners[banno++] = argv[j];
134: else
135: break;
136: for (j = 0; j < banno; j++)
137: fprintf(cfp, "L%s\n", banners[j]);
138: if (i == argc)
139: lpr(NULL);
140: else
141: for (; i<argc; i++)
142: lpr(argv[i]);
143: lprterm();
144: for (i=3; i<_NFILE; i++)
145: close(i);
146: close(0);
147: execl(lpd, lpd, NULL);
148: lperr("cannot find daemon '%s'", lpd);
149: }
150:
151: /*
152: * Initialise the control file.
153: * Set up the banners.
154: */
155: void
156: lprinit(ac, av) int ac; char **av;
157: {
158: time_t xtime;
159: register int i;
160: register struct passwd *pwp;
161: register char *s;
162:
163: myuid = getuid();
164: wd = getwd();
165: if (chdir(spooldir) < 0)
166: lperr("bad directory '%s'", spooldir);
167: tfname = tfspace;
168: sprintf(tfname, "tf%ld", unique());
169: strcpy(cfname, tfname);
170: cfname[0] = 'c';
171: if ((cfp = fopen(tfname, "w")) == NULL)
172: lperr("cannot create control file");
173: putc('D', cfp);
174: for (i=0; i<ac; i++)
175: fprintf(cfp, "%s%c", av[i], i==ac-1 ? '\n' : ' ');
176: banners[0] = "\35\36\37";
177: banners[1] = "Coherent"; /* Mark Williams logo */
178: xtime = time(NULL);
179: s = ctime(&xtime);
180: s[16] = '\0';
181: banners[2] = s;
182: if ((myuname = getlogin()) == NULL)
183: if ((pwp = getpwuid(myuid))==NULL)
184: myuname = "Guess who?";
185: if (myuname == NULL)
186: banners[3] = "Guess who?"; else
187: banners[3] = myuname;
188: }
189:
190: /*
191: * Called for each file to put
192: * an entry for it in the control
193: * file and do any copies to the
194: * spool area.
195: * The NULL 'file' is stdin.
196: */
197: void
198: lpr(file) char *file;
199: {
200: FILE *ifp;
201: char *abfile;
202:
203: if (file == NULL)
204: ifp = stdin;
205: else {
206: abfile = absname(file);
207: if ((ifp = fopen(abfile, "r")) == NULL)
208: lperr("cannot open %s", file);
209: }
210: if (cflag || file==NULL) {
211: copy(ifp);
212: #ifdef LASER
213: if (fflag)
214: fprintf(cfp, "F%s %d\n", dfname, fontindex++);
215: else
216: #endif
217: fprintf(cfp, "A%s\n", dfname);
218: fprintf(cfp, "U%s\n", dfname);
219: dfname[0] = '\0';
220: } else {
221: #ifdef LASER
222: if (fflag)
223: fprintf(cfp, "F%s %d\n", abfile, fontindex++);
224: else
225: #endif
226: fprintf(cfp, "A%s\n", abfile);
227: }
228: if (rflag && file!=NULL) {
229: if (unperm(abfile)<0 || unlink(abfile)<0)
230: lperr("cannot unlink %s", file);
231: }
232: if (file != NULL)
233: fclose(ifp);
234: }
235:
236: /*
237: * Given a file, see if we have permissions to unlink it.
238: */
239: unperm(np)
240: register char *np;
241: {
242: register char *cp;
243: char name[NFNAME];
244:
245: cp = name;
246: while ((*cp++=*np++) != '\0')
247: ;
248: while (*--cp != '/') {
249: if (cp == name) {
250: *cp = '.';
251: break;
252: }
253: }
254: cp[1] = '\0';
255: return (access(name, 2));
256: }
257:
258: /*
259: * Clean up and close out
260: * control file.
261: */
262: lprterm()
263: {
264: if (mflag)
265: if (myuname == NULL)
266: fprintf(cfp, "M%d\n", myuid); else
267: fprintf(cfp, "M%s\n", myuname);
268: fflush(cfp);
269: if (ferror(cfp))
270: lperr("control file I/O error");
271: fclose(cfp);
272: link(tfname, cfname);
273: unlink(tfname);
274: tfname = NULL;
275: }
276:
277: /*
278: * Copy the data to a data file
279: * in the spool directory.
280: */
281: copy(inf)
282: register FILE *inf;
283: {
284: register int c;
285: register FILE *outf;
286:
287: sprintf(dfname, "df%ld", unique());
288: if ((outf = fopen(dfname, "w")) == NULL)
289: lperr("cannot create data file");
290: while ((c = getc(inf)) != EOF)
291: putc(c, outf);
292: fflush(outf);
293: if (ferror(outf))
294: lperr("data file I/O error");
295: fclose(outf);
296: }
297:
298: /*
299: * Return an absolute pathname
300: * for the given filename.
301: * (Uses the variable 'wd' which
302: * contains the process's working
303: * directory.)
304: */
305: char *
306: absname(fn)
307: char *fn;
308: {
309: static char name[NFNAME];
310:
311: if (*fn == '/')
312: return (fn);
313: sprintf(name, "%s/%s", wd, fn);
314: return (name);
315: }
316:
317: usage()
318: {
319: fprintf(stderr, USAGE, argv0);
320: rmexit(1);
321: }
322:
323: /* VARARGS */
324: lperr(x)
325: {
326: fprintf(stderr, "%s: %r\n", argv0, &x);
327: rmexit(1);
328: }
329:
330: /*
331: * Exit, removing any files that
332: * are left lying around.
333: */
334: rmexit(s)
335: {
336: if (tfname != NULL)
337: unlink(tfname);
338: if (dfname[0] != '\0')
339: unlink(dfname);
340: exit(s);
341: }
342:
343: /* end of lpr.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.