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