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