3 * This generates printcaps and other files for Athena print servers
5 * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
10 #include <mit-copyright.h>
12 #include <moira_site.h>
15 #include <sys/types.h>
23 EXEC SQL INCLUDE sqlca;
27 char *whoami = "print.gen";
28 char *db = "moira/moira";
30 void do_host(char *host);
31 void dump_acl(FILE *out, int id, int realms);
34 #define MAX(a, b) ( (a) > (b) ? (a) : (b) )
37 int main(int argc, char **argv)
39 EXEC SQL BEGIN DECLARE SECTION;
40 char name[MACHINE_NAME_SIZE];
41 EXEC SQL END DECLARE SECTION;
45 EXEC SQL WHENEVER SQLERROR DO sqlerr();
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;
53 EXEC SQL FETCH csr_hosts INTO :name;
60 EXEC SQL CLOSE csr_hosts;
65 void do_host(char *host)
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;
79 char filename[MAXPATHLEN];
80 time_t mtime, now = time(NULL);
82 sprintf(filename, "%s/print/%s", DCM_DIR, host);
83 tf = tarfile_open(filename);
85 out = tarfile_start(tf, "/etc/printcap.moira", 0644, 0, 0,
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;
99 EXEC SQL FETCH csr_printcap INTO :rp, :name, :duplexname,
100 :hwtype, :hostname, :rm, :rq, :ka, :pc, :ac, :location, :contact;
115 fprintf(out, "# %s: %s\n", name, location);
117 fprintf(out, "# %s\n", name);
118 if (strcmp(location, contact))
119 fprintf(out, "# contact: %s\n", contact);
121 fprintf(out, "%s|%s %s", rp, location, hwtype);
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);
135 fprintf(out, "\t:ac=/var/spool/printer/%s/restrict.list:pa:\\\n", rp);
137 if (!strcmp(hwtype, "HP"))
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");
151 fprintf(out, "\t:mx#0:\n\n");
153 EXEC SQL CLOSE csr_printcap;
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;
165 EXEC SQL FETCH csr_spool INTO :name, :duplexname, :hwtype,
166 :hostname, :ac, :lpc_acl, :banner, :modtime;
174 mtime = unixtime(strtrim(modtime));
176 sprintf(filename, "/var/spool/printer/%s", name);
177 tarfile_mkdir(tf, filename, 0755, 1, 1, "daemon", "daemon", mtime);
179 /* If spooling to an HP printer, make a .options file. */
180 if (!strcmp(hwtype, "HP"))
182 sprintf(filename, "/var/spool/printer/%s/.options", name);
183 out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
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,
194 /* If we have a duplex name, make a .spooler file. */
197 sprintf(filename, "/var/spool/printer/%s/.spooler", name);
198 out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
200 fprintf(out, "%s -F /usr/athena/lib/lpdfilters/duplex2\n",
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
210 /* Access-control list. */
213 sprintf(filename, "/var/spool/printer/%s/restrict.list", name);
214 out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
216 dump_acl(out, ac, 0);
220 /* printer-specific lpc access. */
223 sprintf(filename, "/var/spool/printer/%s/lpcaccess.%s", name, name);
224 out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
226 fprintf(out, "all:\n");
227 dump_acl(out, lpc_acl, 1);
231 EXEC SQL CLOSE csr_spool;
236 void dump_acl(FILE *out, int id, int realms)
238 EXEC SQL BEGIN DECLARE SECTION;
240 char login[USERS_LOGIN_SIZE], princ[STRINGS_STRING_SIZE];
241 EXEC SQL END DECLARE SECTION;
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;
250 EXEC SQL FETCH csr_users INTO :login;
254 fprintf(out, "%s%s\n", strtrim(login), realms ? "@ATHENA.MIT.EDU" : "");
256 EXEC SQL CLOSE csr_users;
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;
265 EXEC SQL FETCH csr_krb INTO :princ;
271 if (strchr(princ, '@'))
272 *strchr(princ, '@') = '\0';
275 fprintf(out, "%s\n", strtrim(princ));
277 EXEC SQL CLOSE csr_krb;
282 db_error(sqlca.sqlcode);