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