]> andersk Git - moira.git/blobdiff - gen/hesiod.pc
Revised EXCHANGE behavior.
[moira.git] / gen / hesiod.pc
index 06ad00380e01e2d87924ec140698b16b27b0385b..1f4b9006eb5ae1cac0d0a015aa323f0b634490c6 100644 (file)
-/* $Header$
+/* $Id$
  *
  * This generates the zone files necessary to load a hesiod server.
  * The following zones are generated: passwd, uid, pobox, group,
  * grplist, gid, filsys, cluster, pcap, sloc, service.
  *
- *  (c) Copyright 1988, 1990 by the Massachusetts Institute of Technology.
- *  For copying and distribution information, please see the file
- *  <mit-copyright.h>.
+ * (c) Copyright 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
  */
 
 #include <mit-copyright.h>
-#include <stdio.h>
 #include <moira.h>
 #include <moira_site.h>
-#include <sys/types.h>
+
 #include <sys/stat.h>
-#include <sys/time.h>
-#include <ctype.h>
+
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+
+#include "util.h"
+
 EXEC SQL INCLUDE sqlca;
 
+RCSID("$Header$");
 
 #ifndef HTYPE
 #define HTYPE "TXT"
 #endif
 #ifndef HCLASS
-#define HCLASS "IN"
+#define HCLASS ""
 #endif
 
 #ifndef HESIOD_SUBDIR
 #define HESIOD_SUBDIR "hesiod"
 #endif
 
-/* max number of bytes of a data record that can be returned in a hesiod 
- * query.  This is 512 - overhead (~66) [derived empirically]
+/* max number of bytes of a data record that can be returned in a hesiod
+ * query.  This is 512 - overhead (~78) [derived empirically]
+ * (it used to be 446 with older versions of bind)
  */
-#define MAXHESSIZE 446
+#define MAXHESSIZE 256
 
-char hesiod_dir[64];
+char hesiod_dir[MAXPATHLEN];
 
-#define min(x,y)       ((x) < (y) ? (x) : (y))
+#define min(x, y)      ((x) < (y) ? (x) : (y))
 struct hash *machines = NULL;
 struct hash *users = NULL;
 char *whoami = "hesiod.gen";
 char *db = "moira/moira";
 
 struct grp {
-    struct grp *next;
-    char *lid;
+  struct grp *next;
+  char *lid;
 };
 struct user {
-    char name[9];
-    struct grp *lists;
+  char name[USERS_LOGIN_SIZE];
+  struct grp *lists;
 };
 
-void lowercase();
-char *malloc(), *strsave();
+/*
+ * Modified from sys/types.h:
+ */
+int setsize;   /* = howmany(setbits, NSETBITS) */
 
+typedef long   set_mask;
+#define NSETBITS       (sizeof(set_mask) * NBBY)       /* bits per mask */
+#ifndef howmany
+#define        howmany(x, y)   (((x) + ((y) - 1)) / (y))
+#endif
 
