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