]> andersk Git - moira.git/blame - gen/hesiod.pc
IMAPpy goodness. add imap_id to users and make some device and dir
[moira.git] / gen / hesiod.pc
CommitLineData
7ac48069 1/* $Id$
bac4ceaa 2 *
3 * This generates the zone files necessary to load a hesiod server.
4 * The following zones are generated: passwd, uid, pobox, group,
5 * grplist, gid, filsys, cluster, pcap, sloc, service.
6 *
7ac48069 7 * (c) Copyright 1988-1998 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, please see the file
9 * <mit-copyright.h>.
bac4ceaa 10 */
11
12#include <mit-copyright.h>
bac4ceaa 13#include <moira.h>
14#include <moira_site.h>
7ac48069 15
bac4ceaa 16#include <sys/stat.h>
7ac48069 17
18#include <stdio.h>
19#include <stdlib.h>
9c04b191 20#include <string.h>
7ac48069 21
22#include "util.h"
23
bac4ceaa 24EXEC SQL INCLUDE sqlca;
25
7ac48069 26RCSID("$Header$");
bac4ceaa 27
9c04b191 28#ifndef HTYPE
e14de0ca 29#define HTYPE "TXT"
9c04b191 30#endif
31#ifndef HCLASS
d8aec3bb 32#define HCLASS ""
9c04b191 33#endif
34
35#ifndef HESIOD_SUBDIR
36#define HESIOD_SUBDIR "hesiod"
bac4ceaa 37#endif
38
5eaef520 39/* max number of bytes of a data record that can be returned in a hesiod
d8aec3bb 40 * query. This is 512 - overhead (~78) [derived empirically]
41 * (it used to be 446 with older versions of bind)
4821a398 42 */
d8aec3bb 43#define MAXHESSIZE 434
4821a398 44
dfaf9b68 45char hesiod_dir[MAXPATHLEN];
bac4ceaa 46
5eaef520 47#define min(x, y) ((x) < (y) ? (x) : (y))
bac4ceaa 48struct hash *machines = NULL;
49struct hash *users = NULL;
50char *whoami = "hesiod.gen";
9c04b191 51char *db = "moira/moira";
bac4ceaa 52
53struct grp {
5eaef520 54 struct grp *next;
55 char *lid;
bac4ceaa 56};
57struct user {
dfaf9b68 58 char name[USERS_LOGIN_SIZE];
5eaef520 59 struct grp *lists;
bac4ceaa 60};
61
7ac48069 62/*
63 * Modified from sys/types.h:
64 */
65int setsize; /* = howmany(setbits, NSETBITS) */
66
67typedef long set_mask;
68#define NSETBITS (sizeof(set_mask) * NBBY) /* bits per mask */
69#ifndef howmany
70#define howmany(x, y) (((x) + ((y) - 1)) / (y))
71#endif
72
73#define SET_SET(n, p) ((p)[(n)/NSETBITS] |= (1 << ((n) % NSETBITS)))
74#define SET_CLR(n, p) ((p)[(n)/NSETBITS] &= ~(1 << ((n) % NSETBITS)))
75#define SET_ISSET(n, p) ((p)[(n)/NSETBITS] & (1 << ((n) % NSETBITS)))
76#define SET_CREATE() (malloc(setsize * sizeof(set_mask)))
77#define SET_ZERO(p) memset(p, 0, setsize * sizeof(set_mask))
78#define SET_CMP(p1, p2) (memcmp(p1, p2, setsize * sizeof(set_mask)))
79
80
81void get_mach(void);
82int nbitsset(set_mask *set);
2203d8f9 83int valid(char *name);
7ac48069 84
85int do_passwd(void);
86int do_groups(void);
87int do_filsys(void);
88int do_cluster(void);
89int do_printcap(void);
7ac48069 90int do_sloc(void);
91int do_service(void);
bac4ceaa 92
5eaef520 93int main(int argc, char **argv)
bac4ceaa 94{
5eaef520 95 char cmd[64];
96 struct stat sb;
97 int changed = 0;
98
99 if (argc > 2)
100 {
101 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
102 exit(MR_ARGS);
bac4ceaa 103 }
104
5eaef520 105 initialize_sms_error_table();
106 sprintf(hesiod_dir, "%s/%s", DCM_DIR, HESIOD_SUBDIR);
107
108 EXEC SQL CONNECT :db;
109
110 changed = do_passwd();
111 changed += do_filsys();
112 changed += do_cluster();
113 changed += do_printcap();
5eaef520 114 changed += do_sloc();
115 changed += do_service();
116 changed += do_groups();
117
118 if (!changed)
119 {
120 fprintf(stderr, "No files updated.\n");
121 if (argc == 2 && stat(argv[1], &sb) == 0)
122 exit(MR_NO_CHANGE);
bac4ceaa 123 }
124
5eaef520 125 if (argc == 2)
126 {
127 fprintf(stderr, "Building tar file.\n");
128 sprintf(cmd, "cd %s; tar cf %s .", hesiod_dir, argv[1]);
129 if (system(cmd))
130 exit(MR_TAR_FAIL);
bac4ceaa 131 }
132
5eaef520 133 exit(MR_SUCCESS);
bac4ceaa 134}
135
136
7ac48069 137void get_mach(void)
bac4ceaa 138{
5eaef520 139 EXEC SQL BEGIN DECLARE SECTION;
140 int id;
dfaf9b68 141 char name[MACHINE_NAME_SIZE];
5eaef520 142 EXEC SQL END DECLARE SECTION;
143
144 if (machines)
145 return;
146
147 machines = create_hash(1000);
148 EXEC SQL DECLARE m_cursor CURSOR FOR
149 SELECT name, mach_id
150 FROM machine
151 WHERE status = 1 and mach_id != 0
152 ORDER BY mach_id;
153 EXEC SQL OPEN m_cursor;
154 while (1)
155 {
156 EXEC SQL FETCH m_cursor INTO :name, :id;
157 if (sqlca.sqlcode)
158 break;
2203d8f9 159 strtrim(name);
160 if (!valid(name))
161 continue;
162 hash_store(machines, id, strdup(name));
5eaef520 163 }
164 if (sqlca.sqlcode < 0)
165 db_error(sqlca.sqlcode);
166 EXEC SQL CLOSE m_cursor;
167 EXEC SQL COMMIT;
bac4ceaa 168}
169
170
2203d8f9 171/* Determine whether or not a name is a valid DNS label.
172 (Can't start or end with . or have two .s in a row) */
173int valid(char *name)
174{
175 int sawdot;
176
177 for (sawdot = 1; *name; name++)
178 {
179 if (*name == '.')
180 {
181 if (sawdot)
182 return 0;
183 else
184 sawdot = 1;
185 }
186 else
187 sawdot = 0;
188 }
189 return !sawdot;
190}
191
192
5eaef520 193int do_passwd(void)
bac4ceaa 194{
5eaef520 195 FILE *pout, *uout, *bout;
dfaf9b68 196 char poutf[MAXPATHLEN], uoutf[MAXPATHLEN], poutft[MAXPATHLEN];
197 char uoutft[MAXPATHLEN], boutf[MAXPATHLEN], boutft[MAXPATHLEN];
5eaef520 198 struct stat psb, usb, bsb;
199 time_t ftime;
200 struct user *u;
201 char *mach;
202 EXEC SQL BEGIN DECLARE SECTION;
dfaf9b68 203 char login[USERS_LOGIN_SIZE], shell[USERS_SHELL_SIZE];
204 char fullname[USERS_FULLNAME_SIZE], oa[USERS_OFFICE_ADDR_SIZE];
205 char op[USERS_OFFICE_PHONE_SIZE], hp[USERS_HOME_PHONE_SIZE];
206 char nn[USERS_NICKNAME_SIZE], ptype[USERS_POTYPE_SIZE];
5eaef520 207 int uid, flag1, flag2, id, pid, status;
208 EXEC SQL END DECLARE SECTION;
209
210 sprintf(poutf, "%s/passwd.db", hesiod_dir);
211 sprintf(uoutf, "%s/uid.db", hesiod_dir);
212 sprintf(boutf, "%s/pobox.db", hesiod_dir);
213
214 if (stat(poutf, &psb) == 0 && stat(uoutf, &usb) == 0 &&
215 stat(boutf, &bsb) == 0)
216 {
217 ftime = min(min(psb.st_mtime, usb.st_mtime), bsb.st_mtime);
218 if (ModDiff (&flag1, "users", ftime) ||
219 ModDiff (&flag2, "machine", ftime))
220 exit(MR_DATE);
221 if (flag1 < 0 && flag2 < 0)
222 {
223 fprintf(stderr, "Files passwd.db, uid.db, and pobox.db "
224 "do not need to be rebuilt.\n");
225 return 0;
226 }
227 }
228
229 sprintf(poutft, "%s~", poutf);
230 pout = fopen(poutft, "w");
231 if (!pout)
232 {
233 perror("cannot open passwd.db~ for write");
234 exit(MR_OCONFIG);
235 }
236 sprintf(uoutft, "%s~", uoutf);
237 uout = fopen(uoutft, "w");
238 if (!uout)
239 {
240 perror("cannot open uid.db~ for write");
241 exit(MR_OCONFIG);
242 }
243 sprintf(boutft, "%s~", boutf);
244 bout = fopen(boutft, "w");
245 if (!bout)
246 {
247 perror("cannot open pobox.db for write");
248 exit(MR_OCONFIG);
bac4ceaa 249 }
bac4ceaa 250
5eaef520 251 fprintf(stderr, "Building passwd.db, uid.db, and pobox.db\n");
252 get_mach();
253
254 users = create_hash(12001);
255 EXEC SQL DECLARE u_cursor CURSOR FOR
256 SELECT login, unix_uid, shell, fullname, nickname, office_addr,
257 office_phone, home_phone, users_id, pop_id, potype, status
258 FROM users
3fe4e44d 259 WHERE status = 1 OR status = 2 OR status = 5 OR status = 6
5eaef520 260 ORDER BY users_id;
261 EXEC SQL OPEN u_cursor;
262 while (1)
263 {
264 EXEC SQL FETCH u_cursor INTO :login, :uid, :shell, :fullname, :nn,
265 :oa, :op, :hp, :id, :pid, :ptype, :status;
266 if (sqlca.sqlcode)
267 break;
268 strtrim(login);
269 dequote(fullname);
270 dequote(nn);
271 dequote(oa);
272 dequote(op);
273 dequote(hp);
274 dequote(shell);
275 u = malloc(sizeof(struct user));
276 strcpy(u->name, login);
277 u->lists = NULL;
278 hash_store(users, id, u);
45116bc1 279 if (status == 1 || status == 2)
5eaef520 280 {
281 fprintf(pout, "%s.passwd\t%s %s \"%s:*:%d:101:%s,%s,%s,%s,%s:/mit/%s:%s\"\n",
282 login, HCLASS, HTYPE, login, uid, fullname, nn, oa,
283 op, hp, login, shell);
284 fprintf(uout, "%d.uid\t%s CNAME %s.passwd\n", uid, HCLASS, login);
285 }
286 if (pid != 0 && (mach = hash_lookup(machines, pid)))
287 {
288 fprintf(bout, "%s.pobox\t%s %s \"POP %s %s\"\n",
289 login, HCLASS, HTYPE, mach, login);
290 }
bac4ceaa 291 }
5eaef520 292 if (sqlca.sqlcode < 0)
293 db_error(sqlca.sqlcode);
294 EXEC SQL CLOSE u_cursor;
295 EXEC SQL COMMIT;
296
297 if (fclose(pout) || fclose(uout) || fclose(bout))
298 {
299 fprintf(stderr, "Unsuccessful file close of passwd.db, uid.db, or pobox.db\n");
300 exit(MR_CCONFIG);
301 }
302 fix_file(poutf);
303 fix_file(uoutf);
304 fix_file(boutf);
305 return 1;
bac4ceaa 306}
307
308
5eaef520 309int do_groups(void)
bac4ceaa 310{
5eaef520 311 FILE *iout, *gout, *lout;
dfaf9b68 312 char ioutf[MAXPATHLEN], goutf[MAXPATHLEN], loutf[MAXPATHLEN];
313 char buf[MAXPATHLEN], *l;
5eaef520 314 struct hash *groups;
44d12d58 315 struct bucket *b, **p;
5eaef520 316 struct grp *g;
317 struct user *u;
318 struct stat isb, gsb, lsb;
319 time_t ftime;
320 EXEC SQL BEGIN DECLARE SECTION;
dfaf9b68 321 char name[LIST_NAME_SIZE];
5eaef520 322 int gid, id, lid, flag1, flag2, flag3, len;
323 EXEC SQL END DECLARE SECTION;
324
325 /* open files */
326 sprintf(ioutf, "%s/gid.db", hesiod_dir);
327 sprintf(goutf, "%s/group.db", hesiod_dir);
328 sprintf(loutf, "%s/grplist.db", hesiod_dir);
329
330 if (stat(ioutf, &isb) == 0 && stat(goutf, &gsb) == 0 &&
331 stat(loutf, &lsb) == 0)
332 {
333 ftime = min(isb.st_mtime, min(gsb.st_mtime, lsb.st_mtime));
334 if (ModDiff (&flag1, "users", ftime) ||
335 ModDiff (&flag2, "list", ftime) ||
336 ModDiff (&flag3, "imembers", ftime))
337 exit(MR_DATE);
338 if (flag1 < 0 && flag2 < 0 && flag3 < 0)
339 {
340 fprintf(stderr, "Files gid.db, group.db and grplist.db "
341 "do not need to be rebuilt.\n");
342 return 0;
343 }
344 }
345
346 sprintf(buf, "%s~", ioutf);
347 iout = fopen(buf, "w");
348 if (!iout)
349 {
350 perror("cannot open gid.db for write");
351 exit(MR_OCONFIG);
352 }
353 sprintf(buf, "%s~", goutf);
354 gout = fopen(buf, "w");
355 if (!gout)
356 {
357 perror("cannot open group.db for write");
358 exit(MR_OCONFIG);
359 }
360 sprintf(buf, "%s~", loutf);
361 lout = fopen(buf, "w");
362 if (!lout)
363 {
364 perror("cannot open grplist.db for write");
365 exit(MR_OCONFIG);
366 }
367
368 fprintf(stderr, "Building gid.db, group.db, and grplist.db\n");
369
370 /* make space for group list */
371 groups = create_hash(15001);
372
373 /* The following WHENEVER is declarative, not executed,
374 * and applies for the remainder of this file only.
375 */
376 EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
377
378 EXEC SQL DECLARE l_cursor CURSOR FOR
379 SELECT name, gid, list_id
380 FROM list
381 WHERE grouplist != 0 AND active != 0
382 ORDER BY list_id;
383 EXEC SQL OPEN l_cursor;
384 while (1)
385 {
dfaf9b68 386 char buf[LIST_NAME_SIZE + 10];
387
5eaef520 388 EXEC SQL FETCH l_cursor INTO :name, :gid, :lid;
389 if (sqlca.sqlcode)
390 break;
391 strtrim(name);
2203d8f9 392 if (!valid(name))
393 continue;
5eaef520 394 sprintf(buf, "%s:%d", name, gid);
7ac48069 395 hash_store(groups, lid, strdup(buf));
5eaef520 396 fprintf(iout, "%d.gid\t%s CNAME %s.group\n", gid, HCLASS, name);
397 fprintf(gout, "%s.group\t%s %s \"%s:*:%d:\"\n",
398 name, HCLASS, HTYPE, name, gid);
399 }
400 EXEC SQL CLOSE l_cursor;
401
402 fflush(iout);
403 fflush(gout);
404
405 /* now do grplists */
406 if (!users)
407 {
408 users = create_hash(12001);
409 EXEC SQL DECLARE u_cursor2 CURSOR FOR
410 SELECT users_id, login
411 FROM users
3fe4e44d 412 WHERE status = 1 OR status = 2
5eaef520 413 ORDER BY users_id;
414 EXEC SQL OPEN u_cursor2;
415 while (1)
416 {
417 EXEC SQL FETCH u_cursor2 INTO :id, :name;
418 if (sqlca.sqlcode)
419 break;
420 u = malloc(sizeof(struct user));
421 strcpy(u->name, strtrim(name));
422 u->lists = NULL;
423 hash_store(users, id, u);
bac4ceaa 424 }
5eaef520 425 EXEC SQL CLOSE u_cursor2;
426 }
427
428 EXEC SQL DECLARE i_cursor CURSOR FOR
429 SELECT list_id, member_id
430 FROM imembers
431 WHERE member_type = 'USER'
432 ORDER BY list_id;
433 EXEC SQL OPEN i_cursor;
434 while (1)
435 {
436 EXEC SQL FETCH i_cursor INTO :lid, :id;
437 if (sqlca.sqlcode)
438 break;
7ac48069 439 if ((l = hash_lookup(groups, lid)) && (u = hash_lookup(users, id)))
5eaef520 440 {
441 g = malloc(sizeof(struct grp));
442 g->next = u->lists;
443 u->lists = g;
444 g->lid = l;
bac4ceaa 445 }
446 }
5eaef520 447 EXEC SQL CLOSE i_cursor;
448
449 EXEC SQL COMMIT;
450
451 for (p = &(users->data[users->size - 1]); p >= users->data; p--)
452 {
453 for (b = *p; b; b = b->next)
454 {
455 if (!(g = ((struct user *)b->data)->lists))
456 continue;
457 fprintf(lout, "%s.grplist\t%s %s \"",
458 ((struct user *)b->data)->name, HCLASS, HTYPE);
459 len = 0;
460 for (; g; g = g->next)
461 {
462 if (len + strlen(g->lid) + 1 < MAXHESSIZE)
463 {
464 fputs(g->lid, lout);
465 if (g->next)
466 putc(':', lout);
467 len += strlen(g->lid) + 1;
468 }
469 else
470 {
471 com_err(whoami, 0, "truncated grp list for user %s",
472 ((struct user *)b->data)->name);
473 break;
4821a398 474 }
bac4ceaa 475 }
5eaef520 476 fputs("\"\n", lout);
bac4ceaa 477 }
478 }
479
5eaef520 480 if (fclose(iout) || fclose(gout) || fclose(lout))
481 {
482 fprintf(stderr, "Unsuccessful close of gid.db, group.db, or grplist.db\n");
483 exit(MR_CCONFIG);
bac4ceaa 484 }
5eaef520 485 fix_file(ioutf);
486 fix_file(goutf);
487 fix_file(loutf);
488 return 1;
489sqlerr:
490 db_error(sqlca.sqlcode);
491 return 0;
bac4ceaa 492}
493
494
5eaef520 495int do_filsys(void)
bac4ceaa 496{
5eaef520 497 FILE *out;
dfaf9b68 498 char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach, *group;
5eaef520 499 struct stat sb;
500 time_t ftime;
7ac48069 501 struct save_queue *sq, *sq2;
5eaef520 502 EXEC SQL BEGIN DECLARE SECTION;
dfaf9b68 503 char name[FILESYS_LABEL_SIZE], type[FILESYS_TYPE_SIZE];
504 char loc[FILESYS_NAME_SIZE], access[FILESYS_RWACCESS_SIZE];
505 char mount[FILESYS_MOUNT_SIZE], comments[FILESYS_COMMENTS_SIZE];
506 char key[FSGROUP_KEY_SIZE];
507 char aname[ALIAS_NAME_SIZE], trans[ALIAS_TRANS_SIZE];
5eaef520 508 int flag1, flag2, flag3, flag4, id, fid;
509 EXEC SQL END DECLARE SECTION;
510
511 sprintf(outf, "%s/filsys.db", hesiod_dir);
512
513 if (stat(outf, &sb) == 0)
514 {
515 ftime = sb.st_mtime;
516
517 if (ModDiff(&flag1, "filesys", ftime))
518 exit(MR_DATE);
519 if (ModDiff(&flag2, "machine", ftime))
520 exit(MR_DATE);
521 if (ModDiff(&flag3, "alias", ftime))
522 exit(MR_DATE);
523 if (ModDiff(&flag4, "fsgroup", ftime))
524 exit(MR_DATE);
525
526 if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0)
527 {
528 fprintf(stderr, "File filsys.db does not need to be rebuilt.\n");
529 return 0;
530 }
531 }
532
533 sprintf(outft, "%s~", outf);
534 out = fopen(outft, "w");
535 if (!out)
536 {
537 perror("cannot open filsys.db for write");
538 exit(MR_OCONFIG);
539 }
540
541 fprintf(stderr, "Building filsys.db\n");
542 get_mach();
543 sq = sq_create();
544 sq2 = sq_create();
545
546 EXEC SQL DECLARE f_cursor CURSOR FOR
547 SELECT label, type, name, mach_id, rwaccess, mount, comments, filsys_id
548 FROM filesys
549 ORDER BY filsys_id;
550 EXEC SQL OPEN f_cursor;
551 while (1)
552 {
553 EXEC SQL FETCH f_cursor INTO :name, :type, :loc, :id, :access,
554 :mount, :comments, :fid;
555 if (sqlca.sqlcode)
556 break;
2203d8f9 557 strtrim(name);
558 if (!valid(name))
559 continue;
5eaef520 560 strtrim(type);
561 if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
562 {
7ac48069 563 if ((mach = hash_lookup(machines, id)))
5eaef520 564 {
565 fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s\"\n",
2203d8f9 566 name, HCLASS, HTYPE, type, strtrim(loc),
5eaef520 567 mach, strtrim(access), strtrim(mount));
bac4ceaa 568 }
5eaef520 569 }
570 else if (!strcmp(type, "AFS"))
571 {
572 fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s\"\n",
2203d8f9 573 name, HCLASS, HTYPE, strtrim(loc),
5eaef520 574 strtrim(access), strtrim(mount));
575 }
576 else if (!strcmp(type, "ERR"))
577 {
578 fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
2203d8f9 579 name, HCLASS, HTYPE, strtrim(comments));
5eaef520 580 }
581 else if (!strcmp(type, "FSGROUP"))
582 {
dfaf9b68 583 char buf[FILESYS_NAME_SIZE + 10];
2203d8f9 584 sprintf(buf, "%s:%d", name, fid);
dfaf9b68 585 sq_save_data(sq, strdup(buf));
5eaef520 586 }
587 else if (!strcmp(type, "MUL"))
588 {
dfaf9b68 589 char buf[FILESYS_NAME_SIZE + 10];
2203d8f9 590 sprintf(buf, "%s:%d", name, fid);
dfaf9b68 591 sq_save_data(sq2, strdup(buf));
bac4ceaa 592 }
593 }
5eaef520 594 EXEC SQL CLOSE f_cursor;
595
596 while (sq_get_data(sq, &group))
597 {
598 fid = atoi(strchr(group, ':') + 1);
599 *strchr(group, ':') = 0;
600
601 EXEC SQL DECLARE f_cursor2 CURSOR FOR
602 SELECT DISTINCT f.type, f.name, f.mach_id, f.rwaccess, f.mount,
603 f.comments, f.label, g.key
604 FROM filesys f, fsgroup g
605 WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
606 ORDER BY key, label;
607 EXEC SQL OPEN f_cursor2;
608 for (flag1 = 1; ; flag1++)
609 {
610 EXEC SQL FETCH f_cursor2 INTO :type, :loc, :id, :access, :mount,
dfaf9b68 611 :comments, :name, :key;
5eaef520 612 if (sqlca.sqlcode)
613 break;
614 strtrim(type);
615 if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
616 {
7ac48069 617 if ((mach = hash_lookup(machines, id)))
5eaef520 618 {
619 fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s %d\"\n",
620 group, HCLASS, HTYPE, type, strtrim(loc), mach,
621 strtrim(access), strtrim(mount), flag1);
bac4ceaa 622 }
5eaef520 623 }
624 else if (!strcmp(type, "AFS"))
625 {
626 fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s %d\"\n",
627 group, HCLASS, HTYPE, strtrim(loc), strtrim(access),
628 strtrim(mount), flag1);
629 }
630 else if (!strcmp(type, "ERR"))
631 {
632 fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
633 group, HCLASS, HTYPE, strtrim(comments));
bac4ceaa 634 }
635 }
5eaef520 636 EXEC SQL CLOSE f_cursor2;
637 free(group);
638 }
639 sq_destroy(sq);
640
641 while (sq_get_data(sq2, &group))
642 {
643 fid = atoi(strchr(group, ':') + 1);
644 *strchr(group, ':') = 0;
645 fprintf(out, "%s.filsys\t%s %s \"MUL", group, HCLASS, HTYPE);
646 EXEC SQL DECLARE f_cursor3 CURSOR FOR
647 SELECT DISTINCT f.label, g.key
648 FROM filesys f, fsgroup g
649 WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
650 ORDER BY key, label;
651 EXEC SQL OPEN f_cursor3;
652 while (1)
653 {
dfaf9b68 654 EXEC SQL FETCH f_cursor3 INTO :name, :key;
5eaef520 655 if (sqlca.sqlcode)
656 break;
657 fprintf(out, " %s", strtrim(name));
542bdacb 658 }
5eaef520 659 EXEC SQL CLOSE f_cursor3;
660 fprintf(out, "\"\n");
661 free(group);
662 }
663 sq_destroy(sq2);
664
665 EXEC SQL DECLARE a_cursor CURSOR FOR
666 SELECT name, trans
667 FROM alias
668 WHERE type = 'FILESYS';
669 EXEC SQL OPEN a_cursor;
670 while (1)
671 {
dfaf9b68 672 EXEC SQL FETCH a_cursor INTO :aname, :trans;
5eaef520 673 if (sqlca.sqlcode)
674 break;
2203d8f9 675 strtrim(aname);
676 strtrim(trans);
677 if (!valid(aname) || !valid(trans))
678 continue;
5eaef520 679 fprintf(out, "%s.filsys\t%s CNAME %s.filsys\n",
2203d8f9 680 aname, HCLASS, trans);
5eaef520 681 }
682 EXEC SQL CLOSE a_cursor;
683
684 EXEC SQL COMMIT;
685
686 if (fclose(out))
687 {
688 fprintf(stderr, "Unsuccessful close of filsys.db\n");
689 exit(MR_CCONFIG);
690 }
691 fix_file(outf);
692 return 1;
693sqlerr:
694 db_error(sqlca.sqlcode);
695 return 0;
bac4ceaa 696}
697
dfaf9b68 698int nbitsset(set_mask *set)
bac4ceaa 699{
5eaef520 700 int i, ret;
701 ret = 0;
702 for (i = 0; i < setsize * NSETBITS; i++)
703 {
bac4ceaa 704 if (SET_ISSET(i, set))
705 ret++;
5eaef520 706 }
707 return ret;
bac4ceaa 708}
709
710
5eaef520 711int do_cluster(void)
bac4ceaa 712{
5eaef520 713 FILE *out;
dfaf9b68 714 char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
715 char machbuf[MACHINE_NAME_SIZE], clubuf[CLUSTERS_NAME_SIZE], *p;
5eaef520 716 struct stat sb;
717 time_t ftime;
718 EXEC SQL BEGIN DECLARE SECTION;
719 int flag1, flag2, flag3, flag4, maxmach, maxclu, mid, cid, id;
dfaf9b68 720 char name[CLUSTERS_NAME_SIZE];
721 char label[SVC_SERV_LABEL_SIZE], data[SVC_SERV_CLUSTER_SIZE];
5eaef520 722 EXEC SQL END DECLARE SECTION;
723 set_mask **machs, *ms, *ps;
5eaef520 724
725 sprintf(outf, "%s/cluster.db", hesiod_dir);
726
727 if (stat(outf, &sb) == 0)
728 {
729 ftime = sb.st_mtime;
730 if (ModDiff (&flag1, "clusters", ftime)
731 || ModDiff (&flag2, "machine", ftime)
732 || ModDiff (&flag3, "mcmap", ftime)
733 || ModDiff (&flag4, "svc", ftime))
734 exit(MR_DATE);
735 if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0)
736 {
737 fprintf(stderr, "File cluster.db does not need to be rebuilt.\n");
738 return 0;
bac4ceaa 739 }
5eaef520 740 }
741
742 sprintf(outft, "%s~", outf);
743 out = fopen(outft, "w");
744 if (!out)
745 {
746 perror("cannot open cluster.db for write");
747 exit(MR_OCONFIG);
748 }
749
750 fprintf(stderr, "Building cluster.db\n");
751 get_mach();
752
753 EXEC SQL SELECT MAX(clu_id) INTO :maxclu FROM clusters;
754 maxclu++;
755 setsize = howmany(maxclu, NSETBITS);
756
757 EXEC SQL SELECT MAX(mach_id) INTO :maxmach FROM machine;
758 maxmach++;
759 machs = malloc((maxmach + 1) * sizeof(set_mask **));
760 memset(machs, 0, (maxmach + 1) * sizeof(int));
761
762 EXEC SQL DECLARE p_cursor CURSOR FOR
763 SELECT mach_id, clu_id
764 FROM mcmap
765 ORDER BY mach_id;
766 EXEC SQL OPEN p_cursor;
767 while (1)
768 {
769 EXEC SQL FETCH p_cursor INTO :mid, :cid;
770 if (sqlca.sqlcode)
771 break;
772 if (!(ms = machs[mid]))
773 {
774 ms = machs[mid] = SET_CREATE();
775 SET_ZERO(ms);
776 }
777 SET_SET(cid, ms);
778 }
779 EXEC SQL CLOSE p_cursor;
780
781 for (mid = 1; mid < maxmach; mid++)
782 {
783 if (!machs[mid])
784 continue;
785 ms = machs[mid];
786 if (nbitsset(ms) > 1)
787 {
ed7faf49 788 sprintf(clubuf, "mrinternal-%d", mid);
5eaef520 789 for (cid = 1; cid < maxclu; cid++)
790 {
791 if (SET_ISSET(cid, ms))
792 {
793 EXEC SQL DECLARE d_cursor CURSOR FOR
794 SELECT serv_label, serv_cluster
795 FROM svc
796 WHERE clu_id = :cid;
797 EXEC SQL OPEN d_cursor;
798 while (1)
799 {
dfaf9b68 800 EXEC SQL FETCH d_cursor INTO :label, :data;
5eaef520 801 if (sqlca.sqlcode)
802 break;
dfaf9b68 803 strtrim(label);
5eaef520 804 strtrim(data);
ed7faf49 805 fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
dfaf9b68 806 clubuf, HCLASS, HTYPE, label, data);
bac4ceaa 807 }
5eaef520 808 EXEC SQL CLOSE d_cursor;
bac4ceaa 809 }
810 }
5eaef520 811 }
812 else
813 {
5eaef520 814 for (cid = 1; cid < maxclu; cid++)
815 if (SET_ISSET(cid, ms))
816 break;
817
818 EXEC SQL SELECT name INTO :name FROM clusters WHERE clu_id = :cid;
819 strtrim(name);
2203d8f9 820 if (!valid(name))
821 continue;
ed7faf49 822 strcpy(clubuf, name);
bac4ceaa 823 }
824
5eaef520 825 if ((mach = hash_lookup(machines, mid)))
826 {
ed7faf49 827 fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
828 mach, HCLASS, clubuf);
5eaef520 829 for (p = machbuf; *mach && *mach != '.'; mach++)
830 *p++ = *mach;
ed7faf49 831 if (!strcasecmp(mach, ".mit.edu"))
5eaef520 832 {
ed7faf49 833 *p = '\0';
9c04b191 834 fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
ed7faf49 835 machbuf, HCLASS, clubuf);
5eaef520 836 }
bac4ceaa 837 }
5eaef520 838 for (id = mid + 1; id < maxmach; id++)
839 {
840 if ((ps = machs[id]) && !SET_CMP(ms, ps))
841 {
842 free(ps);
843 machs[id] = NULL;
844 if ((mach = hash_lookup(machines, id)))
845 {
ed7faf49 846 fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
847 mach, HCLASS, clubuf);
5eaef520 848 for (p = machbuf; *mach && *mach != '.'; mach++)
849 *p++ = *mach;
ed7faf49 850 if (!strcasecmp(mach, ".mit.edu"))
5eaef520 851 {
ed7faf49 852 *p = '\0';
9c04b191 853 fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
ed7faf49 854 machbuf, HCLASS, clubuf);
5eaef520 855 }
bac4ceaa 856 }
857 }
858 }
5eaef520 859 free(ms);
860 machs[mid] = NULL;
861 }
862
863 EXEC SQL DECLARE d_cursor2 CURSOR FOR
864 SELECT c.name, d.serv_label, d.serv_cluster
865 FROM svc d, clusters c
866 WHERE c.clu_id = d.clu_id;
867 EXEC SQL OPEN d_cursor2;
868 while (1)
869 {
dfaf9b68 870 EXEC SQL FETCH d_cursor2 INTO :name, :label, :data;
5eaef520 871 if (sqlca.sqlcode)
872 break;
873 strtrim(name);
2203d8f9 874 if (!valid(name))
875 continue;
dfaf9b68 876 strtrim(label);
5eaef520 877 strtrim(data);
878 fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
dfaf9b68 879 name, HCLASS, HTYPE, label, data);
5eaef520 880 }
881 free(machs);
882 EXEC SQL COMMIT;
883
884 if (fclose(out))
885 {
886 fprintf(stderr, "Unsuccessful close of cluster.db\n");
887 exit(MR_CCONFIG);
888 }
889 fix_file(outf);
890 return 1;
891sqlerr:
892 db_error(sqlca.sqlcode);
893 return 0;
bac4ceaa 894}
895
896
5eaef520 897int do_printcap(void)
bac4ceaa 898{
5eaef520 899 FILE *out;
dfaf9b68 900 char outf[MAXPATHLEN], outft[MAXPATHLEN];
5eaef520 901 struct stat sb;
902 time_t ftime;
903 EXEC SQL BEGIN DECLARE SECTION;
ed9a436f 904 char name[PRINTERS_NAME_SIZE], duplexname[PRINTERS_DUPLEXNAME_SIZE];
905 char rp[PRINTERS_RP_SIZE], type[PRINTERS_TYPE_SIZE];
88b66768 906 char duplexrp[PRINTERS_RP_SIZE], pskind[PRINTSERVERS_KIND_SIZE];
907 int flag1, flag2, ka, rm;
5eaef520 908 EXEC SQL END DECLARE SECTION;
88b66768 909 char *rmname;
5eaef520 910
911 sprintf(outf, "%s/printcap.db", hesiod_dir);
912
913 if (stat(outf, &sb) == 0)
914 {
915 ftime = sb.st_mtime;
88b66768 916 if (ModDiff (&flag1, "printers", ftime)
917 || ModDiff (&flag2, "printservers", ftime)
5eaef520 918 || ModDiff (&flag2, "machine", ftime))
919 exit(MR_DATE);
920 if (flag1 < 0 && flag2 < 0)
921 {
922 fprintf(stderr, "File printcap.db does not need to be rebuilt.\n");
923 return 0;
924 }
925 }
926
927 sprintf(outft, "%s~", outf);
928 out = fopen(outft, "w");
929 if (!out)
930 {
931 perror("cannot open printcap.db for write");
932 exit(MR_OCONFIG);
933 }
934
935 fprintf(stderr, "Building printcap.db\n");
936 get_mach();
937
938 EXEC SQL DECLARE p_cursor2 CURSOR FOR
88b66768 939 SELECT p.name, p.duplexname, p.type, p.rp, p.rm, p.ka, ps.kind
940 FROM printers p, printservers ps
941 WHERE p.rm = ps.mach_id;
5eaef520 942 EXEC SQL OPEN p_cursor2;
943 while (1)
944 {
ed9a436f 945 EXEC SQL FETCH p_cursor2 INTO :name, :duplexname, :type,
88b66768 946 :rp, :rm, :ka, :pskind;
5eaef520 947 if (sqlca.sqlcode)
948 break;
ed9a436f 949 if (!(rmname = hash_lookup(machines, rm)))
5eaef520 950 continue;
951 strtrim(name);
2203d8f9 952 if (!valid(name))
953 continue;
5eaef520 954 strtrim(rp);
88b66768 955 fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:",
956 name, HCLASS, HTYPE, name, rp, rmname, ka);
957
958 strtrim(pskind);
959 if (!strcmp(pskind, "BSD"))
960 fprintf(out, "auth=none:remote_support=RQM:");
961 else if (!strcmp(pskind, "ATHENA"))
00b3c5aa 962 {
963 fprintf(out, "auth=%s:az:remote_support=RQM:",
964 ka ? "kerberos4" : "none");
965 }
88b66768 966 else if (!strcmp(pskind, "LPRNG"))
967 fprintf(out, "auth=kerberos5:xn:");
968
969 fputs("\"\n", out);
bac4ceaa 970
ed9a436f 971 strtrim(duplexname);
972 if (!valid(duplexname))
973 continue;
974 if (!strcmp(strtrim(type), "ALIAS"))
5eaef520 975 {
ed9a436f 976 EXEC SQL SELECT duplexname INTO :duplexrp
977 FROM printers WHERE name = :rp;
978 strtrim(duplexrp);
5eaef520 979 }
ed9a436f 980 else
981 strcpy(duplexrp, duplexname);
88b66768 982 fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:",
ed9a436f 983 duplexname, HCLASS, HTYPE, duplexname, duplexrp,
88b66768 984 rmname, ka);
985
986 if (!strcmp(pskind, "BSD"))
987 fprintf(out, "auth=none:remote_support=RQM:");
988 else if (!strcmp(pskind, "ATHENA"))
00b3c5aa 989 {
990 fprintf(out, "auth=%s:az:remote_support=RQM:",
991 ka ? "kerberos4" : "none");
992 }
88b66768 993 else if (!strcmp(pskind, "LPRNG"))
994 fprintf(out, "auth=kerberos5:xn:");
995
996 fputs("\"\n", out);
5eaef520 997 }
ed9a436f 998 EXEC SQL CLOSE p_cursor2;
5eaef520 999
1000 EXEC SQL COMMIT;
1001
1002 if (fclose(out))
1003 {
ed9a436f 1004 fprintf(stderr, "Unsuccessful close of pcap.db\n");
5eaef520 1005 exit(MR_CCONFIG);
1006 }
1007 fix_file(outf);
1008 return 1;
1009sqlerr:
1010 db_error(sqlca.sqlcode);
1011 return 0;
bac4ceaa 1012}
1013
1014
5eaef520 1015int do_sloc(void)
bac4ceaa 1016{
5eaef520 1017 FILE *out;
dfaf9b68 1018 char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
5eaef520 1019 struct stat sb;
1020 time_t ftime;
1021 EXEC SQL BEGIN DECLARE SECTION;
dfaf9b68 1022 char service[SERVERHOSTS_SERVICE_SIZE];
5eaef520 1023 int flag1, flag2, id;
1024 EXEC SQL END DECLARE SECTION;
1025
1026 sprintf(outf, "%s/sloc.db", hesiod_dir);
1027
1028 if (stat(outf, &sb) == 0)
1029 {
1030 ftime = sb.st_mtime;
1031 if ((ModDiff (&flag1, "serverhosts", ftime)) ||
1032 (ModDiff (&flag2, "machine", ftime)))
1033 exit(MR_DATE);
1034 if (flag1 < 0 && flag2 < 0)
1035 {
1036 fprintf(stderr, "File sloc.db does not need to be rebuilt.\n");
1037 return 0;
1038 }
1039 }
1040
1041 sprintf(outft, "%s~", outf);
1042 out = fopen(outft, "w");
1043 if (!out)
1044 {
1045 perror("cannot open sloc.db for write");
1046 exit(MR_OCONFIG);
1047 }
1048
1049 fprintf(stderr, "Building sloc.db\n");
1050 get_mach();
1051
1052 EXEC SQL DECLARE s_cursor CURSOR FOR
1053 SELECT DISTINCT service, mach_id
1054 FROM serverhosts
1055 ORDER BY service;
1056 EXEC SQL OPEN s_cursor;
1057 while (1)
1058 {
1059 EXEC SQL FETCH s_cursor INTO :service, :id;
1060 if (sqlca.sqlcode)
1061 break;
1062 strtrim(service);
2203d8f9 1063 if (valid(service) && (mach = hash_lookup(machines, id)))
5eaef520 1064 fprintf(out, "%s.sloc\t%s %s %s\n", service, HCLASS, HTYPE, mach);
1065 }
1066 EXEC SQL CLOSE s_cursor;
1067
1068 EXEC SQL COMMIT;
1069
1070 if (fclose(out))
1071 {
1072 fprintf(stderr, "Unsuccessful close of sloc.db\n");
1073 exit(MR_CCONFIG);
1074 }
1075
1076 fix_file(outf);
1077 return 1;
1078sqlerr:
1079 db_error(sqlca.sqlcode);
1080 return 0;
bac4ceaa 1081}
1082
5eaef520 1083int do_service(void)
bac4ceaa 1084{
5eaef520 1085 FILE *out;
dfaf9b68 1086 char outf[MAXPATHLEN], outft[MAXPATHLEN];
5eaef520 1087 struct stat sb;
1088 time_t ftime;
1089 EXEC SQL BEGIN DECLARE SECTION;
dfaf9b68 1090 char service[SERVICES_NAME_SIZE], protocol[SERVICES_PROTOCOL_SIZE];
1091 char aname[ALIAS_NAME_SIZE], trans[ALIAS_TRANS_SIZE];
5eaef520 1092 int port, flag1;
1093 EXEC SQL END DECLARE SECTION;
1094
1095 sprintf(outf, "%s/service.db", hesiod_dir);
1096
1097 if (stat(outf, &sb) == 0)
1098 {
1099 ftime = sb.st_mtime;
1100 if (ModDiff (&flag1, "services", ftime))
1101 exit(MR_DATE);
1102 if (flag1 < 0)
1103 {
1104 fprintf(stderr, "File service.db does not need to be rebuilt.\n");
1105 return 0;
1106 }
1107 }
1108
1109 sprintf(outft, "%s~", outf);
1110 out = fopen(outft, "w");
1111 if (!out)
1112 {
1113 perror("cannot open service.db for write");
1114 exit(MR_OCONFIG);
1115 }
1116
1117 fprintf(stderr, "Building service.db\n");
1118
1119 EXEC SQL DECLARE s_cursor2 CURSOR FOR
1120 SELECT name, protocol, port
1121 FROM services;
1122 EXEC SQL OPEN s_cursor2;
1123 while (1)
1124 {
1125 EXEC SQL FETCH s_cursor2 INTO :service, :protocol, :port;
1126 if (sqlca.sqlcode)
1127 break;
1128 lowercase(protocol); /* Convert protocol to lowercase */
1129 strtrim(service);
2203d8f9 1130 if (!valid(service))
1131 continue;
5eaef520 1132 strtrim(protocol);
1133 fprintf(out, "%s.service\t%s %s \"%s %s %d\"\n",
1134 service, HCLASS, HTYPE, service, protocol, port);
1135 }
1136 EXEC SQL CLOSE s_cursor2;
1137
1138 EXEC SQL DECLARE a_cursor3 CURSOR FOR
1139 SELECT name, trans
1140 FROM alias
1141 WHERE type = 'SERVICE';
1142 EXEC SQL OPEN a_cursor3;
1143 while (1)
1144 {
dfaf9b68 1145 EXEC SQL FETCH a_cursor3 INTO :aname, :trans;
5eaef520 1146 if (sqlca.sqlcode)
1147 break;
dfaf9b68 1148 strtrim(aname);
1149 strtrim(trans);
2203d8f9 1150 if (!valid(aname) || !valid(trans))
1151 continue;
dfaf9b68 1152 fprintf(out, "%s.service\t%s CNAME %s.service\n", aname, HCLASS,
1153 trans);
5eaef520 1154 }
1155 EXEC SQL CLOSE a_cursor3;
1156
1157 EXEC SQL COMMIT;
1158
1159 if (fclose(out))
1160 {
1161 fprintf(stderr, "Unsuccessful close of service.db\n");
1162 exit(MR_CCONFIG);
1163 }
1164 fix_file(outf);
1165 return 1;
1166sqlerr:
1167 db_error(sqlca.sqlcode);
1168 return 0;
bac4ceaa 1169}
This page took 0.279541 seconds and 5 git commands to generate.