From 63812b6235c7350cf053a2681266d0d5aad8ab52 Mon Sep 17 00:00:00 2001 From: mar Date: Wed, 28 Jun 1989 13:52:59 +0000 Subject: [PATCH] Initial revision --- gen/mailhub.qc | 428 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 gen/mailhub.qc diff --git a/gen/mailhub.qc b/gen/mailhub.qc new file mode 100644 index 00000000..c920703a --- /dev/null +++ b/gen/mailhub.qc @@ -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 + * . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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); +} -- 2.45.2