X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/46c8036acd7652b1cb94396eaca21bcaead42ab4..e35622fc2ccc96373a383fe1550e1e5b17202d28:/gen/mailhub.pc diff --git a/gen/mailhub.pc b/gen/mailhub.pc index 7a624fa2..6e531aa5 100644 --- a/gen/mailhub.pc +++ b/gen/mailhub.pc @@ -34,8 +34,6 @@ char *divide = "##############################################################"; #define FALSE 0 #define TRUE (!FALSE) -FILE *out = stdout; - struct hash *users, *machines, *strings, *lists; struct user { char *login; @@ -52,14 +50,16 @@ struct list { char *description; char acl_t; int acl_id; + char mailman; + char *mailman_server; struct member *m; }; void get_info(void); -void save_mlist(int id, void *list, void *force); int check_string(char *s); void output_login(int dummy, void *names, void *out); -void output_mlist(int id, struct list *l); +void output_mlist(int id, void *list, void *out); +void output_membership(struct list *l, FILE *out); void put_fill(FILE *aliases, char *string); void do_people(void); @@ -69,25 +69,13 @@ int main(int argc, char **argv) { time_t tm = time(NULL); char filename[MAXPATHLEN], *targetfile; - struct stat sb; - int flag1, flag2; + FILE *out = stdout; + srand(tm); EXEC SQL CONNECT :db; if (argc == 2) { - if (stat(argv[1], &sb) == 0) - { - if (ModDiff(&flag1, "users", sb.st_mtime) || - ModDiff(&flag2, "list", sb.st_mtime)) - exit(MR_DATE); - if (flag1 < 0 && flag2 < 0) - { - fprintf(stderr, "File %s does not need to be rebuilt.\n", - argv[1]); - exit(MR_NO_CHANGE); - } - } targetfile = argv[1]; sprintf(filename, "%s~", targetfile); if (!(out = fopen(filename, "w"))) @@ -112,7 +100,7 @@ int main(int argc, char **argv) incount = 0; fprintf(out, "\n%s\n# Mailing lists\n%s\n\n", divide, divide); - hash_step(lists, save_mlist, FALSE); + hash_step(lists, output_mlist, out); fprintf(stderr, "Output %d lists\n", incount); incount = 0; @@ -136,11 +124,11 @@ int main(int argc, char **argv) void get_info(void) { EXEC SQL BEGIN DECLARE SECTION; - int id, pid, iid, bid, cnt, maillistp, acl, mid; + int id, pid, iid, bid, cnt, maillistp, acl, mid, mailman; char mname[MACHINE_NAME_SIZE], str[STRINGS_STRING_SIZE]; char login[USERS_LOGIN_SIZE], potype[USERS_POTYPE_SIZE]; char lname[LIST_NAME_SIZE], desc[LIST_DESCRIPTION_SIZE]; - char type[LIST_ACL_TYPE_SIZE]; + char type[LIST_ACL_TYPE_SIZE], mailman_server[MACHINE_NAME_SIZE]; EXEC SQL END DECLARE SECTION; char *s; struct user *u; @@ -160,7 +148,9 @@ void get_info(void) SELECT mach_id, name FROM machine WHERE status = 1 - AND mach_id IN ( SELECT UNIQUE pop_id FROM users ) + AND ( mach_id IN ( SELECT UNIQUE pop_id FROM users ) OR + mach_id IN ( SELECT UNIQUE mach_id FROM filesys + WHERE type = 'IMAP' ) ) ORDER BY mach_id; EXEC SQL OPEN m_cursor; while (1) @@ -221,29 +211,52 @@ void get_info(void) EXEC SQL OPEN u_cursor; while (1) { + char *saddr = NULL, *paddr = NULL; + EXEC SQL FETCH u_cursor INTO :id, :login, :potype, :pid, :iid, :bid; if (sqlca.sqlcode) break; u = malloc(sizeof(struct user)); u->login = strdup(strtrim(login)); - if (potype[0] == 'I') - { - EXEC SQL SELECT f.mach_id INTO :pid FROM filesys f, users u - WHERE u.users_id = :id AND f.filsys_id = u.imap_id; - if (sqlca.sqlcode == 0) - potype[0] = 'P'; - } - if (potype[0] == 'P' && (s = hash_lookup(machines, pid))) + if (!strcmp(strtrim(potype), "NONE")) + u->pobox = NULL; + else { - char *buf = malloc(strlen(u->login) + strlen(s) + 2); - sprintf(buf, "%s@%s", u->login, s); - u->pobox = buf; + /* If SMTP or SPLIT, get SMTP address. */ + if (potype[0] == 'S') + { + saddr = hash_lookup(strings, bid); + + /* If SMTP, clear pid and iid. */ + if (potype[1] == 'M') + pid = iid = 0; + } + + /* If IMAP, or SPLIT with IMAP, set pid to mach_id. */ + if (potype[0] == 'I' || (potype[0] == 'S' && iid)) + { + EXEC SQL SELECT mach_id INTO :pid FROM filesys + WHERE filsys_id = :iid; + } + + if (pid && (s = hash_lookup(machines, pid))) + { + paddr = malloc(strlen(u->login) + strlen(s) + 2); + sprintf(paddr, "%s@%s", u->login, s); + } + + if (paddr && saddr) + { + u->pobox = malloc(strlen(paddr) + strlen(saddr) + 3); + sprintf(u->pobox, "%s, %s", paddr, saddr); + free(paddr); + } + else if (paddr) + u->pobox = paddr; + else + u->pobox = saddr; } - else if (potype[0] == 'S') - u->pobox = hash_lookup(strings, bid); - else - u->pobox = NULL; check_string(u->login); if (hash_store(users, id, u) < 0) @@ -260,14 +273,16 @@ void get_info(void) lists = create_hash(15000); EXEC SQL DECLARE l_cursor CURSOR FOR - SELECT list_id, name, maillist, description, acl_type, acl_id - FROM list - WHERE active != 0 + SELECT l.list_id, l.name, l.maillist, l.description, l.acl_type, l.acl_id, + l.mailman, m.name + FROM list l, machine m + WHERE active != 0 AND l.mailman_id = m.mach_id ORDER BY list_id; EXEC SQL OPEN l_cursor; while (1) { - EXEC SQL FETCH l_cursor INTO :id, :lname, :maillistp, :desc, :type, :acl; + EXEC SQL FETCH l_cursor INTO :id, :lname, :maillistp, :desc, :type, :acl, + :mailman, :mailman_server; if (sqlca.sqlcode) break; l = malloc(sizeof(struct list)); @@ -276,6 +291,8 @@ void get_info(void) l->description = strdup(strtrim(desc)); l->acl_t = type[0]; l->acl_id = acl; + l->mailman = mailman; + l->mailman_server = strdup(strtrim(mailman_server)); l->m = NULL; if (hash_store(lists, id, l) < 0) { @@ -338,67 +355,79 @@ sqlerr: } -void save_mlist(int id, void *list, void *force) +void output_login(int dummy, void *user, void *out) +{ + struct user *u = user; + + incount++; + if (u->pobox && check_string(u->login) && u->login[0] != '#') + fprintf(out, "%s: %s\n", u->login, u->pobox); +} + +int line_width, alias_width; +static const char *mailman_suffixes[] = { "-admin", "-owner", "-request", + "-bounces", "-confirm", "-join", + "-leave", "-subscribe", + "-unsubscribe", NULL }; + +void output_mlist(int id, void *list, void *out) { - struct member *m; struct list *l = list, *l1; + struct user *u; + int len = strlen(l->name), i; - if (l->maillist > 1 || (l->maillist == 0 && !force) || - !check_string(l->name)) + if (!l->maillist || !check_string(l->name)) return; - /* If user group appears on list, replace with user. */ + /* If standard user group appears on a list, substitute in the user. */ if (l->m && l->m->next == NULL && !strcasecmp(l->name, l->m->name)) - { - l->maillist = 3; - return; - } - l->maillist = 2; - output_mlist(id, l); + return; - if (l->acl_t == 'L' && (l1 = hash_lookup(lists, l->acl_id))) - save_mlist(0, l1, (void *)TRUE); + put_fill(out, l->description); - for (m = l->m; m; m = m->next) + if (l->mailman && strcmp(l->mailman_server, "[NONE]")) { - if (m->list_id && (l1 = hash_lookup(lists, m->list_id))) - save_mlist(0, l1, (void *)TRUE); + for (i = 0; mailman_suffixes[i]; i++) + fprintf(out, "%s%s: %s%s@%s\n", l->name, mailman_suffixes[i], l->name, + mailman_suffixes[i], l->mailman_server); + fprintf(out, "owner-%s: %s-owner@%s\n", l->name, l->name, + l->mailman_server); } -} - -void output_login(int dummy, void *user, void *out) -{ - struct user *u = user; + else if (l->acl_t == 'L' && (l1 = hash_lookup(lists, l->acl_id))) + { + fprintf(out, "owner-%s: ", l->name); + if ((l1->maillist) && (strcmp(l->name, l1->name))) + fprintf(out, "%s\n", l1->name); + else + { + alias_width = line_width = len + 8; + output_membership(l1, out); + fprintf(out, "\n"); + } + } + else if (l->acl_t == 'U' && (u = hash_lookup(users, l->acl_id))) + fprintf(out, "owner-%s: %s\n", l->name, u->login); + fprintf(out, "%s: ", l->name); + alias_width = line_width = len + 2; + output_membership(l, out); + fprintf(out, "\n\n"); incount++; - if (u->pobox && check_string(u->login) && u->login[0] != '#') - fprintf(out, "%s: %s\n", u->login, u->pobox); } -void output_mlist(int id, struct list *l) +void output_membership(struct list *l, FILE *out) { - struct list *l1; struct member *m; - struct user *u; - int line_width, alias_width, word_width, beginning; + struct list *l1; + int word_width, linestart = 1; static int cont = 1; char str[8]; - put_fill(out, l->description); - if (l->acl_t == 'L' && (l1 = hash_lookup(lists, l->acl_id))) - fprintf(out, "owner-%s: %s\n%s: ", l->name, l1->name, l->name); - else if (l->acl_t == 'U' && (u = hash_lookup(users, l->acl_id))) - fprintf(out, "owner-%s: %s\n%s: ", l->name, u->login, l->name); - else - fprintf(out, "%s: ", l->name); - - alias_width = line_width = strlen(l->name) + 2; - beginning = 1; for (m = l->m; m; m = m->next) { word_width = strlen(m->name); - if (!beginning && alias_width + word_width + 2 > MAX_ALIAS_WIDTH) + if (!linestart && alias_width + word_width + 2 > MAX_ALIAS_WIDTH) { /* Make a continuation. */ sprintf(str, "%c%c%c%c%c%c", rand() % 26 + 97, rand() % 26 + 97, @@ -407,20 +436,18 @@ void output_mlist(int id, struct list *l) fprintf(out, ",\n\tcont%d-%s\ncont%d-%s: ", cont, str, cont, str); cont++; alias_width = line_width = 17 + word_width; - fputs(m->name, out); } - else if (beginning) + else if (linestart) { - /* Beginning of alias, so don't wrap. */ + /* First word on line, so we can't wrap. */ line_width += word_width; alias_width = line_width; - fputs(m->name, out); - beginning = 0; + linestart = 0; } else if (line_width + word_width + 2 > MAX_LINE_WIDTH) { /* Wrap. */ - fprintf(out, ",\n\t%s", m->name); + fputs(",\n\t", out); alias_width += line_width + word_width + 2; line_width = word_width + 8; } @@ -428,13 +455,16 @@ void output_mlist(int id, struct list *l) { /* Continue line. */ line_width += word_width + 2; - fprintf(out, ", %s", m->name); + fputs(", ", out); } + + if (m->list_id && (l1 = hash_lookup(lists, m->list_id)) && !l1->maillist) + output_membership(l1, out); + else + fputs(m->name, out); } if (!l->m) fprintf(out, "/dev/null"); - fprintf(out, "\n\n"); - incount++; } /* Write a word-wrapped list description to the aliases file as a @@ -491,8 +521,10 @@ void put_fill(FILE *aliases, char *string) } -/* Illegal chars: this should correspond to the array used by - * setup_alis. */ +/* Illegal chars: this no longer corresponds to the array + * in setup_alis. '+' is a valid character in a string on + * a list, but is not a valid character in a listname. + */ static int illegalchars[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */