]> andersk Git - moira.git/blob - gen/hesiod.pc
Change MAXHESSIZE #define for new BIND codebase.
[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 256
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], potype[USERS_POTYPE_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, potype, 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, :potype, :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       dequote(potype);
259       u = malloc(sizeof(struct user));
260       strcpy(u->name, login);
261       u->lists = NULL;
262       hash_store(users, id, u);
263       if (status == 1 || status == 2)
264         {
265           fprintf(pout, "%s.passwd\t%s %s \"%s:*:%d:101:%s,%s,%s,%s,%s:/mit/%s:%s\"\n",
266                   login, HCLASS, HTYPE, login, uid, fullname, nn, oa,
267                   op, hp, login, shell);
268           fprintf(uout, "%d.uid\t%s CNAME %s.passwd\n", uid, HCLASS, login);
269         }
270
271       if (iid != 0)
272         {
273           EXEC SQL SELECT mach_id INTO :mid FROM filesys
274             WHERE filsys_id = :iid AND type = 'IMAP';
275           if (sqlca.sqlcode == 0)
276             pid = mid;
277         }
278
279       if ((strcmp(potype, "NONE") != 0) &&  pid != 0 &&
280           (mach = hash_lookup(machines, pid)))
281         {
282           fprintf(bout, "%s.pobox\t%s %s \"POP %s %s\"\n",
283                   login, HCLASS, HTYPE, mach, login);
284         }
285     }
286   if (sqlca.sqlcode < 0)
287     db_error(sqlca.sqlcode);
288   EXEC SQL CLOSE u_cursor;
289   EXEC SQL COMMIT;
290
291   if (fclose(pout) || fclose(uout) || fclose(bout))
292     {
293       fprintf(stderr, "Unsuccessful file close of passwd.db, uid.db, or pobox.db\n");
294       exit(MR_CCONFIG);
295     }
296   fix_file(poutf);
297   fix_file(uoutf);
298   fix_file(boutf);
299   return 1;
300 }
301
302
303 int do_groups(void)
304 {
305   FILE *iout, *gout, *lout;
306   char ioutf[MAXPATHLEN], goutf[MAXPATHLEN], loutf[MAXPATHLEN];
307   char buf[MAXPATHLEN], *l;
308   struct hash *groups;
309   struct bucket *b, **p;
310   struct grp *g;
311   struct user *u;
312   EXEC SQL BEGIN DECLARE SECTION;
313   char name[LIST_NAME_SIZE];
314   int gid, id, lid, len;
315   EXEC SQL END DECLARE SECTION;
316
317   /* open files */
318   sprintf(ioutf, "%s/gid.db", hesiod_dir);
319   sprintf(goutf, "%s/group.db", hesiod_dir);
320   sprintf(loutf, "%s/grplist.db", hesiod_dir);
321
322   sprintf(buf, "%s~", ioutf);
323   iout = fopen(buf, "w");
324   if (!iout)
325     {
326       perror("cannot open gid.db for write");
327       exit(MR_OCONFIG);
328     }
329   sprintf(buf, "%s~", goutf);
330   gout = fopen(buf, "w");
331   if (!gout)
332     {
333       perror("cannot open group.db for write");
334       exit(MR_OCONFIG);
335     }
336   sprintf(buf, "%s~", loutf);
337   lout = fopen(buf, "w");
338   if (!lout)
339     {
340       perror("cannot open grplist.db for write");
341       exit(MR_OCONFIG);
342     }
343
344   fprintf(stderr, "Building gid.db, group.db, and grplist.db\n");
345
346   /* make space for group list */
347   groups = create_hash(15001);
348
349   /* The following WHENEVER is declarative, not executed,
350    * and applies for the remainder of this file only.
351    */
352   EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
353
354   EXEC SQL DECLARE l_cursor CURSOR FOR
355     SELECT name, gid, list_id
356     FROM list
357     WHERE grouplist != 0 AND active != 0
358     ORDER BY list_id;
359   EXEC SQL OPEN l_cursor;
360   while (1)
361     {
362       char buf[LIST_NAME_SIZE + 10];
363
364       EXEC SQL FETCH l_cursor INTO :name, :gid, :lid;
365       if (sqlca.sqlcode)
366         break;
367       strtrim(name);
368       if (!valid(name))
369         continue;
370       sprintf(buf, "%s:%d", name, gid);
371       hash_store(groups, lid, strdup(buf));
372       fprintf(iout, "%d.gid\t%s CNAME %s.group\n", gid, HCLASS, name);
373       fprintf(gout, "%s.group\t%s %s \"%s:*:%d:\"\n",
374               name, HCLASS, HTYPE, name, gid);
375     }
376   EXEC SQL CLOSE l_cursor;
377
378   fflush(iout);
379   fflush(gout);
380
381   /* now do grplists */
382   if (!users)
383     {
384       users = create_hash(12001);
385       EXEC SQL DECLARE u_cursor2 CURSOR FOR
386         SELECT users_id, login
387         FROM users
388         WHERE status = 1 OR status = 2;
389       EXEC SQL OPEN u_cursor2;
390       while (1)
391         {
392           EXEC SQL FETCH u_cursor2 INTO :id, :name;
393           if (sqlca.sqlcode)
394             break;
395           u = malloc(sizeof(struct user));
396           strcpy(u->name, strtrim(name));
397           u->lists = NULL;
398           hash_store(users, id, u);
399         }
400       EXEC SQL CLOSE u_cursor2;
401     }
402
403   EXEC SQL DECLARE i_cursor CURSOR FOR
404     SELECT m.list_id, m.member_id
405     FROM imembers m, list l 
406     WHERE m.member_type = 'USER'
407     AND m.list_id = l.list_id AND l.grouplist = 1 AND l.nfsgroup = 1;
408   EXEC SQL OPEN i_cursor;
409   while (1)
410     {
411       EXEC SQL FETCH i_cursor INTO :lid, :id;
412       if (sqlca.sqlcode)
413         break;
414       if ((l = hash_lookup(groups, lid)) && (u = hash_lookup(users, id)))
415         {
416           g = malloc(sizeof(struct grp));
417           g->next = u->lists;
418           u->lists = g;
419           g->lid = l;
420         }
421     }
422   EXEC SQL CLOSE i_cursor;
423
424   EXEC SQL COMMIT;
425
426   for (p = &(users->data[users->size - 1]); p >= users->data; p--)
427     {
428       for (b = *p; b; b = b->next)
429         {
430           if (!(g = ((struct user *)b->data)->lists))
431             continue;
432           fprintf(lout, "%s.grplist\t%s %s \"",
433                   ((struct user *)b->data)->name, HCLASS, HTYPE);
434           len = 0;
435           for (; g; g = g->next)
436             {
437               if (len + strlen(g->lid) + 1 < MAXHESSIZE)
438                 {
439                   fputs(g->lid, lout);
440                   if (g->next)
441                     putc(':', lout);
442                   len += strlen(g->lid) + 1;
443                 }
444               else
445                 {
446                   com_err(whoami, 0, "truncated grp list for user %s",
447                           ((struct user *)b->data)->name);
448                   break;
449                 }
450             }
451           fputs("\"\n", lout);
452         }
453     }
454
455   if (fclose(iout) || fclose(gout) || fclose(lout))
456     {
457       fprintf(stderr, "Unsuccessful close of gid.db, group.db, or grplist.db\n");
458       exit(MR_CCONFIG);
459     }
460   fix_file(ioutf);
461   fix_file(goutf);
462   fix_file(loutf);
463   return 1;
464 sqlerr:
465   db_error(sqlca.sqlcode);
466   return 0;
467 }
468
469
470 int do_filsys(void)
471 {
472   FILE *out;
473   char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach, *group;
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 flag, id, fid;
482   EXEC SQL END DECLARE SECTION;
483
484   sprintf(outf, "%s/filsys.db", hesiod_dir);
485
486   sprintf(outft, "%s~", outf);
487   out = fopen(outft, "w");
488   if (!out)
489     {
490       perror("cannot open filsys.db for write");
491       exit(MR_OCONFIG);
492     }
493
494   fprintf(stderr, "Building filsys.db\n");
495   get_mach();
496   sq = sq_create();
497   sq2 = sq_create();
498
499   EXEC SQL DECLARE f_cursor CURSOR FOR
500     SELECT label, type, name, mach_id, rwaccess, mount, comments, filsys_id
501     FROM filesys
502     ORDER BY filsys_id;
503   EXEC SQL OPEN f_cursor;
504   while (1)
505     {
506       EXEC SQL FETCH f_cursor INTO :name, :type, :loc, :id, :access,
507         :mount, :comments, :fid;
508       if (sqlca.sqlcode)
509         break;
510       strtrim(name);
511       if (!valid(name))
512         continue;
513       strtrim(type);
514       if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
515         {
516           if ((mach = hash_lookup(machines, id)))
517             {
518               fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s\"\n",
519                       name, HCLASS, HTYPE, type, strtrim(loc),
520                       mach, strtrim(access), strtrim(mount));
521             }
522         }
523       else if (!strcmp(type, "AFS"))
524         {
525           fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s\"\n",
526                   name, HCLASS, HTYPE, strtrim(loc),
527                   strtrim(access), strtrim(mount));
528         }
529       else if (!strcmp(type, "ERR"))
530         {
531           fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
532                   name, HCLASS, HTYPE, strtrim(comments));
533         }
534       else if (!strcmp(type, "FSGROUP"))
535         {
536           char buf[FILESYS_NAME_SIZE + 10];
537           sprintf(buf, "%s:%d", name, fid);
538           sq_save_data(sq, strdup(buf));
539         }
540       else if (!strcmp(type, "MUL"))
541         {
542           char buf[FILESYS_NAME_SIZE + 10];
543           sprintf(buf, "%s:%d", name, fid);
544           sq_save_data(sq2, strdup(buf));
545         }
546     }
547   EXEC SQL CLOSE f_cursor;
548
549   while (sq_get_data(sq, &group))
550     {
551       fid = atoi(strchr(group, ':') + 1);
552       *strchr(group, ':') = 0;
553
554       EXEC SQL DECLARE f_cursor2 CURSOR FOR
555         SELECT DISTINCT f.type, f.name, f.mach_id, f.rwaccess, f.mount,
556         f.comments, f.label, g.key
557         FROM filesys f, fsgroup g
558         WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
559         ORDER BY key, label;
560       EXEC SQL OPEN f_cursor2;
561       for (flag = 1; ; flag++)
562         {
563           EXEC SQL FETCH f_cursor2 INTO :type, :loc, :id, :access, :mount,
564             :comments, :name, :key;
565           if (sqlca.sqlcode)
566             break;
567           strtrim(type);
568           if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
569             {
570               if ((mach = hash_lookup(machines, id)))
571                 {
572                   fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s %d\"\n",
573                           group, HCLASS, HTYPE, type, strtrim(loc), mach,
574                           strtrim(access), strtrim(mount), flag);
575                 }
576             }
577           else if (!strcmp(type, "AFS"))
578             {
579               fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s %d\"\n",
580                       group, HCLASS, HTYPE, strtrim(loc), strtrim(access),
581                       strtrim(mount), flag);
582             }
583           else if (!strcmp(type, "ERR"))
584             {
585               fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
586                       group, HCLASS, HTYPE, strtrim(comments));
587             }
588         }
589       EXEC SQL CLOSE f_cursor2;
590       free(group);
591     }
592   sq_destroy(sq);
593
594   while (sq_get_data(sq2, &group))
595     {
596       fid = atoi(strchr(group, ':') + 1);
597       *strchr(group, ':') = 0;
598       fprintf(out, "%s.filsys\t%s %s \"MUL", group, HCLASS, HTYPE);
599       EXEC SQL DECLARE f_cursor3 CURSOR FOR
600         SELECT DISTINCT f.label, g.key
601         FROM filesys f, fsgroup g
602         WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
603         ORDER BY key, label;
604       EXEC SQL OPEN f_cursor3;
605       while (1)
606         {
607           EXEC SQL FETCH f_cursor3 INTO :name, :key;
608           if (sqlca.sqlcode)
609             break;
610           fprintf(out, " %s", strtrim(name));
611         }
612       EXEC SQL CLOSE f_cursor3;
613       fprintf(out, "\"\n");
614       free(group);
615     }
616   sq_destroy(sq2);
617
618   EXEC SQL DECLARE a_cursor CURSOR FOR
619     SELECT name, trans
620     FROM alias
621     WHERE type = 'FILESYS';
622   EXEC SQL OPEN a_cursor;
623   while (1)
624     {
625       EXEC SQL FETCH a_cursor INTO :aname, :trans;
626       if (sqlca.sqlcode)
627         break;
628       strtrim(aname);
629       strtrim(trans);
630       if (!valid(aname) || !valid(trans))
631         continue;
632       fprintf(out, "%s.filsys\t%s CNAME %s.filsys\n",
633               aname, HCLASS, trans);
634     }
635   EXEC SQL CLOSE a_cursor;
636
637   EXEC SQL COMMIT;
638
639   if (fclose(out))
640     {
641       fprintf(stderr, "Unsuccessful close of filsys.db\n");
642       exit(MR_CCONFIG);
643     }
644   fix_file(outf);
645   return 1;
646 sqlerr:
647   db_error(sqlca.sqlcode);
648   return 0;
649 }
650
651 int nbitsset(set_mask *set)
652 {
653   int i, ret;
654   ret = 0;
655   for (i = 0; i < setsize * NSETBITS; i++)
656     {
657       if (SET_ISSET(i, set))
658         ret++;
659     }
660   return ret;
661 }
662
663
664 int do_cluster(void)
665 {
666   FILE *out;
667   char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
668   char machbuf[MACHINE_NAME_SIZE], clubuf[CLUSTERS_NAME_SIZE], *p;
669   EXEC SQL BEGIN DECLARE SECTION;
670   int maxmach, maxclu, mid, cid, id;
671   char name[CLUSTERS_NAME_SIZE];
672   char label[SVC_SERV_LABEL_SIZE], data[SVC_SERV_CLUSTER_SIZE];
673   EXEC SQL END DECLARE SECTION;
674   set_mask **machs, *ms, *ps;
675
676   sprintf(outf, "%s/cluster.db", hesiod_dir);
677
678   sprintf(outft, "%s~", outf);
679   out = fopen(outft, "w");
680   if (!out)
681     {
682       perror("cannot open cluster.db for write");
683       exit(MR_OCONFIG);
684     }
685
686   fprintf(stderr, "Building cluster.db\n");
687   get_mach();
688
689   EXEC SQL SELECT MAX(clu_id) INTO :maxclu FROM clusters;
690   maxclu++;
691   setsize = howmany(maxclu, NSETBITS);
692
693   EXEC SQL SELECT MAX(mach_id) INTO :maxmach FROM machine;
694   maxmach++;
695   machs = malloc((maxmach + 1) * sizeof(set_mask **));
696   memset(machs, 0, (maxmach + 1) * sizeof(int));
697
698   EXEC SQL DECLARE p_cursor CURSOR FOR
699     SELECT mach_id, clu_id
700     FROM mcmap
701     ORDER BY mach_id;
702   EXEC SQL OPEN p_cursor;
703   while (1)
704     {
705       EXEC SQL FETCH p_cursor INTO :mid, :cid;
706       if (sqlca.sqlcode)
707         break;
708       if (!(ms = machs[mid]))
709         {
710           ms = machs[mid] = SET_CREATE();
711           SET_ZERO(ms);
712         }
713       SET_SET(cid, ms);
714     }
715   EXEC SQL CLOSE p_cursor;
716
717   for (mid = 1; mid < maxmach; mid++)
718     {
719       if (!machs[mid])
720         continue;
721       ms = machs[mid];
722       if (nbitsset(ms) > 1)
723         {
724           sprintf(clubuf, "mrinternal-%d", mid);
725           for (cid = 1; cid < maxclu; cid++)
726             {
727               if (SET_ISSET(cid, ms))
728                 {
729                   EXEC SQL DECLARE d_cursor CURSOR FOR
730                     SELECT serv_label, serv_cluster
731                     FROM svc
732                     WHERE clu_id = :cid;
733                   EXEC SQL OPEN d_cursor;
734                   while (1)
735                     {
736                       EXEC SQL FETCH d_cursor INTO :label, :data;
737                       if (sqlca.sqlcode)
738                         break;
739                       strtrim(label);
740                       strtrim(data);
741                       fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
742                               clubuf, HCLASS, HTYPE, label, data);
743                     }
744                   EXEC SQL CLOSE d_cursor;
745                 }
746             }
747         }
748       else
749         {
750           for (cid = 1; cid < maxclu; cid++)
751             if (SET_ISSET(cid, ms))
752               break;
753
754           EXEC SQL SELECT name INTO :name FROM clusters WHERE clu_id = :cid;
755           strtrim(name);
756           if (!valid(name))
757             continue;
758           strcpy(clubuf, name);
759         }
760
761       if ((mach = hash_lookup(machines, mid)))
762         {
763           fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
764                   mach, HCLASS, clubuf);
765           for (p = machbuf; *mach && *mach != '.'; mach++)
766             *p++ = *mach;
767           if (!strcasecmp(mach, ".mit.edu"))
768             {
769               *p = '\0';
770               fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
771                       machbuf, HCLASS, clubuf);
772             }
773         }
774       for (id = mid + 1; id < maxmach; id++)
775         {
776           if ((ps = machs[id]) && !SET_CMP(ms, ps))
777             {
778               free(ps);
779               machs[id] = NULL;
780               if ((mach = hash_lookup(machines, id)))
781                 {
782                   fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
783                           mach, HCLASS, clubuf);
784                   for (p = machbuf; *mach && *mach != '.'; mach++)
785                     *p++ = *mach;
786                   if (!strcasecmp(mach, ".mit.edu"))
787                     {
788                       *p = '\0';
789                       fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
790                               machbuf, HCLASS, clubuf);
791                     }
792                 }
793             }
794         }
795       free(ms);
796       machs[mid] = NULL;
797     }
798
799   EXEC SQL DECLARE d_cursor2 CURSOR FOR
800     SELECT c.name, d.serv_label, d.serv_cluster
801     FROM svc d, clusters c
802     WHERE c.clu_id = d.clu_id;
803   EXEC SQL OPEN d_cursor2;
804   while (1)
805     {
806       EXEC SQL FETCH d_cursor2 INTO :name, :label, :data;
807       if (sqlca.sqlcode)
808         break;
809       strtrim(name);
810       if (!valid(name))
811         continue;
812       strtrim(label);
813       strtrim(data);
814       fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
815               name, HCLASS, HTYPE, label, data);
816     }
817   free(machs);
818   EXEC SQL COMMIT;
819
820   if (fclose(out))
821     {
822       fprintf(stderr, "Unsuccessful close of cluster.db\n");
823       exit(MR_CCONFIG);
824     }
825   fix_file(outf);
826   return 1;
827 sqlerr:
828   db_error(sqlca.sqlcode);
829   return 0;
830 }
831
832
833 int do_printcap(void)
834 {
835   FILE *out;
836   char outf[MAXPATHLEN], outft[MAXPATHLEN];
837   EXEC SQL BEGIN DECLARE SECTION;
838   char name[PRINTERS_NAME_SIZE], duplexname[PRINTERS_DUPLEXNAME_SIZE];
839   char rp[PRINTERS_RP_SIZE], type[PRINTERS_TYPE_SIZE];
840   char duplexrp[PRINTERS_RP_SIZE], pskind[PRINTSERVERS_KIND_SIZE];
841   int ka, rm, mc;
842   EXEC SQL END DECLARE SECTION;
843   char *rmname;
844
845   sprintf(outf, "%s/printcap.db", hesiod_dir);
846
847   sprintf(outft, "%s~", outf);
848   out = fopen(outft, "w");
849   if (!out)
850     {
851       perror("cannot open printcap.db for write");
852       exit(MR_OCONFIG);
853     }
854
855   fprintf(stderr, "Building printcap.db\n");
856   get_mach();
857
858   EXEC SQL DECLARE p_cursor2 CURSOR FOR
859     SELECT p.name, p.duplexname, p.type, p.rp, p.rm, p.ka, p.mc, ps.kind
860     FROM printers p, printservers ps
861     WHERE p.rm = ps.mach_id;
862   EXEC SQL OPEN p_cursor2;
863   while (1)
864     {
865       EXEC SQL FETCH p_cursor2 INTO :name, :duplexname, :type,
866         :rp, :rm, :ka, :mc, :pskind;
867       if (sqlca.sqlcode)
868         break;
869       if (!(rmname = hash_lookup(machines, rm)))
870         continue;
871       strtrim(name);
872       if (!valid(name))
873         continue;
874       strtrim(rp);
875       fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:mc#%d:",
876               name, HCLASS, HTYPE, name, rp, rmname, ka, mc);
877
878       strtrim(pskind);
879       if (!strcmp(pskind, "BSD"))
880         fprintf(out, "auth=none:remote_support=RQM:");
881       else if (!strcmp(pskind, "ATHENA"))
882         {
883           fprintf(out, "auth=%s:az:remote_support=RQM:",
884                   ka ? "kerberos4" : "none");
885         }
886       else if (!strcmp(pskind, "LPRNG"))
887         fprintf(out, "auth=kerberos5:xn:");
888
889       fputs("\"\n", out);
890
891       strtrim(duplexname);
892       if (!valid(duplexname))
893         continue;
894       if (!strcmp(strtrim(type), "ALIAS"))
895         {
896           EXEC SQL SELECT duplexname INTO :duplexrp
897             FROM printers WHERE name = :rp;
898           strtrim(duplexrp);
899         }
900       else
901         strcpy(duplexrp, duplexname);
902       fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:mc#%d:",
903               duplexname, HCLASS, HTYPE, duplexname, duplexrp,
904               rmname, ka, mc);
905
906       if (!strcmp(pskind, "BSD"))
907         fprintf(out, "auth=none:remote_support=RQM:");
908       else if (!strcmp(pskind, "ATHENA"))
909         {
910           fprintf(out, "auth=%s:az:remote_support=RQM:",
911                   ka ? "kerberos4" : "none");
912         }
913       else if (!strcmp(pskind, "LPRNG"))
914         fprintf(out, "auth=kerberos5:xn:");
915
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_sloc(void)
936 {
937   FILE *out;
938   char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
939   EXEC SQL BEGIN DECLARE SECTION;
940   char service[SERVERHOSTS_SERVICE_SIZE];
941   int id;
942   EXEC SQL END DECLARE SECTION;
943
944   sprintf(outf, "%s/sloc.db", hesiod_dir);
945
946   sprintf(outft, "%s~", outf);
947   out = fopen(outft, "w");
948   if (!out)
949     {
950       perror("cannot open sloc.db for write");
951       exit(MR_OCONFIG);
952     }
953
954   fprintf(stderr, "Building sloc.db\n");
955   get_mach();
956
957   EXEC SQL DECLARE s_cursor CURSOR FOR
958     SELECT DISTINCT service, mach_id
959     FROM serverhosts
960     ORDER BY service;
961   EXEC SQL OPEN s_cursor;
962   while (1)
963     {
964       EXEC SQL FETCH s_cursor INTO :service, :id;
965       if (sqlca.sqlcode)
966         break;
967       strtrim(service);
968       if (valid(service) && (mach = hash_lookup(machines, id)))
969         fprintf(out, "%s.sloc\t%s %s %s\n", service, HCLASS, HTYPE, mach);
970     }
971   EXEC SQL CLOSE s_cursor;
972
973   EXEC SQL COMMIT;
974
975   if (fclose(out))
976     {
977       fprintf(stderr, "Unsuccessful close of sloc.db\n");
978       exit(MR_CCONFIG);
979     }
980
981   fix_file(outf);
982   return 1;
983 sqlerr:
984   db_error(sqlca.sqlcode);
985   return 0;
986 }
987
988 int do_service(void)
989 {
990   FILE *out;
991   char outf[MAXPATHLEN], outft[MAXPATHLEN];
992   EXEC SQL BEGIN DECLARE SECTION;
993   char service[SERVICES_NAME_SIZE], protocol[SERVICES_PROTOCOL_SIZE];
994   char aname[ALIAS_NAME_SIZE], trans[ALIAS_TRANS_SIZE];
995   int port;
996   EXEC SQL END DECLARE SECTION;
997
998   sprintf(outf, "%s/service.db", hesiod_dir);
999
1000   sprintf(outft, "%s~", outf);
1001   out = fopen(outft, "w");
1002   if (!out)
1003     {
1004       perror("cannot open service.db for write");
1005       exit(MR_OCONFIG);
1006     }
1007
1008   fprintf(stderr, "Building service.db\n");
1009
1010   EXEC SQL DECLARE s_cursor2 CURSOR FOR
1011     SELECT name, protocol, port
1012     FROM services;
1013   EXEC SQL OPEN s_cursor2;
1014   while (1)
1015     {
1016       EXEC SQL FETCH s_cursor2 INTO :service, :protocol, :port;
1017       if (sqlca.sqlcode)
1018         break;
1019       lowercase(protocol);      /* Convert protocol to lowercase */
1020       strtrim(service);
1021       if (!valid(service))
1022         continue;
1023       strtrim(protocol);
1024       fprintf(out, "%s.service\t%s %s \"%s %s %d\"\n",
1025               service, HCLASS, HTYPE, service, protocol, port);
1026     }
1027   EXEC SQL CLOSE s_cursor2;
1028
1029   EXEC SQL DECLARE a_cursor3 CURSOR FOR
1030     SELECT name, trans
1031     FROM alias
1032     WHERE type = 'SERVICE';
1033   EXEC SQL OPEN a_cursor3;
1034   while (1)
1035     {
1036       EXEC SQL FETCH a_cursor3 INTO :aname, :trans;
1037       if (sqlca.sqlcode)
1038         break;
1039       strtrim(aname);
1040       strtrim(trans);
1041       if (!valid(aname) || !valid(trans))
1042         continue;
1043       fprintf(out, "%s.service\t%s CNAME %s.service\n", aname, HCLASS,
1044               trans);
1045     }
1046   EXEC SQL CLOSE a_cursor3;
1047
1048   EXEC SQL COMMIT;
1049
1050   if (fclose(out))
1051     {
1052       fprintf(stderr, "Unsuccessful close of service.db\n");
1053       exit(MR_CCONFIG);
1054     }
1055   fix_file(outf);
1056   return 1;
1057 sqlerr:
1058   db_error(sqlca.sqlcode);
1059   return 0;
1060 }
This page took 1.027016 seconds and 5 git commands to generate.