]> andersk Git - moira.git/blob - gen/hesiod.pc
Remove ModDiff(). unixtime() moved from moddiff.pc to util.c.
[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 ""
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 (~78) [derived empirically]
41  * (it used to be 446 with older versions of bind)
42  */
43 #define MAXHESSIZE 434
44
45 char hesiod_dir[MAXPATHLEN];
46
47 #define min(x, y)       ((x) < (y) ? (x) : (y))
48 struct hash *machines = NULL;
49 struct hash *users = NULL;
50 char *whoami = "hesiod.gen";
51 char *db = "moira/moira";
52
53 struct grp {
54   struct grp *next;
55   char *lid;
56 };
57 struct user {
58   char name[USERS_LOGIN_SIZE];
59   struct grp *lists;
60 };
61
62 /*
63  * Modified from sys/types.h:
64  */
65 int setsize;    /* = howmany(setbits, NSETBITS) */
66
67 typedef long    set_mask;
68 #define NSETBITS        (sizeof(set_mask) * NBBY)       /* bits per mask */
69 #ifndef howmany
70 #define howmany(x, y)   (((x) + ((y) - 1)) / (y))
71 #endif
72
73 #define SET_SET(n, p)   ((p)[(n)/NSETBITS] |=  (1 << ((n) % NSETBITS)))
74 #define SET_CLR(n, p)   ((p)[(n)/NSETBITS] &= ~(1 << ((n) % NSETBITS)))
75 #define SET_ISSET(n, p) ((p)[(n)/NSETBITS] &   (1 << ((n) % NSETBITS)))
76 #define SET_CREATE()    (malloc(setsize * sizeof(set_mask)))
77 #define SET_ZERO(p)     memset(p, 0, setsize * sizeof(set_mask))
78 #define SET_CMP(p1, p2) (memcmp(p1, p2, setsize * sizeof(set_mask)))
79
80
81 void get_mach(void);
82 int nbitsset(set_mask *set);
83 int valid(char *name);
84
85 int do_passwd(void);
86 int do_groups(void);
87 int do_filsys(void);
88 int do_cluster(void);
89 int do_printcap(void);
90 int do_sloc(void);
91 int do_service(void);
92
93 int main(int argc, char **argv)
94 {
95   char cmd[64];
96   struct stat sb;
97   int changed = 0;
98
99   if (argc > 2)
100     {
101       fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
102       exit(MR_ARGS);
103     }
104
105   initialize_sms_error_table();
106   sprintf(hesiod_dir, "%s/%s", DCM_DIR, HESIOD_SUBDIR);
107
108   EXEC SQL CONNECT :db;
109
110   changed = do_passwd();
111   changed += do_filsys();
112   changed += do_cluster();
113   changed += do_printcap();
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       strtrim(name);
160       if (!valid(name))
161         continue;
162       hash_store(machines, id, strdup(name));
163     }
164   if (sqlca.sqlcode < 0)
165     db_error(sqlca.sqlcode);
166   EXEC SQL CLOSE m_cursor;
167   EXEC SQL COMMIT;
168 }
169
170
171 /* Determine whether or not a name is a valid DNS label.
172    (Can't start or end with . or have two .s in a row) */
173 int valid(char *name)
174 {
175   int sawdot;
176
177   for (sawdot = 1; *name; name++)
178     {
179       if (*name == '.')
180         {
181           if (sawdot)
182             return 0;
183           else
184             sawdot = 1;
185         }
186       else
187         sawdot = 0;
188     }
189   return !sawdot;
190 }
191
192
193 int do_passwd(void)
194 {
195   FILE *pout, *uout, *bout;
196   char poutf[MAXPATHLEN], uoutf[MAXPATHLEN], poutft[MAXPATHLEN];
197   char uoutft[MAXPATHLEN], boutf[MAXPATHLEN], boutft[MAXPATHLEN];
198   struct user *u;
199   char *mach;
200   EXEC SQL BEGIN DECLARE SECTION;
201   char login[USERS_LOGIN_SIZE], shell[USERS_SHELL_SIZE];
202   char fullname[USERS_FULLNAME_SIZE], oa[USERS_OFFICE_ADDR_SIZE];
203   char op[USERS_OFFICE_PHONE_SIZE], hp[USERS_HOME_PHONE_SIZE];
204   char nn[USERS_NICKNAME_SIZE];
205   int uid, id, pid, iid, mid, status;
206   EXEC SQL END DECLARE SECTION;
207
208   sprintf(poutf, "%s/passwd.db", hesiod_dir);
209   sprintf(uoutf, "%s/uid.db", hesiod_dir);
210   sprintf(boutf, "%s/pobox.db", hesiod_dir);
211
212   sprintf(poutft, "%s~", poutf);
213   pout = fopen(poutft, "w");
214   if (!pout)
215     {
216       perror("cannot open passwd.db~ for write");
217       exit(MR_OCONFIG);
218     }
219   sprintf(uoutft, "%s~", uoutf);
220   uout = fopen(uoutft, "w");
221   if (!uout)
222     {
223       perror("cannot open uid.db~ for write");
224       exit(MR_OCONFIG);
225     }
226   sprintf(boutft, "%s~", boutf);
227   bout = fopen(boutft, "w");
228   if (!bout)
229     {
230       perror("cannot open pobox.db for write");
231       exit(MR_OCONFIG);
232     }
233
234   fprintf(stderr, "Building passwd.db, uid.db, and pobox.db\n");
235   get_mach();
236
237   users = create_hash(12001);
238   EXEC SQL DECLARE u_cursor CURSOR FOR
239     SELECT login, unix_uid, shell, fullname, nickname, office_addr,
240     office_phone, home_phone, users_id, pop_id, imap_id, status
241     FROM users
242     WHERE status = 1 OR status = 2 OR status = 5 OR status = 6
243     ORDER BY users_id;
244   EXEC SQL OPEN u_cursor;
245   while (1)
246     {
247       EXEC SQL FETCH u_cursor INTO :login, :uid, :shell, :fullname, :nn,
248         :oa, :op, :hp, :id, :pid, :iid, :status;
249       if (sqlca.sqlcode)
250         break;
251       strtrim(login);
252       dequote(fullname);
253       dequote(nn);
254       dequote(oa);
255       dequote(op);
256       dequote(hp);
257       dequote(shell);
258       u = malloc(sizeof(struct user));
259       strcpy(u->name, login);
260       u->lists = NULL;
261       hash_store(users, id, u);
262       if (status == 1 || status == 2)
263         {
264           fprintf(pout, "%s.passwd\t%s %s \"%s:*:%d:101:%s,%s,%s,%s,%s:/mit/%s:%s\"\n",
265                   login, HCLASS, HTYPE, login, uid, fullname, nn, oa,
266                   op, hp, login, shell);
267           fprintf(uout, "%d.uid\t%s CNAME %s.passwd\n", uid, HCLASS, login);
268         }
269
270       if (iid != 0)
271         {
272           EXEC SQL SELECT mach_id INTO :mid FROM filesys
273             WHERE filsys_id = :iid AND type = 'IMAP';
274           if (sqlca.sqlcode == 0)
275             pid = mid;
276         }
277
278       if (pid != 0 && (mach = hash_lookup(machines, pid)))
279         {
280           fprintf(bout, "%s.pobox\t%s %s \"POP %s %s\"\n",
281                   login, HCLASS, HTYPE, mach, login);
282         }
283     }
284   if (sqlca.sqlcode < 0)
285     db_error(sqlca.sqlcode);
286   EXEC SQL CLOSE u_cursor;
287   EXEC SQL COMMIT;
288
289   if (fclose(pout) || fclose(uout) || fclose(bout))
290     {
291       fprintf(stderr, "Unsuccessful file close of passwd.db, uid.db, or pobox.db\n");
292       exit(MR_CCONFIG);
293     }
294   fix_file(poutf);
295   fix_file(uoutf);
296   fix_file(boutf);
297   return 1;
298 }
299
300
301 int do_groups(void)
302 {
303   FILE *iout, *gout, *lout;
304   char ioutf[MAXPATHLEN], goutf[MAXPATHLEN], loutf[MAXPATHLEN];
305   char buf[MAXPATHLEN], *l;
306   struct hash *groups;
307   struct bucket *b, **p;
308   struct grp *g;
309   struct user *u;
310   EXEC SQL BEGIN DECLARE SECTION;
311   char name[LIST_NAME_SIZE];
312   int gid, id, lid, len;
313   EXEC SQL END DECLARE SECTION;
314
315   /* open files */
316   sprintf(ioutf, "%s/gid.db", hesiod_dir);
317   sprintf(goutf, "%s/group.db", hesiod_dir);
318   sprintf(loutf, "%s/grplist.db", hesiod_dir);
319
320   sprintf(buf, "%s~", ioutf);
321   iout = fopen(buf, "w");
322   if (!iout)
323     {
324       perror("cannot open gid.db for write");
325       exit(MR_OCONFIG);
326     }
327   sprintf(buf, "%s~", goutf);
328   gout = fopen(buf, "w");
329   if (!gout)
330     {
331       perror("cannot open group.db for write");
332       exit(MR_OCONFIG);
333     }
334   sprintf(buf, "%s~", loutf);
335   lout = fopen(buf, "w");
336   if (!lout)
337     {
338       perror("cannot open grplist.db for write");
339       exit(MR_OCONFIG);
340     }
341
342   fprintf(stderr, "Building gid.db, group.db, and grplist.db\n");
343
344   /* make space for group list */
345   groups = create_hash(15001);
346
347   /* The following WHENEVER is declarative, not executed,
348    * and applies for the remainder of this file only.
349    */
350   EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
351
352   EXEC SQL DECLARE l_cursor CURSOR FOR
353     SELECT name, gid, list_id
354     FROM list
355     WHERE grouplist != 0 AND active != 0
356     ORDER BY list_id;
357   EXEC SQL OPEN l_cursor;
358   while (1)
359     {
360       char buf[LIST_NAME_SIZE + 10];
361
362       EXEC SQL FETCH l_cursor INTO :name, :gid, :lid;
363       if (sqlca.sqlcode)
364         break;
365       strtrim(name);
366       if (!valid(name))
367         continue;
368       sprintf(buf, "%s:%d", name, gid);
369       hash_store(groups, lid, strdup(buf));
370       fprintf(iout, "%d.gid\t%s CNAME %s.group\n", gid, HCLASS, name);
371       fprintf(gout, "%s.group\t%s %s \"%s:*:%d:\"\n",
372               name, HCLASS, HTYPE, name, gid);
373     }
374   EXEC SQL CLOSE l_cursor;
375
376   fflush(iout);
377   fflush(gout);
378
379   /* now do grplists */
380   if (!users)
381     {
382       users = create_hash(12001);
383       EXEC SQL DECLARE u_cursor2 CURSOR FOR
384         SELECT users_id, login
385         FROM users
386         WHERE status = 1 OR status = 2;
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 m.list_id, m.member_id
403     FROM imembers m, list l 
404     WHERE m.member_type = 'USER'
405     AND m.list_id = l.list_id AND l.grouplist = 1 AND l.nfsgroup = 1;
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 save_queue *sq, *sq2;
473   EXEC SQL BEGIN DECLARE SECTION;
474   char name[FILESYS_LABEL_SIZE], type[FILESYS_TYPE_SIZE];
475   char loc[FILESYS_NAME_SIZE], access[FILESYS_RWACCESS_SIZE];
476   char mount[FILESYS_MOUNT_SIZE], comments[FILESYS_COMMENTS_SIZE];
477   char key[FSGROUP_KEY_SIZE];
478   char aname[ALIAS_NAME_SIZE], trans[ALIAS_TRANS_SIZE];
479   int flag, id, fid;
480   EXEC SQL END DECLARE SECTION;
481
482   sprintf(outf, "%s/filsys.db", hesiod_dir);
483
484   sprintf(outft, "%s~", outf);
485   out = fopen(outft, "w");
486   if (!out)
487     {
488       perror("cannot open filsys.db for write");
489       exit(MR_OCONFIG);
490     }
491
492   fprintf(stderr, "Building filsys.db\n");
493   get_mach();
494   sq = sq_create();
495   sq2 = sq_create();
496
497   EXEC SQL DECLARE f_cursor CURSOR FOR
498     SELECT label, type, name, mach_id, rwaccess, mount, comments, filsys_id
499     FROM filesys
500     ORDER BY filsys_id;
501   EXEC SQL OPEN f_cursor;
502   while (1)
503     {
504       EXEC SQL FETCH f_cursor INTO :name, :type, :loc, :id, :access,
505         :mount, :comments, :fid;
506       if (sqlca.sqlcode)
507         break;
508       strtrim(name);
509       if (!valid(name))
510         continue;
511       strtrim(type);
512       if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
513         {
514           if ((mach = hash_lookup(machines, id)))
515             {
516               fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s\"\n",
517                       name, HCLASS, HTYPE, type, strtrim(loc),
518                       mach, strtrim(access), strtrim(mount));
519             }
520         }
521       else if (!strcmp(type, "AFS"))
522         {
523           fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s\"\n",
524                   name, HCLASS, HTYPE, strtrim(loc),
525                   strtrim(access), strtrim(mount));
526         }
527       else if (!strcmp(type, "ERR"))
528         {
529           fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
530                   name, HCLASS, HTYPE, strtrim(comments));
531         }
532       else if (!strcmp(type, "FSGROUP"))
533         {
534           char buf[FILESYS_NAME_SIZE + 10];
535           sprintf(buf, "%s:%d", name, fid);
536           sq_save_data(sq, strdup(buf));
537         }
538       else if (!strcmp(type, "MUL"))
539         {
540           char buf[FILESYS_NAME_SIZE + 10];
541           sprintf(buf, "%s:%d", name, fid);
542           sq_save_data(sq2, strdup(buf));
543         }
544     }
545   EXEC SQL CLOSE f_cursor;
546
547   while (sq_get_data(sq, &group))
548     {
549       fid = atoi(strchr(group, ':') + 1);
550       *strchr(group, ':') = 0;
551
552       EXEC SQL DECLARE f_cursor2 CURSOR FOR
553         SELECT DISTINCT f.type, f.name, f.mach_id, f.rwaccess, f.mount,
554         f.comments, f.label, g.key
555         FROM filesys f, fsgroup g
556         WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
557         ORDER BY key, label;
558       EXEC SQL OPEN f_cursor2;
559       for (flag = 1; ; flag++)
560         {
561           EXEC SQL FETCH f_cursor2 INTO :type, :loc, :id, :access, :mount,
562             :comments, :name, :key;
563           if (sqlca.sqlcode)
564             break;
565           strtrim(type);
566           if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
567             {
568               if ((mach = hash_lookup(machines, id)))
569                 {
570                   fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s %d\"\n",
571                           group, HCLASS, HTYPE, type, strtrim(loc), mach,
572                           strtrim(access), strtrim(mount), flag);
573                 }
574             }
575           else if (!strcmp(type, "AFS"))
576             {
577               fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s %d\"\n",
578                       group, HCLASS, HTYPE, strtrim(loc), strtrim(access),
579                       strtrim(mount), flag);
580             }
581           else if (!strcmp(type, "ERR"))
582             {
583               fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
584                       group, HCLASS, HTYPE, strtrim(comments));
585             }
586         }
587       EXEC SQL CLOSE f_cursor2;
588       free(group);
589     }
590   sq_destroy(sq);
591
592   while (sq_get_data(sq2, &group))
593     {
594       fid = atoi(strchr(group, ':') + 1);
595       *strchr(group, ':') = 0;
596       fprintf(out, "%s.filsys\t%s %s \"MUL", group, HCLASS, HTYPE);
597       EXEC SQL DECLARE f_cursor3 CURSOR FOR
598         SELECT DISTINCT f.label, g.key
599         FROM filesys f, fsgroup g
600         WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
601         ORDER BY key, label;
602       EXEC SQL OPEN f_cursor3;
603       while (1)
604         {
605           EXEC SQL FETCH f_cursor3 INTO :name, :key;
606           if (sqlca.sqlcode)
607             break;
608           fprintf(out, " %s", strtrim(name));
609         }
610       EXEC SQL CLOSE f_cursor3;
611       fprintf(out, "\"\n");
612       free(group);
613     }
614   sq_destroy(sq2);
615
616   EXEC SQL DECLARE a_cursor CURSOR FOR
617     SELECT name, trans
618     FROM alias
619     WHERE type = 'FILESYS';
620   EXEC SQL OPEN a_cursor;
621   while (1)
622     {
623       EXEC SQL FETCH a_cursor INTO :aname, :trans;
624       if (sqlca.sqlcode)
625         break;
626       strtrim(aname);
627       strtrim(trans);
628       if (!valid(aname) || !valid(trans))
629         continue;
630       fprintf(out, "%s.filsys\t%s CNAME %s.filsys\n",
631               aname, HCLASS, trans);
632     }
633   EXEC SQL CLOSE a_cursor;
634
635   EXEC SQL COMMIT;
636
637   if (fclose(out))
638     {
639       fprintf(stderr, "Unsuccessful close of filsys.db\n");
640       exit(MR_CCONFIG);
641     }
642   fix_file(outf);
643   return 1;
644 sqlerr:
645   db_error(sqlca.sqlcode);
646   return 0;
647 }
648
649 int nbitsset(set_mask *set)
650 {
651   int i, ret;
652   ret = 0;
653   for (i = 0; i < setsize * NSETBITS; i++)
654     {
655       if (SET_ISSET(i, set))
656         ret++;
657     }
658   return ret;
659 }
660
661
662 int do_cluster(void)
663 {
664   FILE *out;
665   char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
666   char machbuf[MACHINE_NAME_SIZE], clubuf[CLUSTERS_NAME_SIZE], *p;
667   EXEC SQL BEGIN DECLARE SECTION;
668   int maxmach, maxclu, mid, cid, id;
669   char name[CLUSTERS_NAME_SIZE];
670   char label[SVC_SERV_LABEL_SIZE], data[SVC_SERV_CLUSTER_SIZE];
671   EXEC SQL END DECLARE SECTION;
672   set_mask **machs, *ms, *ps;
673
674   sprintf(outf, "%s/cluster.db", hesiod_dir);
675
676   sprintf(outft, "%s~", outf);
677   out = fopen(outft, "w");
678   if (!out)
679     {
680       perror("cannot open cluster.db for write");
681       exit(MR_OCONFIG);
682     }
683
684   fprintf(stderr, "Building cluster.db\n");
685   get_mach();
686
687   EXEC SQL SELECT MAX(clu_id) INTO :maxclu FROM clusters;
688   maxclu++;
689   setsize = howmany(maxclu, NSETBITS);
690
691   EXEC SQL SELECT MAX(mach_id) INTO :maxmach FROM machine;
692   maxmach++;
693   machs = malloc((maxmach + 1) * sizeof(set_mask **));
694   memset(machs, 0, (maxmach + 1) * sizeof(int));
695
696   EXEC SQL DECLARE p_cursor CURSOR FOR
697     SELECT mach_id, clu_id
698     FROM mcmap
699     ORDER BY mach_id;
700   EXEC SQL OPEN p_cursor;
701   while (1)
702     {
703       EXEC SQL FETCH p_cursor INTO :mid, :cid;
704       if (sqlca.sqlcode)
705         break;
706       if (!(ms = machs[mid]))
707         {
708           ms = machs[mid] = SET_CREATE();
709           SET_ZERO(ms);
710         }
711       SET_SET(cid, ms);
712     }
713   EXEC SQL CLOSE p_cursor;
714
715   for (mid = 1; mid < maxmach; mid++)
716     {
717       if (!machs[mid])
718         continue;
719       ms = machs[mid];
720       if (nbitsset(ms) > 1)
721         {
722           sprintf(clubuf, "mrinternal-%d", mid);
723           for (cid = 1; cid < maxclu; cid++)
724             {
725               if (SET_ISSET(cid, ms))
726                 {
727                   EXEC SQL DECLARE d_cursor CURSOR FOR
728                     SELECT serv_label, serv_cluster
729                     FROM svc
730                     WHERE clu_id = :cid;
731                   EXEC SQL OPEN d_cursor;
732                   while (1)
733                     {
734                       EXEC SQL FETCH d_cursor INTO :label, :data;
735                       if (sqlca.sqlcode)
736                         break;
737                       strtrim(label);
738                       strtrim(data);
739                       fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
740                               clubuf, HCLASS, HTYPE, label, data);
741                     }
742                   EXEC SQL CLOSE d_cursor;
743                 }
744             }
745         }
746       else
747         {
748           for (cid = 1; cid < maxclu; cid++)
749             if (SET_ISSET(cid, ms))
750               break;
751
752           EXEC SQL SELECT name INTO :name FROM clusters WHERE clu_id = :cid;
753           strtrim(name);
754           if (!valid(name))
755             continue;
756           strcpy(clubuf, name);
757         }
758
759       if ((mach = hash_lookup(machines, mid)))
760         {
761           fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
762                   mach, HCLASS, clubuf);
763           for (p = machbuf; *mach && *mach != '.'; mach++)
764             *p++ = *mach;
765           if (!strcasecmp(mach, ".mit.edu"))
766             {
767               *p = '\0';
768               fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
769                       machbuf, HCLASS, clubuf);
770             }
771         }
772       for (id = mid + 1; id < maxmach; id++)
773         {
774           if ((ps = machs[id]) && !SET_CMP(ms, ps))
775             {
776               free(ps);
777               machs[id] = NULL;
778               if ((mach = hash_lookup(machines, id)))
779                 {
780                   fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
781                           mach, HCLASS, clubuf);
782                   for (p = machbuf; *mach && *mach != '.'; mach++)
783                     *p++ = *mach;
784                   if (!strcasecmp(mach, ".mit.edu"))
785                     {
786                       *p = '\0';
787                       fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
788                               machbuf, HCLASS, clubuf);
789                     }
790                 }
791             }
792         }
793       free(ms);
794       machs[mid] = NULL;
795     }
796
797   EXEC SQL DECLARE d_cursor2 CURSOR FOR
798     SELECT c.name, d.serv_label, d.serv_cluster
799     FROM svc d, clusters c
800     WHERE c.clu_id = d.clu_id;
801   EXEC SQL OPEN d_cursor2;
802   while (1)
803     {
804       EXEC SQL FETCH d_cursor2 INTO :name, :label, :data;
805       if (sqlca.sqlcode)
806         break;
807       strtrim(name);
808       if (!valid(name))
809         continue;
810       strtrim(label);
811       strtrim(data);
812       fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
813               name, HCLASS, HTYPE, label, data);
814     }
815   free(machs);
816   EXEC SQL COMMIT;
817
818   if (fclose(out))
819     {
820       fprintf(stderr, "Unsuccessful close of cluster.db\n");
821       exit(MR_CCONFIG);
822     }
823   fix_file(outf);
824   return 1;
825 sqlerr:
826   db_error(sqlca.sqlcode);
827   return 0;
828 }
829
830
831 int do_printcap(void)
832 {
833   FILE *out;
834   char outf[MAXPATHLEN], outft[MAXPATHLEN];
835   EXEC SQL BEGIN DECLARE SECTION;
836   char name[PRINTERS_NAME_SIZE], duplexname[PRINTERS_DUPLEXNAME_SIZE];
837   char rp[PRINTERS_RP_SIZE], type[PRINTERS_TYPE_SIZE];
838   char duplexrp[PRINTERS_RP_SIZE], pskind[PRINTSERVERS_KIND_SIZE];
839   int ka, rm, mc;
840   EXEC SQL END DECLARE SECTION;
841   char *rmname;
842
843   sprintf(outf, "%s/printcap.db", hesiod_dir);
844
845   sprintf(outft, "%s~", outf);
846   out = fopen(outft, "w");
847   if (!out)
848     {
849       perror("cannot open printcap.db for write");
850       exit(MR_OCONFIG);
851     }
852
853   fprintf(stderr, "Building printcap.db\n");
854   get_mach();
855
856   EXEC SQL DECLARE p_cursor2 CURSOR FOR
857     SELECT p.name, p.duplexname, p.type, p.rp, p.rm, p.ka, p.mc, ps.kind
858     FROM printers p, printservers ps
859     WHERE p.rm = ps.mach_id;
860   EXEC SQL OPEN p_cursor2;
861   while (1)
862     {
863       EXEC SQL FETCH p_cursor2 INTO :name, :duplexname, :type,
864         :rp, :rm, :ka, :mc, :pskind;
865       if (sqlca.sqlcode)
866         break;
867       if (!(rmname = hash_lookup(machines, rm)))
868         continue;
869       strtrim(name);
870       if (!valid(name))
871         continue;
872       strtrim(rp);
873       fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:mc#%d:",
874               name, HCLASS, HTYPE, name, rp, rmname, ka, mc);
875
876       strtrim(pskind);
877       if (!strcmp(pskind, "BSD"))
878         fprintf(out, "auth=none:remote_support=RQM:");
879       else if (!strcmp(pskind, "ATHENA"))
880         {
881           fprintf(out, "auth=%s:az:remote_support=RQM:",
882                   ka ? "kerberos4" : "none");
883         }
884       else if (!strcmp(pskind, "LPRNG"))
885         fprintf(out, "auth=kerberos5:xn:");
886
887       fputs("\"\n", out);
888
889       strtrim(duplexname);
890       if (!valid(duplexname))
891         continue;
892       if (!strcmp(strtrim(type), "ALIAS"))
893         {
894           EXEC SQL SELECT duplexname INTO :duplexrp
895             FROM printers WHERE name = :rp;
896           strtrim(duplexrp);
897         }
898       else
899         strcpy(duplexrp, duplexname);
900       fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:mc#%d:",
901               duplexname, HCLASS, HTYPE, duplexname, duplexrp,
902               rmname, ka, mc);
903
904       if (!strcmp(pskind, "BSD"))
905         fprintf(out, "auth=none:remote_support=RQM:");
906       else if (!strcmp(pskind, "ATHENA"))
907         {
908           fprintf(out, "auth=%s:az:remote_support=RQM:",
909                   ka ? "kerberos4" : "none");
910         }
911       else if (!strcmp(pskind, "LPRNG"))
912         fprintf(out, "auth=kerberos5:xn:");
913
914       fputs("\"\n", out);
915     }
916   EXEC SQL CLOSE p_cursor2;
917
918   EXEC SQL COMMIT;
919
920   if (fclose(out))
921     {
922       fprintf(stderr, "Unsuccessful close of pcap.db\n");
923       exit(MR_CCONFIG);
924     }
925   fix_file(outf);
926   return 1;
927 sqlerr:
928   db_error(sqlca.sqlcode);
929   return 0;
930 }
931
932
933 int do_sloc(void)
934 {
935   FILE *out;
936   char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
937   EXEC SQL BEGIN DECLARE SECTION;
938   char service[SERVERHOSTS_SERVICE_SIZE];
939   int id;
940   EXEC SQL END DECLARE SECTION;
941
942   sprintf(outf, "%s/sloc.db", hesiod_dir);
943
944   sprintf(outft, "%s~", outf);
945   out = fopen(outft, "w");
946   if (!out)
947     {
948       perror("cannot open sloc.db for write");
949       exit(MR_OCONFIG);
950     }
951
952   fprintf(stderr, "Building sloc.db\n");
953   get_mach();
954
955   EXEC SQL DECLARE s_cursor CURSOR FOR
956     SELECT DISTINCT service, mach_id
957     FROM serverhosts
958     ORDER BY service;
959   EXEC SQL OPEN s_cursor;
960   while (1)
961     {
962       EXEC SQL FETCH s_cursor INTO :service, :id;
963       if (sqlca.sqlcode)
964         break;
965       strtrim(service);
966       if (valid(service) && (mach = hash_lookup(machines, id)))
967         fprintf(out, "%s.sloc\t%s %s %s\n", service, HCLASS, HTYPE, mach);
968     }
969   EXEC SQL CLOSE s_cursor;
970
971   EXEC SQL COMMIT;
972
973   if (fclose(out))
974     {
975       fprintf(stderr, "Unsuccessful close of sloc.db\n");
976       exit(MR_CCONFIG);
977     }
978
979   fix_file(outf);
980   return 1;
981 sqlerr:
982   db_error(sqlca.sqlcode);
983   return 0;
984 }
985
986 int do_service(void)
987 {
988   FILE *out;
989   char outf[MAXPATHLEN], outft[MAXPATHLEN];
990   EXEC SQL BEGIN DECLARE SECTION;
991   char service[SERVICES_NAME_SIZE], protocol[SERVICES_PROTOCOL_SIZE];
992   char aname[ALIAS_NAME_SIZE], trans[ALIAS_TRANS_SIZE];
993   int port;
994   EXEC SQL END DECLARE SECTION;
995
996   sprintf(outf, "%s/service.db", hesiod_dir);
997
998   sprintf(outft, "%s~", outf);
999   out = fopen(outft, "w");
1000   if (!out)
1001     {
1002       perror("cannot open service.db for write");
1003       exit(MR_OCONFIG);
1004     }
1005
1006   fprintf(stderr, "Building service.db\n");
1007
1008   EXEC SQL DECLARE s_cursor2 CURSOR FOR
1009     SELECT name, protocol, port
1010     FROM services;
1011   EXEC SQL OPEN s_cursor2;
1012   while (1)
1013     {
1014       EXEC SQL FETCH s_cursor2 INTO :service, :protocol, :port;
1015       if (sqlca.sqlcode)
1016         break;
1017       lowercase(protocol);      /* Convert protocol to lowercase */
1018       strtrim(service);
1019       if (!valid(service))
1020         continue;
1021       strtrim(protocol);
1022       fprintf(out, "%s.service\t%s %s \"%s %s %d\"\n",
1023               service, HCLASS, HTYPE, service, protocol, port);
1024     }
1025   EXEC SQL CLOSE s_cursor2;
1026
1027   EXEC SQL DECLARE a_cursor3 CURSOR FOR
1028     SELECT name, trans
1029     FROM alias
1030     WHERE type = 'SERVICE';
1031   EXEC SQL OPEN a_cursor3;
1032   while (1)
1033     {
1034       EXEC SQL FETCH a_cursor3 INTO :aname, :trans;
1035       if (sqlca.sqlcode)
1036         break;
1037       strtrim(aname);
1038       strtrim(trans);
1039       if (!valid(aname) || !valid(trans))
1040         continue;
1041       fprintf(out, "%s.service\t%s CNAME %s.service\n", aname, HCLASS,
1042               trans);
1043     }
1044   EXEC SQL CLOSE a_cursor3;
1045
1046   EXEC SQL COMMIT;
1047
1048   if (fclose(out))
1049     {
1050       fprintf(stderr, "Unsuccessful close of service.db\n");
1051       exit(MR_CCONFIG);
1052     }
1053   fix_file(outf);
1054   return 1;
1055 sqlerr:
1056   db_error(sqlca.sqlcode);
1057   return 0;
1058 }
This page took 0.12583 seconds and 5 git commands to generate.