]> andersk Git - moira.git/blob - gen/print.pc
don't try to be clever with restrict list and lpcaccess modtimes.
[moira.git] / gen / print.pc
1 /* $Id$
2  *
3  * This generates printcaps and other files for Athena print servers
4  *
5  * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology.
6  * For copying and distribution information, please see the file
7  * <mit-copyright.h>.
8  */
9
10 #include <mit-copyright.h>
11 #include <moira.h>
12 #include <moira_site.h>
13
14 #include <sys/stat.h>
15 #include <sys/types.h>
16
17 #include <ctype.h>
18 #include <stdio.h>
19 #include <string.h>
20
21 #include "util.h"
22
23 EXEC SQL INCLUDE sqlca;
24
25 RCSID("$Header$");
26
27 char *whoami = "print.gen";
28 char *db = "moira/moira";
29
30 void do_host(char *host);
31 void dump_acl(FILE *out, int id, int realms);
32 void sqlerr(void);
33 #ifndef MAX
34 #define MAX(a, b) ( (a) > (b) ? (a) : (b) )
35 #endif
36
37 int main(int argc, char **argv)
38 {
39   EXEC SQL BEGIN DECLARE SECTION;
40   char name[MACHINE_NAME_SIZE];
41   EXEC SQL END DECLARE SECTION;
42
43   EXEC SQL CONNECT :db;
44
45   EXEC SQL WHENEVER SQLERROR DO sqlerr();
46
47   EXEC SQL DECLARE csr_hosts CURSOR FOR
48     SELECT m.name FROM machine m, serverhosts sh
49     WHERE m.mach_id = sh.mach_id AND sh.service = 'PRINT' AND sh.enable = 1;
50   EXEC SQL OPEN csr_hosts;
51   while (1)
52     {
53       EXEC SQL FETCH csr_hosts INTO :name;
54       if (sqlca.sqlcode)
55         break;
56
57       strtrim(name);
58       do_host(name);
59     }
60   EXEC SQL CLOSE csr_hosts;
61
62   exit(MR_SUCCESS);
63 }
64
65 void do_host(char *host)
66 {
67   EXEC SQL BEGIN DECLARE SECTION;
68   char rp[PRINTERS_RP_SIZE], name[PRINTERS_NAME_SIZE];
69   char duplexname[PRINTERS_DUPLEXNAME_SIZE], location[PRINTERS_LOCATION_SIZE];
70   char hwtype[PRINTERS_HWTYPE_SIZE], hostname[MACHINE_NAME_SIZE];
71   char rm[MACHINE_NAME_SIZE], rq[MACHINE_NAME_SIZE];
72   char modtime[PRINTERS_MODTIME_SIZE], lmodtime[LIST_MODTIME_SIZE];
73   char contact[PRINTERS_CONTACT_SIZE];
74   char *spoolhost = host, *unixtime_fmt = UNIXTIME_FMT;
75   int ka, pc, ac, lpc_acl, banner;
76   EXEC SQL END DECLARE SECTION;
77   TARFILE *tf;
78   FILE *out;
79   char filename[MAXPATHLEN];
80   time_t mtime, now = time(NULL);
81
82   sprintf(filename, "%s/print/%s", DCM_DIR, host);
83   tf = tarfile_open(filename);
84
85   out = tarfile_start(tf, "/etc/printcap.moira", 0644, 0, 0,
86                       "root", "root", now);
87
88   EXEC SQL DECLARE csr_printcap CURSOR FOR
89     SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype,
90     m.name, mrm.name, mrq.name, pr.ka, pr.pc, pr.ac,
91     pr.location, pr.contact
92     FROM printers pr, machine m, machine mrm, machine mrq
93     WHERE m.mach_id = pr.mach_id AND mrq.mach_id = pr.rq
94     AND mrm.mach_id = pr.rm AND mrm.name = :spoolhost
95     AND pr.type != 'ALIAS';
96   EXEC SQL OPEN csr_printcap;
97   while (1)
98     {
99       EXEC SQL FETCH csr_printcap INTO :rp, :name, :duplexname,
100         :hwtype, :hostname, :rm, :rq, :ka, :pc, :ac, :location, :contact;
101       if (sqlca.sqlcode)
102         break;
103
104       strtrim(rp);
105       strtrim(name);
106       strtrim(duplexname);
107       strtrim(hwtype);
108       strtrim(hostname);
109       strtrim(rm);
110       strtrim(rq);
111       strtrim(location);
112       strtrim(contact);
113
114       if (location[0])
115         fprintf(out, "# %s: %s\n", name, location);
116       else
117         fprintf(out, "# %s\n", name);
118       if (strcmp(location, contact))
119         fprintf(out, "# contact: %s\n", contact);
120
121       fprintf(out, "%s|%s %s", rp, location, hwtype);
122       if (*duplexname)
123         fprintf(out, "|%s", duplexname);
124       fprintf(out, ":\\\n\t:lp=/dev/null:rp=%s:rm=%s:\\\n"
125               "\t:sd=/var/spool/printer/%s:\\\n"
126               "\t:lf=/var/spool/printer/%s/%s-log:\\\n"
127               "\t:af=/var/spool/printer/%s/%s-acct:\\\n"
128               "\t:ka#%d:pc#%d:\\\n",
129               !strcmp(hwtype, "LPR") ? "raw" : rp,
130               !strcmp(hwtype, "HP") ? rm : hostname,
131               rp, rp, rp, rp, rp, ka, pc);
132       if (strcmp(rq, "[NONE]"))
133         fprintf(out, "\t:rq=%s:\\\n", rq);
134       if (ac)
135         fprintf(out, "\t:ac=/var/spool/printer/%s/restrict.list:pa:\\\n", rp);
136
137       if (!strcmp(hwtype, "HP"))
138         {
139           fprintf(out, "\t:if=/usr/athena/lib/lpdfilters/hpif:\\\n"
140                   "\t:of=/usr/athena/lib/lpdfilters/hpof:\\\n"
141                   "\t:gf=/usr/athena/lib/lpdfilters/hpgf:\\\n"
142                   "\t:nf=/usr/athena/lib/lpdfilters/hpnf:\\\n"
143                   "\t:tf=/usr/athena/lib/lpdfilters/hptf:\\\n"
144                   "\t:rf=/usr/athena/lib/lpdfilters/hprf:\\\n"
145                   "\t:vf=/usr/athena/lib/lpdfilters/hpvf:\\\n"
146                   "\t:cf=/usr/athena/lib/lpdfilters/hpcf:\\\n"
147                   "\t:df=/usr/athena/lib/lpdfilters/hpdf:\\\n"
148                   "\t:sf:sb:mx#0:\n\n");
149         }
150       else
151         fprintf(out, "\t:mx#0:\n\n");
152     }
153   EXEC SQL CLOSE csr_printcap;
154   tarfile_end(tf);
155
156   EXEC SQL DECLARE csr_spool CURSOR FOR
157     SELECT UNIQUE pr.rp, pr.duplexname, pr.hwtype, m.name, pr.ac,
158     pr.lpc_acl, pr.banner, TO_CHAR(pr.modtime, :unixtime_fmt)
159     FROM printers pr, machine m, machine mrm
160     WHERE m.mach_id = pr.mach_id
161     AND mrm.mach_id = pr.rm AND mrm.name = :spoolhost;
162   EXEC SQL OPEN csr_spool;
163   while (1)
164     {
165       EXEC SQL FETCH csr_spool INTO :name, :duplexname, :hwtype,
166         :hostname, :ac, :lpc_acl, :banner, :modtime;
167       if (sqlca.sqlcode)
168         break;
169
170       strtrim(name);
171       strtrim(duplexname);
172       strtrim(hwtype);
173       strtrim(hostname);
174       mtime = unixtime(strtrim(modtime));
175
176       sprintf(filename, "/var/spool/printer/%s", name);
177       tarfile_mkdir(tf, filename, 0755, 1, 1, "daemon", "daemon", mtime);
178
179       /* If spooling to an HP printer, make a .options file. */
180       if (!strcmp(hwtype, "HP"))
181         {
182           sprintf(filename, "/var/spool/printer/%s/.options", name);
183           out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
184                               mtime);
185           fprintf(out, "BANNERFIRST=%d\nBANNERLAST=%d\nREVERSE=\n"
186                   "DUPLEXING=0\nINTERFACE=0\nNETNAME=%s\nPRINTER=%s\n"
187                   "export BANNERFIRST BANNERLAST REVERSE DUPLEXING\n"
188                   "export PRINTER NETNAME INTERFACE VERBOSELOG\n",
189                   banner == PRN_BANNER_FIRST, banner == PRN_BANNER_LAST,
190                   hostname, name);
191           tarfile_end(tf);
192         }
193
194       /* If we have a duplex name, make a .spooler file. */
195       if (*duplexname)
196         {
197           sprintf(filename, "/var/spool/printer/%s/.spooler", name);
198           out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
199                               mtime);
200           fprintf(out, "%s -F /usr/athena/lib/lpdfilters/duplex2\n",
201                   duplexname);
202           tarfile_end(tf);
203         }
204
205       /* The ac and lpc_acl lists may have sublists, and changes to those
206        * won't affect the superlist's modtime. So we just set the modtime
207        * to now.
208        */
209
210       /* Access-control list. */
211       if (ac)
212         {
213           sprintf(filename, "/var/spool/printer/%s/restrict.list", name);
214           out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
215                               now);
216           dump_acl(out, ac, 0);
217           tarfile_end(tf);
218         }
219
220       /* printer-specific lpc access. */
221       if (lpc_acl)
222         {
223           sprintf(filename, "/var/spool/printer/%s/lpcaccess.%s", name, name);
224           out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
225                               now);
226           fprintf(out, "all:\n");
227           dump_acl(out, lpc_acl, 1);
228           tarfile_end(tf);
229         }
230     }
231   EXEC SQL CLOSE csr_spool;
232
233   tarfile_close(tf);
234 }
235
236 void dump_acl(FILE *out, int id, int realms)
237 {
238   EXEC SQL BEGIN DECLARE SECTION;
239   int lid = id;
240   char login[USERS_LOGIN_SIZE], princ[STRINGS_STRING_SIZE];
241   EXEC SQL END DECLARE SECTION;
242
243   EXEC SQL DECLARE csr_users CURSOR FOR
244     SELECT u.login FROM users u, imembers im
245     WHERE u.users_id = im.member_id
246     AND im.member_type = 'USER' AND im.list_id = :lid;
247   EXEC SQL OPEN csr_users;
248   while (1)
249     {
250       EXEC SQL FETCH csr_users INTO :login;
251       if (sqlca.sqlcode)
252         break;
253
254       fprintf(out, "%s%s\n", strtrim(login), realms ? "@ATHENA.MIT.EDU" : "");
255     }
256   EXEC SQL CLOSE csr_users;
257
258   EXEC SQL DECLARE csr_krb CURSOR FOR
259     SELECT s.string FROM strings s, imembers im
260     WHERE s.string_id = im.member_id
261     AND im.member_type = 'KERBEROS' AND im.list_id = :lid;
262   EXEC SQL OPEN csr_krb;
263   while (1)
264     {
265       EXEC SQL FETCH csr_krb INTO :princ;
266       if (sqlca.sqlcode)
267         break;
268
269       if (!realms)
270         {
271           if (strchr(princ, '@'))
272             *strchr(princ, '@') = '\0';
273         }
274
275       fprintf(out, "%s\n", strtrim(princ));
276     }
277   EXEC SQL CLOSE csr_krb;
278 }
279
280 void sqlerr(void)
281 {
282   db_error(sqlca.sqlcode);
283 }
This page took 0.057564 seconds and 5 git commands to generate.