3 * This generates the /usr/lib/aliases file for the mailhub, and an additional
4 * information file for helper programs that send back error messages.
6 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, please see the file
11 #include <mit-copyright.h>
17 #include <sys/types.h>
22 char *whoami = "aliases.gen";
23 char *ingres_date_and_time();
24 char *divide = "################################################################\n";
33 char filename[64], *targetfile;
41 ## set lockmode session where level = table
44 if (stat(argv[1], &sb) == 0) {
45 filetime = ingres_date_and_time(sb.st_mtime);
46 ## retrieve (flag = int4(interval("min",tblstats.modtime - filetime)))
47 ## where tblstats.table = "users"
49 fprintf(stderr, "File %s does not need to be rebuilt.\n",
55 sprintf(filename, "%s~", targetfile);
56 if ((out = fopen(filename, "w")) == NULL) {
57 fprintf(stderr, "unable to open %s for output\n", filename);
60 } else if (argc != 1) {
61 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
65 fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
66 fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
73 fprintf(stderr, "Sorting Info\n");
76 fprintf(stderr, "Dumping information\n");
79 fprintf(out, "\n%s\n# End of aliases file\n", divide);
82 perror("close failed");
93 * ingerr: (supposedly) called when Ingres indicates an error.
94 * I have not yet been able to get this to work to intercept a
95 * database open error.
97 #define INGRES_DEADLOCK 4700
99 static int ingerr(num)
106 case INGRES_DEADLOCK:
107 ingres_errno = SMS_DEADLOCK;
110 ingres_errno = SMS_INGRES_ERR;
112 com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
113 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
117 struct hash *users, *machines, *strings, *names;
120 unsigned short status;
140 ## int id, pid, bid, stat, cnt;
141 ## char name[129], type[9], fname[17], mname[17], lname[17], year[9];
142 ## char dept[13], oaddr[17], ophone[13], buf[257], haddr[17], hphone[13];
143 char *s, *depttmp, *savedat(), *office_addr, *office_phone;
144 register struct user *u;
147 ## retrieve (buf = users.modtime) where users.users_id = 0
150 machines = create_hash(1000);
151 ## retrieve (id = machine.mach_id, name = machine.#name) {
152 if (s = index(name, '.'))
154 sprintf(buf, "%s.LOCAL", name);
155 hash_store(machines, id, strsave(buf));
158 fprintf(stderr, "Loaded %d machines\n", cnt);
161 strings = create_hash(2000);
162 ## retrieve (id = strings.string_id, name = strings.string) {
163 hash_store(strings, id, strsave(strtrim(name)));
166 fprintf(stderr, "Loaded %d strings\n", cnt);
169 users = create_hash(15000);
170 ## range of u is users
171 ## retrieve (id = u.users_id, name = u.login, stat = u.status,
172 ## fname = u.first, mname = u.middle, lname = u.last,
173 ## year = u.mit_year, dept = u.mit_dept,
174 ## oaddr = u.office_addr, ophone = u.office_phone,
175 ## haddr = u.home_addr, hphone = u.home_phone,
176 ## type = u.potype, pid = u.pop_id, bid = u.box_id) {
177 u = (struct user *) malloc(sizeof(struct user));
179 u->login = strsave(strtrim(name));
180 u->first = strsave(strtrim(fname));
181 u->last = strsave(strtrim(lname));
186 if (atoi(year) > 1900)
187 depttmp = "Undergraduate";
189 depttmp = strtrim(dept);
190 sprintf(buf, "%s, %s %c; ID: %s; Dept: %s %s",
191 u->last, u->first, u->mi ? u->mi : ' ',
192 u->login, depttmp, strtrim(year));
193 u->fullname = strsave(buf);
195 office_addr = strtrim(oaddr);
196 if (*office_addr == 0) {
197 office_addr = strtrim(haddr);
199 office_phone = strtrim(ophone);
200 if (*office_phone == 0) {
201 office_phone = strtrim(hphone);
205 sprintf(buf, "%s; %s",
206 office_addr, office_phone);
207 u->addr = strsave(buf);
212 u->pobox = (char *) NULL;
214 if (type[0] == 'P') {
215 if (s = hash_lookup(machines, pid)) {
216 sprintf(buf, "%s@%s", strtrim(name), s);
217 u->pobox = strsave(buf);
220 "User %s's pobox is on a missing machine!\n",
223 } else if (type[0] == 'S') {
224 if ((u->pobox = hash_lookup(strings, bid)) == NULL)
226 "User %s's pobox string is missing!\n",
230 hash_store(users, id, u);
233 fprintf(stderr, "Loaded %d users\n", cnt);
241 register char *ss = &buf[0];
242 char *lastchar = NULL;
252 } else if (islower(*s)) {
263 if ((ss = (char *) malloc(strlen(buf)+1)) == NULL) {
264 fprintf(stderr, "ran out of memory saving data\n");
272 void insert_names(id, u, dummy)
279 if (u->status != 0 && u->status != 4)
280 insert_name(u->login, id);
281 insert_name(u->last, id);
282 sprintf(buffer, "%s_%s", u->first, u->last);
283 insert_name(buffer, id);
285 sprintf(buffer, "%s_%c_%s", u->first, u->mi, u->last);
286 insert_name(buffer, id);
297 register struct names *ns;
299 register struct idblock *ra;
303 ns = (struct names *) hash_lookup(names, code);
305 if ((ns = (struct names *) malloc(sizeof(struct names))) == NULL) {
306 fprintf(stderr, "ran out of memory inserting name (sorting)\n");
309 ns->name = strsave(s);
312 hash_store(names, code, ns);
315 if (strcasecmp(ns->name, s)) {
318 if (!strcasecmp(ns->name, s))
321 if ((ns->next = (struct names *)malloc(sizeof(struct names))) == NULL) {
322 fprintf(stderr, "ran out of memory insterting name (sorting)\n");
326 ns->name = strsave(s);
329 hash_store(names, code, ns);
333 if (ns->count < MAXIDS - 1) {
334 ns->ids[ns->count++] = id;
347 for (result = 0; *s; s++) {
352 /* result = result * 31 + *s; */
353 result = (result << 5) - result + c - 'a';
355 return(result < 0 ? -result : result);
361 names = create_hash(10000);
362 hash_step(users, insert_names, NULL);
363 fprintf(stderr, "Inserted %d names\n", incount);
370 output_data(dummy, nms, out)
375 register struct names *ns;
376 register struct user *u;
380 for (ns = nms; ns; ns = ns->next) {
381 if (strlen(ns->name) < 2)
383 if (ns->count == 1) {
384 u = (struct user *) hash_lookup(users, ns->ids[0]);
386 fprintf(out, "%s: %s\n", ns->name, u->pobox);
392 fprintf(msgs, "%s\n %s\n\001", u->fullname, u->addr);
393 offset += strlen(u->fullname) + strlen(u->addr) + 5;
395 fprintf(msgs, "%s\n\001", u->fullname);
396 offset += strlen(u->fullname) + 2;
399 fprintf(out, "%s: +%d+@no_po_box\n", ns->name, u->id);
400 } else if (ns->count < 10) {
401 fprintf(out, "%s: +%d+@ambiguous\n", ns->name, offset);
402 for (i = 0; i < ns->count; i++) {
403 u = (struct user *) hash_lookup(users, ns->ids[i]);
404 fprintf(msgs, "%s\n", u->fullname);
405 offset += strlen(u->fullname) + 1;
410 fprintf(out, "%s: +%d+@too_many\n", ns->name, ns->count);
420 msgs = fopen("aliases.strings", "w");
424 hash_step(names, output_data, out);
427 fprintf(stderr, "Output %d entries\n", incount);