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