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.
7 * (c) Copyright 1988, 1990 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, please see the file
12 #include <mit-copyright.h>
16 #include <moira_site.h>
17 #include <sys/types.h>
22 EXEC SQL INCLUDE sqlca;
33 #define HESIOD_SUBDIR "hesiod"
36 /* max number of bytes of a data record that can be returned in a hesiod
37 * query. This is 512 - overhead (~66) [derived empirically]
39 #define MAXHESSIZE 446
43 #define min(x, y) ((x) < (y) ? (x) : (y))
44 struct hash *machines = NULL;
45 struct hash *users = NULL;
46 char *whoami = "hesiod.gen";
47 char *db = "moira/moira";
59 int main(int argc, char **argv)
67 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
71 initialize_sms_error_table();
72 sprintf(hesiod_dir, "%s/%s", DCM_DIR, HESIOD_SUBDIR);
76 changed = do_passwd();
77 changed += do_filsys();
78 changed += do_cluster();
79 changed += do_printcap();
80 changed += do_palladium();
82 changed += do_service();
83 changed += do_groups();
87 fprintf(stderr, "No files updated.\n");
88 if (argc == 2 && stat(argv[1], &sb) == 0)
94 fprintf(stderr, "Building tar file.\n");
95 sprintf(cmd, "cd %s; tar cf %s .", hesiod_dir, argv[1]);
106 EXEC SQL BEGIN DECLARE SECTION;
109 EXEC SQL END DECLARE SECTION;
114 machines = create_hash(1000);
115 EXEC SQL DECLARE m_cursor CURSOR FOR
118 WHERE status = 1 and mach_id != 0
120 EXEC SQL OPEN m_cursor;
123 EXEC SQL FETCH m_cursor INTO :name, :id;
126 hash_store(machines, id, strsave(strtrim(name)));
128 if (sqlca.sqlcode < 0)
129 db_error(sqlca.sqlcode);
130 EXEC SQL CLOSE m_cursor;
137 FILE *pout, *uout, *bout;
138 char poutf[64], uoutf[64], poutft[64], uoutft[64], boutf[64], boutft[64];
139 struct stat psb, usb, bsb;
143 EXEC SQL BEGIN DECLARE SECTION;
144 char login[9], shell[33], fullname[33], oa[17], op[13], hp[17];
145 char nn[17], ptype[9];
146 int uid, flag1, flag2, id, pid, status;
147 EXEC SQL END DECLARE SECTION;
149 sprintf(poutf, "%s/passwd.db", hesiod_dir);
150 sprintf(uoutf, "%s/uid.db", hesiod_dir);
151 sprintf(boutf, "%s/pobox.db", hesiod_dir);
153 if (stat(poutf, &psb) == 0 && stat(uoutf, &usb) == 0 &&
154 stat(boutf, &bsb) == 0)
156 ftime = min(min(psb.st_mtime, usb.st_mtime), bsb.st_mtime);
157 if (ModDiff (&flag1, "users", ftime) ||
158 ModDiff (&flag2, "machine", ftime))
160 if (flag1 < 0 && flag2 < 0)
162 fprintf(stderr, "Files passwd.db, uid.db, and pobox.db "
163 "do not need to be rebuilt.\n");
168 sprintf(poutft, "%s~", poutf);
169 pout = fopen(poutft, "w");
172 perror("cannot open passwd.db~ for write");
175 sprintf(uoutft, "%s~", uoutf);
176 uout = fopen(uoutft, "w");
179 perror("cannot open uid.db~ for write");
182 sprintf(boutft, "%s~", boutf);
183 bout = fopen(boutft, "w");
186 perror("cannot open pobox.db for write");
190 fprintf(stderr, "Building passwd.db, uid.db, and pobox.db\n");
193 users = create_hash(12001);
194 EXEC SQL DECLARE u_cursor CURSOR FOR
195 SELECT login, unix_uid, shell, fullname, nickname, office_addr,
196 office_phone, home_phone, users_id, pop_id, potype, status
198 WHERE status = 1 or status = 5 or status = 6
200 EXEC SQL OPEN u_cursor;
203 EXEC SQL FETCH u_cursor INTO :login, :uid, :shell, :fullname, :nn,
204 :oa, :op, :hp, :id, :pid, :ptype, :status;
214 u = malloc(sizeof(struct user));
215 strcpy(u->name, login);
217 hash_store(users, id, u);
220 fprintf(pout, "%s.passwd\t%s %s \"%s:*:%d:101:%s,%s,%s,%s,%s:/mit/%s:%s\"\n",
221 login, HCLASS, HTYPE, login, uid, fullname, nn, oa,
222 op, hp, login, shell);
223 fprintf(uout, "%d.uid\t%s CNAME %s.passwd\n", uid, HCLASS, login);
225 if (pid != 0 && (mach = hash_lookup(machines, pid)))
227 fprintf(bout, "%s.pobox\t%s %s \"POP %s %s\"\n",
228 login, HCLASS, HTYPE, mach, login);
231 if (sqlca.sqlcode < 0)
232 db_error(sqlca.sqlcode);
233 EXEC SQL CLOSE u_cursor;
236 if (fclose(pout) || fclose(uout) || fclose(bout))
238 fprintf(stderr, "Unsuccessful file close of passwd.db, uid.db, or pobox.db\n");
250 FILE *iout, *gout, *lout;
251 char ioutf[64], goutf[64], loutf[64], buf[2048], *l;
253 struct bucket *b, **p;
256 struct stat isb, gsb, lsb;
258 EXEC SQL BEGIN DECLARE SECTION;
260 int gid, id, lid, flag1, flag2, flag3, len;
261 EXEC SQL END DECLARE SECTION;
264 sprintf(ioutf, "%s/gid.db", hesiod_dir);
265 sprintf(goutf, "%s/group.db", hesiod_dir);
266 sprintf(loutf, "%s/grplist.db", hesiod_dir);
268 if (stat(ioutf, &isb) == 0 && stat(goutf, &gsb) == 0 &&
269 stat(loutf, &lsb) == 0)
271 ftime = min(isb.st_mtime, min(gsb.st_mtime, lsb.st_mtime));
272 if (ModDiff (&flag1, "users", ftime) ||
273 ModDiff (&flag2, "list", ftime) ||
274 ModDiff (&flag3, "imembers", ftime))
276 if (flag1 < 0 && flag2 < 0 && flag3 < 0)
278 fprintf(stderr, "Files gid.db, group.db and grplist.db "
279 "do not need to be rebuilt.\n");
284 sprintf(buf, "%s~", ioutf);
285 iout = fopen(buf, "w");
288 perror("cannot open gid.db for write");
291 sprintf(buf, "%s~", goutf);
292 gout = fopen(buf, "w");
295 perror("cannot open group.db for write");
298 sprintf(buf, "%s~", loutf);
299 lout = fopen(buf, "w");
302 perror("cannot open grplist.db for write");
306 fprintf(stderr, "Building gid.db, group.db, and grplist.db\n");
308 /* make space for group list */
309 groups = create_hash(15001);
311 /* The following WHENEVER is declarative, not executed,
312 * and applies for the remainder of this file only.
314 EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
316 EXEC SQL DECLARE l_cursor CURSOR FOR
317 SELECT name, gid, list_id
319 WHERE grouplist != 0 AND active != 0
321 EXEC SQL OPEN l_cursor;
324 EXEC SQL FETCH l_cursor INTO :name, :gid, :lid;
328 sprintf(buf, "%s:%d", name, gid);
329 hash_store(groups, lid, strsave(buf));
330 fprintf(iout, "%d.gid\t%s CNAME %s.group\n", gid, HCLASS, name);
331 fprintf(gout, "%s.group\t%s %s \"%s:*:%d:\"\n",
332 name, HCLASS, HTYPE, name, gid);
334 EXEC SQL CLOSE l_cursor;
339 /* now do grplists */
342 users = create_hash(12001);
343 EXEC SQL DECLARE u_cursor2 CURSOR FOR
344 SELECT users_id, login
348 EXEC SQL OPEN u_cursor2;
351 EXEC SQL FETCH u_cursor2 INTO :id, :name;
354 u = malloc(sizeof(struct user));
355 strcpy(u->name, strtrim(name));
357 hash_store(users, id, u);
359 EXEC SQL CLOSE u_cursor2;
362 EXEC SQL DECLARE i_cursor CURSOR FOR
363 SELECT list_id, member_id
365 WHERE member_type = 'USER'
367 EXEC SQL OPEN i_cursor;
370 EXEC SQL FETCH i_cursor INTO :lid, :id;
373 if ((l = hash_lookup(groups, lid)) &&
374 (u = (struct user *) hash_lookup(users, id)))
376 g = malloc(sizeof(struct grp));
382 EXEC SQL CLOSE i_cursor;
386 for (p = &(users->data[users->size - 1]); p >= users->data; p--)
388 for (b = *p; b; b = b->next)
390 if (!(g = ((struct user *)b->data)->lists))
392 fprintf(lout, "%s.grplist\t%s %s \"",
393 ((struct user *)b->data)->name, HCLASS, HTYPE);
395 for (; g; g = g->next)
397 if (len + strlen(g->lid) + 1 < MAXHESSIZE)
402 len += strlen(g->lid) + 1;
406 com_err(whoami, 0, "truncated grp list for user %s",
407 ((struct user *)b->data)->name);
415 if (fclose(iout) || fclose(gout) || fclose(lout))
417 fprintf(stderr, "Unsuccessful close of gid.db, group.db, or grplist.db\n");
425 db_error(sqlca.sqlcode);
433 char outf[64], outft[64], *mach, *group;
437 struct save_queue *sq, *sq2, *sq_create();
438 EXEC SQL BEGIN DECLARE SECTION;
439 char name[33], type[9], loc[81], access[2], mount[33], trans[257];
441 int flag1, flag2, flag3, flag4, id, fid;
442 EXEC SQL END DECLARE SECTION;
444 sprintf(outf, "%s/filsys.db", hesiod_dir);
446 if (stat(outf, &sb) == 0)
450 if (ModDiff(&flag1, "filesys", ftime))
452 if (ModDiff(&flag2, "machine", ftime))
454 if (ModDiff(&flag3, "alias", ftime))
456 if (ModDiff(&flag4, "fsgroup", ftime))
459 if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0)
461 fprintf(stderr, "File filsys.db does not need to be rebuilt.\n");
466 sprintf(outft, "%s~", outf);
467 out = fopen(outft, "w");
470 perror("cannot open filsys.db for write");
474 fprintf(stderr, "Building filsys.db\n");
479 EXEC SQL DECLARE f_cursor CURSOR FOR
480 SELECT label, type, name, mach_id, rwaccess, mount, comments, filsys_id
483 EXEC SQL OPEN f_cursor;
486 EXEC SQL FETCH f_cursor INTO :name, :type, :loc, :id, :access,
487 :mount, :comments, :fid;
491 if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
493 if (mach = hash_lookup(machines, id))
495 fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s\"\n",
496 strtrim(name), HCLASS, HTYPE, type, strtrim(loc),
497 mach, strtrim(access), strtrim(mount));
500 else if (!strcmp(type, "AFS"))
502 fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s\"\n",
503 strtrim(name), HCLASS, HTYPE, strtrim(loc),
504 strtrim(access), strtrim(mount));
506 else if (!strcmp(type, "ERR"))
508 fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
509 strtrim(name), HCLASS, HTYPE, strtrim(comments));
511 else if (!strcmp(type, "FSGROUP"))
513 sprintf(trans, "%s:%d", strtrim(name), fid);
514 sq_save_data(sq, strsave(trans));
516 else if (!strcmp(type, "MUL"))
518 sprintf(trans, "%s:%d", strtrim(name), fid);
519 sq_save_data(sq2, strsave(trans));
522 EXEC SQL CLOSE f_cursor;
524 while (sq_get_data(sq, &group))
526 fid = atoi(strchr(group, ':') + 1);
527 *strchr(group, ':') = 0;
529 EXEC SQL DECLARE f_cursor2 CURSOR FOR
530 SELECT DISTINCT f.type, f.name, f.mach_id, f.rwaccess, f.mount,
531 f.comments, f.label, g.key
532 FROM filesys f, fsgroup g
533 WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
535 EXEC SQL OPEN f_cursor2;
536 for (flag1 = 1; ; flag1++)
538 EXEC SQL FETCH f_cursor2 INTO :type, :loc, :id, :access, :mount,
539 :comments, :name, :trans;
543 if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
545 if (mach = hash_lookup(machines, id))
547 fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s %d\"\n",
548 group, HCLASS, HTYPE, type, strtrim(loc), mach,
549 strtrim(access), strtrim(mount), flag1);
552 else if (!strcmp(type, "AFS"))
554 fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s %d\"\n",
555 group, HCLASS, HTYPE, strtrim(loc), strtrim(access),
556 strtrim(mount), flag1);
558 else if (!strcmp(type, "ERR"))
560 fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
561 group, HCLASS, HTYPE, strtrim(comments));
564 EXEC SQL CLOSE f_cursor2;
569 while (sq_get_data(sq2, &group))
571 fid = atoi(strchr(group, ':') + 1);
572 *strchr(group, ':') = 0;
573 fprintf(out, "%s.filsys\t%s %s \"MUL", group, HCLASS, HTYPE);
574 EXEC SQL DECLARE f_cursor3 CURSOR FOR
575 SELECT DISTINCT f.label, g.key
576 FROM filesys f, fsgroup g
577 WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
579 EXEC SQL OPEN f_cursor3;
582 EXEC SQL FETCH f_cursor3 INTO :name, :trans;
585 fprintf(out, " %s", strtrim(name));
587 EXEC SQL CLOSE f_cursor3;
588 fprintf(out, "\"\n");
593 EXEC SQL DECLARE a_cursor CURSOR FOR
596 WHERE type = 'FILESYS';
597 EXEC SQL OPEN a_cursor;
600 EXEC SQL FETCH a_cursor INTO :name, :trans;
603 fprintf(out, "%s.filsys\t%s CNAME %s.filsys\n",
604 strtrim(name), HCLASS, strtrim(trans));
606 EXEC SQL CLOSE a_cursor;
612 fprintf(stderr, "Unsuccessful close of filsys.db\n");
618 db_error(sqlca.sqlcode);
624 * Modified from sys/types.h:
626 int setsize; /* = howmany(setbits, NSETBITS) */
628 typedef long set_mask;
629 #define NSETBITS (sizeof(set_mask) * NBBY) /* bits per mask */
631 #define howmany(x, y) (((x) + ((y) - 1)) / (y))
634 #define SET_SET(n, p) ((p)[(n)/NSETBITS] |= (1 << ((n) % NSETBITS)))
635 #define SET_CLR(n, p) ((p)[(n)/NSETBITS] &= ~(1 << ((n) % NSETBITS)))
636 #define SET_ISSET(n, p) ((p)[(n)/NSETBITS] & (1 << ((n) % NSETBITS)))
637 #define SET_CREATE() (malloc(setsize * sizeof(set_mask)))
638 #define SET_ZERO(p) memset(p, 0, setsize * sizeof(set_mask))
639 #define SET_CMP(p1, p2) (memcmp(p1, p2, setsize * sizeof(set_mask)))
641 int nbitsset(set_mask *set)
645 for (i = 0; i < setsize * NSETBITS; i++)
647 if (SET_ISSET(i, set))
657 char outf[64], outft[64], *mach, machbuf[41], *p;
660 EXEC SQL BEGIN DECLARE SECTION;
661 int flag1, flag2, flag3, flag4, maxmach, maxclu, mid, cid, id;
662 char name[41], label2[17], data[33];
663 EXEC SQL END DECLARE SECTION;
664 set_mask **machs, *ms, *ps;
667 sprintf(outf, "%s/cluster.db", hesiod_dir);
669 if (stat(outf, &sb) == 0)
672 if (ModDiff (&flag1, "clusters", ftime)
673 || ModDiff (&flag2, "machine", ftime)
674 || ModDiff (&flag3, "mcmap", ftime)
675 || ModDiff (&flag4, "svc", ftime))
677 if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0)
679 fprintf(stderr, "File cluster.db does not need to be rebuilt.\n");
684 sprintf(outft, "%s~", outf);
685 out = fopen(outft, "w");
688 perror("cannot open cluster.db for write");
692 fprintf(stderr, "Building cluster.db\n");
695 EXEC SQL SELECT MAX(clu_id) INTO :maxclu FROM clusters;
697 setsize = howmany(maxclu, NSETBITS);
699 EXEC SQL SELECT MAX(mach_id) INTO :maxmach FROM machine;
701 machs = malloc((maxmach + 1) * sizeof(set_mask **));
702 memset(machs, 0, (maxmach + 1) * sizeof(int));
704 EXEC SQL DECLARE p_cursor CURSOR FOR
705 SELECT mach_id, clu_id
708 EXEC SQL OPEN p_cursor;
711 EXEC SQL FETCH p_cursor INTO :mid, :cid;
714 if (!(ms = machs[mid]))
716 ms = machs[mid] = SET_CREATE();
721 EXEC SQL CLOSE p_cursor;
723 for (mid = 1; mid < maxmach; mid++)
728 if (nbitsset(ms) > 1)
731 for (cid = 1; cid < maxclu; cid++)
733 if (SET_ISSET(cid, ms))
735 EXEC SQL DECLARE d_cursor CURSOR FOR
736 SELECT serv_label, serv_cluster
739 EXEC SQL OPEN d_cursor;
742 EXEC SQL FETCH d_cursor INTO :label2, :data;
747 fprintf(out, "mrinternal-%d.cluster\t%s %s \"%s %s\"\n",
748 mid, HCLASS, HTYPE, label2, data);
750 EXEC SQL CLOSE d_cursor;
757 for (cid = 1; cid < maxclu; cid++)
758 if (SET_ISSET(cid, ms))
761 EXEC SQL SELECT name INTO :name FROM clusters WHERE clu_id = :cid;
765 if ((mach = hash_lookup(machines, mid)))
767 for (p = machbuf; *mach && *mach != '.'; mach++)
772 fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
773 machbuf, HCLASS, name);
777 fprintf(out, "%s.cluster\t%s CNAME mrinternal-%d.cluster\n",
778 machbuf, HCLASS, mid);
781 for (id = mid + 1; id < maxmach; id++)
783 if ((ps = machs[id]) && !SET_CMP(ms, ps))
787 if ((mach = hash_lookup(machines, id)))
789 for (p = machbuf; *mach && *mach != '.'; mach++)
794 fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
795 machbuf, HCLASS, name);
800 "%s.cluster\t%s CNAME mrinternal-%d.cluster\n",
801 machbuf, HCLASS, mid);
810 EXEC SQL DECLARE d_cursor2 CURSOR FOR
811 SELECT c.name, d.serv_label, d.serv_cluster
812 FROM svc d, clusters c
813 WHERE c.clu_id = d.clu_id;
814 EXEC SQL OPEN d_cursor2;
817 EXEC SQL FETCH d_cursor2 INTO :name, :label2, :data;
823 fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
824 name, HCLASS, HTYPE, label2, data);
831 fprintf(stderr, "Unsuccessful close of cluster.db\n");
837 db_error(sqlca.sqlcode);
842 int do_printcap(void)
845 char outf[64], outft[64];
848 EXEC SQL BEGIN DECLARE SECTION;
849 char name[17], rp[17], sd[33];
850 int flag1, flag2, ka, pc, rm, rq;
851 EXEC SQL END DECLARE SECTION;
853 sprintf(outf, "%s/printcap.db", hesiod_dir);
855 if (stat(outf, &sb) == 0)
858 if (ModDiff (&flag1, "printcap", ftime)
859 || ModDiff (&flag2, "machine", ftime))
861 if (flag1 < 0 && flag2 < 0)
863 fprintf(stderr, "File printcap.db does not need to be rebuilt.\n");
868 sprintf(outft, "%s~", outf);
869 out = fopen(outft, "w");
872 perror("cannot open printcap.db for write");
876 fprintf(stderr, "Building printcap.db\n");
879 EXEC SQL DECLARE p_cursor2 CURSOR FOR
880 SELECT name, rp, dir, mach_id, auth, price, quotaserver
882 EXEC SQL OPEN p_cursor2;
885 EXEC SQL FETCH p_cursor2 INTO :name, :rp, :sd, :rm, :ka, :pc, :rq;
888 if (!hash_lookup(machines, rm))
893 fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:sd=%s:ka#%d:pc#%d",
894 name, HCLASS, HTYPE, name, rp, hash_lookup(machines, rm),
896 if (rq && hash_lookup(machines, rq))
897 fprintf(out, ":rq=%s\"\n", hash_lookup(machines, rq));
901 EXEC SQL CLOSE p_cursor2;
907 fprintf(stderr, "Unsuccessful close of pcap.db\n");
913 db_error(sqlca.sqlcode);
918 int do_palladium(void)
921 char outf[64], outft[64];
924 EXEC SQL BEGIN DECLARE SECTION;
925 char name[33], trans[129];
926 int flag, flag1, identifier, rm;
927 EXEC SQL END DECLARE SECTION;
929 sprintf(outf, "%s/palladium.db", hesiod_dir);
931 if (stat(outf, &sb) == 0)
934 if ((ModDiff (&flag, "palladium", ftime)) ||
935 (ModDiff (&flag1, "alias", ftime)))
937 if (flag < 0 && flag1 < 0)
939 fprintf(stderr, "File palladium.db does not need to be rebuilt.\n");
944 sprintf(outft, "%s~", outf);
945 out = fopen(outft, "w");
948 perror("cannot open palladium.db for write");
952 fprintf(stderr, "Building palladium.db\n");
955 EXEC SQL DECLARE p_cursor3 CURSOR FOR
956 SELECT name, identifier, mach_id
958 EXEC SQL OPEN p_cursor3;
961 EXEC SQL FETCH p_cursor3 INTO :name, :identifier, :rm;
964 if (!hash_lookup(machines, rm))
967 fprintf(out, "%s.palladium\t%s %s \"%s %d %s interface directory\"\n",
968 name, HCLASS, HTYPE, hash_lookup(machines, rm), identifier,
971 EXEC SQL CLOSE p_cursor3;
973 EXEC SQL DECLARE a_cursor2 CURSOR FOR
976 WHERE type = 'PALLADIUM';
977 EXEC SQL OPEN a_cursor2;
980 EXEC SQL FETCH a_cursor2 INTO :name, :trans;
985 fprintf(out, "%s.palladium\t%s %s \"%s\"\n", name, HCLASS, HTYPE, trans);
987 EXEC SQL CLOSE a_cursor2;
993 fprintf(stderr, "Unsuccessful close of palladium.db\n");
999 db_error(sqlca.sqlcode);
1007 char outf[64], outft[64], *mach;
1010 EXEC SQL BEGIN DECLARE SECTION;
1012 int flag1, flag2, id;
1013 EXEC SQL END DECLARE SECTION;
1015 sprintf(outf, "%s/sloc.db", hesiod_dir);
1017 if (stat(outf, &sb) == 0)
1019 ftime = sb.st_mtime;
1020 if ((ModDiff (&flag1, "serverhosts", ftime)) ||
1021 (ModDiff (&flag2, "machine", ftime)))
1023 if (flag1 < 0 && flag2 < 0)
1025 fprintf(stderr, "File sloc.db does not need to be rebuilt.\n");
1030 sprintf(outft, "%s~", outf);
1031 out = fopen(outft, "w");
1034 perror("cannot open sloc.db for write");
1038 fprintf(stderr, "Building sloc.db\n");
1041 EXEC SQL DECLARE s_cursor CURSOR FOR
1042 SELECT DISTINCT service, mach_id
1045 EXEC SQL OPEN s_cursor;
1048 EXEC SQL FETCH s_cursor INTO :service, :id;
1052 if (mach = hash_lookup(machines, id))
1053 fprintf(out, "%s.sloc\t%s %s %s\n", service, HCLASS, HTYPE, mach);
1055 EXEC SQL CLOSE s_cursor;
1061 fprintf(stderr, "Unsuccessful close of sloc.db\n");
1068 db_error(sqlca.sqlcode);
1072 int do_service(void)
1075 char outf[64], outft[64];
1078 EXEC SQL BEGIN DECLARE SECTION;
1079 char service[33], protocol[9], altserv[129];
1081 EXEC SQL END DECLARE SECTION;
1083 sprintf(outf, "%s/service.db", hesiod_dir);
1085 if (stat(outf, &sb) == 0)
1087 ftime = sb.st_mtime;
1088 if (ModDiff (&flag1, "services", ftime))
1092 fprintf(stderr, "File service.db does not need to be rebuilt.\n");
1097 sprintf(outft, "%s~", outf);
1098 out = fopen(outft, "w");
1101 perror("cannot open service.db for write");
1105 fprintf(stderr, "Building service.db\n");
1107 EXEC SQL DECLARE s_cursor2 CURSOR FOR
1108 SELECT name, protocol, port
1110 EXEC SQL OPEN s_cursor2;
1113 EXEC SQL FETCH s_cursor2 INTO :service, :protocol, :port;
1116 lowercase(protocol); /* Convert protocol to lowercase */
1119 fprintf(out, "%s.service\t%s %s \"%s %s %d\"\n",
1120 service, HCLASS, HTYPE, service, protocol, port);
1122 EXEC SQL CLOSE s_cursor2;
1124 EXEC SQL DECLARE a_cursor3 CURSOR FOR
1127 WHERE type = 'SERVICE';
1128 EXEC SQL OPEN a_cursor3;
1131 EXEC SQL FETCH a_cursor3 INTO :service, :altserv;
1136 fprintf(out, "%s.service\t%s CNAME %s.service\n", service, HCLASS,
1139 EXEC SQL CLOSE a_cursor3;
1145 fprintf(stderr, "Unsuccessful close of service.db\n");
1151 db_error(sqlca.sqlcode);