]> andersk Git - moira.git/blame - gen/aliases.qc
don't allow duplicate MIT_ID's in ausr; allow rusr with status 6
[moira.git] / gen / aliases.qc
CommitLineData
67796c83 1/* $Header$
2 *
3 * This generates the /usr/lib/aliases mail aliases file for the mailhub.
4 * The aliases file will contain:
5 * user pobox entries
6 * maillist expansions
7 * sublists of maillists
0a5ff702 8 *
9 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, please see the file
11 * <mit-copyright.h>.
67796c83 12 */
13
14
0a5ff702 15#include <mit-copyright.h>
67796c83 16#include <stdio.h>
39b94410 17#include <string.h>
2ce085d2 18#include <moira.h>
19#include <moira_site.h>
5076cbb9 20#include <sys/types.h>
21#include <sys/stat.h>
22#include <sys/time.h>
23
67796c83 24
25#define ML_WID 72
26#define AL_MAX_WID 896
27
28char *divide = "########################################################################";
29extern int errno;
335b0c5e 30char *whoami = "aliases.gen";
5076cbb9 31char *ingres_date_and_time();
2c376b69 32FILE *out;
67796c83 33
34main(argc, argv)
35int argc;
36char **argv;
37{
38 long tm = time(NULL);
39b94410 39 char filename[64], *targetfile;
5076cbb9 40 struct stat sb;
39b94410 41## int flag1, flag2, flag3;
5076cbb9 42## char *filetime;
335b0c5e 43 int ingerr();
5076cbb9 44
2c376b69 45 out= stdout;
335b0c5e 46 IIseterr(ingerr);
2f2d93fc 47 initialize_sms_error_table();
5076cbb9 48## ingres sms
8b585119 49## set lockmode session where level = table
67796c83 50
51 if (argc == 2) {
5076cbb9 52 if (stat(argv[1], &sb) == 0) {
53 filetime = ingres_date_and_time(sb.st_mtime);
54## retrieve (flag1 = int4(interval("min",tblstats.modtime - filetime)))
55## where tblstats.table = "list"
56## retrieve (flag2 = int4(interval("min",tblstats.modtime - filetime)))
4b6e833d 57## where tblstats.table = "imembers"
5076cbb9 58## retrieve (flag3 = int4(interval("min",tblstats.modtime - filetime)))
59## where tblstats.table = "users"
60 if (flag1 < 0 && flag2 < 0 && flag3 < 0) {
61 fprintf(stderr, "File %s does not need to be rebuilt.\n",
62 argv[1]);
2ce085d2 63 exit(MR_NO_CHANGE);
5076cbb9 64 }
65 }
39b94410 66 targetfile = argv[1];
67 sprintf(filename, "%s~", targetfile);
68 if ((out = fopen(filename, "w")) == NULL) {
69 fprintf(stderr, "unable to open %s for output\n", filename);
2ce085d2 70 exit(MR_OCONFIG);
67796c83 71 }
72 } else if (argc != 1) {
73 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
2ce085d2 74 exit(MR_ARGS);
67796c83 75 }
76
67796c83 77 fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
78 fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
79
39b94410 80## begin transaction
81 get_info();
82## end transaction
83## exit
84
85 fprintf(stderr, "Dumping information\n");
67796c83 86 do_mlists(out);
87 do_poboxes(out);
67796c83 88
89 fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
90
67796c83 91
92 if (fclose(out)) {
93 perror("close failed");
2ce085d2 94 exit(MR_CCONFIG);
67796c83 95 }
39b94410 96
97 if (argc == 2)
98 fix_file(targetfile);
2ce085d2 99 exit(MR_SUCCESS);
67796c83 100}
101
102
335b0c5e 103/*
104 * ingerr: (supposedly) called when Ingres indicates an error.
105 * I have not yet been able to get this to work to intercept a
106 * database open error.
107 */
108#define INGRES_DEADLOCK 4700
109
110static int ingerr(num)
111 int *num;
112{
113 char buf[256];
114 int ingres_errno;
115
116 switch (*num) {
117 case INGRES_DEADLOCK:
2ce085d2 118 ingres_errno = MR_DEADLOCK;
335b0c5e 119 break;
120 default:
2ce085d2 121 ingres_errno = MR_INGRES_ERR;
335b0c5e 122 }
2ce085d2 123 com_err(whoami, MR_INGRES_ERR, " code %d\n", *num);
335b0c5e 124 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
125 exit(ingres_errno);
126}
127
128
39b94410 129struct hash *users, *machines, *strings, *lists;
130struct user {
131 char login[9];
132 char *pobox;
133};
134struct member {
135 struct member *next;
136 char *name;
137 int list_id;
138};
139struct list {
d1e41440 140 char *name;
39b94410 141 char maillist;
142 char acl_t;
d1e41440 143 char *description;
39b94410 144 int acl_id;
145 struct member *m;
146};
147
148
149get_info()
150##{
151## int id, maillistp, acl, pid, bid, mid;
152## char name[129], type[9], buf[257];
153 char *s;
154 register struct user *u;
155 register struct list *l;
156 register struct member *m;
12116e76 157 register struct list *memberlist;
39b94410 158
8b585119 159 /* get locks */
160## retrieve (buf = list.modtime) where list.list_id = 0
161## retrieve (buf = users.modtime) where users.users_id = 0
162
39b94410 163 fprintf(stderr, "Loading machines\n");
164 machines = create_hash(1000);
165## retrieve (id = machine.mach_id, name = machine.#name) {
166 if (s = index(name, '.'))
167 *s = 0;
b131a92e 168#ifdef ATHENA
d1e41440 169 strcat(name, ".LOCAL");
b131a92e 170#endif
d1e41440 171 hash_store(machines, id, strsave(name));
39b94410 172## }
173
174 fprintf(stderr, "Loading strings\n");
175 strings = create_hash(2000);
176## retrieve (id = strings.string_id, name = strings.string) {
177 hash_store(strings, id, strsave(strtrim(name)));
178## }
179
180 fprintf(stderr, "Loading users\n");
d1e41440 181 users = create_hash(12001);
39b94410 182## range of u is users
183## retrieve (id = u.users_id, name = u.login, type = u.potype,
491a7a83 184## pid = u.pop_id, bid = u.box_id)
185## where u.status = 1 or u.status = 5 or u.status = 6 {
39b94410 186 u = (struct user *) malloc(sizeof(struct user));
187 strcpy(u->login, strtrim(name));
39b94410 188 if (type[0] == 'P') {
189 if (s = hash_lookup(machines, pid)) {
190 sprintf(buf, "%s@%s", name, s);
191 u->pobox = strsave(buf);
192 } else {
d1e41440 193 u->pobox = (char *) NULL;
39b94410 194 fprintf(stderr, "User %s's pobox is on a missing machine!\n",
195 u->login);
196 }
197 } else if (type[0] == 'S') {
d1e41440 198 if ((u->pobox = hash_lookup(strings, bid)) == NULL) {
199 u->pobox = (char *) NULL;
200 fprintf(stderr, "User %s's pobox string is missing!\n",
201 u->login);
202 }
203 } else
204 u->pobox = (char *) NULL;
39b94410 205 hash_store(users, id, u);
206## }
207
208 fprintf(stderr, "Loading lists\n");
d1e41440 209 lists = create_hash(15001);
39b94410 210## range of l is list
211## retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist,
212## buf = l.desc, type = l.acl_type, acl = l.acl_id)
213## where l.active != 0 {
214 l = (struct list *) malloc(sizeof(struct list));
d1e41440 215 l->name = strsave(strtrim(name));
39b94410 216 l->maillist = maillistp;
d1e41440 217 l->description = strsave(strtrim(buf));
39b94410 218 l->acl_t = type[0];
219 l->acl_id = acl;
220 l->m = (struct member *) NULL;
221 hash_store(lists, id, l);
222## }
223
224
225 fprintf(stderr, "Loading members\n");
4b6e833d 226## range of m is imembers
227## retrieve (id = m.list_id, type = m.member_type, mid = m.member_id)
228## where m.direct = 1 {
39b94410 229 if (l = (struct list *) hash_lookup(lists, id)) {
230 m = (struct member *) malloc(sizeof(struct member));
d1e41440 231 if (type[0] == 'U' &&
232 (u = (struct user *) hash_lookup(users, mid))) {
39b94410 233 m->list_id = 0;
d1e41440 234 m->name = u->login;
235 m->next = l->m;
236 l->m = m;
237 } else if (type[0] == 'L' &&
238 (memberlist = (struct list *) hash_lookup(lists, mid))) {
39b94410 239 m->list_id = mid;
d1e41440 240 m->name = memberlist->name;
241 m->next = l->m;
242 l->m = m;
243 } else if (type[0] == 'S' &&
244 (s = hash_lookup(strings, mid))) {
39b94410 245 m->list_id = 0;
d1e41440 246 m->name = s;
39b94410 247 m->next = l->m;
248 l->m = m;
249 }
250 }
251## }
252##}
253
254
2c376b69 255save_mlist(id, l, force)
39b94410 256int id;
d1e41440 257register struct list *l;
2c376b69 258int force;
39b94410 259{
2c376b69 260 register struct member *m;
d1e41440 261 struct list *l1;
39b94410 262
2c376b69 263 if (l->maillist == 2 ||
264 (l->maillist == 0 && !force))
265 return;
266
267 if (l->m && l->m->next == NULL &&
268 !strcasecmp(l->name, l->m->name)) {
269 l->maillist = 0;
270 return;
271 }
272 l->maillist = 2;
273 output_mlist(id, l, out);
274
275 if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
276 save_mlist(0, l1, 1);
277
278 for (m = l->m; m; m = m->next) {
279 if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
280 save_mlist(0, l1, 0);
281 }
282}
39b94410 283
67796c83 284
12116e76 285int lwid, bol, awid;
67796c83 286
d1e41440 287output_mlist(id, l, dummy)
2c376b69 288int id;
289register struct list *l;
d1e41440 290int dummy;
39b94410 291{
39b94410 292 struct list *l1;
293 register struct member *m;
294 struct user *u;
39b94410 295 int id;
67796c83 296
2c376b69 297 put_fill(out, l->description);
298 if (l->acl_t == 'L') {
299 if (l1 = (struct list *) hash_lookup(lists, l->acl_id))
300 fprintf(out, "owner-%s: %s\n", l->name, l1->name);
301 } else if (l->acl_t == 'U') {
302 if (u = (struct user *) hash_lookup(users, l->acl_id))
303 fprintf(out, "owner-%s: %s\n", l->name, u->login);
67796c83 304 }
305
2c376b69 306 fprintf(out, "%s: ", l->name);
307 lwid = strlen(l->name) + 2;
308 bol = 1;
309 for (m = l->m; m; m = m->next)
310 do_member(out, m->name);
311 if (l->m == (struct member *)NULL)
312 fprintf(out, "/dev/null");
313 fprintf(out, "\n\n");
314}
315
316
317/* Extract mailing lists. Make a list of all mailinglists, then
318 * process them, adding any sub-lists or acl lists to the list of lists
319 * to be processed. If further sublists are encountered, repeat...
320 */
321
322do_mlists(out)
323FILE *out;
324{
325 fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
326 hash_step(lists, save_mlist, 0);
39b94410 327}
67796c83 328
329
330/* print out strings separated by commas, doing line breaks as appropriate */
331
332do_member(out, s)
333FILE *out;
334register char *s;
335{
336 register wwid;
67796c83 337 static int cont = 1;
338
67796c83 339 wwid = strlen(s);
340
12116e76 341 if (!bol && awid + wwid + 2 > AL_MAX_WID) {
67796c83 342 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
343 cont++;
d1e41440 344 awid = lwid = 17 + wwid;
345 fputs(s, out);
346 return;
67796c83 347 }
348
349 if (bol) {
350 lwid += wwid;
351 awid = lwid;
d1e41440 352 fputs(s, out);
67796c83 353 bol = 0;
354 return;
355 }
356 if (lwid + wwid + 2 > ML_WID) {
357 fprintf(out, ",\n\t%s", s);
12116e76 358 awid += lwid + wwid + 2;
67796c83 359 lwid = wwid + 8;
360 return;
361 }
362 lwid += wwid + 2;
363 fprintf(out, ", %s", s);
364}
365
39b94410 366do_pobox(id, u, out)
367int id;
368register struct user *u;
369FILE *out;
370{
371 if (u->pobox)
372 fprintf(out, "%s: %s\n", u->login, u->pobox);
373}
374
67796c83 375
39b94410 376/* Do user poboxes. Just step through the users table, and print any
377 * we extracted earlier.
67796c83 378 */
379
380do_poboxes(out)
381FILE *out;
39b94410 382{
383 register char *p;
384 char *index();
67796c83 385
386 fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
387
39b94410 388 hash_step(users, do_pobox, out);
389}
67796c83 390
391
392put_fill(aliases, string)
393FILE *aliases;
394register char *string;
395{
396 register char *c;
397 register int lwid;
398 register int wwid;
399
400 if (*string == 0) return;
401 fputs("# ", aliases);
402 lwid = 3;
403
404 while (1) {
405 while (*string && *string == ' ') string++;
406 c = (char *)index(string, ' ');
407 if (c == 0) {
408 wwid = strlen(string);
409 } else {
410 wwid = c - string;
411 *c = 0;
412 }
413
414 if ((lwid + wwid) > ML_WID) {
415 fputs("\n# ", aliases);
416 lwid = 3;
417 fputs(string, aliases);
418 } else {
419 fputs(string, aliases);
420 }
421
422 if (c == (char *)0) break;
423 /* add a space after the word */
424 (void) fputc(' ', aliases);
425 wwid++;
426 lwid += wwid;
427 string += wwid;
428 /* add another if after a period */
429 if (*--c == '.') {
430 (void) fputc(' ', aliases);
431 lwid++;
432 }
433 }
434
435 (void) fputc('\n', aliases);
436}
This page took 0.135895 seconds and 5 git commands to generate.