Commit | Line | Data |
---|---|---|
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 | ||
10 | struct { | |
11 | int ino; | |
12 | char name[14]; | |
13 | } dbuf; | |
14 | ||
15 | char line[128]; | |
16 | char banbuf[64]; | |
17 | int linel; | |
18 | int dfb[259]; | |
19 | char dfname[26] = "/usr/lpd/"; | |
20 | int waittm = 60; | |
21 | ||
22 | main(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); | |
45 | again: | |
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 | ||
64 | trysend(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 | ||
114 | sendmail() | |
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 | ||
140 | getline() | |
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 | ||
164 | send() | |
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 | } |