]> andersk Git - moira.git/blame - gen/aliases.dc
New database and field names for Moira2.
[moira.git] / gen / aliases.dc
CommitLineData
5d5f5413 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, 1990 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>
23EXEC SQL INCLUDE sqlca;
24
25
26#define ML_WID 72
27#define AL_MAX_WID 896
28
29char *divide = "########################################################################";
30extern int errno;
31char *whoami = "aliases.gen";
5d5f5413 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
43 out = stdout;
44 initialize_sms_error_table();
45#ifsql INGRES
13f3b2fd 46 EXEC SQL CONNECT moira;
5d5f5413 47#endsql
48#ifsql INFORMIX
13f3b2fd 49 EXEC SQL DATABASE moira;
5d5f5413 50#endsql
51
52
53 if (argc == 2) {
54 if (stat(argv[1], &sb) == 0) {
55
56 if (ModDiff (&flag1, "list", sb.st_mtime) ||
57 ModDiff (&flag2, "imembers", sb.st_mtime) ||
58 ModDiff (&flag3, "users", sb.st_mtime)) exit (MR_DATE);
59
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 get_info();
81#ifsql INFORMIX
82 EXEC SQL COMMIT WORK;
83#endif
84#ifsql INGRES
85 EXEC SQL DISCONNECT;
86#endsql
87
88 fprintf(stderr, "Dumping information\n");
89 do_mlists(out);
90 do_poboxes(out);
91
92 fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
93
94
95 if (fclose(out)) {
96 perror("close failed");
97 exit(MR_CCONFIG);
98 }
99
100 if (argc == 2)
101 fix_file(targetfile);
102 exit(MR_SUCCESS);
103}
104
105
106struct hash *users, *machines, *strings, *lists;
107struct user {
108 char login[9];
109 char *pobox;
110};
111struct member {
112 struct member *next;
113 char *name;
114 int list_id;
115};
116struct list {
117 char *name;
118 char maillist;
119 char acl_t;
120 char *description;
121 int acl_id;
122 struct member *m;
123};
124
125
126get_info()
127{
128 EXEC SQL BEGIN DECLARE SECTION;
129 int id, maillistp, acl, pid, bid, mid;
130 char name[129], type[9], buf[257];
131 EXEC SQL END DECLARE SECTION;
132 char *s;
133 register struct user *u;
134 register struct list *l;
135 register struct member *m;
136 register struct list *memberlist;
137
13f3b2fd 138 /* The following WHENEVER is declarative, not executed,
139 * and applies for the remainder of this file only.
140 */
5d5f5413 141 EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
142
143 /* get locks */
13f3b2fd 144 EXEC SQL SELECT modtime INTO :buf FROM list WHERE list_id = 0;
145 EXEC SQL SELECT modtime INTO :buf FROM list WHERE users_id = 0;
5d5f5413 146
147 fprintf(stderr, "Loading machines\n");
148 machines = create_hash(1000);
149
150 EXEC SQL DECLARE m_cursor CURSOR FOR
151 SELECT mach_id, name
152 FROM machine;
153 EXEC SQL OPEN m_cursor;
154 while (1) {
155 EXEC SQL FETCH m_cursor INTO :id, :name;
156 if (sqlca.sqlcode != 0) break;
157 if (s = index(name, '.'))
158 *s = 0;
159#ifdef ATHENA
160 strcat(name, ".LOCAL");
161#endif
162 hash_store(machines, id, strsave(name));
163 }
164 EXEC SQL CLOSE m_cursor;
165
166
167 fprintf(stderr, "Loading strings\n");
168 strings = create_hash(2000);
169
170 EXEC SQL DECLARE s_cursor CURSOR FOR
171 SELECT string_id, string
172 FROM strings;
173 EXEC SQL OPEN s_cursor;
174 while (1) {
175 EXEC SQL FETCH s_cursor INTO :id, :name;
176 if (sqlca.sqlcode != 0) break;
177 hash_store(strings, id, strsave(strtrim(name)));
178 }
179 EXEC SQL CLOSE s_cursor;
180
181 fprintf(stderr, "Loading users\n");
182 users = create_hash(12001);
183
184 EXEC SQL DECLARE u_cursor CURSOR FOR
185 SELECT users_id, login, potype, pop_id, box_id
186 FROM users WHERE status = 1 OR status = 5 OR status = 6;
187 EXEC SQL OPEN u_cursor;
188 while (1) {
189 EXEC SQL FETCH u_cursor INTO :id, :name, :type, :pid, :bid;
190 if (sqlca.sqlcode != 0) break;
191 u = (struct user *) malloc(sizeof(struct user));
192 strcpy(u->login, strtrim(name));
193 if (type[0] == 'P') {
194 if (s = hash_lookup(machines, pid)) {
195 sprintf(buf, "%s@%s", name, s);
196 u->pobox = strsave(buf);
197 } else {
198 u->pobox = (char *) NULL;
199 fprintf(stderr, "User %s's pobox is on a missing machine!\n",
200 u->login);
201 }
202 } else if (type[0] == 'S') {
203 if ((u->pobox = hash_lookup(strings, bid)) == NULL) {
204 u->pobox = (char *) NULL;
205 fprintf(stderr, "User %s's pobox string is missing!\n",
206 u->login);
207 }
208 } else
209 u->pobox = (char *) NULL;
210 hash_store(users, id, u);
211 }
212 EXEC SQL CLOSE u_cursor;
213
214 fprintf(stderr, "Loading lists\n");
215 lists = create_hash(15001);
216
217 EXEC SQL DECLARE l_cursor CURSOR FOR
13f3b2fd 218 SELECT list_id, name, maillist, description, acl_type, acl_id
5d5f5413 219 FROM list WHERE active != 0;
220 EXEC SQL OPEN l_cursor;
221 while (1) {
222 EXEC SQL FETCH l_cursor INTO :id, :name, :maillistp,
223 :buf, :type, :acl;
224 if (sqlca.sqlcode != 0) break;
225 l = (struct list *) malloc(sizeof(struct list));
226 l->name = strsave(strtrim(name));
227 l->maillist = maillistp;
228 l->description = strsave(strtrim(buf));
229 l->acl_t = type[0];
230 l->acl_id = acl;
231 l->m = (struct member *) NULL;
232 hash_store(lists, id, l);
233 }
234 EXEC SQL CLOSE l_cursor;
235
236 fprintf(stderr, "Loading members\n");
237
238 EXEC SQL DECLARE mem_cursor CURSOR FOR
239 SELECT list_id, member_type, member_id
240 FROM imembers WHERE direct = 1;
241 EXEC SQL OPEN mem_cursor;
242 while (1) {
243 EXEC SQL FETCH mem_cursor INTO :id, :type, :mid;
244 if (sqlca.sqlcode != 0) break;
245 if (l = (struct list *) hash_lookup(lists, id)) {
246 m = (struct member *) malloc(sizeof(struct member));
247 if (type[0] == 'U' &&
248 (u = (struct user *) hash_lookup(users, mid))) {
249 m->list_id = 0;
250 m->name = u->login;
251 m->next = l->m;
252 l->m = m;
253 } else if (type[0] == 'L' &&
254 (memberlist = (struct list *) hash_lookup(lists, mid))) {
255 m->list_id = mid;
256 m->name = memberlist->name;
257 m->next = l->m;
258 l->m = m;
259 } else if (type[0] == 'S' &&
260 (s = hash_lookup(strings, mid))) {
261 m->list_id = 0;
262 m->name = s;
263 m->next = l->m;
264 l->m = m;
265 }
266 }
267 }
268 EXEC SQL CLOSE mem_cursor;
269 return;
270 sqlerr:
271 com_err(whoami, MR_INGRES_ERR, " code %d\n", sqlca.sqlcode);
272 critical_alert("DCM", "Alias build encountered INGRES ERROR %d",
273 sqlca.sqlcode);
274 exit(MR_INGRES_ERR);
275}
276
277
278save_mlist(id, l, force)
279int id;
280register struct list *l;
281int force;
282{
283 register struct member *m;
284 struct list *l1;
285
286 if (l->maillist == 2 ||
287 (l->maillist == 0 && !force))
288 return;
289
290 if (l->m && l->m->next == NULL &&
291 !strcasecmp(l->name, l->m->name)) {
292 l->maillist = 0;
293 return;
294 }
295 l->maillist = 2;
296 output_mlist(id, l);
297
298 if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
299 save_mlist(0, l1, 1);
300
301 for (m = l->m; m; m = m->next) {
302 if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
303 save_mlist(0, l1, 1);
304 }
305}
306
307
308int lwid, bol, awid;
309
310output_mlist(id, l)
311int id;
312register struct list *l;
313{
314 struct list *l1;
315 register struct member *m;
316 struct user *u;
317
318 put_fill(out, l->description);
319 if (l->acl_t == 'L') {
320 if (l1 = (struct list *) hash_lookup(lists, l->acl_id))
321 fprintf(out, "owner-%s: %s\n", l->name, l1->name);
322 } else if (l->acl_t == 'U') {
323 if (u = (struct user *) hash_lookup(users, l->acl_id))
324 fprintf(out, "owner-%s: %s\n", l->name, u->login);
325 }
326
327 fprintf(out, "%s: ", l->name);
328 lwid = strlen(l->name) + 2;
329 bol = 1;
330 for (m = l->m; m; m = m->next)
331 do_member(out, m->name);
332 if (l->m == (struct member *)NULL)
333 fprintf(out, "/dev/null");
334 fprintf(out, "\n\n");
335}
336
337
338/* Extract mailing lists. Make a list of all mailinglists, then
339 * process them, adding any sub-lists or acl lists to the list of lists
340 * to be processed. If further sublists are encountered, repeat...
341 */
342
343do_mlists(out)
344FILE *out;
345{
346 fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
347 hash_step(lists, save_mlist, 0);
348}
349
350
351/* print out strings separated by commas, doing line breaks as appropriate */
352
353do_member(out, s)
354FILE *out;
355register char *s;
356{
357 register wwid;
358 static int cont = 1;
359
360 wwid = strlen(s);
361
362 if (!bol && awid + wwid + 2 > AL_MAX_WID) {
363 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
364 cont++;
365 awid = lwid = 17 + wwid;
366 fputs(s, out);
367 return;
368 }
369
370 if (bol) {
371 lwid += wwid;
372 awid = lwid;
373 fputs(s, out);
374 bol = 0;
375 return;
376 }
377 if (lwid + wwid + 2 > ML_WID) {
378 fprintf(out, ",\n\t%s", s);
379 awid += lwid + wwid + 2;
380 lwid = wwid + 8;
381 return;
382 }
383 lwid += wwid + 2;
384 fprintf(out, ", %s", s);
385}
386
387do_pobox(id, u, out)
388int id;
389register struct user *u;
390FILE *out;
391{
392 if (u->pobox)
393 fprintf(out, "%s: %s\n", u->login, u->pobox);
394}
395
396
397/* Do user poboxes. Just step through the users table, and print any
398 * we extracted earlier.
399 */
400
401do_poboxes(out)
402FILE *out;
403{
404 fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
405
406 hash_step(users, do_pobox, out);
407}
408
409
410put_fill(aliases, string)
411FILE *aliases;
412register char *string;
413{
414 register char *c;
415 register int lwid;
416 register int wwid;
417
418 if (*string == 0) return;
419 fputs("# ", aliases);
420 lwid = 3;
421
422 while (1) {
423 while (*string && *string == ' ') string++;
424 c = (char *)index(string, ' ');
425 if (c == 0) {
426 wwid = strlen(string);
427 } else {
428 wwid = c - string;
429 *c = 0;
430 }
431
432 if ((lwid + wwid) > ML_WID) {
433 fputs("\n# ", aliases);
434 lwid = 3;
435 fputs(string, aliases);
436 } else {
437 fputs(string, aliases);
438 }
439
440 if (c == (char *)0) break;
441 /* add a space after the word */
442 (void) fputc(' ', aliases);
443 wwid++;
444 lwid += wwid;
445 string += wwid;
446 /* add another if after a period */
447 if (*--c == '.') {
448 (void) fputc(' ', aliases);
449 lwid++;
450 }
451 }
452
453 (void) fputc('\n', aliases);
454}
This page took 4.262134 seconds and 5 git commands to generate.