]> andersk Git - moira.git/commitdiff
Initial revision
authormar <mar>
Wed, 28 Jun 1989 13:52:59 +0000 (13:52 +0000)
committermar <mar>
Wed, 28 Jun 1989 13:52:59 +0000 (13:52 +0000)
gen/mailhub.qc [new file with mode: 0644]

diff --git a/gen/mailhub.qc b/gen/mailhub.qc
new file mode 100644 (file)
index 0000000..c920703
--- /dev/null
@@ -0,0 +1,428 @@
+/* $Header$
+ *
+ * This generates the /usr/lib/aliases file for the mailhub, and an additional
+ * information file for helper programs that send back error messages.
+ *
+ *  (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 <string.h>
+#include <ctype.h>
+#include <sms.h>
+#include <sms_app.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+extern int errno;
+char *whoami = "aliases.gen";
+char *ingres_date_and_time();
+char *divide = "################################################################\n";
+
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+    long tm = time(NULL);
+    FILE *out= stdout;
+    char filename[64], *targetfile;
+    struct stat sb;
+##  int flag;
+##  char *filetime;
+    int ingerr();
+
+    IIseterr(ingerr);
+##  ingres sms
+##  set lockmode session where level = table
+
+    if (argc == 2) {
+       if (stat(argv[1], &sb) == 0) {
+           filetime = ingres_date_and_time(sb.st_mtime);
+##         retrieve (flag = int4(interval("min",tblstats.modtime - filetime)))
+##             where tblstats.table = "users"
+           if (flag < 0) {
+               fprintf(stderr, "File %s does not need to be rebuilt.\n",
+                       argv[1]);
+               exit(SMS_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);
+       }
+    } else if (argc != 1) {
+       fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
+       exit(SMS_ARGS);
+    }
+
+    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, "Sorting Info\n");
+    sort_info();
+
+    fprintf(stderr, "Dumping information\n");
+    do_people(out);
+
+    fprintf(out, "\n%s\n# End of aliases file\n", divide);
+
+    if (fclose(out)) {
+       perror("close failed");
+       exit(SMS_CCONFIG);
+    }
+
+    if (argc == 2)
+      fix_file(targetfile);
+    exit(SMS_SUCCESS);
+}
+
+
+/*
+ * 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
+
+static int ingerr(num)
+    int *num;
+{
+    char buf[256];
+    int ingres_errno;
+
+    switch (*num) {
+    case INGRES_DEADLOCK:
+       ingres_errno = SMS_DEADLOCK;
+       break;
+    default:
+       ingres_errno = SMS_INGRES_ERR;
+    }
+    com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
+    critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
+    exit(ingres_errno);
+}
+
+struct hash *users, *machines, *strings, *names;
+struct user {
+    char *login;
+    unsigned short status;
+    char *first;
+    char *last;
+    char mi;
+    char *fullname;
+    char *addr;
+    char *pobox;
+    int id;
+};
+#define MAXIDS 10
+struct names {
+    char *name;
+    struct names *next;
+    int ids[MAXIDS];
+    short count;
+};
+
+
+get_info()
+##{
+##  int id, pid, bid, stat, cnt;
+##  char name[129], type[9], fname[17], mname[17], lname[17], year[9];
+##  char dept[13], oaddr[17], ophone[13], buf[257], haddr[17], hphone[13];
+    char *s, *depttmp, *savedat(), *office_addr, *office_phone;
+    register struct user *u;
+
+    /* get locks */
+##  retrieve (buf = users.modtime) where users.users_id = 0
+
+    cnt = 0;
+    machines = create_hash(1000);
+##  retrieve (id = machine.mach_id, name = machine.#name) {
+      if (s = index(name, '.'))
+       *s = 0;
+      sprintf(buf, "%s.LOCAL", name);
+      hash_store(machines, id, strsave(buf));
+      cnt++;
+##  }
+    fprintf(stderr, "Loaded %d machines\n", cnt);
+
+    cnt = 0;
+    strings = create_hash(2000);
+##  retrieve (id = strings.string_id, name = strings.string) {
+       hash_store(strings, id, strsave(strtrim(name)));
+       cnt++;
+##  }
+    fprintf(stderr, "Loaded %d strings\n", cnt);
+
+    cnt = 0;
+    users = create_hash(15000);
+##  range of u is users
+##  retrieve (id = u.users_id, name = u.login, stat = u.status,
+##           fname = u.first, mname = u.middle, lname = u.last,
+##           year = u.mit_year, dept = u.mit_dept,
+##           oaddr = u.office_addr, ophone = u.office_phone,
+##           haddr = u.home_addr, hphone = u.home_phone,
+##           type = u.potype, pid = u.pop_id, bid = u.box_id) {
+       u = (struct user *) malloc(sizeof(struct user));
+       u->status = stat;
+       u->login = strsave(strtrim(name));
+       u->first = strsave(strtrim(fname));
+       u->last  = strsave(strtrim(lname));
+       if (mname[0] != ' ')
+         u->mi = mname[0];
+       else
+         u->mi = 0;
+       if (atoi(year) > 1900)
+         depttmp = "Undergraduate";
+       else
+         depttmp = strtrim(dept);
+       sprintf(buf, "%s, %s %c; ID: %s; Dept: %s %s",
+               u->last, u->first, u->mi ? u->mi : ' ',
+               u->login, depttmp, strtrim(year));
+       u->fullname = strsave(buf);
+
+       office_addr = strtrim(oaddr);
+       if (*office_addr == 0) {
+           office_addr = strtrim(haddr);
+       }
+       office_phone = strtrim(ophone);
+       if (*office_phone == 0) {
+           office_phone = strtrim(hphone);
+       }
+
+       if (*office_addr) {
+           sprintf(buf, "%s; %s",
+                   office_addr, office_phone);
+           u->addr = strsave(buf);
+       } else
+         u->addr = NULL;
+
+       u->id = 0;
+       u->pobox = (char *) NULL;
+       if (stat != 3) {
+           if (type[0] == 'P') {
+               if (s = hash_lookup(machines, pid)) {
+                   sprintf(buf, "%s@%s", strtrim(name), s);
+                   u->pobox = strsave(buf);
+               } else {
+                   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)
+                 fprintf(stderr,
+                         "User %s's pobox string is missing!\n",
+                         u->login);
+           }
+       }
+       hash_store(users, id, u);
+       cnt++;
+##  }
+    fprintf(stderr, "Loaded %d users\n", cnt);
+##}
+
+
+char *savedat(s)
+register char *s;
+{
+    char buf[256];
+    register char *ss = &buf[0];
+    char *lastchar = NULL;
+
+    while (isspace(*s))
+      s++;
+    if (*s == 0)
+      return("");
+
+    for (; *s; s++) {
+       if (isspace(*s)) {
+           *ss++ = '_';
+       } else if (islower(*s)) {
+           *ss++ = toupper(*s);
+           lastchar = ss;
+       } else {
+           *ss++ = *s;
+           lastchar = ss;
+       }
+    }
+    if (lastchar)
+      *lastchar = 0;
+    *ss = 0;
+    if ((ss = (char *) malloc(strlen(buf)+1)) == NULL) {
+       fprintf(stderr, "ran out of memory saving data\n");
+       exit(1);
+    }
+    strcpy(ss, buf);
+    return(ss);
+}
+
+
+void insert_names(id, u, dummy)
+int id;
+struct user *u;
+int dummy;
+{
+    char buffer[256];
+
+    if (u->status != 0 && u->status != 4)
+      insert_name(u->login, id);
+    insert_name(u->last, id);
+    sprintf(buffer, "%s_%s", u->first, u->last);
+    insert_name(buffer, id);
+    if (u->mi) {
+       sprintf(buffer, "%s_%c_%s", u->first, u->mi, u->last);
+       insert_name(buffer, id);
+    }
+}
+
+int incount = 0;
+
+insert_name(s, id)
+char *s;
+int id;
+{
+    int code;
+    register struct names *ns;
+    register int count;
+    register struct idblock *ra;
+
+    incount++;
+    code = hashstr(s);
+    ns = (struct names *) hash_lookup(names, code);
+    if (ns == NULL) {
+       if ((ns = (struct names *) malloc(sizeof(struct names))) == NULL) {
+           fprintf(stderr, "ran out of memory inserting name (sorting)\n");
+           exit(1);
+       }
+       ns->name = strsave(s);
+       ns->count = 1;
+       ns->ids[0] = id;
+       hash_store(names, code, ns);
+       return;
+    }
+    if (strcasecmp(ns->name, s)) {
+       while (ns->next) {
+           ns = ns->next;
+           if (!strcasecmp(ns->name, s))
+             goto foundns;
+       }
+       if ((ns->next = (struct names *)malloc(sizeof(struct names))) == NULL) {
+           fprintf(stderr, "ran out of memory insterting name (sorting)\n");
+           exit(1);
+       }
+       ns = ns->next;
+       ns->name = strsave(s);
+       ns->count = 1;
+       ns->ids[0] = id;
+       hash_store(names, code, ns);
+       return;
+    }
+ foundns:
+    if (ns->count < MAXIDS - 1) {
+       ns->ids[ns->count++] = id;
+       return;
+    }
+    ns->count++;
+}
+
+
+int hashstr(s)
+register char *s;
+{
+    register int result;
+    register int c;
+
+    for (result = 0; *s; s++) {
+       if (isupper(*s))
+         c = tolower(*s);
+       else
+         c = *s;
+/*     result = result * 31 + *s; */
+       result = (result << 5) - result + c - 'a';
+    }
+    return(result < 0 ? -result : result);
+}
+
+
+sort_info()
+{
+    names = create_hash(10000);
+    hash_step(users, insert_names, NULL);
+    fprintf(stderr, "Inserted %d names\n", incount);
+}
+
+
+static long offset;
+static FILE *msgs;
+
+output_data(dummy, nms, out)
+int dummy;
+struct names *nms;
+FILE *out;
+{
+    register struct names *ns;
+    register struct user *u;
+    int i;
+
+    incount++;
+    for (ns = nms; ns; ns = ns->next) {
+       if (strlen(ns->name) < 2)
+         continue;
+       if (ns->count == 1) {
+           u = (struct user *) hash_lookup(users, ns->ids[0]);
+           if (u->pobox) {
+               fprintf(out, "%s: %s\n", ns->name, u->pobox);
+               continue;
+           }
+           if (u->id == 0) {
+               u->id = offset;
+               if (*u->addr) {
+                   fprintf(msgs, "%s\n  %s\n\001", u->fullname, u->addr);
+                   offset += strlen(u->fullname) + strlen(u->addr) + 5;
+               } else {
+                   fprintf(msgs, "%s\n\001", u->fullname);
+                   offset += strlen(u->fullname) + 2;
+               }
+           }
+           fprintf(out, "%s: +%d+@no_po_box\n", ns->name, u->id);
+       } else  if (ns->count < 10) {
+           fprintf(out, "%s: +%d+@ambiguous\n", ns->name, offset);
+           for (i = 0; i < ns->count; i++) {
+               u = (struct user *) hash_lookup(users, ns->ids[i]);
+               fprintf(msgs, "%s\n", u->fullname);
+               offset += strlen(u->fullname) + 1;
+           }
+           fputs("\001", msgs);
+           offset++;
+       } else {
+           fprintf(out, "%s: +%d+@too_many\n", ns->name, ns->count);
+       }
+    }
+}
+
+
+do_people(out)
+FILE *out;
+{
+    incount = 0;
+    msgs = fopen("aliases.strings", "w");
+    fputs(msgs, "\001");
+    offset = 1;
+
+    hash_step(names, output_data, out);
+    fputs("\n", msgs);
+    fclose(msgs);
+    fprintf(stderr, "Output %d entries\n", incount);
+}
This page took 0.045723 seconds and 5 git commands to generate.