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