4 * This generates the /usr/lib/aliases file for the mailhub.
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>
23 char *whoami = "mailhub.gen";
24 char *ingres_date_and_time();
25 char *divide = "##############################################################";
28 #define AL_MAX_WID 896
40 char filename[64], *targetfile;
48 ## set lockmode session where level = table
51 if (stat(argv[1], &sb) == 0) {
52 filetime = ingres_date_and_time(sb.st_mtime);
53 ## retrieve (flag = int4(interval("min",tblstats.modtime - filetime)))
54 ## where tblstats.table = "users"
56 fprintf(stderr, "File %s does not need to be rebuilt.\n",
62 sprintf(filename, "%s~", targetfile);
63 if ((out = fopen(filename, "w")) == NULL) {
64 fprintf(stderr, "unable to open %s for output\n", filename);
67 } else if (argc != 1) {
68 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
72 fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
73 fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
80 fprintf(stderr, "Sorting Info\n");
83 fprintf(stderr, "Dumping information\n");
87 fprintf(out, "\n%s\n# End of aliases file\n", divide);
90 perror("close failed");
101 * ingerr: (supposedly) called when Ingres indicates an error.
102 * I have not yet been able to get this to work to intercept a
103 * database open error.
105 #define INGRES_DEADLOCK 4700
107 static int ingerr(num)
114 case INGRES_DEADLOCK:
115 ingres_errno = SMS_DEADLOCK;
118 ingres_errno = SMS_INGRES_ERR;
120 com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
121 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
125 struct hash *users, *machines, *strings, *lists, *names;
155 ## int id, pid, bid, stat, cnt, maillistp, acl, mid;
156 ## char name[129], type[9], fname[17], mname[17], lname[17], buf[257];
158 register struct user *u;
159 struct list *l, *memberlist;
160 register struct member *m;
163 ## retrieve (buf = users.modtime) where users.users_id = 0
164 ## retrieve (buf = list.modtime) where list.list_id = 0
167 machines = create_hash(1000);
168 ## retrieve (id = machine.mach_id, name = machine.#name) {
169 if (s = index(name, '.'))
171 sprintf(buf, "%s.LOCAL", name);
172 if (hash_store(machines, id, strsave(buf)) < 0) {
173 fprintf(stderr, "Out of memory!\n");
178 fprintf(stderr, "Loaded %d machines\n", cnt);
181 strings = create_hash(2000);
182 ## retrieve (id = strings.string_id, name = strings.string) {
183 if (hash_store(strings, id, strsave(strtrim(name))) < 0) {
184 fprintf(stderr, "Out of memory!\n");
189 fprintf(stderr, "Loaded %d strings\n", cnt);
192 users = create_hash(12001);
193 ## range of u is users
194 ## retrieve (id = u.users_id, name = u.login, fname = u.first,
195 ## mname = u.middle, lname = u.last,
196 ## type = u.potype, pid = u.pop_id, bid = u.box_id)
197 ## where u.status != 3 {
198 u = (struct user *) malloc(sizeof(struct user));
199 u->login = strsave(strtrim(name));
200 u->first = strsave(strtrim(fname));
201 u->last = strsave(strtrim(lname));
207 if (type[0] == 'P' && (s = hash_lookup(machines, pid))) {
208 sprintf(buf, "%s@%s", strtrim(name), s);
209 u->pobox = strsave(buf);
210 } else if (type[0] == 'S') {
211 u->pobox = hash_lookup(strings, bid);
213 u->pobox = (char *) NULL;
214 if (hash_store(users, id, u) < 0) {
215 fprintf(stderr, "Out of memory!\n");
220 fprintf(stderr, "Loaded %d users\n", cnt);
223 lists = create_hash(15000);
224 ## range of l is list
225 ## retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist,
226 ## type = l.acl_type, acl = l.acl_id)
227 ## where l.active != 0 {
228 l = (struct list *) malloc(sizeof(struct list));
229 l->name = strsave(strtrim(name));
230 l->maillist = maillistp;
233 l->m = (struct member *) NULL;
234 if (hash_store(lists, id, l) < 0) {
235 fprintf(stderr, "Out of memory!\n");
240 fprintf(stderr, "Loaded %d lists\n", cnt);
243 ## range of m is imembers
244 ## retrieve (id = m.list_id, type = m.member_type, mid = m.member_id)
245 ## where m.direct = 1 {
247 if (l = (struct list *) hash_lookup(lists, id)) {
248 m = (struct member *) malloc(sizeof(struct member));
249 if (type[0] == 'U' &&
250 (u = (struct user *) hash_lookup(users, mid))) {
255 } else if (type[0] == 'L' &&
256 (memberlist = (struct list *) hash_lookup(lists, mid))) {
258 m->name = memberlist->name;
261 } else if (type[0] == 'S' &&
262 (s = hash_lookup(strings, mid))) {
270 fprintf(stderr, "Loaded %d members\n", cnt);
274 save_mlist(id, l, force)
279 register struct member *m;
280 register struct list *l1;
282 if (l->maillist == 2 ||
284 (l->maillist == 0 && !force))
287 if (l->m && l->m->next == NULL &&
288 !strcasecmp(l->name, l->m->name)) {
293 insert_name(l->name, -id, TRUE, FALSE);
295 if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
296 save_mlist(0, l1, TRUE);
298 for (m = l->m; m; m = m->next) {
299 if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
300 save_mlist(0, l1, TRUE);
305 insert_login(id, u, dummy)
310 if (u->pobox && u->login[0] != '#')
311 insert_name(u->login, id, TRUE, FALSE);
314 void insert_names(id, u, dummy)
321 insert_name(u->last, id, FALSE, FALSE);
322 sprintf(buffer, "%s_%s", u->first, u->last);
323 insert_name(buffer, id, FALSE, TRUE);
324 sprintf(buffer, "%c_%s", u->first[0], u->last);
325 insert_name(buffer, id, FALSE, TRUE);
327 sprintf(buffer, "%s_%c_%s", u->first, u->mi, u->last);
328 insert_name(buffer, id, FALSE, TRUE);
334 insert_name(s, id, nodups, copy)
341 register struct names *ns;
343 register struct idblock *ra;
347 ns = (struct names *) hash_lookup(names, code);
349 if ((ns = (struct names *) malloc(sizeof(struct names))) == NULL) {
350 fprintf(stderr, "ran out of memory inserting name (sorting)\n");
354 ns->name = strsave(s);
359 if (hash_store(names, code, ns) < 0) {
360 fprintf(stderr, "Out of memory!\n");
365 if (strcasecmp(ns->name, s)) {
368 if (!strcasecmp(ns->name, s))
371 if ((ns->next = (struct names *)malloc(sizeof(struct names))) == NULL) {
372 fprintf(stderr, "ran out of memory insterting name (sorting)\n");
377 ns->name = strsave(s);
385 if (nodups || ns->keep)
397 for (result = 0; c = *s; s++) {
400 /* result = result * 31 + *s; */
401 result = (result << 5) - result + c - '`';
403 return(result < 0 ? -result : result);
409 names = create_hash(20001);
410 hash_step(users, insert_login, NULL);
411 hash_step(lists, save_mlist, FALSE);
412 hash_step(users, insert_names, NULL);
413 fprintf(stderr, "Inserted %d names\n", incount);
417 output_data(dummy, nms, out)
422 register struct names *ns;
423 register struct user *u;
427 for (ns = nms; ns; ns = ns->next) {
428 if (ns->name[0] == 0 || ns->name[1] == 0) {
429 fprintf(stderr, "punting %s due to short name\n", ns->name);
433 u = (struct user *) hash_lookup(users, ns->id);
435 fprintf(out, "%s: %s\n", ns->name, u->pobox);
437 fprintf(out, "%s: =%s=@nobox\n", ns->name, ns->name);
439 } else if (ns->id == 0) {
440 fprintf(out, "%s: =%s=@ambig\n", ns->name, ns->name);
448 output_mlist(id, l, out)
450 register struct list *l;
454 register struct member *m;
455 register struct user *u;
457 if (l->maillist != 2)
459 if (l->acl_t == 'L' &&
460 (l1 = (struct list *) hash_lookup(lists, l->acl_id)))
461 fprintf(out, "owner-%s: %s\n", l->name, l1->name);
462 else if (l->acl_t == 'U' &&
463 (u = (struct user *) hash_lookup(users, l->acl_id)))
464 fprintf(out, "owner-%s: %s\n", l->name, u->login);
466 fprintf(out, "%s: ", l->name);
467 lwid = strlen(l->name) + 2;
469 for (m = l->m; m; m = m->next) {
470 do_member(out, m->name);
472 if (l->m == (struct member *)NULL)
473 fprintf(out, "/dev/null");
474 fprintf(out, "\n\n");
479 /* print out strings separated by commas, doing line breaks as appropriate */
490 if (!bol && awid + wwid + 2 > AL_MAX_WID) {
491 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
493 awid = lwid = 17 + wwid;
505 if (lwid + wwid + 2 > ML_WID) {
506 fprintf(out, ",\n\t%s", s);
507 awid += lwid + wwid + 2;
512 fprintf(out, ", %s", s);
520 fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
521 hash_step(lists, output_mlist, out);
522 fprintf(stderr, "Output %d lists\n", incount);
529 fprintf(out, "\n%s\n# People\n%s\n", divide, divide);
530 hash_step(names, output_data, out);
531 fprintf(stderr, "Output %d entries\n", incount);