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