/* $Header$ * * This generates the /usr/lib/aliases mail aliases file for the mailhub. * The aliases file will contain: * user pobox entries * maillist expansions * sublists of maillists * mail alias entries */ #include #include #include #define ML_WID 72 #define AL_MAX_WID 896 char *divide = "########################################################################"; extern int errno; main(argc, argv) int argc; char **argv; { long tm = time(NULL); FILE *out= stdout; ## int error; if (argc == 2) { if ((out = fopen(argv[1], "w")) == NULL) { fprintf(stderr, "unable to open %s for output\n", argv[1]); exit(errno); } } else if (argc != 1) { fprintf(stderr, "usage: %s [outfile]\n", argv[0]); exit(-1); } ## ingres sms ## set lockmode session where readlock = nolock fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm)); fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide); do_mlists(out); do_poboxes(out); do_aliases(out); fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide); ## inquire_equel(error = "errorno") if (error) { fprintf(out, "Ingres error %d\n", error); exit(error); } ## exit if (fclose(out)) { perror("close failed"); exit(errno); } exit(0); } /* Extract mailing lists. First dump all real mailing lists. While doing * this, make a list of all mailing list IDs and all sub-list IDs. Next, * as long as there are sub-lists that aren't mailing lists, extract them * and add them to the list of mailing lists. If further sublists are * encountered, repeat... */ int lwid, bol; do_mlists(out) FILE *out; ##{ ## char name[257], desc[257], own_type[9], owner_name[33]; ## int id, own_id, member_id; struct save_queue *sq, *sq_create(); sq = sq_create(); fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide); ## range of l is list ## retrieve (id = l.list_id) where l.maillist != 0 { sq_save_unique_data(sq, id); ## } ## range of m is members ## range of u is users ## range of s is strings while (sq_get_data(sq, &id)) { ## repeat retrieve (name= l.#name, desc = l.#desc, ## own_type = l.acl_type, own_id = l.acl_id) ## where l.list_id = @id trim(name); trim(desc); trim(own_type); put_fill(out, desc); if (!strcmp(own_type, "LIST")) { ## repeat retrieve (owner_name = l.#name) where l.list_id = @own_id trim(owner_name); fprintf(out, "owner-%s: %s\n", name, owner_name); sq_save_unique_data(sq, own_id); } else if (!strcmp(own_type, "USER")) { ## repeat retrieve (owner_name = u.#login) where u.users_id = @own_id trim(owner_name); fprintf(out, "owner-%s: %s\n", name, owner_name); } fprintf(out, "%s: ", name); lwid = strlen(name) + 2; bol = 1; ## repeat retrieve (name = u.#login) where u.users_id = m.#member_id and ## m.list_id = @id and m.member_type = "USER" { do_member(out, name); ## } ## repeat retrieve (name = l.#name, member_id = m.#member_id) ## where l.list_id = m.#member_id and ## m.list_id = @id and m.member_type = "LIST" { do_member(out, name); sq_save_unique_data(sq, member_id); ## } ## repeat retrieve (name = s.#string) where s.string_id = m.#member_id and ## m.list_id = @id and m.member_type = "STRING" { do_member(out, name); ## } fprintf(out, "\n\n"); } sq_destroy(sq); ##} /* print out strings separated by commas, doing line breaks as appropriate */ do_member(out, s) FILE *out; register char *s; { register wwid; static int awid; static int cont = 1; trim(s); wwid = strlen(s); if (awid + wwid + 2 > AL_MAX_WID) { fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont); cont++; awid = lwid = bol = 17; } if (bol) { lwid += wwid; awid = lwid; fprintf(out, "%s", s); bol = 0; return; } if (lwid + wwid + 2 > ML_WID) { fprintf(out, ",\n\t%s", s); awid = lwid + wwid + 2; lwid = wwid + 8; return; } lwid += wwid + 2; fprintf(out, ", %s", s); } /* Extract user poboxes. First do POP boxes, where the name matches the * login name and the machine name is in the pop_id. Then do SMTP boxes, * where the expansion is stored in the strings table. The remaining boxes * are of type NONE and should be skipped. */ do_poboxes(out) FILE *out; ##{ ## char login[9], name[33], box[129]; fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide); ## range of u is users ## range of m is machine ## retrieve (login = u.#login, name = m.#name) ## where u.potype = "POP" and m.mach_id = u.pop_id { trim(login, name); fprintf(out, "%s: %s@%s\n", login, login, name); ## } fprintf(out, "\n# User Forwarding\n"); ## range of s is strings ## retrieve (login = u.#login, box = s.#string) ## where u.potype = "SMTP" and u.box_id = s.string_id { trim(login); trim(box); fprintf(out, "%s: %s\n", login, box); ## } ##} do_aliases(out) FILE *out; ##{ ## char name[33], trans[129]; fprintf(out, "\n%s\n# Aliases\n%s\n", divide, divide); ## range of a is alias ## retrieve (name = a.#name, trans = a.#trans) where a.type = "MAIL" { trim(name); trim(trans); fprintf(out, "%s: %s\n", name, trans); ## } ##} put_fill(aliases, string) FILE *aliases; register char *string; { register char *c; register int lwid; register int wwid; if (*string == 0) return; fputs("# ", aliases); lwid = 3; while (1) { while (*string && *string == ' ') string++; c = (char *)index(string, ' '); if (c == 0) { wwid = strlen(string); } else { wwid = c - string; *c = 0; } if ((lwid + wwid) > ML_WID) { fputs("\n# ", aliases); lwid = 3; fputs(string, aliases); } else { fputs(string, aliases); } if (c == (char *)0) break; /* add a space after the word */ (void) fputc(' ', aliases); wwid++; lwid += wwid; string += wwid; /* add another if after a period */ if (*--c == '.') { (void) fputc(' ', aliases); lwid++; } } (void) fputc('\n', aliases); } trim(s) register char *s; { register char *p; for (p = s; *s; s++) if (*s != ' ') p = s; if (p != s) { if (*p == ' ') *p = 0; else p[1] = 0; } }