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