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