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