BSD 3 development
[unix-history] / usr / src / cmd / lpr / lpd.c
CommitLineData
15e5cd83
BJ
1/*
2 * Line-printer daemon
3 */
4
5#include <sys/types.h>
6#include <stdio.h>
7#include <dir.h>
8#include <signal.h>
9#include <stat.h>
10#include <sgtty.h>
11
12char line[128];
13char banbuf[64];
14int linel;
15FILE *dfb;
16char dfname[26] = "/usr/spool/lpd/";
17int waittm = 60;
18struct dir dbuf;
19int onalrm();
20
21main(argc, argv)
22{
23 register char *p1, *p2;
24 register int df;
25 register FILE *dp;
26 struct stat stb;
27
28 signal(SIGHUP, SIG_IGN);
29 signal(SIGINT, SIG_IGN);
30 signal(SIGQUIT, SIG_IGN);
31 signal(SIGTERM, SIG_IGN);
32/*
33 * Close all files, open root as 0, 1, 2
34 * to assure standard environment
35 */
36 for (df=0; df<=15; df++)
37 close(df);
38 open("/", 0);
39 dup(0);
40 dup(0);
41 if (stat("/usr/spool/lpd/lock", &stb) >= 0)
42 exit(0);
43 if ((df=creat("/usr/spool/lpd/lock", 0)) < 0)
44 exit(0);
45 close(df);
46 if (fork())
47 exit(0);
48again:
49 dp = fopen("/usr/spool/lpd", "r");
50 do {
51 if (fread(&dbuf, sizeof dbuf, 1, dp) != 1) {
52 feedpage();
53 unlink("/usr/spool/lpd/lock");
54 exit(0);
55 }
56 } while (dbuf.d_ino==0 || dbuf.d_name[0]!='d' || dbuf.d_name[1]!='f');
57 fclose(dp);
58 strcpy(dfname, "/usr/spool/lpd/");
59 strcatn(dfname, dbuf.d_name, DIRSIZ);
60 if (trysend(dfname) == 0)
61 goto again;
62 sleep(waittm);
63 goto again;
64}
65
66trysend(file)
67 char *file;
68{
69 register char *p1, *p2;
70 register int i;
71 extern int badexit();
72
73 dfb = fopen(file, "r");
74 if (dfb == NULL)
75 return(0);
76 banbuf[0] = 0;
77 while (getline()) switch (line[0]) {
78 case 'L':
79 p1 = line+1;
80 p2 = banbuf;
81 while (*p2++ = *p1++);
82 continue;
83
84 case 'F':
85 if (send())
86 return(1);
87 continue;
88
89 case 'U':
90 continue;
91
92 case 'M':
93 continue;
94 }
95/*
96 * Second pass.
97 * Unlink files and send mail.
98 */
99 fseek(dfb, 0L, 0);
100 while (getline()) switch (line[0]) {
101
102 default:
103 continue;
104
105 case 'U':
106 unlink(&line[1]);
107 continue;
108
109 case 'M':
110 sendmail();
111 continue;
112 }
113 fclose(dfb);
114 unlink(file);
115}
116
117sendmail()
118{
119 static int p[2];
120 register i;
121 int stat;
122
123 pipe(p);
124 if (fork()==0) {
125 alarm(0);
126 if (p[0] != 0) {
127 close(0);
128 dup(p[0]);
129 close(p[0]);
130 }
131 close(p[1]);
132 for (i=3; i<=15; i++)
133 close(i);
134 execl("/bin/mail", "mail", &line[1], 0);
135 exit(0);
136 }
137 write(p[1], "Your printer job is done\n", 25);
138 close(p[0]);
139 close(p[1]);
140 wait(&stat);
141}
142
143getline()
144{
145 register char *lp;
146 register int c;
147
148 lp = line;
149 linel = 0;
150 while ((c = getc(dfb)) != '\n') {
151 if (c<0)
152 return(0);
153 if (c=='\t') {
154 do {
155 *lp++ = ' ';
156 linel++;
157 } while ((linel & 07) != 0);
158 continue;
159 }
160 *lp++ = c;
161 linel++;
162 }
163 *lp++ = 0;
164 return(1);
165}
166
167int pid;
168
169send()
170{
171 int p;
172
173 if (pid = fork()) {
174 if (pid == -1)
175 return(1);
176 setexit();
177 signal(SIGALRM, onalrm);
178 alarm(30);
179 wait(&p);
180 alarm(0);
181 return(p);
182 }
183 if (banbuf[0]) {
184 execl("/usr/lib/lpf", "lpf", "-b", banbuf, line+1, 0);
185 return(1);
186 }
187 execl("/usr/lib/lpf", "lpf", line, 0);
188 return(1);
189}
190
191onalrm()
192{
193 struct stat stb;
194
195 signal(SIGALRM, onalrm);
196 if (stat(dfname, &stb) < 0)
197 kill(pid, SIGEMT);
198 reset();
199}
200
201struct sgttyb ttyb = {
202 B9600, B9600,
203 0, 0,
204 XTABS|ANYP|ECHO
205};
206
207feedpage()
208{
209 register int i = 66;
210 FILE *lp;
211
212 lp = fopen("/dev/lp", "w");
213 if (lp == NULL)
214 return;
215 stty(fileno(lp), &ttyb);
216 while (i > 0)
217 fprintf(lp, "\n"), i--;
218 fclose(lp);
219}