]> andersk Git - moira.git/blobdiff - gen/mailhub.qc
Used /bin/sh format instead of /bin/csh format, by accident.
[moira.git] / gen / mailhub.qc
index 294dfacfdde8c38d9f265cf229828b46bf9d4f86..070fdba3d620cbed93977dd02000ccebf7539c2a 100644 (file)
@@ -12,8 +12,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include <sms.h>
-#include <sms_app.h>
+#include <moira.h>
+#include <moira_site.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -23,6 +23,7 @@ extern int errno;
 char *whoami = "mailhub.gen";
 char *ingres_date_and_time();
 char *perm_malloc();
+char *pstrsave();
 char *divide = "##############################################################";
 
 #define ML_WID 72
@@ -31,13 +32,14 @@ char *divide = "##############################################################";
 #define FALSE 0
 #define TRUE (!FALSE)
 
+FILE *out= stdout;
+
 
 main(argc, argv)
 int argc;
 char **argv;
 {
     long tm = time(NULL);
-    FILE *out= stdout;
     char filename[64], *targetfile;
     struct stat sb;
 ##  int flag;
@@ -56,18 +58,18 @@ char **argv;
            if (flag < 0) {
                fprintf(stderr, "File %s does not need to be rebuilt.\n",
                        argv[1]);
-               exit(SMS_NO_CHANGE);
+               exit(MR_NO_CHANGE);
            }
        }
        targetfile = argv[1];
        sprintf(filename, "%s~", targetfile);
        if ((out = fopen(filename, "w")) == NULL) {
            fprintf(stderr, "unable to open %s for output\n", filename);
-           exit(SMS_OCONFIG);
+           exit(MR_OCONFIG);
        }
     } else if (argc != 1) {
        fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
-       exit(SMS_ARGS);
+       exit(MR_ARGS);
     }
 
     fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
@@ -82,19 +84,18 @@ char **argv;
     sort_info();
 
     fprintf(stderr, "Dumping information\n");
-    do_lists(out);
-    do_people(out);
+    do_people();
 
     fprintf(out, "\n%s\n# End of aliases file\n", divide);
 
     if (fclose(out)) {
        perror("close failed");
-       exit(SMS_CCONFIG);
+       exit(MR_CCONFIG);
     }
 
     if (argc == 2)
       fix_file(targetfile);
-    exit(SMS_SUCCESS);
+    exit(MR_SUCCESS);
 }
 
 
@@ -113,12 +114,12 @@ static int ingerr(num)
 
     switch (*num) {
     case INGRES_DEADLOCK:
-       ingres_errno = SMS_DEADLOCK;
+       ingres_errno = MR_DEADLOCK;
        break;
     default:
-       ingres_errno = SMS_INGRES_ERR;
+       ingres_errno = MR_INGRES_ERR;
     }
-    com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
+    com_err(whoami, MR_INGRES_ERR, " code %d\n", *num);
     critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
     exit(ingres_errno);
 }
@@ -165,29 +166,30 @@ get_info()
 ##  retrieve (buf = list.modtime) where list.list_id = 0
 
     cnt = 0;
-    machines = create_hash(1000);
-##  retrieve (id = machine.mach_id, name = machine.#name) {
+    machines = create_hash(10);
+##  retrieve (id = machine.mach_id, name = machine.#name)
+##     where machine.mach_id = users.pop_id {
       if (s = index(name, '.'))
        *s = 0;
+      else
+       strtrim(name);
 #ifdef ATHENA
