Research V7 development
[unix-history] / usr / src / cmd / lpr / spool.c
CommitLineData
538eba61
KT
1#include <signal.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4
5#define ONL 0
6#define TOSS 1
7int INCHAR = 0; /*index of incremented character in
8 temporary file names. */
9
10char version[] = "Version 2/6/79";
11
12char grade;
13char remote[]= "$ remote **,onl";
14char toss[] = "$ sysout toss";
15int remotsw; /*toss-output flag*/
16char *mailfile = 0;
17char wantmail = 0;
18char *pp = 0; /*recipient of mail*/
19char *identf = 0; /*ident card info*/
20int uidf = 0;
21char gcosid[13]; /*gcos userid*/
22char cpflag = 'l'; /*copy/link flag*/
23int rmflag = 0; /*remove flag*/
24int debug = 0;
25int gcdebug = 0; /*GCOS debug switch*/
26int archsw = 0; /*archive switch*/
27
28int argc;
29char **argv;
30char *arg;
31char buf[80]; /*used by card */
32int nact = 0; /*number of non-null files to process.*/
33int gsize = 20; /*size of current file in GCOS blocks.*/
34long usize = 20*1200; /*size of current file in bytes.*/
35FILE *tff; /*temporary control card file*/
36FILE *nfile();
37char *getarg();
38char *sprintf();
39
40
41comopt(o) /*routine to test for common options.*/
42char o;
43{
44 switch (o){
45
46 case 'c':
47 cpflag = 'c';
48 break;
49
50 case 'i':
51 identf = getarg('i');
52 break;
53
54 case 'm':
55 wantmail++;
56 if(arg[2])
57 pp = &arg[2];
58 break;
59
60 case 'n': /*new option to suppress mail. MRW*/
61 wantmail = 0;
62 break;
63
64 case 'o':
65 remotsw = ONL;
66 break;
67
68 case 'r':
69 rmflag++;
70 break;
71
72 case 's':
73 if(arg[2] < '1' || arg[2] > '3')
74 goto unknown;
75 grade = arg[2];
76 break;
77
78 case 't':
79 if(arg[2])
80 goto unknown;
81 remotsw = TOSS;
82 break;
83
84 case '#':
85 debug = 1;
86 break;
87
88 case 'Z': /*GCOS debugging switch*/
89 gcdebug = 1;
90 break;
91
92unknown:
93 default:
94 return(0);
95 }
96 return(1);
97}
98
99
100#if LPR == 0
101
102spool1() /*set up common initial GCOS control cards.*/
103{
104 if(debug)
105 tff = stdout;
106 else
107 if((tff = nfile(tfname)) == NULL){
108 fprintf(stderr, "%s: Can't create %s.\n", NAME, tfname);
109 out();
110 }
111 card('S', "");
112 card('L', sprintf(buf, "$ sgrade %c %s", grade, version ) );
113 if(ident())
114 out();
115 card('L', remote);
116 if(remotsw == TOSS)
117 card('L', toss);
118}
119
120
121spool2() /*add final control cards, and spool job.*/
122{
123 if(wantmail)
124 card('N', mailfile);
125 card('L', "$ endjob");
126 if(debug)
127 out();
128 fclose(tff);
129 if(nact) {
130 dfname[INCHAR]++;
131 if(link(tfname, dfname) < 0){
132 fprintf(stderr, "%s: Cannot rename %s\n", NAME, tfname);
133 out();
134 }
135 unlink(tfname);
136 execl("/usr/lib/dpd", "dpd", 0);
137 execl("/etc/dpd", "dpd", 0);
138 fprintf(stderr, "%s: Can't find dpd.\nFiles left in spooling dir.\n", NAME);
139 exit(1);
140 }
141}
142
143#endif
144
145
146#if FGET == 0
147
148filargs() /*process file arguments for dpr, gcat, fsend, lpr.*/
149{
150 int i;
151 FILE *f;
152
153 if(argc == 1){
154 if(mailfile == 0)
155 mailfile = "pipe.end";
156 if(copy(stdin, mailfile, GCAT) == -1)
157 out();
158 if(archsw)
159 archive();
160 }
161 while(--argc) {
162 arg = *++argv;
163 switch(cpflag){
164
165 case 'l':
166 if(lfname[INCHAR]++ >= 'z')
167 cpflag = rmflag ? 'c' : 'n';
168 else if(link(arg, lfname) == 0){
169 if(size(arg,arg) <= 0)
170 continue;
171 nuact(arg);
172 card(BF, lfname);
173 card('U', lfname);
174 break;
175 }
176
177 case 'n':
178 if(*arg == '/' && !rmflag){
179 if(size(arg,arg) <= 0)
180 continue;
181 nuact(arg);
182 card(BF, arg);
183 break;
184 }
185
186 case 'c':
187 f = fopen(arg, "r");
188 if(f == NULL){
189 fprintf(stderr, "%s: Cannot open %s\n", NAME, arg);
190 continue;
191 }
192 i = copy(f, arg, GCAT);
193 fclose(f);
194 if(i == -1)
195 continue;
196 break;
197 }
198 if(archsw)
199 archive();
200 if(rmflag){
201 if(unlink(arg) < 0)
202 fprintf(stderr, "%s: Cannot remove %s\n", NAME, arg);
203 }
204 if(mailfile == 0)
205 mailfile = arg;
206 }
207}
208
209#endif
210
211
212FILE *nfile(name) /*generate a new file name, and open file.*/
213char *name;
214{
215 FILE *f;
216
217 if(name[INCHAR] >= 'z')
218 return(NULL);
219 name[INCHAR]++;
220 if(!access(name, 0) || (f = fopen(name, "w")) == NULL)
221 return(NULL);
222 return(f);
223}
224
225#if FGET == 0
226
227copy(f, gname, gcatsw)
228FILE *f;
229char *gname;
230int gcatsw;
231{
232 int c;
233 FILE *ff;
234 long cnt;
235
236 if((ff = nfile(cfname)) == NULL){
237 fprintf(stderr, "%s: Too many copy files; %s not copied\n", NAME, gname);
238 return(-1);
239 }
240 cnt = 0;
241 while((c = getc(f)) != EOF){
242 if(gcatsw)
243 if(c != 0){
244 fprintf(stderr, "%s: Bad input from %s.\n", NAME, gname);
245 out();
246 }else gcatsw = 0;
247 if((putc(c, ff) == EOF) && ferror(ff)){
248 fprintf(stderr, "%s: Write error on copy of %s.\n", NAME, gname);
249 break;
250 }
251 cnt++;
252 if(cnt > MAXCOPY){
253 fprintf(stderr, "%s: Copy file %s is too large\n", NAME, gname);
254 break;
255 }
256 }
257 fclose(ff);
258 if(size(cfname,gname) <= 0)
259 return(-1);
260 nuact(gname);
261 card(BF, cfname);
262 card('U', cfname);
263 return(0);
264}
265
266#endif
267
268card(c, s)
269int c;
270char *s;
271{
272 putc( c, tff );
273
274 while( (c = *s++) != '\0') putc( c, tff );
275
276 c = putc( '\n', tff );
277
278 if(c == EOF){
279 fprintf(stderr, "%s: Error writing control file.\n", NAME);
280 out();
281 }
282}
283
284size(file, name)
285char *file, *name;
286{
287 struct stat stbuf;
288
289 if(stat(file,&stbuf) < 0){
290 fprintf(stderr, "%s: Cannot open %s\n", NAME, file);
291 return(-1);
292 }
293 if(!stbuf.st_size){
294 fprintf(stderr, "%s: File %s is empty.\n", NAME, name);
295 return(0);
296 }
297 usize = stbuf.st_size;
298 gsize = usize / 1200;
299 gsize++;
300 nact++;
301 return(gsize);
302}
303
304
305char *
306getarg(c) /*get modifier for complex options --
307 from either same or next argument. MRW
308 e.g. either "-ffile" or "-f file"*/
309char c;
310{
311
312 if(arg[2])
313 return(&arg[2]);
314 else if(--argc>1)
315 return(arg = (++argv)[1]);
316 fprintf(stderr, "%s: Incomplete -%c option\n", NAME,c);
317 out();
318}
319
320#include <pwd.h>
321struct passwd *getpwuid();
322
323ident()
324{
325 int c, i, j, n, test, jsave;
326 struct passwd *b1;
327 static char b2[100];
328
329 if((b1 = getpwuid(getuid())) == NULL) {
330 fprintf(stderr, "%s: Invalid user id\n", NAME);
331 return(1);
332 }
333 j = 0;
334#if LPR == 0
335 while(c = "$ ident "[j])
336 b2[j++] = c;
337
338 i = 0;
339 if(identf)
340 while(c = identf[i++])
341 b2[j++] = c;
342 else{
343 jsave = j; /*use either usg or pwb-style passwd. MRW*/
344 while((c = b1->pw_gecos[i++]) && c != ':')
345 if(c == ')')
346 j = jsave;
347 else
348 b2[j++] = c;
349 }
350 b2[j++] = ',';
351#endif
352
353 i = 0;
354 if(!pp)
355 pp = &b2[j];
356 while(c = b1->pw_name[i++])
357 b2[j++] = c;
358 b2[j] = '\0';
359
360#if LPR == 0
361 i = 0;
362 n = 3;
363 while(--n) {
364 test = 0;
365 while((c=b2[i++]) && c != ',') {
366 if('0' <= c && c <= '9') test += c -'0';
367 else test = 0;
368 }
369 if(test == 0) {
370 b2[j] = '\0';
371 fprintf(stderr, "%s: Invalid IDENT information - %s\n", NAME, b2);
372 return (1);
373 }
374 }
375
376 if(!uidf) {
377 n = 0;
378 while((c = b2[i++]) && c != ',') {
379 if(n >= 12) break;
380 gcosid[n++] = c;
381 }
382 gcosid[n++] = '\0';
383 }
384#endif
385 card('L', b2);
386 if(wantmail){
387 card('M',pp);
388 if(identf)
389 card('Q', b2); /*mail back $IDENT card.*/
390 }
391 return (0);
392}
393
394pidfn() /*rewrite using mktemp. MRW*/
395{
396 int out();
397
398 while(tfname[INCHAR] != 'X')
399 INCHAR++;
400 INCHAR--;
401 mktemp(cfname);
402 mktemp(dfname);
403 mktemp(lfname);
404 mktemp(tfname);
405 mktemp(zfname);
406 if(signal(SIGHUP, SIG_IGN) != SIG_IGN)
407 signal(SIGHUP, out);
408 if(signal(SIGINT, SIG_IGN) != SIG_IGN)
409 signal(SIGINT, out);
410 if(signal(SIGQUIT, SIG_IGN) != SIG_IGN)
411 signal(SIGQUIT, out);
412 if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
413 signal(SIGTERM, out);
414}
415
416out()
417{
418 register i;
419
420 signal(SIGHUP, SIG_IGN);
421 signal(SIGINT, SIG_IGN);
422 signal(SIGQUIT, SIG_IGN);
423 signal(SIGTERM, SIG_IGN);
424 i = INCHAR;
425 for(; cfname[i] != FIRSTCHAR; cfname[i]--)
426 unlink(cfname);
427 if(dfname[i] != FIRSTCHAR)
428 unlink(dfname);
429 for(; lfname[i] != FIRSTCHAR; lfname[i]--)
430 unlink(lfname);
431 if(tfname[i] != FIRSTCHAR)
432 unlink(tfname);
433 for(; zfname[i] != FIRSTCHAR; zfname[i]--)
434 unlink(zfname);
435 exit(1);
436}