]> andersk Git - moira.git/blobdiff - gen/aliases.qc
Used /bin/sh format instead of /bin/csh format, by accident.
[moira.git] / gen / aliases.qc
index 61244a8897bb16c56ce1f1df78643efe325899b5..1b50e534b3c22f038737c328b75d0bfd55d4b101 100644 (file)
@@ -5,13 +5,18 @@
  *     user pobox entries
  *     maillist expansions
  *     sublists of maillists
- *     mail alias entries
+ *
+ *  (c) Copyright 1988 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 <sms.h>
-#include <sms_app.h>
+#include <string.h>
+#include <moira.h>
+#include <moira_site.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 
 char *divide = "########################################################################";
 extern int errno;
+char *whoami = "aliases.gen";
 char *ingres_date_and_time();
-
+FILE *out;
 
 main(argc, argv)
 int argc;
 char **argv;
 {
     long tm = time(NULL);
-    FILE *out= stdout;
+    char filename[64], *targetfile;
     struct stat sb;
-##  int error, flag1, flag2, flag3;
+##  int flag1, flag2, flag3;
 ##  char *filetime;
+    int ingerr();
 
+    out= stdout;
+    IIseterr(ingerr);
+    initialize_sms_error_table();
 ##  ingres sms
+##  set lockmode session where level = table
 
     if (argc == 2) {
        if (stat(argv[1], &sb) == 0) {
@@ -43,119 +54,274 @@ char **argv;
 ##         retrieve (flag1 = int4(interval("min",tblstats.modtime - filetime)))
 ##             where tblstats.table = "list"
 ##         retrieve (flag2 = int4(interval("min",tblstats.modtime - filetime)))
-##             where tblstats.table = "members"
+##             where tblstats.table = "imembers"
 ##         retrieve (flag3 = int4(interval("min",tblstats.modtime - filetime)))
 ##             where tblstats.table = "users"
            if (flag1 < 0 && flag2 < 0 && flag3 < 0) {
                fprintf(stderr, "File %s does not need to be rebuilt.\n",
                        argv[1]);
-               exit(0);
+               exit(MR_NO_CHANGE);
            }
        }
-       if ((out = fopen(argv[1], "w")) == NULL) {
-           fprintf(stderr, "unable to open %s for output\n", argv[1]);
-           exit(errno);
+       targetfile = argv[1];
+       sprintf(filename, "%s~", targetfile);
+       if ((out = fopen(filename, "w")) == NULL) {
+           fprintf(stderr, "unable to open %s for output\n", filename);
+           exit(MR_OCONFIG);
        }
     } else if (argc != 1) {
        fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
-       exit(-1);
+       exit(MR_ARGS);
     }
 
-##  set lockmode session where readlock = nolock
-
-    
     fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
     fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
 
+##  begin transaction
+    get_info();
+##  end transaction
+##  exit
+
+    fprintf(stderr, "Dumping information\n");
     do_mlists(out);
     do_poboxes(out);
-    do_aliases(out);
 
     fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
 
-##  inquire_equel(error = "errorno")
-    if (error)  {
-       fprintf(out, "Ingres error %d\n", error);
-       exit(error);
-    }
-
-##  exit
 
     if (fclose(out)) {
        perror("close failed");
-       exit(errno);
+       exit(MR_CCONFIG);
     }
-    exit(0);
+
+    if (argc == 2)
+      fix_file(targetfile);
+    exit(MR_SUCCESS);
 }
 
 
-/* Extract mailing lists.  First dump all real mailing lists.  While doing
- * this, make a list of all mailing list IDs and all sub-list IDs.  Next,
- * as long as there are sub-lists that aren't mailing lists, extract them
- * and add them to the list of mailing lists.  If further sublists are 
- * encountered, repeat...
+/*
+ * ingerr: (supposedly) called when Ingres indicates an error.
+ * I have not yet been able to get this to work to intercept a
+ * database open error.
  */
+#define INGRES_DEADLOCK 4700
 
-int lwid, bol;
+static int ingerr(num)
+    int *num;
+{
+    int ingres_errno;
+
+    switch (*num) {
+    case INGRES_DEADLOCK:
+       ingres_errno = MR_DEADLOCK;
+       break;
+    default:
+       ingres_errno = MR_INGRES_ERR;
+    }
+    com_err(whoami, MR_INGRES_ERR, " code %d\n", *num);
+    critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
+    exit(ingres_errno);
+}
 
-do_mlists(out)
-FILE *out;
+
+struct hash *users, *machines, *strings, *lists;
+struct user {
+    char login[9];
+    char *pobox;
+};
+struct member {
+    struct member *next;
+    char *name;
+    int list_id;
+};
+struct list {
+    char *name;
+    char maillist;
+    char acl_t;
+    char *description;
+    int acl_id;
+    struct member *m;
+};
+
+
+get_info()
 ##{
-##  char name[257], desc[257], own_type[9], owner_name[33];
-##  int id, own_id, member_id;
-    struct save_queue *sq, *sq_create();
+##  int id, maillistp, acl, pid, bid, mid;
+##  char name[129], type[9], buf[257];
+    char *s;
+    register struct user *u;
+    register struct list *l;
+    register struct member *m;
+    register struct list *memberlist;
+
+    /* get locks */
+##  retrieve (buf = list.modtime) where list.list_id = 0
+##  retrieve (buf = users.modtime) where users.users_id = 0
+
+    fprintf(stderr, "Loading machines\n");
+    machines = create_hash(1000);
+##  retrieve (id = machine.mach_id, name = machine.#name) {
+      if (s = index(name, '.'))
+       *s = 0;
+#ifdef ATHENA
+      strcat(name, ".LOCAL");
+#endif
+      hash_store(machines, id, strsave(name));
+##  }
 
-    sq = sq_create();
-    fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
+    fprintf(stderr, "Loading strings\n");
+    strings = create_hash(2000);
+##  retrieve (id = strings.string_id, name = strings.string) {
+       hash_store(strings, id, strsave(strtrim(name)));
+##  }
 
+    fprintf(stderr, "Loading users\n");
+    users = create_hash(12001);
+##  range of u is users
+##  retrieve (id = u.users_id, name = u.login, type = u.potype,
+##           pid = u.pop_id, bid = u.box_id) 
+##     where u.status = 1 or u.status = 5 or u.status = 6 {
+       u = (struct user *) malloc(sizeof(struct user));
+       strcpy(u->login, strtrim(name));
+       if (type[0] == 'P') {
+           if (s = hash_lookup(machines, pid)) {
+               sprintf(buf, "%s@%s", name, s);
+               u->pobox = strsave(buf);
+           } else {
+               u->pobox = (char *) NULL;
+               fprintf(stderr, "User %s's pobox is on a missing machine!\n",
+                       u->login);
+           }
+       } else if (type[0] ==  'S') {
+           if ((u->pobox = hash_lookup(strings, bid)) == NULL) {
+               u->pobox = (char *) NULL;
+               fprintf(stderr, "User %s's pobox string is missing!\n",
+                       u->login);
+           }
+       } else
+         u->pobox = (char *) NULL;
+       hash_store(users, id, u);
+##  }
+
+    fprintf(stderr, "Loading lists\n");
+    lists = create_hash(15001);
 ##  range of l is list
-##  retrieve (id = l.list_id) where l.maillist != 0 {
-      sq_save_unique_data(sq, id);
+##  retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist,
+##           buf = l.desc, type = l.acl_type, acl = l.acl_id)
+##    where l.active != 0 {
+       l = (struct list *) malloc(sizeof(struct list));
+       l->name = strsave(strtrim(name));
+       l->maillist = maillistp;
+       l->description = strsave(strtrim(buf));
+       l->acl_t = type[0];
+       l->acl_id = acl;
+       l->m = (struct member *) NULL;
+       hash_store(lists, id, l);
 ##  }
 
-##  range of m is members
-##  range of u is users
-##  range of s is strings
-    while (sq_get_data(sq, &id)) {
-##     repeat retrieve (name= l.#name, desc = l.#desc,
-##               own_type = l.acl_type, own_id = l.acl_id)
-##             where l.list_id = @id
-       trim(name);
-       trim(desc);
-       trim(own_type);
-       put_fill(out, desc);
-       if (!strcmp(own_type, "LIST")) {
-##         repeat retrieve (owner_name = l.#name) where l.list_id = @own_id
-           trim(owner_name);
-           fprintf(out, "owner-%s: %s\n", name, owner_name);
-           sq_save_unique_data(sq, own_id);
-       } else if (!strcmp(own_type, "USER")) {
-##         repeat retrieve (owner_name = u.#login) where u.users_id = @own_id
-           trim(owner_name);
-           fprintf(out, "owner-%s: %s\n", name, owner_name);
+
+    fprintf(stderr, "Loading members\n");
+##  range of m is imembers
+##  retrieve (id = m.list_id, type = m.member_type, mid = m.member_id)
+##     where m.direct = 1  {
+       if (l = (struct list *) hash_lookup(lists, id)) {
+           m = (struct member *) malloc(sizeof(struct member));
+           if (type[0] == 'U' &&
+               (u = (struct user *) hash_lookup(users, mid))) {
+               m->list_id = 0;
+               m->name = u->login;
+               m->next = l->m;
+               l->m = m;
+           } else if (type[0] == 'L' &&
+                      (memberlist = (struct list *) hash_lookup(lists, mid))) {
+               m->list_id = mid;
+               m->name = memberlist->name;
+               m->next = l->m;
+               l->m = m;
+           } else if (type[0] == 'S' &&
+                      (s = hash_lookup(strings, mid))) {
+               m->list_id = 0;
+               m->name = s;
+               m->next = l->m;
+               l->m = m;
+           }
        }
-       fprintf(out, "%s: ", name);
-       lwid = strlen(name) + 2;
-       bol = 1;
-##     repeat retrieve (name = u.#login) where u.users_id = m.#member_id and
-##             m.list_id = @id and m.member_type = "USER" {
-           do_member(out, name);
-##     }
-##     repeat retrieve (name = l.#name, member_id = m.#member_id)
-##             where l.list_id = m.#member_id and
-##                   m.list_id = @id and m.member_type = "LIST" {
-           do_member(out, name);
-           sq_save_unique_data(sq, member_id);
-##     }
-##     repeat retrieve (name = s.#string) where s.string_id = m.#member_id and
-##             m.list_id = @id and m.member_type = "STRING" {
-           do_member(out, name);
-##     }
-       fprintf(out, "\n\n");
+##  }
+##}
+
+
+save_mlist(id, l, force)
+int id;
+register struct list *l;
+int force;
+{
+    register struct member *m;
+    struct list *l1;
+
+    if (l->maillist == 2 ||
+       (l->maillist == 0 && !force))
+      return;
+
+    if (l->m && l->m->next == NULL &&
+       !strcasecmp(l->name, l->m->name)) {
+       l->maillist = 0;
+       return;
     }
+    l->maillist = 2;
+    output_mlist(id, l);
 
-    sq_destroy(sq);
-##}
+    if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
+      save_mlist(0, l1, 1);
+    
+    for (m = l->m; m; m = m->next) {
+       if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
+         save_mlist(0, l1, 1);
+    }
+}
+
+
+int lwid, bol, awid;
+
+output_mlist(id, l)
+int id;
+register struct list *l;
+{
+    struct list *l1;
+    register struct member *m;
+    struct user *u;
+
+    put_fill(out, l->description);
+    if (l->acl_t ==  'L') {
+       if (l1 = (struct list *) hash_lookup(lists, l->acl_id))
+         fprintf(out, "owner-%s: %s\n", l->name, l1->name);
+    } else if (l->acl_t ==  'U') {
+       if (u = (struct user *) hash_lookup(users, l->acl_id))
+         fprintf(out, "owner-%s: %s\n", l->name, u->login);
+    }
+
+    fprintf(out, "%s: ", l->name);
+    lwid = strlen(l->name) + 2;
+    bol = 1;
+    for (m = l->m; m; m = m->next)
+      do_member(out, m->name);
+    if (l->m == (struct member *)NULL)
+      fprintf(out, "/dev/null");
+    fprintf(out, "\n\n");
+}
+
+
+/* Extract mailing lists.  Make a list of all mailinglists, then
+ * process them, adding any sub-lists or acl lists to the list of lists
+ * to be processed.  If further sublists are encountered, repeat...
+ */
+
+do_mlists(out)
+FILE *out;
+{
+    fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
+    hash_step(lists, save_mlist, 0);
+}
 
 
 /* print out strings separated by commas, doing line breaks as appropriate */
@@ -165,28 +331,28 @@ FILE *out;
 register char *s;
 {
     register wwid;
-    static int awid;
     static int cont = 1;
 
-    trim(s);
     wwid = strlen(s);
 
-    if (awid + wwid + 2 > AL_MAX_WID) {
+    if (!bol && awid + wwid + 2 > AL_MAX_WID) {
        fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
        cont++;
-       awid = lwid = bol = 17;
+       awid = lwid = 17 + wwid;
+       fputs(s, out);
+       return;
     }
 
     if (bol) {
        lwid += wwid;
        awid = lwid;
-       fprintf(out, "%s", s);
+       fputs(s, out);
        bol = 0;
        return;
     }
     if (lwid + wwid + 2 > ML_WID) {
        fprintf(out, ",\n\t%s", s);
-       awid = lwid + wwid + 2;
+       awid += lwid + wwid + 2;
        lwid = wwid + 8;
        return;
     }
@@ -194,55 +360,27 @@ register char *s;
     fprintf(out, ", %s", s);
 }
 
+do_pobox(id, u, out)
+int id;
+register struct user *u;
+FILE *out;
+{
+    if (u->pobox)
+      fprintf(out, "%s: %s\n", u->login, u->pobox);
+}
+
 
-/* Extract user poboxes.  First do POP boxes, where the name matches the
- * login name and the machine name is in the pop_id.  Then do SMTP boxes,
- * where the expansion is stored in the strings table.  The remaining boxes
- * are of type NONE and should be skipped.
+/* Do user poboxes.  Just step through the users table, and print any
+ * we extracted earlier.
  */
 
 do_poboxes(out)
 FILE *out;
-##{
-##  char login[9], name[33], box[129];
-
+{
     fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
 
-##  range of u is users
-##  range of m is machine
-##  retrieve (login = u.#login, name = m.#name)
-##     where u.potype = "POP" and m.mach_id = u.pop_id {
-      trim(login, name);
-      fprintf(out, "%s: %s@%s\n", login, login, name);
-##  }
-
-    fprintf(out, "\n# User Forwarding\n");
-
-##  range of s is strings
-##  retrieve (login = u.#login, box = s.#string)
-##     where u.potype = "SMTP" and u.box_id = s.string_id {
-      trim(login);
-      trim(box);
-      fprintf(out, "%s: %s\n", login, box);
-##  }
-
-##}
-
-
-do_aliases(out)
-FILE *out;
-##{
-##  char name[33], trans[129];
-
-    fprintf(out, "\n%s\n# Aliases\n%s\n", divide, divide);
-
-##  range of a is alias
-##  retrieve (name = a.#name, trans = a.#trans) where a.type = "MAIL" {
-       trim(name);
-       trim(trans);
-       fprintf(out, "%s: %s\n", name, trans);
-##  }
-##}
+    hash_step(users, do_pobox, out);
+}
 
 
 put_fill(aliases, string)
This page took 0.049219 seconds and 4 git commands to generate.