-      sprintf(buf, "%s.LOCAL", name);
-      if (hash_store(machines, id, strsave(buf)) < 0) {
-#else
-      if (hash_store(machines, id, strsave(name)) < 0) {
+      strcat(name, ".LOCAL");
 #endif
+      if (hash_store(machines, id, pstrsave(name)) < 0) {
          fprintf(stderr, "Out of memory!\n");
-         exit(SMS_NO_MEM);
+         exit(MR_NO_MEM);
       }
       cnt++;
 ##  }
     fprintf(stderr, "Loaded %d machines\n", cnt);
 
     cnt = 0;
-    strings = create_hash(2000);
+    strings = create_hash(4000);
 ##  retrieve (id = strings.string_id, name = strings.string) {
-       if (hash_store(strings, id, strsave(strtrim(name))) < 0) {
+       if (hash_store(strings, id, pstrsave(strtrim(name))) < 0) {
            fprintf(stderr, "Out of memory!\n");
-           exit(SMS_NO_MEM);
+           exit(MR_NO_MEM);
        }
        cnt++;
 ##  }
@@ -201,24 +203,24 @@ get_info()
 ##           type = u.potype, pid = u.pop_id, bid = u.box_id) 
 ##     where u.status != 3 {
        u = (struct user *) perm_malloc(sizeof(struct user));
-       u->login = strsave(strtrim(name));
-       u->first = strsave(strtrim(fname));
-       u->last  = strsave(strtrim(lname));
+       u->login = pstrsave(strtrim(name));
+       u->first = pstrsave(strtrim(fname));
+       u->last  = pstrsave(strtrim(lname));
        if (mname[0] != ' ')
          u->mi = mname[0];
        else
          u->mi = 0;
 
        if (type[0] == 'P' && (s = hash_lookup(machines, pid))) {
-           sprintf(buf, "%s@%s", strtrim(name), s);
-           u->pobox = strsave(buf);
+           sprintf(buf, "%s@%s", u->login, s);
+           u->pobox = pstrsave(buf);
        } else if (type[0] ==  'S') {
            u->pobox = hash_lookup(strings, bid);
        } else
          u->pobox = (char *) NULL;
        if (hash_store(users, id, u) < 0) {
            fprintf(stderr, "Out of memory!\n");
-           exit(SMS_NO_MEM);
+           exit(MR_NO_MEM);
        }
        cnt++;
 ##  }
@@ -231,14 +233,14 @@ get_info()
 ##           type = l.acl_type, acl = l.acl_id)
 ##    where l.active != 0 {
        l = (struct list *) perm_malloc(sizeof(struct list));
-       l->name = strsave(strtrim(name));
+       l->name = pstrsave(strtrim(name));
        l->maillist = maillistp;
        l->acl_t = type[0];
        l->acl_id = acl;
        l->m = (struct member *) NULL;
        if (hash_store(lists, id, l) < 0) {
            fprintf(stderr, "Out of memory!\n");
-           exit(SMS_NO_MEM);
+           exit(MR_NO_MEM);
        }
        cnt++;
 ##  }
@@ -284,8 +286,7 @@ int force;
     register struct member *m;
     register struct list *l1;
 
-    if (l->maillist == 2 ||
-       l->maillist == 3 ||
+    if (l->maillist > 1 ||
        (l->maillist == 0 && !force))
       return;
 
@@ -295,7 +296,8 @@ int force;
        return;
     }
     l->maillist = 2;
-    insert_name(l->name, -id, TRUE, FALSE);
+    insert_name(l->name, -1, TRUE, FALSE);
+    output_mlist(id, l);
 
     if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
       save_mlist(0, l1, TRUE);
@@ -353,17 +355,18 @@ int copy;
     if (ns == NULL) {
        if ((ns = (struct names *) perm_malloc(sizeof(struct names))) == NULL) {
            fprintf(stderr, "ran out of memory inserting name (sorting)\n");
-           exit(SMS_NO_MEM);
+           exit(MR_NO_MEM);
        }
        if (copy)
-         ns->name = strsave(s);
+         ns->name = pstrsave(s);
        else
          ns->name = s;
        ns->keep = nodups;
        ns->id = id;
+       ns->next = NULL;
        if (hash_store(names, code, ns) < 0) {
            fprintf(stderr, "Out of memory!\n");
-           exit(SMS_NO_MEM);
+           exit(MR_NO_MEM);
        }
        return;
     }
@@ -376,20 +379,24 @@ int copy;
        if ((ns->next = (struct names *) perm_malloc(sizeof(struct names)))
                == NULL) {
            fprintf(stderr, "ran out of memory insterting name (sorting)\n");
-           exit(SMS_NO_MEM);
+           exit(MR_NO_MEM);
        }
        ns = ns->next;
        if (copy)
-         ns->name = strsave(s);
+         ns->name = pstrsave(s);
        else
          ns->name = s;
        ns->keep = nodups;
        ns->id = id;
+       ns->next = NULL;
        return;
     }
  foundns:
-    if (nodups || ns->keep)
-      return;
+    if (nodups || ns->keep) {
+       if (nodups && ns->keep)
+         fprintf(stderr, "duplicated named: %s\n", s);
+       return;
+    }
     ns->id = 0;
 }
 
@@ -444,7 +451,10 @@ sort_info()
 {
     names = create_hash(20001);
     hash_step(users, insert_login, NULL);
+    incount = 0;
+    fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
     hash_step(lists, save_mlist, FALSE);
+    fprintf(stderr, "Output %d lists\n", incount);
     hash_step(users, insert_names, NULL);
     fprintf(stderr, "Inserted %d names\n", incount);
 }
@@ -480,23 +490,23 @@ FILE *out;
 
 int lwid, bol, awid;
 
-output_mlist(id, l, out)
+output_mlist(id, l)
 int id;
 register struct list *l;
-FILE *out;
 {
     struct list *l1;
     register struct member *m;
     register struct user *u;
 
-    if (l->maillist != 2)
-      return;
     if (l->acl_t ==  'L' &&
        (l1 = (struct list *) hash_lookup(lists, l->acl_id)))
       fprintf(out, "owner-%s: %s\n%s: ", l->name, l1->name, l->name);
     else if (l->acl_t ==  'U' &&
             (u = (struct user *) hash_lookup(users, l->acl_id)))
       fprintf(out, "owner-%s: %s\n%s: ", l->name, u->login, l->name);
+    else
+      fprintf(out, "%s: ", l->name);
+      
 
     lwid = strlen(l->name) + 2;
     bol = 1;
@@ -547,17 +557,7 @@ register char *s;
 }
 
 
-do_lists(out)
-FILE *out;
-{
-    incount = 0;
-    fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
-    hash_step(lists, output_mlist, out);
-    fprintf(stderr, "Output %d lists\n", incount);
-}
-
-do_people(out)
-FILE *out;
+do_people()
 {
     incount = 0;
     fprintf(out, "\n%s\n# People\n%s\n", divide, divide);
@@ -586,3 +586,180 @@ unsigned size;
     return(ret);
 }
 
+
+/*
+ * Make a (permenant) copy of a string.
+ */
+char *
+pstrsave(s)
+    char *s;
+{
+    register int len;
+    register char *p;
+    /* Kludge for sloppy string semantics */
+    if (!s) {
+           printf("NULL != \"\" !!!!\r\n");
+           p = perm_malloc(1);
+           *p = '\0';
+           return p;
+    }
+    len = strlen(s) + 1;
+    p = perm_malloc((u_int)len);
+    if (p) bcopy(s, p, len);
+    return p;
+}
+
+#define hash_func(h, key) (key >= 0 ? (key % h->size) : (-key % h->size))
+
+/* Create a hash table.  The size is just a hint, not a maximum. */
+
+struct hash *create_hash(size)
+int size;
+{
+    struct hash *h;
+
+    h = (struct hash *) perm_malloc(sizeof(struct hash));
+    if (h == (struct hash *) NULL)
+      return((struct hash *) NULL);
+    h->size = size;
+    h->data = (struct bucket **) perm_malloc(size * sizeof(char *));
+    if (h->data == (struct bucket **) NULL) {
+       free(h);
+       return((struct hash *) NULL);
+    }
+    bzero(h->data, size * sizeof(char *));
+    return(h);
+}
+
+/* Lookup an object in the hash table.  Returns the value associated with
+ * the key, or NULL (thus NULL is not a very good value to store...)
+ */
+
+char *hash_lookup(h, key)
+struct hash *h;
+register int key;
+{
+    register struct bucket *b;
+
+    b = h->data[hash_func(h, key)];
+    while (b && b->key != key)
+      b = b->next;
+    if (b && b->key == key)
+      return(b->data);
+    else
+      return(NULL);
+}
+
+
+/* Update an existing object in the hash table.  Returns 1 if the object
+ * existed, or 0 if not.
+ */
+
+int hash_update(h, key, value)
+struct hash *h;
+register int key;
+char *value;
+{
+    register struct bucket *b;
+
+    b = h->data[hash_func(h, key)];
+    while (b && b->key != key)
+      b = b->next;
+    if (b && b->key == key) {
+       b->data = value;
+       return(1);
+    } else
+      return(0);
+}
+
+
+/* Store an item in the hash table.  Returns 0 if the key was not previously
+ * there, 1 if it was, or -1 if we ran out of memory.
+ */
+
+int hash_store(h, key, value)
+struct hash *h;
+register int key;
+char *value;
+{
+    register struct bucket *b, **p;
+
+    p = &(h->data[hash_func(h, key)]);
+    if (*p == NULL) {
+       b = *p = (struct bucket *) perm_malloc(sizeof(struct bucket));
+       if (b == (struct bucket *) NULL)
+         return(-1);
+       b->next = NULL;
+       b->key = key;
+       b->data = value;
+       return(0);
+    }
+
+    for (b = *p; b && b->key != key; b = *p)
+      p = (struct bucket **) *p;
+    if (b && b->key == key) {
+       b->data = value;
+       return(1);
+    }
+    b = *p = (struct bucket *) perm_malloc(sizeof(struct bucket));
+    if (b == (struct bucket *) NULL)
+      return(-1);
+    b->next = NULL;
+    b->key = key;
+    b->data = value;
+    return(0);
+}
+
+
+/* Search through the hash table for a given value.  For each piece of
+ * data with that value, call the callback proc with the corresponding key.
+ */
+
+hash_search(h, value, callback)
+struct hash *h;
+register char *value;
+void (*callback)();
+{
+    register struct bucket *b, **p;
+
+    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
+       for (b = *p; b; b = b->next) {
+           if (b->data == value)
+             (*callback)(b->key);
+       }
+    }
+}
+
+
+/* Step through the hash table, calling the callback proc with each key.
+ */
+
+hash_step(h, callback, hint)
+struct hash *h;
+void (*callback)();
+char *hint;
+{
+    register struct bucket *b, **p;
+
+    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
+       for (b = *p; b; b = b->next) {
+           (*callback)(b->key, b->data, hint);
+       }
+    }
+}
+
+
+/* Deallocate all of the memory associated with a table */
+
+hash_destroy(h)
+struct hash *h;
+{
+    register struct bucket *b, **p, *b1;
+
+    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
+       for (b = *p; b; b = b1) {
+           b1 = b->next;
+           free(b);
+       }
+    }
+}
This page took 0.165351 seconds and 4 git commands to generate.