Bell 32V development
[unix-history] / usr / src / cmd / lpd.c
CommitLineData
3b600ead
TL
1#include <signal.h>
2/*
3 * Line-printer daemon for Versatek
4 *
5 */
6
7#define TIMEOUT 100
8#define DAEMUID 1
9
10struct {
11 int ino;
12 char name[14];
13} dbuf;
14
15char line[128];
16char banbuf[64];
17int linel;
18int dfb[259];
19char dfname[26] = "/usr/lpd/";
20int waittm = 60;
21
22main(argc, argv)
23{
24 register char *p1, *p2;
25 register df;
26
27 setuid(DAEMUID);
28 signal(SIGHUP, SIG_IGN);
29 signal(SIGINT, SIG_IGN);
30 signal(SIGQUIT, SIG_IGN);
31/*
32 * Close all files, open root as 0, 1, 2
33 * to assure standard environment
34 */
35 for (df=0; df<=15; df++)
36 close(df);
37 open("/", 0);
38 dup(0);
39 dup(0);
40 if ((df=creat("/usr/lpd/lock", 0)) < 0)
41 exit(0);
42 close(df);
43 if (fork())
44 exit(0);
45again:
46 df = open("/usr/lpd", 0);
47 do {
48 if (read(df, &dbuf, sizeof dbuf) < sizeof dbuf) {
49 unlink("/usr/lpd/lock");
50 exit(0);
51 }
52 } while (dbuf.ino==0 || dbuf.name[0]!='d' || dbuf.name[1]!='f');
53 close(df);
54 p1 = dbuf.name;
55 p2 = &dfname[9];
56 while (p1 < &dbuf.name[14])
57 *p2++ = *p1++;
58 if (trysend(dfname) == 0)
59 goto again;
60 sleep(waittm);
61 goto again;
62}
63
64trysend(file)
65{
66 register char *p1, *p2;
67 register i;
68 extern int badexit();
69
70 if (fopen(file, dfb) < 0)
71 return(0);
72 banbuf[0] = 0;
73 while (getline()) switch (line[0]) {
74 case 'L':
75 p1 = line+1;
76 p2 = banbuf;
77 while (*p2++ = *p1++);
78 continue;
79
80 case 'F':
81 if (send())
82 return(1);
83 continue;
84
85 case 'U':
86 continue;
87
88 case 'M':
89 continue;
90 }
91/*
92 * Second pass.
93 * Unlink files and send mail.
94 */
95 lseek(dfb[0], 0L, 0);
96 dfb[1] = 0;
97 while (getline()) switch (line[0]) {
98
99 default:
100 continue;
101
102 case 'U':
103 unlink(&line[1]);
104 continue;
105
106 case 'M':
107 sendmail();
108 continue;
109 }
110 close(dfb[0]);
111 unlink(file);
112}
113
114sendmail()
115{
116 static int p[2];
117 register i;
118 int stat;
119
120 pipe(p);
121 if (fork()==0) {
122 alarm(0);
123 close(0);
124 dup(p[0]);
125 for (i=3; i<=15; i++)
126 close(i);
127 execl("/bin/mail", "mail", &line[1], 0);
128 exit(0);
129 }
130 close(1);
131 dup(p[1]);
132 printf("Your printer job is done\n");
133 close(1);
134 close(p[0]);
135 close(p[1]);
136 open("/", 0);
137 wait(&stat);
138}
139
140getline()
141{
142 register char *lp;
143 register c;
144
145 lp = line;
146 linel = 0;
147 while ((c = getc(dfb)) != '\n') {
148 if (c<0)
149 return(0);
150 if (c=='\t') {
151 do {
152 *lp++ = ' ';
153 linel++;
154 } while ((linel & 07) != 0);
155 continue;
156 }
157 *lp++ = c;
158 linel++;
159 }
160 *lp++ = 0;
161 return(1);
162}
163
164send()
165{
166 int p;
167
168 if (p = fork()) {
169 if (p == -1)
170 return(1);
171 wait(&p);
172 return(p);
173 }
174 if (banbuf[0]) {
175 execl("/usr/bin/vpr", "vpr", "-b", banbuf, line+1, 0);
176 return(1);
177 }
178 execl("/usr/bin/vpr", "vpr", line, 0);
179 return(1);
180}