]> andersk Git - moira.git/blob - gen/hesiod.pc
second code style cleanup: void/void * usage, proper #includes. try to
[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[41], *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   int oneclu;
678
679   sprintf(outf, "%s/cluster.db", hesiod_dir);
680
681   if (stat(outf, &sb) == 0)
682     {
683       ftime = sb.st_mtime;
684       if (ModDiff (&flag1, "clusters", ftime)
685           || ModDiff (&flag2, "machine", ftime)
686           || ModDiff (&flag3, "mcmap", ftime)
687           || ModDiff (&flag4, "svc", ftime))
688         exit(MR_DATE);
689       if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0)
690         {
691           fprintf(stderr, "File cluster.db does not need to be rebuilt.\n");
692           return 0;
693         }
694     }
695
696   sprintf(outft, "%s~", outf);
697   out = fopen(outft, "w");
698   if (!out)
699     {
700       perror("cannot open cluster.db for write");
701       exit(MR_OCONFIG);
702     }
703
704   fprintf(stderr, "Building cluster.db\n");
705   get_mach();
706
707   EXEC SQL SELECT MAX(clu_id) INTO :maxclu FROM clusters;
708   maxclu++;
709   setsize = howmany(maxclu, NSETBITS);
710
711   EXEC SQL SELECT MAX(mach_id) INTO :maxmach FROM machine;
712   maxmach++;
713   machs = malloc((maxmach + 1) * sizeof(set_mask **));
714   memset(machs, 0, (maxmach + 1) * sizeof(int));
715
716   EXEC SQL DECLARE p_cursor CURSOR FOR
717     SELECT mach_id, clu_id
718     FROM mcmap
719     ORDER BY mach_id;
720   EXEC SQL OPEN p_cursor;
721   while (1)
722     {
723       EXEC SQL FETCH p_cursor INTO :mid, :cid;
724       if (sqlca.sqlcode)
725         break;
726       if (!(ms = machs[mid]))
727         {
728           ms = machs[mid] = SET_CREATE();
729           SET_ZERO(ms);
730         }
731       SET_SET(cid, ms);
732     }
733   EXEC SQL CLOSE p_cursor;
734
735   for (mid = 1; mid < maxmach; mid++)
736     {
737       if (!machs[mid])
738         continue;
739       ms = machs[mid];
740       if (nbitsset(ms) > 1)
741         {
742           oneclu = 0;
743           for (cid = 1; cid < maxclu; cid++)
744             {
745               if (SET_ISSET(cid, ms))
746                 {
747                   EXEC SQL DECLARE d_cursor CURSOR FOR
748                     SELECT serv_label, serv_cluster
749                     FROM svc
750                     WHERE clu_id = :cid;
751                   EXEC SQL OPEN d_cursor;
752                   while (1)
753                     {
754                       EXEC SQL FETCH d_cursor INTO :label2, :data;
755                       if (sqlca.sqlcode)
756                         break;
757                       strtrim(label2);
758                       strtrim(data);
759                       fprintf(out, "mrinternal-%d.cluster\t%s %s \"%s %s\"\n",
760                               mid, HCLASS, HTYPE, label2, data);
761                     }
762                   EXEC SQL CLOSE d_cursor;
763                 }
764             }
765         }
766       else
767         {
768           oneclu = 1;
769           for (cid = 1; cid < maxclu; cid++)
770             if (SET_ISSET(cid, ms))
771               break;
772
773           EXEC SQL SELECT name INTO :name FROM clusters WHERE clu_id = :cid;
774           strtrim(name);
775         }
776
777       if ((mach = hash_lookup(machines, mid)))
778         {
779           for (p = machbuf; *mach && *mach != '.'; mach++)
780             *p++ = *mach;
781           *p = '\0';
782           if (oneclu)
783             {
784               fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
785                       machbuf, HCLASS, name);
786             }
787           else
788             {
789               fprintf(out, "%s.cluster\t%s CNAME mrinternal-%d.cluster\n",
790                       machbuf, HCLASS, mid);
791             }
792         }
793       for (id = mid + 1; id < maxmach; id++)
794         {
795           if ((ps = machs[id]) && !SET_CMP(ms, ps))
796             {
797               free(ps);
798               machs[id] = NULL;
799               if ((mach = hash_lookup(machines, id)))
800                 {
801                   for (p = machbuf; *mach && *mach != '.'; mach++)
802                     *p++ = *mach;
803                   *p = '\0';
804                   if (oneclu)
805                     {
806                       fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
807                               machbuf, HCLASS, name);
808                     }
809                   else
810                     {
811                       fprintf(out,
812                               "%s.cluster\t%s CNAME mrinternal-%d.cluster\n",
813                               machbuf, HCLASS, mid);
814                     }
815                 }
816             }
817         }
818       free(ms);
819       machs[mid] = NULL;
820     }
821
822   EXEC SQL DECLARE d_cursor2 CURSOR FOR
823     SELECT c.name, d.serv_label, d.serv_cluster
824     FROM svc d, clusters c
825     WHERE c.clu_id = d.clu_id;
826   EXEC SQL OPEN d_cursor2;
827   while (1)
828     {
829       EXEC SQL FETCH d_cursor2 INTO :name, :label2, :data;
830       if (sqlca.sqlcode)
831         break;
832       strtrim(name);
833       strtrim(label2);
834       strtrim(data);
835       fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
836               name, HCLASS, HTYPE, label2, data);
837     }
838   free(machs);
839   EXEC SQL COMMIT;
840
841   if (fclose(out))
842     {
843       fprintf(stderr, "Unsuccessful close of cluster.db\n");
844       exit(MR_CCONFIG);
845     }
846   fix_file(outf);
847   return 1;
848 sqlerr:
849   db_error(sqlca.sqlcode);
850   return 0;
851 }
852
853
854 int do_printcap(void)
855 {
856   FILE *out;
857   char outf[64], outft[64];
858   struct stat sb;
859   time_t ftime;
860   EXEC SQL BEGIN DECLARE SECTION;
861   char name[17], rp[17], sd[33];
862   int flag1, flag2, ka, pc, rm, rq;
863   EXEC SQL END DECLARE SECTION;
864
865   sprintf(outf, "%s/printcap.db", hesiod_dir);
866
867   if (stat(outf, &sb) == 0)
868     {
869       ftime = sb.st_mtime;
870       if (ModDiff (&flag1, "printcap", ftime)
871           || ModDiff (&flag2, "machine", ftime))
872         exit(MR_DATE);
873       if (flag1 < 0 && flag2 < 0)
874         {
875           fprintf(stderr, "File printcap.db does not need to be rebuilt.\n");
876           return 0;
877         }
878     }
879
880   sprintf(outft, "%s~", outf);
881   out = fopen(outft, "w");
882   if (!out)
883     {
884       perror("cannot open printcap.db for write");
885       exit(MR_OCONFIG);
886     }
887
888   fprintf(stderr, "Building printcap.db\n");
889   get_mach();
890
891   EXEC SQL DECLARE p_cursor2 CURSOR FOR
892     SELECT name, rp, dir, mach_id, auth, price, quotaserver
893     FROM printcap;
894   EXEC SQL OPEN p_cursor2;
895   while (1)
896     {
897       EXEC SQL FETCH p_cursor2 INTO :name, :rp, :sd, :rm, :ka, :pc, :rq;
898       if (sqlca.sqlcode)
899         break;
900       if (!hash_lookup(machines, rm))
901         continue;
902       strtrim(name);
903       strtrim(rp);
904       strtrim(sd);
905       fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:sd=%s:ka#%d:pc#%d",
906               name, HCLASS, HTYPE, name, rp, (char *)hash_lookup(machines, rm),
907               sd, ka, pc);
908       if (rq && hash_lookup(machines, rq))
909         fprintf(out, ":rq=%s\"\n", (char *)hash_lookup(machines, rq));
910       else
911         fputs("\"\n", out);
912     }
913   EXEC SQL CLOSE p_cursor2;
914
915   EXEC SQL COMMIT;
916
917   if (fclose(out))
918     {
919       fprintf(stderr, "Unsuccessful close of pcap.db\n");
920       exit(MR_CCONFIG);
921     }
922   fix_file(outf);
923   return 1;
924 sqlerr:
925   db_error(sqlca.sqlcode);
926   return 0;
927 }
928
929
930 int do_palladium(void)
931 {
932   FILE *out;
933   char outf[64], outft[64];
934   struct stat sb;
935   time_t ftime;
936   EXEC SQL BEGIN DECLARE SECTION;
937   char name[33], trans[129];
938   int flag, flag1, identifier, rm;
939   EXEC SQL END DECLARE SECTION;
940
941   sprintf(outf, "%s/palladium.db", hesiod_dir);
942
943   if (stat(outf, &sb) == 0)
944     {
945       ftime = sb.st_mtime;
946       if ((ModDiff (&flag, "palladium", ftime)) ||
947           (ModDiff (&flag1, "alias", ftime)))
948         exit(MR_DATE);
949       if (flag < 0 && flag1 < 0)
950         {
951           fprintf(stderr, "File palladium.db does not need to be rebuilt.\n");
952           return 0;
953         }
954     }
955
956   sprintf(outft, "%s~", outf);
957   out = fopen(outft, "w");
958   if (!out)
959     {
960       perror("cannot open palladium.db for write");
961       exit(MR_OCONFIG);
962     }
963
964   fprintf(stderr, "Building palladium.db\n");
965   get_mach();
966
967   EXEC SQL DECLARE p_cursor3 CURSOR FOR
968     SELECT name, identifier, mach_id
969     FROM palladium;
970   EXEC SQL OPEN p_cursor3;
971   while (1)
972     {
973       EXEC SQL FETCH p_cursor3 INTO :name, :identifier, :rm;
974       if (sqlca.sqlcode)
975         break;
976       if (!hash_lookup(machines, rm))
977         break;
978       strtrim(name);
979       fprintf(out, "%s.palladium\t%s %s \"%s %d %s interface directory\"\n",
980               name, HCLASS, HTYPE, (char *)hash_lookup(machines, rm),
981               identifier, name);
982     }
983   EXEC SQL CLOSE p_cursor3;
984
985   EXEC SQL DECLARE a_cursor2 CURSOR FOR
986     SELECT name, trans
987     FROM alias
988     WHERE type = 'PALLADIUM';
989   EXEC SQL OPEN a_cursor2;
990   while (1)
991     {
992       EXEC SQL FETCH a_cursor2 INTO :name, :trans;
993       if (sqlca.sqlcode)
994         break;
995       strtrim(name);
996       strtrim(trans);
997       fprintf(out, "%s.palladium\t%s %s \"%s\"\n", name, HCLASS, HTYPE, trans);
998     }
999   EXEC SQL CLOSE a_cursor2;
1000
1001   EXEC SQL COMMIT;
1002
1003   if (fclose(out))
1004     {
1005       fprintf(stderr, "Unsuccessful close of palladium.db\n");
1006       exit(MR_CCONFIG);
1007     }
1008   fix_file(outf);
1009   return 1;
1010 sqlerr:
1011   db_error(sqlca.sqlcode);
1012   return 0;
1013 }
1014
1015
1016 int do_sloc(void)
1017 {
1018   FILE *out;
1019   char outf[64], outft[64], *mach;
1020   struct stat sb;
1021   time_t ftime;
1022   EXEC SQL BEGIN DECLARE SECTION;
1023   char service[17];
1024   int flag1, flag2, id;
1025   EXEC SQL END DECLARE SECTION;
1026
1027   sprintf(outf, "%s/sloc.db", hesiod_dir);
1028
1029   if (stat(outf, &sb) == 0)
1030     {
1031       ftime = sb.st_mtime;
1032       if ((ModDiff (&flag1, "serverhosts", ftime)) ||
1033           (ModDiff (&flag2, "machine", ftime)))
1034         exit(MR_DATE);
1035       if (flag1 < 0 && flag2 < 0)
1036         {
1037           fprintf(stderr, "File sloc.db does not need to be rebuilt.\n");
1038           return 0;
1039         }
1040     }
1041
1042   sprintf(outft, "%s~", outf);
1043   out = fopen(outft, "w");
1044   if (!out)
1045     {
1046       perror("cannot open sloc.db for write");
1047       exit(MR_OCONFIG);
1048     }
1049
1050   fprintf(stderr, "Building sloc.db\n");
1051   get_mach();
1052
1053   EXEC SQL DECLARE s_cursor CURSOR FOR
1054     SELECT DISTINCT service, mach_id
1055     FROM serverhosts
1056     ORDER BY service;
1057   EXEC SQL OPEN s_cursor;
1058   while (1)
1059     {
1060       EXEC SQL FETCH s_cursor INTO :service, :id;
1061       if (sqlca.sqlcode)
1062         break;
1063       strtrim(service);
1064       if ((mach = hash_lookup(machines, id)))
1065         fprintf(out, "%s.sloc\t%s %s %s\n", service, HCLASS, HTYPE, mach);
1066     }
1067   EXEC SQL CLOSE s_cursor;
1068
1069   EXEC SQL COMMIT;
1070
1071   if (fclose(out))
1072     {
1073       fprintf(stderr, "Unsuccessful close of sloc.db\n");
1074       exit(MR_CCONFIG);
1075     }
1076
1077   fix_file(outf);
1078   return 1;
1079 sqlerr:
1080   db_error(sqlca.sqlcode);
1081   return 0;
1082 }
1083
1084 int do_service(void)
1085 {
1086   FILE *out;
1087   char outf[64], outft[64];
1088   struct stat sb;
1089   time_t ftime;
1090   EXEC SQL BEGIN DECLARE SECTION;
1091   char service[33], protocol[9], altserv[129];
1092   int port, flag1;
1093   EXEC SQL END DECLARE SECTION;
1094
1095   sprintf(outf, "%s/service.db", hesiod_dir);
1096
1097   if (stat(outf, &sb) == 0)
1098     {
1099       ftime = sb.st_mtime;
1100       if (ModDiff (&flag1, "services", ftime))
1101         exit(MR_DATE);
1102       if (flag1 < 0)
1103         {
1104           fprintf(stderr, "File service.db does not need to be rebuilt.\n");
1105           return 0;
1106         }
1107     }
1108
1109   sprintf(outft, "%s~", outf);
1110   out = fopen(outft, "w");
1111   if (!out)
1112     {
1113       perror("cannot open service.db for write");
1114       exit(MR_OCONFIG);
1115     }
1116
1117   fprintf(stderr, "Building service.db\n");
1118
1119   EXEC SQL DECLARE s_cursor2 CURSOR FOR
1120     SELECT name, protocol, port
1121     FROM services;
1122   EXEC SQL OPEN s_cursor2;
1123   while (1)
1124     {
1125       EXEC SQL FETCH s_cursor2 INTO :service, :protocol, :port;
1126       if (sqlca.sqlcode)
1127         break;
1128       lowercase(protocol);      /* Convert protocol to lowercase */
1129       strtrim(service);
1130       strtrim(protocol);
1131       fprintf(out, "%s.service\t%s %s \"%s %s %d\"\n",
1132               service, HCLASS, HTYPE, service, protocol, port);
1133     }
1134   EXEC SQL CLOSE s_cursor2;
1135
1136   EXEC SQL DECLARE a_cursor3 CURSOR FOR
1137     SELECT name, trans
1138     FROM alias
1139     WHERE type = 'SERVICE';
1140   EXEC SQL OPEN a_cursor3;
1141   while (1)
1142     {
1143       EXEC SQL FETCH a_cursor3 INTO :service, :altserv;
1144       if (sqlca.sqlcode)
1145         break;
1146       strtrim(service);
1147       strtrim(altserv);
1148       fprintf(out, "%s.service\t%s CNAME %s.service\n", service, HCLASS,
1149               altserv);
1150     }
1151   EXEC SQL CLOSE a_cursor3;
1152
1153   EXEC SQL COMMIT;
1154
1155   if (fclose(out))
1156     {
1157       fprintf(stderr, "Unsuccessful close of service.db\n");
1158       exit(MR_CCONFIG);
1159     }
1160   fix_file(outf);
1161   return 1;
1162 sqlerr:
1163   db_error(sqlca.sqlcode);
1164   return 0;
1165 }
This page took 0.135989 seconds and 5 git commands to generate.