]> andersk Git - moira.git/blame - gen/mailhub.qc
make sure that make depend will make compile_et first
[moira.git] / gen / mailhub.qc
CommitLineData
8e7a00be 1
63812b62 2/* $Header$
3 *
8e7a00be 4 * This generates the /usr/lib/aliases file for the mailhub.
63812b62 5 *
6 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
9 */
10
11#include <mit-copyright.h>
12#include <stdio.h>
13#include <string.h>
14#include <ctype.h>
15#include <sms.h>
16#include <sms_app.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <sys/time.h>
20
8e7a00be 21
63812b62 22extern int errno;
8e7a00be 23char *whoami = "mailhub.gen";
63812b62 24char *ingres_date_and_time();
8e7a00be 25char *divide = "##############################################################";
26
27#define ML_WID 72
28#define AL_MAX_WID 896
29
30#define FALSE 0
31#define TRUE (!FALSE)
63812b62 32
33
34main(argc, argv)
35int argc;
36char **argv;
37{
38 long tm = time(NULL);
39 FILE *out= stdout;
40 char filename[64], *targetfile;
41 struct stat sb;
42## int flag;
43## char *filetime;
44 int ingerr();
45
46 IIseterr(ingerr);
47## ingres sms
48## set lockmode session where level = table
49
50 if (argc == 2) {
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"
55 if (flag < 0) {
56 fprintf(stderr, "File %s does not need to be rebuilt.\n",
57 argv[1]);
58 exit(SMS_NO_CHANGE);
59 }
60 }
61 targetfile = argv[1];
62 sprintf(filename, "%s~", targetfile);
63 if ((out = fopen(filename, "w")) == NULL) {
64 fprintf(stderr, "unable to open %s for output\n", filename);
65 exit(SMS_OCONFIG);
66 }
67 } else if (argc != 1) {
68 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
69 exit(SMS_ARGS);
70 }
71
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);
74
75## begin transaction
76 get_info();
77## end transaction
78## exit
79
80 fprintf(stderr, "Sorting Info\n");
81 sort_info();
82
83 fprintf(stderr, "Dumping information\n");
8e7a00be 84 do_lists(out);
63812b62 85 do_people(out);
86
87 fprintf(out, "\n%s\n# End of aliases file\n", divide);
88
89 if (fclose(out)) {
90 perror("close failed");
91 exit(SMS_CCONFIG);
92 }
93
94 if (argc == 2)
95 fix_file(targetfile);
96 exit(SMS_SUCCESS);
97}
98
99
100/*
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.
104 */
105#define INGRES_DEADLOCK 4700
106
107static int ingerr(num)
108 int *num;
109{
110 char buf[256];
111 int ingres_errno;
112
113 switch (*num) {
114 case INGRES_DEADLOCK:
115 ingres_errno = SMS_DEADLOCK;
116 break;
117 default:
118 ingres_errno = SMS_INGRES_ERR;
119 }
120 com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
121 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
122 exit(ingres_errno);
123}
124
8e7a00be 125struct hash *users, *machines, *strings, *lists, *names;
63812b62 126struct user {
127 char *login;
63812b62 128 char *first;
129 char *last;
130 char mi;
63812b62 131 char *pobox;
63812b62 132};
8e7a00be 133struct member {
134 struct member *next;
135 char *name;
136 int list_id;
137};
138struct list {
139 char *name;
140 char maillist;
141 char acl_t;
142 int acl_id;
143 struct member *m;
144};
63812b62 145struct names {
146 char *name;
147 struct names *next;
8e7a00be 148 int keep:1;
149 int id:31;
63812b62 150};
151
152
153get_info()
154##{
8e7a00be 155## int id, pid, bid, stat, cnt, maillistp, acl, mid;
156## char name[129], type[9], fname[17], mname[17], lname[17], buf[257];
157 char *s;
63812b62 158 register struct user *u;
8e7a00be 159 struct list *l, *memberlist;
160 register struct member *m;
63812b62 161
162 /* get locks */
163## retrieve (buf = users.modtime) where users.users_id = 0
8e7a00be 164## retrieve (buf = list.modtime) where list.list_id = 0
63812b62 165
166 cnt = 0;
167 machines = create_hash(1000);
168## retrieve (id = machine.mach_id, name = machine.#name) {
169 if (s = index(name, '.'))
170 *s = 0;
171 sprintf(buf, "%s.LOCAL", name);
8e7a00be 172 if (hash_store(machines, id, strsave(buf)) < 0) {
173 fprintf(stderr, "Out of memory!\n");
174 exit(SMS_NO_MEM);
175 }
63812b62 176 cnt++;
177## }
178 fprintf(stderr, "Loaded %d machines\n", cnt);
179
180 cnt = 0;
181 strings = create_hash(2000);
182## retrieve (id = strings.string_id, name = strings.string) {
8e7a00be 183 if (hash_store(strings, id, strsave(strtrim(name))) < 0) {
184 fprintf(stderr, "Out of memory!\n");
185 exit(SMS_NO_MEM);
186 }
63812b62 187 cnt++;
188## }
189 fprintf(stderr, "Loaded %d strings\n", cnt);
190
191 cnt = 0;
8e7a00be 192 users = create_hash(12001);
63812b62 193## range of u is users
8e7a00be 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 {
63812b62 198 u = (struct user *) malloc(sizeof(struct user));
63812b62 199 u->login = strsave(strtrim(name));
200 u->first = strsave(strtrim(fname));
201 u->last = strsave(strtrim(lname));
202 if (mname[0] != ' ')
203 u->mi = mname[0];
204 else
205 u->mi = 0;
63812b62 206
8e7a00be 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);
63812b62 212 } else
8e7a00be 213 u->pobox = (char *) NULL;
214 if (hash_store(users, id, u) < 0) {
215 fprintf(stderr, "Out of memory!\n");
216 exit(SMS_NO_MEM);
63812b62 217 }
63812b62 218 cnt++;
219## }
220 fprintf(stderr, "Loaded %d users\n", cnt);
8e7a00be 221
222 cnt = 0;
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;
231 l->acl_t = type[0];
232 l->acl_id = acl;
233 l->m = (struct member *) NULL;
234 if (hash_store(lists, id, l) < 0) {
235 fprintf(stderr, "Out of memory!\n");
236 exit(SMS_NO_MEM);
237 }
238 cnt++;
239## }
240 fprintf(stderr, "Loaded %d lists\n", cnt);
241
242 cnt = 0;
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 {
246 cnt++;
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))) {
251 m->list_id = 0;
252 m->name = u->login;
253 m->next = l->m;
254 l->m = m;
255 } else if (type[0] == 'L' &&
256 (memberlist = (struct list *) hash_lookup(lists, mid))) {
257 m->list_id = mid;
258 m->name = memberlist->name;
259 m->next = l->m;
260 l->m = m;
261 } else if (type[0] == 'S' &&
262 (s = hash_lookup(strings, mid))) {
263 m->list_id = 0;
264 m->next = l->m;
265 l->m = m;
266 m->name = s;
267 }
268 }
269## }
270 fprintf(stderr, "Loaded %d members\n", cnt);
63812b62 271##}
272
273
8e7a00be 274save_mlist(id, l, force)
275int id;
276struct list *l;
277int force;
63812b62 278{
8e7a00be 279 register struct member *m;
280 register struct list *l1;
281
282 if (l->maillist == 2 ||
283 l->maillist == 3 ||
284 (l->maillist == 0 && !force))
285 return;
286
287 if (l->m && l->m->next == NULL &&
288 !strcasecmp(l->name, l->m->name)) {
289 l->maillist = 3;
290 return;
63812b62 291 }
8e7a00be 292 l->maillist = 2;
293 insert_name(l->name, -id, TRUE, FALSE);
294
295 if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
296 save_mlist(0, l1, TRUE);
297
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);
63812b62 301 }
63812b62 302}
303
304
8e7a00be 305insert_login(id, u, dummy)
306int id;
307struct user *u;
308int dummy;
309{
310 if (u->pobox && u->login[0] != '#')
311 insert_name(u->login, id, TRUE, FALSE);
312}
313
63812b62 314void insert_names(id, u, dummy)
315int id;
316struct user *u;
317int dummy;
318{
319 char buffer[256];
320
8e7a00be 321 insert_name(u->last, id, FALSE, FALSE);
63812b62 322 sprintf(buffer, "%s_%s", u->first, u->last);
8e7a00be 323 insert_name(buffer, id, FALSE, TRUE);
324 sprintf(buffer, "%c_%s", u->first[0], u->last);
325 insert_name(buffer, id, FALSE, TRUE);
63812b62 326 if (u->mi) {
327 sprintf(buffer, "%s_%c_%s", u->first, u->mi, u->last);
8e7a00be 328 insert_name(buffer, id, FALSE, TRUE);
63812b62 329 }
330}
331
332int incount = 0;
333
8e7a00be 334insert_name(s, id, nodups, copy)
63812b62 335char *s;
336int id;
8e7a00be 337int nodups;
338int copy;
63812b62 339{
340 int code;
341 register struct names *ns;
342 register int count;
343 register struct idblock *ra;
344
345 incount++;
346 code = hashstr(s);
347 ns = (struct names *) hash_lookup(names, code);
348 if (ns == NULL) {
349 if ((ns = (struct names *) malloc(sizeof(struct names))) == NULL) {
350 fprintf(stderr, "ran out of memory inserting name (sorting)\n");
8e7a00be 351 exit(SMS_NO_MEM);
352 }
353 if (copy)
354 ns->name = strsave(s);
355 else
356 ns->name = s;
357 ns->keep = nodups;
358 ns->id = id;
359 if (hash_store(names, code, ns) < 0) {
360 fprintf(stderr, "Out of memory!\n");
361 exit(SMS_NO_MEM);
63812b62 362 }
63812b62 363 return;
364 }
365 if (strcasecmp(ns->name, s)) {
366 while (ns->next) {
367 ns = ns->next;
368 if (!strcasecmp(ns->name, s))
369 goto foundns;
370 }
371 if ((ns->next = (struct names *)malloc(sizeof(struct names))) == NULL) {
372 fprintf(stderr, "ran out of memory insterting name (sorting)\n");
8e7a00be 373 exit(SMS_NO_MEM);
63812b62 374 }
375 ns = ns->next;
8e7a00be 376 if (copy)
377 ns->name = strsave(s);
378 else
379 ns->name = s;
380 ns->keep = nodups;
381 ns->id = id;
63812b62 382 return;
383 }
384 foundns:
8e7a00be 385 if (nodups || ns->keep)
386 return;
387 ns->id = 0;
63812b62 388}
389
390
391int hashstr(s)
392register char *s;
393{
394 register int result;
395 register int c;
396
8e7a00be 397 for (result = 0; c = *s; s++) {
398 if (isupper(c))
399 c = *s = tolower(c);
63812b62 400/* result = result * 31 + *s; */
8e7a00be 401 result = (result << 5) - result + c - '`';
63812b62 402 }
403 return(result < 0 ? -result : result);
404}
405
406
407sort_info()
408{
8e7a00be 409 names = create_hash(20001);
410 hash_step(users, insert_login, NULL);
411 hash_step(lists, save_mlist, FALSE);
63812b62 412 hash_step(users, insert_names, NULL);
413 fprintf(stderr, "Inserted %d names\n", incount);
414}
415
416
63812b62 417output_data(dummy, nms, out)
418int dummy;
419struct names *nms;
420FILE *out;
421{
422 register struct names *ns;
423 register struct user *u;
424 int i;
425
426 incount++;
427 for (ns = nms; ns; ns = ns->next) {
8e7a00be 428 if (ns->name[0] == 0 || ns->name[1] == 0) {
429 fprintf(stderr, "punting %s due to short name\n", ns->name);
430 continue;
431 }
432 if (ns->id > 0) {
433 u = (struct user *) hash_lookup(users, ns->id);
63812b62 434 if (u->pobox) {
435 fprintf(out, "%s: %s\n", ns->name, u->pobox);
8e7a00be 436 } else {
437 fprintf(out, "%s: =%s=@nobox\n", ns->name, ns->name);
63812b62 438 }
8e7a00be 439 } else if (ns->id == 0) {
440 fprintf(out, "%s: =%s=@ambig\n", ns->name, ns->name);
63812b62 441 }
442 }
443}
444
445
8e7a00be 446int lwid, bol, awid;
447
448output_mlist(id, l, out)
449int id;
450register struct list *l;
451FILE *out;
452{
453 struct list *l1;
454 register struct member *m;
455 register struct user *u;
456
457 if (l->maillist != 2)
458 return;
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);
465
466 fprintf(out, "%s: ", l->name);
467 lwid = strlen(l->name) + 2;
468 bol = 1;
469 for (m = l->m; m; m = m->next) {
470 do_member(out, m->name);
471 }
472 if (l->m == (struct member *)NULL)
473 fprintf(out, "/dev/null");
474 fprintf(out, "\n\n");
475 incount++;
476}
477
478
479/* print out strings separated by commas, doing line breaks as appropriate */
480
481do_member(out, s)
482FILE *out;
483register char *s;
484{
485 register wwid;
486 static int cont = 1;
487
488 wwid = strlen(s);
489
490 if (!bol && awid + wwid + 2 > AL_MAX_WID) {
491 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
492 cont++;
493 awid = lwid = 17 + wwid;
494 fputs(s, out);
495 return;
496 }
497
498 if (bol) {
499 lwid += wwid;
500 awid = lwid;
501 fputs(s, out);
502 bol = 0;
503 return;
504 }
505 if (lwid + wwid + 2 > ML_WID) {
506 fprintf(out, ",\n\t%s", s);
507 awid += lwid + wwid + 2;
508 lwid = wwid + 8;
509 return;
510 }
511 lwid += wwid + 2;
512 fprintf(out, ", %s", s);
513}
514
515
516do_lists(out)
63812b62 517FILE *out;
518{
519 incount = 0;
8e7a00be 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);
523}
63812b62 524
8e7a00be 525do_people(out)
526FILE *out;
527{
528 incount = 0;
529 fprintf(out, "\n%s\n# People\n%s\n", divide, divide);
63812b62 530 hash_step(names, output_data, out);
63812b62 531 fprintf(stderr, "Output %d entries\n", incount);
532}
This page took 0.197623 seconds and 5 git commands to generate.