]> andersk Git - moira.git/blame - gen/aliases.qc
fixed make clean
[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>
67796c83 18#include <sms.h>
19#include <sms_app.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();
67796c83 32
33
34main(argc, argv)
35int argc;
36char **argv;
37{
38 long tm = time(NULL);
39 FILE *out= stdout;
39b94410 40 char filename[64], *targetfile;
5076cbb9 41 struct stat sb;
39b94410 42## int flag1, flag2, flag3;
5076cbb9 43## char *filetime;
335b0c5e 44 int ingerr();
5076cbb9 45
335b0c5e 46 IIseterr(ingerr);
5076cbb9 47## ingres sms
8b585119 48## set lockmode session where level = table
67796c83 49
50 if (argc == 2) {
5076cbb9 51 if (stat(argv[1], &sb) == 0) {
52 filetime = ingres_date_and_time(sb.st_mtime);
53## retrieve (flag1 = int4(interval("min",tblstats.modtime - filetime)))
54## where tblstats.table = "list"
55## retrieve (flag2 = int4(interval("min",tblstats.modtime - filetime)))
4b6e833d 56## where tblstats.table = "imembers"
5076cbb9 57## retrieve (flag3 = int4(interval("min",tblstats.modtime - filetime)))
58## where tblstats.table = "users"
59 if (flag1 < 0 && flag2 < 0 && flag3 < 0) {
60 fprintf(stderr, "File %s does not need to be rebuilt.\n",
61 argv[1]);
39b94410 62 exit(SMS_NO_CHANGE);
5076cbb9 63 }
64 }
39b94410 65 targetfile = argv[1];
66 sprintf(filename, "%s~", targetfile);
67 if ((out = fopen(filename, "w")) == NULL) {
68 fprintf(stderr, "unable to open %s for output\n", filename);
69 exit(SMS_OCONFIG);
67796c83 70 }
71 } else if (argc != 1) {
72 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
39b94410 73 exit(SMS_ARGS);
67796c83 74 }
75
67796c83 76 fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
77 fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
78
39b94410 79## begin transaction
80 get_info();
81## end transaction
82## exit
83
84 fprintf(stderr, "Dumping information\n");
67796c83 85 do_mlists(out);
86 do_poboxes(out);
67796c83 87
88 fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
89
67796c83 90
91 if (fclose(out)) {
92 perror("close failed");
39b94410 93 exit(SMS_CCONFIG);
67796c83 94 }
39b94410 95
96 if (argc == 2)
97 fix_file(targetfile);
98 exit(SMS_SUCCESS);
67796c83 99}
100
101
335b0c5e 102/*
103 * ingerr: (supposedly) called when Ingres indicates an error.
104 * I have not yet been able to get this to work to intercept a
105 * database open error.
106 */
107#define INGRES_DEADLOCK 4700
108
109static int ingerr(num)
110 int *num;
111{
112 char buf[256];
113 int ingres_errno;
114
115 switch (*num) {
116 case INGRES_DEADLOCK:
117 ingres_errno = SMS_DEADLOCK;
118 break;
119 default:
120 ingres_errno = SMS_INGRES_ERR;
121 }
122 com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
123 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
124 exit(ingres_errno);
125}
126
127
39b94410 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[33];
140 char maillist;
141 char acl_t;
142 char description[256];
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;
12116e76 156 register struct list *memberlist;
39b94410 157
8b585119 158 /* get locks */
159## retrieve (buf = list.modtime) where list.list_id = 0
160## retrieve (buf = users.modtime) where users.users_id = 0
161
39b94410 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 sprintf(buf, "%s.LOCAL", name);
168 hash_store(machines, id, strsave(buf));
169## }
170
171 fprintf(stderr, "Loading strings\n");
172 strings = create_hash(2000);
173## retrieve (id = strings.string_id, name = strings.string) {
174 hash_store(strings, id, strsave(strtrim(name)));
175## }
176
177 fprintf(stderr, "Loading users\n");
178 users = create_hash(15000);
179## range of u is users
180## retrieve (id = u.users_id, name = u.login, type = u.potype,
181## pid = u.pop_id, bid = u.box_id) where u.status = 1 {
182 u = (struct user *) malloc(sizeof(struct user));
183 strcpy(u->login, strtrim(name));
184 u->pobox = (char *) NULL;
185 if (type[0] == 'P') {
186 if (s = hash_lookup(machines, pid)) {
187 sprintf(buf, "%s@%s", name, s);
188 u->pobox = strsave(buf);
189 } else {
190 fprintf(stderr, "User %s's pobox is on a missing machine!\n",
191 u->login);
192 }
193 } else if (type[0] == 'S') {
194 if ((u->pobox = hash_lookup(strings, bid)) == NULL)
195 fprintf(stderr, "User %s's pobox string is missing!\n", u->login);
196 }
197 hash_store(users, id, u);
198## }
199
200 fprintf(stderr, "Loading lists\n");
201 lists = create_hash(15000);
202## range of l is list
203## retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist,
204## buf = l.desc, type = l.acl_type, acl = l.acl_id)
205## where l.active != 0 {
206 l = (struct list *) malloc(sizeof(struct list));
207 strcpy(l->name, strtrim(name));
208 l->maillist = maillistp;
209 strcpy(l->description, strtrim(buf));
210 l->acl_t = type[0];
211 l->acl_id = acl;
212 l->m = (struct member *) NULL;
213 hash_store(lists, id, l);
214## }
215
216
217 fprintf(stderr, "Loading members\n");
4b6e833d 218## range of m is imembers
219## retrieve (id = m.list_id, type = m.member_type, mid = m.member_id)
220## where m.direct = 1 {
39b94410 221 if (l = (struct list *) hash_lookup(lists, id)) {
222 m = (struct member *) malloc(sizeof(struct member));
223 m->name = (char *) NULL;
224 if (type[0] == 'U') {
225 m->list_id = 0;
226 if (u = (struct user *) hash_lookup(users, mid))
227 m->name = u->login;
228 } else if (type[0] == 'L') {
229 m->list_id = mid;
12116e76 230 if (memberlist = (struct list *) hash_lookup(lists, mid))
231 m->name = memberlist->name;
39b94410 232 } else if (type[0] == 'S') {
233 m->list_id = 0;
234 if (s = hash_lookup(strings, mid))
235 m->name = s;
236 }
237 if (m->name != (char *) NULL) {
238 m->next = l->m;
239 l->m = m;
240 }
241 }
242## }
243##}
244
245
246void save_mlist(id, l, sq)
247int id;
248struct list *l;
249struct save_queue *sq;
250{
251 if (l->maillist)
252 sq_save_unique_data(sq, id);
253}
254
255
39b94410 256/* Extract mailing lists. Make a list of all mailinglists, then
257 * process them, adding any sub-lists or acl lists to the list of lists
258 * to be processed. If further sublists are encountered, repeat...
67796c83 259 */
260
12116e76 261int lwid, bol, awid;
67796c83 262
263do_mlists(out)
264FILE *out;
39b94410 265{
266 register struct list *l;
267 struct list *l1;
268 register struct member *m;
269 struct user *u;
270 register struct save_queue *sq;
271 struct save_queue *sq_create();
272 int id;
67796c83 273
274 sq = sq_create();
275 fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
276
39b94410 277 hash_step(lists, save_mlist, sq);
67796c83 278
67796c83 279 while (sq_get_data(sq, &id)) {
39b94410 280 l = (struct list *) hash_lookup(lists, id);
281 if (l->m && /* there's at least one member */
282 l->m->next == NULL && /* there's only one member */
283 !strcmp(l->name, l->m->name)) /* the member is same as list */
284 continue;
285 put_fill(out, l->description);
286 if (l->acl_t == 'L') {
287 if (l1 = (struct list *) hash_lookup(lists, l->acl_id)) {
288 fprintf(out, "owner-%s: %s\n", l->name, l1->name);
12116e76 289 sq_save_unique_data(sq, l->acl_id);
39b94410 290 }
291 } else if (l->acl_t == 'U') {
292 if (u = (struct user *) hash_lookup(users, l->acl_id))
293 fprintf(out, "owner-%s: %s\n", l->name, u->login);
67796c83 294 }
39b94410 295 fprintf(out, "%s: ", l->name);
296 lwid = strlen(l->name) + 2;
67796c83 297 bol = 1;
39b94410 298 for (m = l->m; m; m = m->next) {
12116e76 299 if (m->list_id != 0)
39b94410 300 sq_save_unique_data(sq, m->list_id);
301 do_member(out, m->name);
302 }
67796c83 303 fprintf(out, "\n\n");
304 }
305
12116e76 306/* Removed for speed, since this take 10 minutes to free, and we don't
307 * really need the memory reclaimed.
308 * sq_destroy(sq); */
39b94410 309}
67796c83 310
311
312/* print out strings separated by commas, doing line breaks as appropriate */
313
314do_member(out, s)
315FILE *out;
316register char *s;
317{
318 register wwid;
67796c83 319 static int cont = 1;
320
39b94410 321 strtrim(s);
67796c83 322 wwid = strlen(s);
323
12116e76 324 if (!bol && awid + wwid + 2 > AL_MAX_WID) {
67796c83 325 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
326 cont++;
327 awid = lwid = bol = 17;
328 }
329
330 if (bol) {
331 lwid += wwid;
332 awid = lwid;
333 fprintf(out, "%s", s);
334 bol = 0;
335 return;
336 }
337 if (lwid + wwid + 2 > ML_WID) {
338 fprintf(out, ",\n\t%s", s);
12116e76 339 awid += lwid + wwid + 2;
67796c83 340 lwid = wwid + 8;
341 return;
342 }
343 lwid += wwid + 2;
344 fprintf(out, ", %s", s);
345}
346
39b94410 347do_pobox(id, u, out)
348int id;
349register struct user *u;
350FILE *out;
351{
352 if (u->pobox)
353 fprintf(out, "%s: %s\n", u->login, u->pobox);
354}
355
67796c83 356
39b94410 357/* Do user poboxes. Just step through the users table, and print any
358 * we extracted earlier.
67796c83 359 */
360
361do_poboxes(out)
362FILE *out;
39b94410 363{
364 register char *p;
365 char *index();
67796c83 366
367 fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
368
39b94410 369 hash_step(users, do_pobox, out);
370}
67796c83 371
372
373put_fill(aliases, string)
374FILE *aliases;
375register char *string;
376{
377 register char *c;
378 register int lwid;
379 register int wwid;
380
381 if (*string == 0) return;
382 fputs("# ", aliases);
383 lwid = 3;
384
385 while (1) {
386 while (*string && *string == ' ') string++;
387 c = (char *)index(string, ' ');
388 if (c == 0) {
389 wwid = strlen(string);
390 } else {
391 wwid = c - string;
392 *c = 0;
393 }
394
395 if ((lwid + wwid) > ML_WID) {
396 fputs("\n# ", aliases);
397 lwid = 3;
398 fputs(string, aliases);
399 } else {
400 fputs(string, aliases);
401 }
402
403 if (c == (char *)0) break;
404 /* add a space after the word */
405 (void) fputc(' ', aliases);
406 wwid++;
407 lwid += wwid;
408 string += wwid;
409 /* add another if after a period */
410 if (*--c == '.') {
411 (void) fputc(' ', aliases);
412 lwid++;
413 }
414 }
415
416 (void) fputc('\n', aliases);
417}
This page took 0.11821 seconds and 5 git commands to generate.