3 * This generates the /usr/lib/aliases mail aliases file for the mailhub.
4 * The aliases file will contain:
7 * sublists of maillists
9 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, please see the file
15 #include <mit-copyright.h>
20 #include <sys/types.h>
26 #define AL_MAX_WID 896
28 char *divide = "########################################################################";
30 char *whoami = "aliases.gen";
31 char *ingres_date_and_time();
39 char filename[64], *targetfile;
41 ## int flag1, flag2, flag3;
47 initialize_sms_error_table();
49 ## set lockmode session where level = table
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",
67 sprintf(filename, "%s~", targetfile);
68 if ((out = fopen(filename, "w")) == NULL) {
69 fprintf(stderr, "unable to open %s for output\n", filename);
72 } else if (argc != 1) {
73 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
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);
85 fprintf(stderr, "Dumping information\n");
89 fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
93 perror("close failed");
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.
108 #define INGRES_DEADLOCK 4700
110 static int ingerr(num)
117 case INGRES_DEADLOCK:
118 ingres_errno = SMS_DEADLOCK;
121 ingres_errno = SMS_INGRES_ERR;
123 com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
124 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
129 struct hash *users, *machines, *strings, *lists;
143 char description[256];
151 ## int id, maillistp, acl, pid, bid, mid;
152 ## char name[129], type[9], buf[257];
154 register struct user *u;
155 register struct list *l;
156 register struct member *m;
157 register struct list *memberlist;
160 ## retrieve (buf = list.modtime) where list.list_id = 0
161 ## retrieve (buf = users.modtime) where users.users_id = 0
163 fprintf(stderr, "Loading machines\n");
164 machines = create_hash(1000);
165 ## retrieve (id = machine.mach_id, name = machine.#name) {
166 if (s = index(name, '.'))
168 sprintf(buf, "%s.LOCAL", name);
169 hash_store(machines, id, strsave(buf));
172 fprintf(stderr, "Loading strings\n");
173 strings = create_hash(2000);
174 ## retrieve (id = strings.string_id, name = strings.string) {
175 hash_store(strings, id, strsave(strtrim(name)));
178 fprintf(stderr, "Loading users\n");
179 users = create_hash(15000);
180 ## range of u is users
181 ## retrieve (id = u.users_id, name = u.login, type = u.potype,
182 ## pid = u.pop_id, bid = u.box_id)
183 ## where u.status = 1 or u.status = 5 or u.status = 6 {
184 u = (struct user *) malloc(sizeof(struct user));
185 strcpy(u->login, strtrim(name));
186 u->pobox = (char *) NULL;
187 if (type[0] == 'P') {
188 if (s = hash_lookup(machines, pid)) {
189 sprintf(buf, "%s@%s", name, s);
190 u->pobox = strsave(buf);
192 fprintf(stderr, "User %s's pobox is on a missing machine!\n",
195 } else if (type[0] == 'S') {
196 if ((u->pobox = hash_lookup(strings, bid)) == NULL)
197 fprintf(stderr, "User %s's pobox string is missing!\n", u->login);
199 hash_store(users, id, u);
202 fprintf(stderr, "Loading lists\n");
203 lists = create_hash(15000);
204 ## range of l is list
205 ## retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist,
206 ## buf = l.desc, type = l.acl_type, acl = l.acl_id)
207 ## where l.active != 0 {
208 l = (struct list *) malloc(sizeof(struct list));
209 strcpy(l->name, strtrim(name));
210 l->maillist = maillistp;
211 strcpy(l->description, strtrim(buf));
214 l->m = (struct member *) NULL;
215 hash_store(lists, id, l);
219 fprintf(stderr, "Loading members\n");
220 ## range of m is imembers
221 ## retrieve (id = m.list_id, type = m.member_type, mid = m.member_id)
222 ## where m.direct = 1 {
223 if (l = (struct list *) hash_lookup(lists, id)) {
224 m = (struct member *) malloc(sizeof(struct member));
225 m->name = (char *) NULL;
226 if (type[0] == 'U') {
228 if (u = (struct user *) hash_lookup(users, mid))
230 } else if (type[0] == 'L') {
232 if (memberlist = (struct list *) hash_lookup(lists, mid))
233 m->name = memberlist->name;
234 } else if (type[0] == 'S') {
236 if (s = hash_lookup(strings, mid))
239 if (m->name != (char *) NULL) {
248 save_mlist(id, l, force)
253 register struct member *m;
254 register struct list *l1;
256 if (l->maillist == 2 ||
257 (l->maillist == 0 && !force))
260 if (l->m && l->m->next == NULL &&
261 !strcasecmp(l->name, l->m->name)) {
266 output_mlist(id, l, out);
268 if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
269 save_mlist(0, l1, 1);
271 for (m = l->m; m; m = m->next) {
272 if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
273 save_mlist(0, l1, 0);
280 output_mlist(id, l, out)
282 register struct list *l;
286 register struct member *m;
290 put_fill(out, l->description);
291 if (l->acl_t == 'L') {
292 if (l1 = (struct list *) hash_lookup(lists, l->acl_id))
293 fprintf(out, "owner-%s: %s\n", l->name, l1->name);
294 } else if (l->acl_t == 'U') {
295 if (u = (struct user *) hash_lookup(users, l->acl_id))
296 fprintf(out, "owner-%s: %s\n", l->name, u->login);
299 fprintf(out, "%s: ", l->name);
300 lwid = strlen(l->name) + 2;
302 for (m = l->m; m; m = m->next)
303 do_member(out, m->name);
304 if (l->m == (struct member *)NULL)
305 fprintf(out, "/dev/null");
306 fprintf(out, "\n\n");
310 /* Extract mailing lists. Make a list of all mailinglists, then
311 * process them, adding any sub-lists or acl lists to the list of lists
312 * to be processed. If further sublists are encountered, repeat...
318 fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
319 hash_step(lists, save_mlist, 0);
323 /* print out strings separated by commas, doing line breaks as appropriate */
335 if (!bol && awid + wwid + 2 > AL_MAX_WID) {
336 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
338 awid = lwid = bol = 17;
344 fprintf(out, "%s", s);
348 if (lwid + wwid + 2 > ML_WID) {
349 fprintf(out, ",\n\t%s", s);
350 awid += lwid + wwid + 2;
355 fprintf(out, ", %s", s);
360 register struct user *u;
364 fprintf(out, "%s: %s\n", u->login, u->pobox);
368 /* Do user poboxes. Just step through the users table, and print any
369 * we extracted earlier.
378 fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
380 hash_step(users, do_pobox, out);
384 put_fill(aliases, string)
386 register char *string;
392 if (*string == 0) return;
393 fputs("# ", aliases);
397 while (*string && *string == ' ') string++;
398 c = (char *)index(string, ' ');
400 wwid = strlen(string);
406 if ((lwid + wwid) > ML_WID) {
407 fputs("\n# ", aliases);
409 fputs(string, aliases);
411 fputs(string, aliases);
414 if (c == (char *)0) break;
415 /* add a space after the word */
416 (void) fputc(' ', aliases);
420 /* add another if after a period */
422 (void) fputc(' ', aliases);
427 (void) fputc('\n', aliases);