-main(argc, argv)
-int argc;
-char **argv;
-{
-    char cmd[64];
-    struct stat sb;
-    int changed = 0;
+#define        SET_SET(n, p)   ((p)[(n)/NSETBITS] |=  (1 << ((n) % NSETBITS)))
+#define        SET_CLR(n, p)   ((p)[(n)/NSETBITS] &= ~(1 << ((n) % NSETBITS)))
+#define        SET_ISSET(n, p) ((p)[(n)/NSETBITS] &   (1 << ((n) % NSETBITS)))
+#define SET_CREATE()   (malloc(setsize * sizeof(set_mask)))
+#define SET_ZERO(p)    memset(p, 0, setsize * sizeof(set_mask))
+#define SET_CMP(p1, p2) (memcmp(p1, p2, setsize * sizeof(set_mask)))
+
+
+void get_mach(void);
+int nbitsset(set_mask *set);
+int valid(char *name);
 
-    if (argc > 2) {
-       fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
-       exit(MR_ARGS);
+int do_passwd(void);
+int do_groups(void);
+int do_filsys(void);
+int do_cluster(void);
+int do_printcap(void);
+int do_sloc(void);
+int do_service(void);
+
+int main(int argc, char **argv)
+{
+  char cmd[64];
+  struct stat sb;
+  int changed = 0;
+
+  if (argc > 2)
+    {
+      fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
+      exit(MR_ARGS);
     }
 
-    initialize_sms_error_table ();
-    sprintf(hesiod_dir, "%s/%s", DCM_DIR, HESIOD_SUBDIR);
+  initialize_sms_error_table();
+  sprintf(hesiod_dir, "%s/%s", DCM_DIR, HESIOD_SUBDIR);
 
-    EXEC SQL CONNECT :db;
+  EXEC SQL CONNECT :db;
 
-    changed = do_passwd();
-    changed += do_filsys();
-    changed += do_cluster();
-    changed += do_printcap();
-    changed += do_palladium();
-    changed += do_sloc();
-    changed += do_service();
-    changed += do_groups();
+  changed = do_passwd();
+  changed += do_filsys();
+  changed += do_cluster();
+  changed += do_printcap();
+  changed += do_sloc();
+  changed += do_service();
+  changed += do_groups();
 
-    if (!changed) {
-       fprintf(stderr, "No files updated.\n");
-       if (argc == 2 && stat(argv[1], &sb) == 0)
-         exit(MR_NO_CHANGE);
+  if (!changed)
+    {
+      fprintf(stderr, "No files updated.\n");
+      if (argc == 2 && stat(argv[1], &sb) == 0)
+       exit(MR_NO_CHANGE);
     }
 
-    if (argc == 2) {
-       fprintf(stderr, "Building tar file.\n");
-       sprintf(cmd, "cd %s; tar cf %s .", hesiod_dir, argv[1]);
-       if (system(cmd))
-         exit(MR_TAR_FAIL);
+  if (argc == 2)
+    {
+      fprintf(stderr, "Building tar file.\n");
+      sprintf(cmd, "cd %s; tar cf %s .", hesiod_dir, argv[1]);
+      if (system(cmd))
+       exit(MR_TAR_FAIL);
     }
 
-    exit(MR_SUCCESS);
+  exit(MR_SUCCESS);
 }
 
 
-get_mach()
+void get_mach(void)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    int id;
-    char name[41];
-    EXEC SQL END DECLARE SECTION;
-
-    if (machines)
-      return;
-
-    machines = create_hash(1000);
-    EXEC SQL DECLARE m_cursor CURSOR FOR
-      SELECT name, mach_id
-      FROM machine
-      WHERE status = 1 and mach_id != 0
-      ORDER BY mach_id;
-    EXEC SQL OPEN m_cursor;
-    while (1) {
-        EXEC SQL FETCH m_cursor INTO :name, :id;
-        if (sqlca.sqlcode != 0) break;
-       hash_store(machines, id, strsave(strtrim(name)));
-    }
-    if (sqlca.sqlcode < 0) db_error(sqlca.sqlcode);
-    EXEC SQL CLOSE m_cursor;
-    EXEC SQL COMMIT;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int id;
+  char name[MACHINE_NAME_SIZE];
+  EXEC SQL END DECLARE SECTION;
+
+  if (machines)
+    return;
+
+  machines = create_hash(1000);
+  EXEC SQL DECLARE m_cursor CURSOR FOR
+    SELECT name, mach_id
+    FROM machine
+    WHERE status = 1 and mach_id != 0
+    ORDER BY mach_id;
+  EXEC SQL OPEN m_cursor;
+  while (1)
+    {
+      EXEC SQL FETCH m_cursor INTO :name, :id;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(name);
+      if (!valid(name))
+       continue;
+      hash_store(machines, id, strdup(name));
+    }
+  if (sqlca.sqlcode < 0)
+    db_error(sqlca.sqlcode);
+  EXEC SQL CLOSE m_cursor;
+  EXEC SQL COMMIT;
 }
 
 
-do_passwd()
+/* Determine whether or not a name is a valid DNS label.
+   (Can't start or end with . or have two .s in a row) */
+int valid(char *name)
 {
-    FILE *pout, *uout, *bout;
-    char poutf[64], uoutf[64], poutft[64], uoutft[64], boutf[64], boutft[64];
-    struct stat psb, usb, bsb;
-    time_t ftime;
-    struct user *u;
-    char *mach;
-    EXEC SQL BEGIN DECLARE SECTION;
-    char login[9], shell[33], fullname[33], oa[17], op[13], hp[17];
-    char nn[17], ptype[9];
-    int uid, flag1, flag2, id, pid, status;
-    EXEC SQL END DECLARE SECTION;
-
-    sprintf(poutf, "%s/passwd.db", hesiod_dir);
-    sprintf(uoutf, "%s/uid.db", hesiod_dir);
-    sprintf(boutf, "%s/pobox.db", hesiod_dir);
-
-    if (stat(poutf, &psb) == 0 && stat(uoutf, &usb) == 0 &&
-       stat(boutf, &bsb) == 0) {
-       ftime = min(min(psb.st_mtime, usb.st_mtime), bsb.st_mtime);
-        if (ModDiff (&flag1, "users", ftime) ||
-            ModDiff (&flag2, "machine", ftime))
-            exit (MR_DATE);
-       if (flag1 < 0 && flag2 < 0) {
-           fprintf(stderr, "Files passwd.db, uid.db, and pobox.db do not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(poutft, "%s~", poutf);
-    pout = fopen(poutft, "w");
-    if (!pout) {
-       perror("cannot open passwd.db~ for write");
-       exit(MR_OCONFIG);
-    }
-    sprintf(uoutft, "%s~", uoutf);
-    uout = fopen(uoutft, "w");
-    if (!uout) {
-       perror("cannot open uid.db~ for write");
-       exit(MR_OCONFIG);
-    }
-    sprintf(boutft, "%s~", boutf);
-    bout = fopen(boutft, "w");
-    if (!bout) {
-       perror("cannot open pobox.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building passwd.db, uid.db, and pobox.db\n");
-    get_mach();
-
-    users = create_hash(12001);
-    EXEC SQL DECLARE u_cursor CURSOR FOR
-      SELECT login, unix_uid, shell, fullname, nickname, office_addr,
-            office_phone, home_phone, users_id, pop_id, potype, status
-      FROM users
-      WHERE status = 1 or status = 5 or status = 6
-      ORDER BY users_id;
-    EXEC SQL OPEN u_cursor;
-    while (1) {
-        EXEC SQL FETCH u_cursor INTO :login, :uid, :shell, :fullname, :nn,
-                       :oa, :op, :hp, :id, :pid, :ptype, :status;
-            if (sqlca.sqlcode != 0) break;
-           strtrim(login);
-           dequote(fullname);
-           dequote(nn);
-           dequote(oa);
-           dequote(op);
-           dequote(hp);
-           dequote(shell);
-           u = (struct user *) malloc(sizeof(struct user));
-           strcpy(u->name, login);
-           u->lists = NULL;
-           hash_store(users, id, u);
-           if (status == 1) {
-               fprintf(pout, "%s.passwd\t%s %s \"%s:*:%d:101:%s,%s,%s,%s,%s:/mit/%s:%s\"\n",
-                       login, HCLASS, HTYPE, login, uid, fullname, nn, oa,
-                       op, hp, login, shell);
-               fprintf(uout, "%d.uid\t%s CNAME %s.passwd\n", uid, HCLASS,
-                       login);
-           }
-           if (pid != 0 && (mach = hash_lookup(machines, pid))) {
-               fprintf(bout, "%s.pobox\t%s %s \"POP %s %s\"\n",
-                       login, HCLASS, HTYPE, mach, login);
+  int sawdot;
+
+  for (sawdot = 1; *name; name++)
+    {
+      if (*name == '$')
+       return 0;
+      if (*name == '.')
+       {
+         if (sawdot)
+           return 0;
+         else
+           sawdot = 1;
+       }
+      else
+       sawdot = 0;
+    }
+  return !sawdot;
+}
+
+
+int do_passwd(void)
+{
+  FILE *pout, *uout, *bout;
+  char poutf[MAXPATHLEN], uoutf[MAXPATHLEN], poutft[MAXPATHLEN];
+  char uoutft[MAXPATHLEN], boutf[MAXPATHLEN], boutft[MAXPATHLEN];
+  struct user *u;
+  char *mach;
+  EXEC SQL BEGIN DECLARE SECTION;
+  char login[USERS_LOGIN_SIZE], shell[USERS_SHELL_SIZE];
+  char fullname[USERS_FULLNAME_SIZE], oa[USERS_OFFICE_ADDR_SIZE];
+  char op[USERS_OFFICE_PHONE_SIZE], hp[USERS_HOME_PHONE_SIZE];
+  char nn[USERS_NICKNAME_SIZE], potype[USERS_POTYPE_SIZE];
+  int uid, id, pid, iid, eid, mid, status;
+  EXEC SQL END DECLARE SECTION;
+
+  sprintf(poutf, "%s/passwd.db", hesiod_dir);
+  sprintf(uoutf, "%s/uid.db", hesiod_dir);
+  sprintf(boutf, "%s/pobox.db", hesiod_dir);
+
+  sprintf(poutft, "%s~", poutf);
+  pout = fopen(poutft, "w");
+  if (!pout)
+    {
+      perror("cannot open passwd.db~ for write");
+      exit(MR_OCONFIG);
+    }
+  sprintf(uoutft, "%s~", uoutf);
+  uout = fopen(uoutft, "w");
+  if (!uout)
+    {
+      perror("cannot open uid.db~ for write");
+      exit(MR_OCONFIG);
+    }
+  sprintf(boutft, "%s~", boutf);
+  bout = fopen(boutft, "w");
+  if (!bout)
+    {
+      perror("cannot open pobox.db for write");
+      exit(MR_OCONFIG);
+    }
+
+  fprintf(stderr, "Building passwd.db, uid.db, and pobox.db\n");
+  get_mach();
+
+  users = create_hash(12001);
+  EXEC SQL DECLARE u_cursor CURSOR FOR
+    SELECT login, unix_uid, shell, fullname, nickname, office_addr,
+    office_phone, home_phone, users_id, potype, pop_id, imap_id, exchange_id,
+    status
+    FROM users
+    WHERE status = 1 OR status = 2 OR status = 5 OR status = 6
+    ORDER BY users_id;
+  EXEC SQL OPEN u_cursor;
+  while (1)
+    {
+      EXEC SQL FETCH u_cursor INTO :login, :uid, :shell, :fullname, :nn,
+       :oa, :op, :hp, :id, :potype, :pid, :iid, :eid, :status;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(login);
+      dequote(fullname);
+      dequote(nn);
+      dequote(oa);
+      dequote(op);
+      dequote(hp);
+      dequote(shell);
+      dequote(potype);
+      u = malloc(sizeof(struct user));
+      strcpy(u->name, login);
+      u->lists = NULL;
+      hash_store(users, id, u);
+      if (status == 1 || status == 2)
+       {
+         fprintf(pout, "%s.passwd\t%s %s \"%s:*:%d:101:%s,%s,%s,%s,%s:/mit/%s:%s\"\n",
+                 login, HCLASS, HTYPE, login, uid, fullname, nn, oa,
+                 op, hp, login, shell);
+         fprintf(uout, "%d.uid\t%s CNAME %s.passwd\n", uid, HCLASS, login);
+       }
+
+      if (eid != 0)
+       {
+         /* Check for IMAP.  Can't use iid because it should be zero. */
+         EXEC SQL SELECT mach_id INTO :mid FROM filesys
+           WHERE label = :login || '.po' AND type = 'IMAP';
+         if (sqlca.sqlcode == 0)
+           pid = mid;
+         else
+           {
+             /* EXCHANGE user with no IMAP filesystem.  Give them
+              * IMAP.EXCHANGE.MIT.EDU instead of EXCHANGE.MIT.EDU.
+              */
+             EXEC SQL SELECT mach_id INTO :eid FROM machine
+               WHERE name = 'IMAP.EXCHANGE.MIT.EDU';
+             if (sqlca.sqlcode == 0)
+               pid = eid;
            }
+       }
+
+      if (iid != 0)
+       {
+         EXEC SQL SELECT mach_id INTO :mid FROM filesys
+           WHERE filsys_id = :iid AND type = 'IMAP';
+         if (sqlca.sqlcode == 0)
+           pid = mid;
+       }
+
+      if ((strcmp(potype, "NONE") != 0) &&  pid != 0 &&
+         (mach = hash_lookup(machines, pid)))
+       {
+         fprintf(bout, "%s.pobox\t%s %s \"POP %s %s\"\n",
+                 login, HCLASS, HTYPE, mach, login);
+       }
     }
-    if (sqlca.sqlcode < 0) db_error(sqlca.sqlcode);
-    EXEC SQL CLOSE u_cursor;
-    EXEC SQL COMMIT;
+  if (sqlca.sqlcode < 0)
+    db_error(sqlca.sqlcode);
+  EXEC SQL CLOSE u_cursor;
+  EXEC SQL COMMIT;
 
-    if (fclose(pout) || fclose(uout) || fclose(bout)) {
-       fprintf(stderr, "Unsuccessful file close of passwd.db, uid.db, or pobox.db\n");
-       exit(MR_CCONFIG);
+  if (fclose(pout) || fclose(uout) || fclose(bout))
+    {
+      fprintf(stderr, "Unsuccessful file close of passwd.db, uid.db, or pobox.db\n");
+      exit(MR_CCONFIG);
     }
-    fix_file(poutf);
-    fix_file(uoutf);
-    fix_file(boutf);
-    return(1);
+  fix_file(poutf);
+  fix_file(uoutf);
+  fix_file(boutf);
+  return 1;
 }
 
 
-do_groups()
+int do_groups(void)
 {
-    FILE *iout, *gout, *lout;
-    char ioutf[64], goutf[64], loutf[64], buf[2048], *l;
-    struct hash *groups;
-    register struct bucket *b, **p;
-    struct grp *g;
-    struct user *u;
-    struct stat isb, gsb, lsb;
-    time_t ftime;
-    EXEC SQL BEGIN DECLARE SECTION;
-    char name[33];
-    int gid, id, lid, flag1, flag2, flag3, len;
-    EXEC SQL END DECLARE SECTION;
-
-    /* open files */
-    sprintf(ioutf, "%s/gid.db", hesiod_dir);
-    sprintf(goutf, "%s/group.db", hesiod_dir);
-    sprintf(loutf, "%s/grplist.db", hesiod_dir);
-
-    if (stat(ioutf, &isb) == 0 && stat(goutf, &gsb) == 0 && stat(loutf, &lsb) == 0) {
-       ftime = min(isb.st_mtime, min(gsb.st_mtime, lsb.st_mtime));
-        if (ModDiff (&flag1, "users", ftime) ||
-            ModDiff (&flag2, "list", ftime) ||
-            ModDiff (&flag3, "imembers", ftime))
-            exit (MR_DATE);
-       if (flag1 < 0 && flag2 < 0 && flag3 < 0) {
-           fprintf(stderr, "Files gid.db, group.db and grplist.db do not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(buf, "%s~", ioutf);
-    iout = fopen(buf, "w");
-    if (!iout) {
-       perror("cannot open gid.db for write");
-       exit(MR_OCONFIG);
-    }
-    sprintf(buf, "%s~", goutf);
-    gout = fopen(buf, "w");
-    if (!gout) {
-       perror("cannot open group.db for write");
-       exit(MR_OCONFIG);
-    }
-    sprintf(buf, "%s~", loutf);
-    lout = fopen(buf, "w");
-    if (!lout) {
-       perror("cannot open grplist.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building gid.db, group.db, and grplist.db\n");
-
-    /* make space for group list */
-    groups = create_hash(15001);
-
-    /* The following WHENEVER is declarative, not executed,
-     * and applies for the remainder of this file only.
-     */
-    EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
-
-    EXEC SQL DECLARE l_cursor CURSOR FOR
-      SELECT name, gid, list_id
-      FROM list
-      WHERE grouplist != 0 AND active != 0
-      ORDER BY list_id;
-    EXEC SQL OPEN l_cursor;
-    while (1) {
-       EXEC SQL FETCH l_cursor INTO :name, :gid, :lid;
-       if (sqlca.sqlcode != 0) break;
-       strtrim(name);
-       sprintf(buf, "%s:%d", name, gid);
-       hash_store(groups, lid, strsave(buf));
-       fprintf(iout, "%d.gid\t%s CNAME %s.group\n", gid, HCLASS, name);
-       fprintf(gout, "%s.group\t%s %s \"%s:*:%d:\"\n",
-               name, HCLASS, HTYPE, name, gid);
-    }
-    EXEC SQL CLOSE l_cursor;
-
-    fflush(iout);
-    fflush(gout);
-
-    /* now do grplists */
-    if (users == NULL) {
-       users = create_hash(12001);
-       EXEC SQL DECLARE u_cursor2 CURSOR FOR
-         SELECT users_id, login
-         FROM users
-         WHERE status = 1
-         ORDER BY users_id;
-       EXEC SQL OPEN u_cursor2;
-        while (1) {
-           EXEC SQL FETCH u_cursor2 INTO :id, :name;
-           if (sqlca.sqlcode != 0) break;
-           u = (struct user *) malloc(sizeof(struct user));
-           strcpy(u->name, strtrim(name));
-           u->lists = NULL;
-           hash_store(users, id, u);
+  FILE *iout, *gout, *lout;
+  char ioutf[MAXPATHLEN], goutf[MAXPATHLEN], loutf[MAXPATHLEN];
+  char buf[MAXPATHLEN], *l;
+  struct hash *groups;
+  struct bucket *b, **p;
+  struct grp *g;
+  struct user *u;
+  EXEC SQL BEGIN DECLARE SECTION;
+  char name[LIST_NAME_SIZE];
+  int gid, id, lid, len;
+  EXEC SQL END DECLARE SECTION;
+
+  /* open files */
+  sprintf(ioutf, "%s/gid.db", hesiod_dir);
+  sprintf(goutf, "%s/group.db", hesiod_dir);
+  sprintf(loutf, "%s/grplist.db", hesiod_dir);
+
+  sprintf(buf, "%s~", ioutf);
+  iout = fopen(buf, "w");
+  if (!iout)
+    {
+      perror("cannot open gid.db for write");
+      exit(MR_OCONFIG);
+    }
+  sprintf(buf, "%s~", goutf);
+  gout = fopen(buf, "w");
+  if (!gout)
+    {
+      perror("cannot open group.db for write");
+      exit(MR_OCONFIG);
+    }
+  sprintf(buf, "%s~", loutf);
+  lout = fopen(buf, "w");
+  if (!lout)
+    {
+      perror("cannot open grplist.db for write");
+      exit(MR_OCONFIG);
+    }
+
+  fprintf(stderr, "Building gid.db, group.db, and grplist.db\n");
+
+  /* make space for group list */
+  groups = create_hash(15001);
+
+  /* The following WHENEVER is declarative, not executed,
+   * and applies for the remainder of this file only.
+   */
+  EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
+
+  EXEC SQL DECLARE l_cursor CURSOR FOR
+    SELECT name, gid, list_id
+    FROM list
+    WHERE grouplist != 0 AND active != 0
+    ORDER BY list_id;
+  EXEC SQL OPEN l_cursor;
+  while (1)
+    {
+      char buf[LIST_NAME_SIZE + 10];
+
+      EXEC SQL FETCH l_cursor INTO :name, :gid, :lid;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(name);
+      if (!valid(name))
+       continue;
+      sprintf(buf, "%s:%d", name, gid);
+      hash_store(groups, lid, strdup(buf));
+      fprintf(iout, "%d.gid\t%s CNAME %s.group\n", gid, HCLASS, name);
+      fprintf(gout, "%s.group\t%s %s \"%s:*:%d:\"\n",
+             name, HCLASS, HTYPE, name, gid);
+    }
+  EXEC SQL CLOSE l_cursor;
+
+  fflush(iout);
+  fflush(gout);
+
+  /* now do grplists */
+  if (!users)
+    {
+      users = create_hash(12001);
+      EXEC SQL DECLARE u_cursor2 CURSOR FOR
+       SELECT users_id, login
+       FROM users
+       WHERE status = 1 OR status = 2;
+      EXEC SQL OPEN u_cursor2;
+      while (1)
+       {
+         EXEC SQL FETCH u_cursor2 INTO :id, :name;
+         if (sqlca.sqlcode)
+           break;
+         u = malloc(sizeof(struct user));
+         strcpy(u->name, strtrim(name));
+         u->lists = NULL;
+         hash_store(users, id, u);
        }
-       EXEC SQL CLOSE u_cursor2;
-    }
-
-    EXEC SQL DECLARE i_cursor CURSOR FOR
-      SELECT list_id, member_id
-      FROM imembers
-      WHERE member_type = 'USER'
-      ORDER BY list_id;
-    EXEC SQL OPEN i_cursor;
-    while (1) {
-       EXEC SQL FETCH i_cursor INTO :lid, :id;
-       if (sqlca.sqlcode != 0) break;
-       if (((l = hash_lookup(groups, lid)) != NULL) &&
-           (u = (struct user *) hash_lookup(users, id))) {
-           g = (struct grp *) malloc(sizeof(struct grp));
-           g->next = u->lists;
-           u->lists = g;
-           g->lid = l;
+      EXEC SQL CLOSE u_cursor2;
+    }
+
+  EXEC SQL DECLARE i_cursor CURSOR FOR
+    SELECT m.list_id, m.member_id
+    FROM imembers m, list l 
+    WHERE m.member_type = 'USER'
+    AND m.list_id = l.list_id AND l.grouplist = 1 AND l.nfsgroup = 1;
+  EXEC SQL OPEN i_cursor;
+  while (1)
+    {
+      EXEC SQL FETCH i_cursor INTO :lid, :id;
+      if (sqlca.sqlcode)
+       break;
+      if ((l = hash_lookup(groups, lid)) && (u = hash_lookup(users, id)))
+       {
+         g = malloc(sizeof(struct grp));
+         g->next = u->lists;
+         u->lists = g;
+         g->lid = l;
        }
     }
-    EXEC SQL CLOSE i_cursor;
-
-    EXEC SQL COMMIT;
-
-    for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
-       for (b = *p; b; b = b->next) {
-           if ((g = ((struct user *)b->data)->lists) == NULL)
-             continue;
-           fprintf(lout, "%s.grplist\t%s %s \"",
-                   ((struct user *)b->data)->name, HCLASS, HTYPE);
-           len = 0;
-           for (; g; g = g->next) {
-               if (len + strlen(g->lid) + 1 < MAXHESSIZE) {
-                   fputs(g->lid, lout);
-                   if (g->next)
-                     putc(':', lout);
-                   len += strlen(g->lid) + 1;
-               } else {
-                   com_err(whoami, 0, "truncated grp list for user %s",
-                           ((struct user *)b->data)->name);
-                   break;
+  EXEC SQL CLOSE i_cursor;
+
+  EXEC SQL COMMIT;
+
+  for (p = &(users->data[users->size - 1]); p >= users->data; p--)
+    {
+      for (b = *p; b; b = b->next)
+       {
+         if (!(g = ((struct user *)b->data)->lists))
+           continue;
+         fprintf(lout, "%s.grplist\t%s %s \"",
+                 ((struct user *)b->data)->name, HCLASS, HTYPE);
+         len = 0;
+         for (; g; g = g->next)
+           {
+             if (len + strlen(g->lid) + 1 < MAXHESSIZE)
+               {
+                 fputs(g->lid, lout);
+                 if (g->next)
+                   putc(':', lout);
+                 len += strlen(g->lid) + 1;
+               }
+             else
+               {
+                 com_err(whoami, 0, "truncated grp list for user %s",
+                         ((struct user *)b->data)->name);
+                 break;
                }
            }
-           fputs("\"\n", lout);
+         fputs("\"\n", lout);
        }
     }
 
-    if (fclose(iout) || fclose(gout) || fclose(lout)) {
-       fprintf(stderr, "Unsuccessful close of gid.db, group.db, or grplist.db\n");
-       exit(MR_CCONFIG);
+  if (fclose(iout) || fclose(gout) || fclose(lout))
+    {
+      fprintf(stderr, "Unsuccessful close of gid.db, group.db, or grplist.db\n");
+      exit(MR_CCONFIG);
     }
-    fix_file(ioutf);
-    fix_file(goutf);
-    fix_file(loutf);
-    return(1);
- sqlerr:
-    db_error(sqlca.sqlcode);
-    return(0);
+  fix_file(ioutf);
+  fix_file(goutf);
+  fix_file(loutf);
+  return 1;
+sqlerr:
+  db_error(sqlca.sqlcode);
+  return 0;
 }
 
 
-do_filsys()
+int do_filsys(void)
 {
-    FILE *out;
-    char outf[64], outft[64], *mach, *group;
-    register char *p;
-    struct stat sb;
-    time_t ftime;
-    struct save_queue *sq, *sq2, *sq_create();
-    EXEC SQL BEGIN DECLARE SECTION;
-    char name[33], type[9], loc[81], access[2], mount[33], trans[257];
-    char comments[65];
-    int flag1, flag2, flag3, flag4, id, fid;
-    EXEC SQL END DECLARE SECTION;
-
-    sprintf(outf, "%s/filsys.db", hesiod_dir);
-
-    if (stat(outf, &sb) == 0) {
-       ftime = sb.st_mtime;
-
-       if (ModDiff(&flag1, "filesys", ftime)) exit (MR_DATE);
-       if (ModDiff(&flag2, "machine", ftime)) exit (MR_DATE);
-       if (ModDiff(&flag3, "alias", ftime)) exit (MR_DATE);
-       if (ModDiff(&flag4, "fsgroup", ftime)) exit (MR_DATE);
-
-       if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0) {
-           fprintf(stderr, "File filsys.db does not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(outft, "%s~", outf);
-    out = fopen(outft, "w");
-    if (!out) {
-       perror("cannot open filsys.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building filsys.db\n");
-    get_mach();
-    sq = sq_create();
-    sq2 = sq_create();
-
-    EXEC SQL DECLARE f_cursor CURSOR FOR
-      SELECT label, type, name, mach_id, rwaccess, mount, comments, filsys_id
-      FROM filesys
-      ORDER BY filsys_id;
-    EXEC SQL OPEN f_cursor;
-    while (1) {
-       EXEC SQL FETCH f_cursor INTO :name, :type, :loc, :id, :access, 
-                                   :mount, :comments, :fid;
-       if (sqlca.sqlcode != 0) break;
-       strtrim(type);
-       if (!strcmp(type, "NFS") || !strcmp(type, "RVD")) {
-           if (mach = hash_lookup(machines, id)) {
-               fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s\"\n",
-                       strtrim(name), HCLASS, HTYPE, type, strtrim(loc),
-                       mach, strtrim(access), strtrim(mount));
+  FILE *out;
+  char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach, *group;
+  struct save_queue *sq, *sq2;
+  EXEC SQL BEGIN DECLARE SECTION;
+  char name[FILESYS_LABEL_SIZE], type[FILESYS_TYPE_SIZE];
+  char loc[FILESYS_NAME_SIZE], access[FILESYS_RWACCESS_SIZE];
+  char mount[FILESYS_MOUNT_SIZE], comments[FILESYS_COMMENTS_SIZE];
+  char key[FSGROUP_KEY_SIZE];
+  char aname[ALIAS_NAME_SIZE], trans[ALIAS_TRANS_SIZE];
+  int flag, id, fid;
+  EXEC SQL END DECLARE SECTION;
+
+  sprintf(outf, "%s/filsys.db", hesiod_dir);
+
+  sprintf(outft, "%s~", outf);
+  out = fopen(outft, "w");
+  if (!out)
+    {
+      perror("cannot open filsys.db for write");
+      exit(MR_OCONFIG);
+    }
+
+  fprintf(stderr, "Building filsys.db\n");
+  get_mach();
+  sq = sq_create();
+  sq2 = sq_create();
+
+  EXEC SQL DECLARE f_cursor CURSOR FOR
+    SELECT label, type, name, mach_id, rwaccess, mount, comments, filsys_id
+    FROM filesys
+    ORDER BY filsys_id;
+  EXEC SQL OPEN f_cursor;
+  while (1)
+    {
+      EXEC SQL FETCH f_cursor INTO :name, :type, :loc, :id, :access,
+       :mount, :comments, :fid;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(name);
+      if (!valid(name))
+       continue;
+      strtrim(type);
+      if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
+       {
+         if ((mach = hash_lookup(machines, id)))
+           {
+             fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s\"\n",
+                     name, HCLASS, HTYPE, type, strtrim(loc),
+                     mach, strtrim(access), strtrim(mount));
            }
-       } else if (!strcmp(type, "AFS")) {
-           fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s\"\n",
-                   strtrim(name), HCLASS, HTYPE, strtrim(loc),
-                   strtrim(access), strtrim(mount));
-       } else if (!strcmp(type, "ERR")) {
-           fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
-                   strtrim(name), HCLASS, HTYPE, strtrim(comments));
-       } else if (!strcmp(type, "FSGROUP")) {
-           sprintf(trans, "%s:%d", strtrim(name), fid);
-           sq_save_data(sq, strsave(trans));
-       } else if (!strcmp(type, "MUL")) {
-           sprintf(trans, "%s:%d", strtrim(name), fid);
-           sq_save_data(sq2, strsave(trans));
+       }
+      else if (!strcmp(type, "AFS"))
+       {
+         fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s\"\n",
+                 name, HCLASS, HTYPE, strtrim(loc),
+                 strtrim(access), strtrim(mount));
+       }
+      else if (!strcmp(type, "ERR"))
+       {
+         fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
+                 name, HCLASS, HTYPE, strtrim(comments));
+       }
+      else if (!strcmp(type, "FSGROUP"))
+       {
+         char buf[FILESYS_NAME_SIZE + 10];
+         sprintf(buf, "%s:%d", name, fid);
+         sq_save_data(sq, strdup(buf));
+       }
+      else if (!strcmp(type, "MUL"))
+       {
+         char buf[FILESYS_NAME_SIZE + 10];
+         sprintf(buf, "%s:%d", name, fid);
+         sq_save_data(sq2, strdup(buf));
        }
     }
-    EXEC SQL CLOSE f_cursor;
-
-    while (sq_get_data(sq, &group)) {
-       fid = atoi(strchr(group, ':')+1);
-       *strchr(group, ':') = 0;
-
-       EXEC SQL DECLARE f_cursor2 CURSOR FOR
-         SELECT DISTINCT f.type, f.name, f.mach_id, f.rwaccess, f.mount,
-               f.comments, f.label, g.key
-         FROM filesys f, fsgroup g
-         WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
-         ORDER BY key, label;
-       EXEC SQL OPEN f_cursor2;
-       for (flag1=1;;flag1++) {
-            EXEC SQL FETCH f_cursor2 INTO :type, :loc, :id, :access,:mount,
-                                    :comments, :name, :trans;
-            if (sqlca.sqlcode != 0) break;
-           strtrim(type);
-           if (!strcmp(type, "NFS") || !strcmp(type, "RVD")) {
-               if (mach = hash_lookup(machines, id)) {
-                   fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s %d\"\n",
-                           group, HCLASS, HTYPE, type, strtrim(loc), mach,
-                           strtrim(access), strtrim(mount), flag1);
+  EXEC SQL CLOSE f_cursor;
+
+  while (sq_get_data(sq, &group))
+    {
+      fid = atoi(strchr(group, ':') + 1);
+      *strchr(group, ':') = 0;
+
+      EXEC SQL DECLARE f_cursor2 CURSOR FOR
+       SELECT DISTINCT f.type, f.name, f.mach_id, f.rwaccess, f.mount,
+       f.comments, f.label, g.key
+       FROM filesys f, fsgroup g
+       WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
+       ORDER BY key, label;
+      EXEC SQL OPEN f_cursor2;
+      for (flag = 1; ; flag++)
+       {
+         EXEC SQL FETCH f_cursor2 INTO :type, :loc, :id, :access, :mount,
+           :comments, :name, :key;
+         if (sqlca.sqlcode)
+           break;
+         strtrim(type);
+         if (!strcmp(type, "NFS") || !strcmp(type, "RVD"))
+           {
+             if ((mach = hash_lookup(machines, id)))
+               {
+                 fprintf(out, "%s.filsys\t%s %s \"%s %s %s %s %s %d\"\n",
+                         group, HCLASS, HTYPE, type, strtrim(loc), mach,
+                         strtrim(access), strtrim(mount), flag);
                }
-           } else if (!strcmp(type, "AFS")) {
-               fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s %d\"\n",
-                       group, HCLASS, HTYPE, strtrim(loc), strtrim(access),
-                       strtrim(mount), flag1);
-           } else if (!strcmp(type, "ERR")) {
-               fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
-                       group, HCLASS, HTYPE, strtrim(comments));
+           }
+         else if (!strcmp(type, "AFS"))
+           {
+             fprintf(out, "%s.filsys\t%s %s \"AFS %s %s %s %d\"\n",
+                     group, HCLASS, HTYPE, strtrim(loc), strtrim(access),
+                     strtrim(mount), flag);
+           }
+         else if (!strcmp(type, "ERR"))
+           {
+             fprintf(out, "%s.filsys\t%s %s \"ERR %s\"\n",
+                     group, HCLASS, HTYPE, strtrim(comments));
            }
        }
-        EXEC SQL CLOSE f_cursor2;
-       free(group);
-    }
-    sq_destroy(sq);
-
-    while (sq_get_data(sq2, &group)) {
-        fid = atoi(strchr(group, ':') + 1);
-        *strchr(group, ':') = 0;
-        fprintf(out, "%s.filsys\t%s %s \"MUL", group, HCLASS, HTYPE);
-       EXEC SQL DECLARE f_cursor3 CURSOR FOR
-           SELECT DISTINCT f.label, g.key
-           FROM filesys f, fsgroup g
-           WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
-           ORDER BY key, label;
-       EXEC SQL OPEN f_cursor3;
-       while (1) {
-           EXEC SQL FETCH f_cursor3 INTO :name, :trans;
-           if (sqlca.sqlcode != 0) break;
-            fprintf(out, " %s", strtrim(name));
+      EXEC SQL CLOSE f_cursor2;
+      free(group);
+    }
+  sq_destroy(sq);
+
+  while (sq_get_data(sq2, &group))
+    {
+      fid = atoi(strchr(group, ':') + 1);
+      *strchr(group, ':') = 0;
+      fprintf(out, "%s.filsys\t%s %s \"MUL", group, HCLASS, HTYPE);
+      EXEC SQL DECLARE f_cursor3 CURSOR FOR
+       SELECT DISTINCT f.label, g.key
+       FROM filesys f, fsgroup g
+       WHERE f.filsys_id = g.filsys_id AND g.group_id = :fid
+       ORDER BY key, label;
+      EXEC SQL OPEN f_cursor3;
+      while (1)
+       {
+         EXEC SQL FETCH f_cursor3 INTO :name, :key;
+         if (sqlca.sqlcode)
+           break;
+         fprintf(out, " %s", strtrim(name));
        }
-       EXEC SQL CLOSE f_cursor3;
-        fprintf(out, "\"\n");
-        free(group);
-    }
-    sq_destroy(sq2);
-
-    EXEC SQL DECLARE a_cursor CURSOR FOR
-      SELECT name, trans
-      FROM alias
-      WHERE type = 'FILESYS';
-    EXEC SQL OPEN a_cursor;
-    while (1) {
-        EXEC SQL FETCH a_cursor INTO :name, :trans;
-        if (sqlca.sqlcode != 0) break;
-       fprintf(out, "%s.filsys\t%s CNAME %s.filsys\n",
-               strtrim(name), HCLASS, strtrim(trans));
-    }
-    EXEC SQL CLOSE a_cursor;
-
-    EXEC SQL COMMIT;
-
-    if (fclose(out)) {
-       fprintf(stderr, "Unsuccessful close of filsys.db\n");
-       exit(MR_CCONFIG);
-    }
-    fix_file(outf);
-    return(1);
- sqlerr:
-    db_error(sqlca.sqlcode);
-    return(0);
-}
-
-
-/*
- * Modified from sys/types.h:
- */
-int setsize;   /* = howmany(setbits, NSETBITS) */
+      EXEC SQL CLOSE f_cursor3;
+      fprintf(out, "\"\n");
+      free(group);
+    }
+  sq_destroy(sq2);
+
+  EXEC SQL DECLARE a_cursor CURSOR FOR
+    SELECT name, trans
+    FROM alias
+    WHERE type = 'FILESYS';
+  EXEC SQL OPEN a_cursor;
+  while (1)
+    {
+      EXEC SQL FETCH a_cursor INTO :aname, :trans;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(aname);
+      strtrim(trans);
+      if (!valid(aname) || !valid(trans))
+       continue;
+      fprintf(out, "%s.filsys\t%s CNAME %s.filsys\n",
+             aname, HCLASS, trans);
+    }
+  EXEC SQL CLOSE a_cursor;
 
-typedef long   set_mask;
-#define NSETBITS       (sizeof(set_mask) * NBBY)       /* bits per mask */
-#ifndef howmany
-#define        howmany(x, y)   (((x)+((y)-1))/(y))
-#endif
+  EXEC SQL COMMIT;
 
-#define        SET_SET(n, p)   ((p)[(n)/NSETBITS] |=  (1 << ((n) % NSETBITS)))
-#define        SET_CLR(n, p)   ((p)[(n)/NSETBITS] &= ~(1 << ((n) % NSETBITS)))
-#define        SET_ISSET(n, p) ((p)[(n)/NSETBITS] &   (1 << ((n) % NSETBITS)))
-#define SET_CREATE()   ((set_mask *)malloc(setsize * sizeof(set_mask)))
-#define SET_ZERO(p)    memset((char *)(p), 0, setsize * sizeof(set_mask))
-#define SET_CMP(p1, p2) (memcmp((p1), (p2), setsize * sizeof(set_mask)))
+  if (fclose(out))
+    {
+      fprintf(stderr, "Unsuccessful close of filsys.db\n");
+      exit(MR_CCONFIG);
+    }
+  fix_file(outf);
+  return 1;
+sqlerr:
+  db_error(sqlca.sqlcode);
+  return 0;
+}
 
-int nbitsset(set)
-set_mask *set;
+int nbitsset(set_mask *set)
 {
-    int i, ret;
-    ret = 0;
-    for (i = 0; i < setsize * NSETBITS; i++)
+  int i, ret;
+  ret = 0;
+  for (i = 0; i < setsize * NSETBITS; i++)
+    {
       if (SET_ISSET(i, set))
        ret++;
-    return(ret);
+    }
+  return ret;
 }
 
 
-do_cluster()
+int do_cluster(void)
 {
-    FILE *out;
-    char outf[64], outft[64], *mach, machbuf[41], *p;
-    struct stat sb;
-    time_t ftime;
-    EXEC SQL BEGIN DECLARE SECTION;
-    int flag1, flag2, flag3, flag4, maxmach, maxclu, mid, cid, id;
-    char name[41], label2[17], data[33];
-    EXEC SQL END DECLARE SECTION;
-    set_mask **machs, *ms, *ps;
-    int oneclu;
-
-    sprintf(outf, "%s/cluster.db", hesiod_dir);
-
-    if (stat(outf, &sb) == 0) {
-       ftime = sb.st_mtime;
-        if (ModDiff (&flag1, "clusters", ftime)
-            || ModDiff (&flag2, "machine", ftime)
-            || ModDiff (&flag3, "mcmap", ftime)
-            || ModDiff (&flag4, "svc", ftime)) exit (MR_DATE);
-       if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0) {
-           fprintf(stderr, "File cluster.db does not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(outft, "%s~", outf);
-    out = fopen(outft, "w");
-    if (!out) {
-       perror("cannot open cluster.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building cluster.db\n");
-    get_mach();
-
-    EXEC SQL SELECT MAX(clu_id) INTO :maxclu FROM clusters;
-    maxclu++;
-    setsize = howmany(maxclu, NSETBITS);
-
-    EXEC SQL SELECT MAX(mach_id) INTO :maxmach FROM machine;
-    maxmach++;
-    machs = (set_mask **)malloc((maxmach + 1) * sizeof(set_mask **));
-    memset(machs, 0, (maxmach + 1) * sizeof(int));
-
-    EXEC SQL DECLARE p_cursor CURSOR FOR
-      SELECT mach_id, clu_id
-      FROM mcmap
-      ORDER BY mach_id;
-    EXEC SQL OPEN p_cursor;
-    while (1) {
-        EXEC SQL FETCH p_cursor INTO :mid, :cid;
-        if (sqlca.sqlcode != 0) break;
-        if (!(ms = machs[mid])) {
-           ms = machs[mid] = SET_CREATE();
-           SET_ZERO(ms);
+  FILE *out;
+  char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
+  char machbuf[MACHINE_NAME_SIZE], clubuf[CLUSTERS_NAME_SIZE], *p;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int maxmach, maxclu, mid, cid, id;
+  char name[CLUSTERS_NAME_SIZE];
+  char label[SVC_SERV_LABEL_SIZE], data[SVC_SERV_CLUSTER_SIZE];
+  EXEC SQL END DECLARE SECTION;
+  set_mask **machs, *ms, *ps;
+
+  sprintf(outf, "%s/cluster.db", hesiod_dir);
+
+  sprintf(outft, "%s~", outf);
+  out = fopen(outft, "w");
+  if (!out)
+    {
+      perror("cannot open cluster.db for write");
+      exit(MR_OCONFIG);
+    }
+
+  fprintf(stderr, "Building cluster.db\n");
+  get_mach();
+
+  EXEC SQL SELECT MAX(clu_id) INTO :maxclu FROM clusters;
+  maxclu++;
+  setsize = howmany(maxclu, NSETBITS);
+
+  EXEC SQL SELECT MAX(mach_id) INTO :maxmach FROM machine;
+  maxmach++;
+  machs = malloc((maxmach + 1) * sizeof(set_mask **));
+  memset(machs, 0, (maxmach + 1) * sizeof(int));
+
+  EXEC SQL DECLARE p_cursor CURSOR FOR
+    SELECT mach_id, clu_id
+    FROM mcmap
+    ORDER BY mach_id;
+  EXEC SQL OPEN p_cursor;
+  while (1)
+    {
+      EXEC SQL FETCH p_cursor INTO :mid, :cid;
+      if (sqlca.sqlcode)
+       break;
+      if (!(ms = machs[mid]))
+       {
+         ms = machs[mid] = SET_CREATE();
+         SET_ZERO(ms);
        }
-       SET_SET(cid, ms);
-    }
-    EXEC SQL CLOSE p_cursor;
-
-    for (mid = 1; mid < maxmach; mid++) {
-       if (!machs[mid])
-         continue;
-       ms = machs[mid];
-       if (nbitsset(ms) > 1) {
-           oneclu = 0;
-           for (cid = 1; cid < maxclu; cid++) {
-               if (SET_ISSET(cid, ms)) {
-                   EXEC SQL DECLARE d_cursor CURSOR FOR
-                     SELECT serv_label, serv_cluster
-                     FROM svc
-                     WHERE clu_id = :cid;
-                   EXEC SQL OPEN d_cursor;
-                   while (1) {
-                       EXEC SQL FETCH d_cursor INTO :label2, :data;
-                       if (sqlca.sqlcode != 0) break;
-                       strtrim(label2);
-                       strtrim(data);
-                       fprintf(out,
-                               "mrinternal-%d.cluster\t%s %s \"%s %s\"\n",
-                               mid, HCLASS, HTYPE, label2, data);
+      SET_SET(cid, ms);
+    }
+  EXEC SQL CLOSE p_cursor;
+
+  for (mid = 1; mid < maxmach; mid++)
+    {
+      if (!machs[mid])
+       continue;
+      ms = machs[mid];
+      if (nbitsset(ms) > 1)
+       {
+         sprintf(clubuf, "mrinternal-%d", mid);
+         for (cid = 1; cid < maxclu; cid++)
+           {
+             if (SET_ISSET(cid, ms))
+               {
+                 EXEC SQL DECLARE d_cursor CURSOR FOR
+                   SELECT serv_label, serv_cluster
+                   FROM svc
+                   WHERE clu_id = :cid;
+                 EXEC SQL OPEN d_cursor;
+                 while (1)
+                   {
+                     EXEC SQL FETCH d_cursor INTO :label, :data;
+                     if (sqlca.sqlcode)
+                       break;
+                     strtrim(label);
+                     strtrim(data);
+                     fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
+                             clubuf, HCLASS, HTYPE, label, data);
                    }
-                   EXEC SQL CLOSE d_cursor;
+                 EXEC SQL CLOSE d_cursor;
                }
            }
-       } else {
-           oneclu = 1;
-           for (cid = 1; cid < maxclu; cid++)
-             if (SET_ISSET(cid, ms)) break;
-
-           EXEC SQL SELECT name INTO :name FROM clusters WHERE clu_id = :cid;
-           strtrim(name);
+       }
+      else
+       {
+         for (cid = 1; cid < maxclu; cid++)
+           if (SET_ISSET(cid, ms))
+             break;
+
+         EXEC SQL SELECT name INTO :name FROM clusters WHERE clu_id = :cid;
+         strtrim(name);
+         if (!valid(name))
+           continue;
+         strcpy(clubuf, name);
        }
 
-       if (mach = hash_lookup(machines, mid)) {
-           for (p = machbuf; *mach && *mach != '.'; mach++)
-             *p++ = *mach;
-           *p = 0;
-           if (oneclu)
+      if ((mach = hash_lookup(machines, mid)))
+       {
+         fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
+                 mach, HCLASS, clubuf);
+         for (p = machbuf; *mach && *mach != '.'; mach++)
+           *p++ = *mach;
+         if (!strcasecmp(mach, ".mit.edu"))
+           {
+             *p = '\0';
              fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
-                     machbuf, HCLASS, name);
-           else
-             fprintf(out, "%s.cluster\t%s CNAME mrinternal-%d.cluster\n",
-                     machbuf, HCLASS, mid);
+                     machbuf, HCLASS, clubuf);
+           }
        }
-       for (id = mid + 1; id < maxmach; id++) {
-           if ((ps = machs[id]) && !SET_CMP(ms, ps)) {
-               free(ps);
-               machs[id] = NULL;
-               if (mach = hash_lookup(machines, id)) {
-                   for (p = machbuf; *mach && *mach != '.'; mach++)
-                     *p++ = *mach;
-                   *p = 0;
-                   if (oneclu)
+      for (id = mid + 1; id < maxmach; id++)
+       {
+         if ((ps = machs[id]) && !SET_CMP(ms, ps))
+           {
+             free(ps);
+             machs[id] = NULL;
+             if ((mach = hash_lookup(machines, id)))
+               {
+                 fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
+                         mach, HCLASS, clubuf);
+                 for (p = machbuf; *mach && *mach != '.'; mach++)
+                   *p++ = *mach;
+                 if (!strcasecmp(mach, ".mit.edu"))
+                   {
+                     *p = '\0';
                      fprintf(out, "%s.cluster\t%s CNAME %s.cluster\n",
-                             machbuf, HCLASS, name);
-                   else
-                     fprintf(out,
-                             "%s.cluster\t%s CNAME mrinternal-%d.cluster\n",
-                             machbuf, HCLASS, mid);
+                             machbuf, HCLASS, clubuf);
+                   }
                }
            }
        }
-       free(ms);
-       machs[mid] = NULL;
-    }
-
-    EXEC SQL DECLARE d_cursor2 CURSOR FOR
-      SELECT c.name, d.serv_label, d.serv_cluster
-      FROM svc d, clusters c
-      WHERE c.clu_id = d.clu_id; 
-    EXEC SQL OPEN d_cursor2; 
-        while (1) { 
-            EXEC SQL FETCH d_cursor2 INTO :name, :label2, :data; 
-            if (sqlca.sqlcode != 0) break;
-           strtrim(name);
-           strtrim(label2);
-           strtrim(data);
-           fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
-                   name, HCLASS, HTYPE, label2, data);
-    }
-    free(machs);
-    EXEC SQL COMMIT;
-
-    if (fclose(out)) {
-       fprintf(stderr, "Unsuccessful close of cluster.db\n");
-       exit(MR_CCONFIG);
-    }
-    fix_file(outf);
-    return(1);
- sqlerr:
-    db_error(sqlca.sqlcode);
-    return(0);
+      free(ms);
+      machs[mid] = NULL;
+    }
+
+  EXEC SQL DECLARE d_cursor2 CURSOR FOR
+    SELECT c.name, d.serv_label, d.serv_cluster
+    FROM svc d, clusters c
+    WHERE c.clu_id = d.clu_id;
+  EXEC SQL OPEN d_cursor2;
+  while (1)
+    {
+      EXEC SQL FETCH d_cursor2 INTO :name, :label, :data;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(name);
+      if (!valid(name))
+       continue;
+      strtrim(label);
+      strtrim(data);
+      fprintf(out, "%s.cluster\t%s %s \"%s %s\"\n",
+             name, HCLASS, HTYPE, label, data);
+    }
+  free(machs);
+  EXEC SQL COMMIT;
+
+  if (fclose(out))
+    {
+      fprintf(stderr, "Unsuccessful close of cluster.db\n");
+      exit(MR_CCONFIG);
+    }
+  fix_file(outf);
+  return 1;
+sqlerr:
+  db_error(sqlca.sqlcode);
+  return 0;
 }
 
 
-do_printcap()
+int do_printcap(void)
 {
-    FILE *out;
-    char outf[64], outft[64];
-    struct stat sb;
-    time_t ftime;
-    EXEC SQL BEGIN DECLARE SECTION;
-    char name[17], rp[17], sd[33];
-    int flag1, flag2, ka, pc, rm, rq;
-    EXEC SQL END DECLARE SECTION;
-
-    sprintf(outf, "%s/printcap.db", hesiod_dir);
-
-    if (stat(outf, &sb) == 0) {
-       ftime = sb.st_mtime;
-       if (ModDiff (&flag1, "printcap", ftime)
-           || ModDiff (&flag2, "machine", ftime))
-         exit (MR_DATE);
-       if (flag1 < 0 && flag2 < 0) {
-           fprintf(stderr, "File printcap.db does not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(outft, "%s~", outf);
-    out = fopen(outft, "w");
-    if (!out) {
-       perror("cannot open printcap.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building printcap.db\n");
-    get_mach();
-
-    EXEC SQL DECLARE p_cursor2 CURSOR FOR
-      SELECT name, rp, dir, mach_id, auth, price, quotaserver
-      FROM printcap;
-    EXEC SQL OPEN p_cursor2; 
-    while (1) { 
-        EXEC SQL FETCH p_cursor2 INTO :name, :rp, :sd, :rm, :ka, :pc, :rq; 
-        if (sqlca.sqlcode != 0) break;
-       if (!hash_lookup(machines, rm)) continue;
-       strtrim(name);
-       strtrim(rp);
-       strtrim(sd);
-       fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:sd=%s:ka#%d:pc#%d",
-               name, HCLASS, HTYPE, name, rp, hash_lookup(machines, rm),
-               sd, ka, pc);
-       if (rq && hash_lookup(machines, rq))
-         fprintf(out, ":rq=%s\"\n", hash_lookup(machines, rq));
-       else
-         fputs("\"\n", out);
-    }
-    EXEC SQL CLOSE p_cursor2;
-
-    EXEC SQL COMMIT;
-
-    if (fclose(out)) {
-       fprintf(stderr, "Unsuccessful close of pcap.db\n");
-       exit(MR_CCONFIG);
-    }
-    fix_file(outf);
-    return(1);
- sqlerr:
-    db_error(sqlca.sqlcode);
-    return(0);
-  }
+  FILE *out;
+  char outf[MAXPATHLEN], outft[MAXPATHLEN];
+  EXEC SQL BEGIN DECLARE SECTION;
+  char name[PRINTERS_NAME_SIZE], duplexname[PRINTERS_DUPLEXNAME_SIZE];
+  char rp[PRINTERS_RP_SIZE], type[PRINTERS_TYPE_SIZE];
+  char duplexrp[PRINTERS_RP_SIZE], pskind[PRINTSERVERS_KIND_SIZE];
+  int ka, rm, mc;
+  EXEC SQL END DECLARE SECTION;
+  char *rmname;
+
+  sprintf(outf, "%s/printcap.db", hesiod_dir);
+
+  sprintf(outft, "%s~", outf);
+  out = fopen(outft, "w");
+  if (!out)
+    {
+      perror("cannot open printcap.db for write");
+      exit(MR_OCONFIG);
+    }
 
+  fprintf(stderr, "Building printcap.db\n");
+  get_mach();
+
+  EXEC SQL DECLARE p_cursor2 CURSOR FOR
+    SELECT p.name, p.duplexname, p.type, p.rp, p.rm, p.ka, p.mc, ps.kind
+    FROM printers p, printservers ps
+    WHERE p.rm = ps.mach_id;
+  EXEC SQL OPEN p_cursor2;
+  while (1)
+    {
+      EXEC SQL FETCH p_cursor2 INTO :name, :duplexname, :type,
+       :rp, :rm, :ka, :mc, :pskind;
+      if (sqlca.sqlcode)
+       break;
+      if (!(rmname = hash_lookup(machines, rm)))
+       continue;
+      strtrim(name);
+      if (!valid(name))
+       continue;
+      strtrim(rp);
+      fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:mc#%d:",
+             name, HCLASS, HTYPE, name, rp, rmname, ka, mc);
+
+      strtrim(pskind);
+      if (!strcmp(pskind, "BSD"))
+       fprintf(out, "auth=none:remote_support=RQM:");
+      else if (!strcmp(pskind, "ATHENA"))
+       {
+         fprintf(out, "auth=%s:az:remote_support=RQM:",
+                 ka ? "kerberos4" : "none");
+       }
+      else if (!strcmp(pskind, "LPRNG"))
+       fprintf(out, "auth=kerberos5:xn:");
+
+      fputs("\"\n", out);
+
+      strtrim(duplexname);
+      if (!valid(duplexname))
+       continue;
+      if (!strcmp(strtrim(type), "ALIAS"))
+       {
+         EXEC SQL SELECT duplexname INTO :duplexrp
+           FROM printers WHERE name = :rp;
+         strtrim(duplexrp);
+       }
+      else
+       strcpy(duplexrp, duplexname);
+      fprintf(out, "%s.pcap\t%s %s \"%s:rp=%s:rm=%s:ka#%d:mc#%d:",
+             duplexname, HCLASS, HTYPE, duplexname, duplexrp,
+             rmname, ka, mc);
+
+      if (!strcmp(pskind, "BSD"))
+       fprintf(out, "auth=none:remote_support=RQM:");
+      else if (!strcmp(pskind, "ATHENA"))
+       {
+         fprintf(out, "auth=%s:az:remote_support=RQM:",
+                 ka ? "kerberos4" : "none");
+       }
+      else if (!strcmp(pskind, "LPRNG"))
+       fprintf(out, "auth=kerberos5:xn:");
 
-do_palladium()
-{
-    FILE *out;
-    char outf[64], outft[64];
-    struct stat sb;
-    time_t ftime;
-    EXEC SQL BEGIN DECLARE SECTION;
-    char name[33], trans[129];
-    int flag, flag1, identifier, rm;
-    EXEC SQL END DECLARE SECTION;
-
-    sprintf(outf, "%s/palladium.db", hesiod_dir);
-
-    if (stat(outf, &sb) == 0) {
-       ftime = sb.st_mtime;
-       if ((ModDiff (&flag, "palladium", ftime)) ||
-            (ModDiff (&flag1, "alias", ftime))) exit (MR_DATE);
-       if (flag < 0 && flag1 < 0) {
-           fprintf(stderr, "File palladium.db does not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(outft, "%s~", outf);
-    out = fopen(outft, "w");
-    if (!out) {
-       perror("cannot open palladium.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building palladium.db\n");
-    get_mach();
-
-    EXEC SQL DECLARE p_cursor3 CURSOR FOR
-      SELECT name, identifier, mach_id
-      FROM palladium;
-    EXEC SQL OPEN p_cursor3; 
-    while (1) { 
-        EXEC SQL FETCH p_cursor3 INTO :name, :identifier, :rm;
-        if (sqlca.sqlcode != 0) break;
-       if (!hash_lookup(machines, rm)) break;
-       strtrim(name);
-       fprintf(out,
-               "%s.palladium\t%s %s \"%s %d %s interface directory\"\n",
-               name, HCLASS, HTYPE, hash_lookup(machines, rm), identifier,
-               name);
-    }
-    EXEC SQL CLOSE p_cursor3;
-
-    EXEC SQL DECLARE a_cursor2 CURSOR FOR
-      SELECT name, trans
-      FROM alias
-      WHERE type = 'PALLADIUM';
-    EXEC SQL OPEN a_cursor2; 
-    while (1) { 
-        EXEC SQL FETCH a_cursor2 INTO :name, :trans;
-        if (sqlca.sqlcode != 0) break;
-       strtrim(name);
-       strtrim(trans);
-       fprintf(out, "%s.palladium\t%s %s \"%s\"\n", name, HCLASS, HTYPE,
-               trans);
-    }
-    EXEC SQL CLOSE a_cursor2;
-
-    EXEC SQL COMMIT;
-
-    if (fclose(out)) {
-       fprintf(stderr, "Unsuccessful close of palladium.db\n");
-       exit(MR_CCONFIG);
-    }
-    fix_file(outf);
-    return(1);
- sqlerr:
-    db_error(sqlca.sqlcode);
-    return(0);
+      fputs("\"\n", out);
+    }
+  EXEC SQL CLOSE p_cursor2;
+
+  EXEC SQL COMMIT;
+
+  if (fclose(out))
+    {
+      fprintf(stderr, "Unsuccessful close of pcap.db\n");
+      exit(MR_CCONFIG);
+    }
+  fix_file(outf);
+  return 1;
+sqlerr:
+  db_error(sqlca.sqlcode);
+  return 0;
 }
 
 
-do_sloc()
+int do_sloc(void)
 {
-    FILE *out;
-    char outf[64], outft[64], *mach;
-    struct stat sb;
-    time_t ftime;
-    EXEC SQL BEGIN DECLARE SECTION;
-    char service[17];
-    int flag1, flag2, id;
-    EXEC SQL END DECLARE SECTION;
-
-    sprintf(outf, "%s/sloc.db", hesiod_dir);
-
-    if (stat(outf, &sb) == 0) {
-       ftime = sb.st_mtime;
-       if ((ModDiff (&flag1, "serverhosts", ftime)) ||
-           (ModDiff (&flag2, "machine", ftime))) exit (MR_DATE);
-       if (flag1 < 0 && flag2 < 0) {
-           fprintf(stderr, "File sloc.db does not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(outft, "%s~", outf);
-    out = fopen(outft, "w");
-    if (!out) {
-       perror("cannot open sloc.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building sloc.db\n");
-    get_mach();
-
-    EXEC SQL DECLARE s_cursor CURSOR FOR
-      SELECT DISTINCT service, mach_id
-      FROM serverhosts
-      ORDER BY service;
-    EXEC SQL OPEN s_cursor; 
-    while (1) { 
-       EXEC SQL FETCH s_cursor INTO :service, :id;
-       if (sqlca.sqlcode != 0) break;
-       strtrim(service);
-       if (mach = hash_lookup(machines, id))
-         fprintf(out, "%s.sloc\t%s %s %s\n", service, HCLASS, HTYPE, mach);
-    }
-    EXEC SQL CLOSE s_cursor;
-
-    EXEC SQL COMMIT;
-
-    if (fclose(out)) {
-       fprintf(stderr, "Unsuccessful close of sloc.db\n");
-       exit(MR_CCONFIG);
-    }
-
-    fix_file(outf);
-    return(1);
- sqlerr:
-    db_error(sqlca.sqlcode);
-    return(0);
+  FILE *out;
+  char outf[MAXPATHLEN], outft[MAXPATHLEN], *mach;
+  EXEC SQL BEGIN DECLARE SECTION;
+  char service[SERVERHOSTS_SERVICE_SIZE];
+  int id;
+  EXEC SQL END DECLARE SECTION;
+
+  sprintf(outf, "%s/sloc.db", hesiod_dir);
+
+  sprintf(outft, "%s~", outf);
+  out = fopen(outft, "w");
+  if (!out)
+    {
+      perror("cannot open sloc.db for write");
+      exit(MR_OCONFIG);
+    }
+
+  fprintf(stderr, "Building sloc.db\n");
+  get_mach();
+
+  EXEC SQL DECLARE s_cursor CURSOR FOR
+    SELECT DISTINCT service, mach_id
+    FROM serverhosts
+    ORDER BY service;
+  EXEC SQL OPEN s_cursor;
+  while (1)
+    {
+      EXEC SQL FETCH s_cursor INTO :service, :id;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(service);
+      if (valid(service) && (mach = hash_lookup(machines, id)))
+       fprintf(out, "%s.sloc\t%s %s %s\n", service, HCLASS, HTYPE, mach);
+    }
+  EXEC SQL CLOSE s_cursor;
+
+  EXEC SQL COMMIT;
+
+  if (fclose(out))
+    {
+      fprintf(stderr, "Unsuccessful close of sloc.db\n");
+      exit(MR_CCONFIG);
+    }
+
+  fix_file(outf);
+  return 1;
+sqlerr:
+  db_error(sqlca.sqlcode);
+  return 0;
 }
 
-do_service()
+int do_service(void)
 {
-    FILE *out;
-    char outf[64], outft[64];
-    struct stat sb;
-    time_t ftime;
-    EXEC SQL BEGIN DECLARE SECTION;
-    char service[33], protocol[9], altserv[129];
-    int port, flag1;
-    EXEC SQL END DECLARE SECTION;
-
-    sprintf(outf, "%s/service.db", hesiod_dir);
-
-    if (stat(outf, &sb) == 0) {
-       ftime = sb.st_mtime;
-       if (ModDiff (&flag1, "services", ftime)) exit (MR_DATE);
-       if (flag1 < 0) {
-           fprintf(stderr, "File service.db does not need to be rebuilt.\n");
-           return(0);
-      }
-    }
-
-    sprintf(outft, "%s~", outf);
-    out = fopen(outft, "w");
-    if (!out) {
-       perror("cannot open service.db for write");
-       exit(MR_OCONFIG);
-    }
-
-    fprintf(stderr, "Building service.db\n");
-
-    EXEC SQL DECLARE s_cursor2 CURSOR FOR
-      SELECT name, protocol, port
-      FROM services;
-    EXEC SQL OPEN s_cursor2;
-    while (1) { 
-        EXEC SQL FETCH s_cursor2 INTO :service, :protocol, :port;
-        if (sqlca.sqlcode != 0) break;
-       lowercase(protocol);      /* Convert protocol to lowercase */
-       strtrim(service);
-       strtrim(protocol);
-       fprintf(out, "%s.service\t%s %s \"%s %s %d\"\n",
-               service, HCLASS, HTYPE, service, protocol, port);
-    }
-    EXEC SQL CLOSE s_cursor2;
-
-    EXEC SQL DECLARE a_cursor3 CURSOR FOR
-      SELECT name, trans
-      FROM alias
-      WHERE type = 'SERVICE';
-    EXEC SQL OPEN a_cursor3; 
-    while (1) { 
-        EXEC SQL FETCH a_cursor3 INTO :service, :altserv;
-        if (sqlca.sqlcode != 0) break;
-       strtrim(service);
-       strtrim(altserv);
-       fprintf(out, "%s.service\t%s CNAME %s.service\n", service, HCLASS,
-               altserv);
-    }
-    EXEC SQL CLOSE a_cursor3;
-
-    EXEC SQL COMMIT;
-
-    if (fclose(out)) {
-       fprintf(stderr, "Unsuccessful close of service.db\n");
-       exit(MR_CCONFIG);
-    }
-    fix_file(outf);
-    return(1);
- sqlerr:
-    db_error(sqlca.sqlcode);
-    return(0);
+  FILE *out;
+  char outf[MAXPATHLEN], outft[MAXPATHLEN];
+  EXEC SQL BEGIN DECLARE SECTION;
+  char service[SERVICES_NAME_SIZE], protocol[SERVICES_PROTOCOL_SIZE];
+  char aname[ALIAS_NAME_SIZE], trans[ALIAS_TRANS_SIZE];
+  int port;
+  EXEC SQL END DECLARE SECTION;
+
+  sprintf(outf, "%s/service.db", hesiod_dir);
+
+  sprintf(outft, "%s~", outf);
+  out = fopen(outft, "w");
+  if (!out)
+    {
+      perror("cannot open service.db for write");
+      exit(MR_OCONFIG);
+    }
+
+  fprintf(stderr, "Building service.db\n");
+
+  EXEC SQL DECLARE s_cursor2 CURSOR FOR
+    SELECT name, protocol, port
+    FROM services;
+  EXEC SQL OPEN s_cursor2;
+  while (1)
+    {
+      EXEC SQL FETCH s_cursor2 INTO :service, :protocol, :port;
+      if (sqlca.sqlcode)
+       break;
+      lowercase(protocol);      /* Convert protocol to lowercase */
+      strtrim(service);
+      if (!valid(service))
+       continue;
+      strtrim(protocol);
+      fprintf(out, "%s.service\t%s %s \"%s %s %d\"\n",
+             service, HCLASS, HTYPE, service, protocol, port);
+    }
+  EXEC SQL CLOSE s_cursor2;
+
+  EXEC SQL DECLARE a_cursor3 CURSOR FOR
+    SELECT name, trans
+    FROM alias
+    WHERE type = 'SERVICE';
+  EXEC SQL OPEN a_cursor3;
+  while (1)
+    {
+      EXEC SQL FETCH a_cursor3 INTO :aname, :trans;
+      if (sqlca.sqlcode)
+       break;
+      strtrim(aname);
+      strtrim(trans);
+      if (!valid(aname) || !valid(trans))
+       continue;
+      fprintf(out, "%s.service\t%s CNAME %s.service\n", aname, HCLASS,
+             trans);
+    }
+  EXEC SQL CLOSE a_cursor3;
+
+  EXEC SQL COMMIT;
+
+  if (fclose(out))
+    {
+      fprintf(stderr, "Unsuccessful close of service.db\n");
+      exit(MR_CCONFIG);
+    }
+  fix_file(outf);
+  return 1;
+sqlerr:
+  db_error(sqlca.sqlcode);
+  return 0;
 }
This page took 0.104054 seconds and 4 git commands to generate.