-/* $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
- *
- * (c) Copyright 1988, 1990 by the Massachusetts Institute of Technology.
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
- */
-
-
-#include <mit-copyright.h>
-#include <stdio.h>
-#include <string.h>
-#include <moira.h>
-#include <moira_site.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-EXEC SQL INCLUDE sqlca;
-
-
-#define ML_WID 72
-#define AL_MAX_WID 592
-
-char *divide = "########################################################################";
-extern int errno;
-char *whoami = "aliases.gen";
-FILE *out;
-
-main(argc, argv)
-int argc;
-char **argv;
-{
- long tm = time(NULL);
- char filename[64], *targetfile;
- struct stat sb;
- int flag1, flag2, flag3;
-
- out = stdout;
- initialize_sms_error_table();
-#ifsql INGRES
- EXEC SQL CONNECT moira;
- EXEC SQL SET LOCKMODE SESSION WHERE LEVEL=TABLE, READLOCK=SHARED;
-#endsql
-#ifsql INFORMIX
- EXEC SQL DATABASE moira;
-#endsql
-
-
- if (argc == 2) {
- if (stat(argv[1], &sb) == 0) {
-
- if (ModDiff (&flag1, "list", sb.st_mtime) ||
- ModDiff (&flag2, "imembers", sb.st_mtime) ||
- ModDiff (&flag3, "users", sb.st_mtime)) exit (MR_DATE);
-
- if (flag1 < 0 && flag2 < 0 && flag3 < 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")) == NULL) {
- fprintf(stderr, "unable to open %s for output\n", filename);
- exit(MR_OCONFIG);
- }
- } else if (argc != 1) {
- fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
- exit(MR_ARGS);
- }
-
- 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);
-
- get_info();
-#ifsql INFORMIX
- EXEC SQL COMMIT WORK;
-#endif
-#ifsql INGRES
- EXEC SQL DISCONNECT;
-#endsql
-
- fprintf(stderr, "Dumping information\n");
- do_mlists(out);
- do_poboxes(out);
-
- fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
-
-
- if (fclose(out)) {
- perror("close failed");
- exit(MR_CCONFIG);
- }
-
- if (argc == 2)
- fix_file(targetfile);
- exit(MR_SUCCESS);
-}
-
-
-struct hash *users, *machines, *strings, *lists;
-struct user {
- char login[9];
- char *pobox;
-};
-struct member {
- struct member *next;
- char *name;
- int list_id;
-};
-struct list {
- char *name;
- char maillist;
- char acl_t;
- char *description;
- int acl_id;
- struct member *m;
-};
-
-
-get_info()
-{
- EXEC SQL BEGIN DECLARE SECTION;
- int id, maillistp, acl, pid, bid, mid;
- char name[129], type[9], buf[257];
- EXEC SQL END DECLARE SECTION;
- char *s;
- register struct user *u;
- register struct list *l;
- register struct member *m;
- register struct list *memberlist;
-
- EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
-
- /* get locks */
- EXEC SQL SELECT modtime INTO :buf FROM list WHERE LIST_ID = 0;
- EXEC SQL SELECT modtime INTO :buf FROM users WHERE USERS_ID = 0;
-
- fprintf(stderr, "Loading machines\n");
- machines = create_hash(1000);
-
- EXEC SQL DECLARE m_cursor CURSOR FOR
- SELECT mach_id, name
- FROM machine
- ORDER BY mach_id;
- EXEC SQL OPEN m_cursor;
- while (1) {
- EXEC SQL FETCH m_cursor INTO :id, :name;
- if (sqlca.sqlcode != 0) break;
- if (s = index(name, '.'))
- *s = 0;
-#ifdef ATHENA
- strcat(name, ".LOCAL");
-#endif
- hash_store(machines, id, strsave(name));
- }
- EXEC SQL CLOSE m_cursor;
-
-
- fprintf(stderr, "Loading strings\n");
- strings = create_hash(11001);
-
- EXEC SQL DECLARE s_cursor CURSOR FOR
- SELECT string_id, trim(string)
- FROM strings
- ORDER BY string_id;
- EXEC SQL OPEN s_cursor;
- while (1) {
- EXEC SQL FETCH s_cursor INTO :id, :name;
- if (sqlca.sqlcode != 0) break;
- hash_store(strings, id, strsave(name));
- }
- EXEC SQL CLOSE s_cursor;
-
- fprintf(stderr, "Loading users\n");
- users = create_hash(12001);
-
- EXEC SQL DECLARE u_cursor CURSOR FOR
- SELECT users_id, login, potype, pop_id, box_id
- FROM users WHERE status = 1 OR status = 5 OR status = 6
- ORDER BY users_id;
- EXEC SQL OPEN u_cursor;
- while (1) {
- EXEC SQL FETCH u_cursor INTO :id, :name, :type, :pid, :bid;
- if (sqlca.sqlcode != 0) break;
- u = (struct user *) malloc(sizeof(struct user));
- strcpy(u->login, strtrim(name));
- if (type[0] == 'P') {
- if (s = hash_lookup(machines, pid)) {
- sprintf(buf, "%s@%s", name, s);
- u->pobox = strsave(buf);
- } else {
- u->pobox = (char *) NULL;
- fprintf(stderr, "User %s's pobox is on a missing machine!\n",
- u->login);
- }
- } else if (type[0] == 'S') {
- if ((u->pobox = hash_lookup(strings, bid)) == NULL) {
- u->pobox = (char *) NULL;
- fprintf(stderr, "User %s's pobox string is missing!\n",
- u->login);
- }
- } else
- u->pobox = (char *) NULL;
- hash_store(users, id, u);
- }
- EXEC SQL CLOSE u_cursor;
- EXEC SQL COMMIT;
-
- fprintf(stderr, "Loading lists\n");
- lists = create_hash(15001);
-
- EXEC SQL DECLARE l_cursor CURSOR FOR
- SELECT list_id, name, maillist, description, acl_type, acl_id
- FROM list WHERE active != 0
- ORDER BY list_id;
- EXEC SQL OPEN l_cursor;
- while (1) {
- EXEC SQL FETCH l_cursor INTO :id, :name, :maillistp,
- :buf, :type, :acl;
- if (sqlca.sqlcode != 0) break;
- l = (struct list *) malloc(sizeof(struct list));
- l->name = strsave(strtrim(name));
- l->maillist = maillistp;
- l->description = strsave(strtrim(buf));
- l->acl_t = type[0];
- l->acl_id = acl;
- l->m = (struct member *) NULL;
- hash_store(lists, id, l);
- }
- EXEC SQL CLOSE l_cursor;
- EXEC SQL COMMIT;
-
- fprintf(stderr, "Loading members\n");
-
- EXEC SQL DECLARE mem_cursor CURSOR FOR
- SELECT list_id, member_type, member_id
- FROM imembers WHERE direct = 1
- ORDER BY list_id;
- EXEC SQL OPEN mem_cursor;
- while (1) {
- EXEC SQL FETCH mem_cursor INTO :id, :type, :mid;
- if (sqlca.sqlcode != 0) break;
- if (l = (struct list *) hash_lookup(lists, id)) {
- m = (struct member *) malloc(sizeof(struct member));
- if (type[0] == 'U' &&
- (u = (struct user *) hash_lookup(users, mid))) {
- m->list_id = 0;
- m->name = u->login;
- m->next = l->m;
- l->m = m;
- } else if (type[0] == 'L' &&
- (memberlist = (struct list *) hash_lookup(lists, mid))) {
- m->list_id = mid;
- m->name = memberlist->name;
- m->next = l->m;
- l->m = m;
- } else if (type[0] == 'S' &&
- (s = hash_lookup(strings, mid))) {
- m->list_id = 0;
- m->name = s;
- m->next = l->m;
- l->m = m;
- }
- }
- }
- EXEC SQL CLOSE mem_cursor;
- return;
- sqlerr:
- com_err(whoami, MR_INGRES_ERR, " code %d\n", sqlca.sqlcode);
- critical_alert("DCM", "Alias build encountered INGRES ERROR %d",
- sqlca.sqlcode);
- exit(MR_INGRES_ERR);
-}
-
-
-save_mlist(id, l, force)
-int id;
-register struct list *l;
-int force;
-{
- register struct member *m;
- struct list *l1;
-
- if (l->maillist == 2 ||
- (l->maillist == 0 && !force))
- return;
-
- if (l->m && l->m->next == NULL &&
- !strcasecmp(l->name, l->m->name)) {
- l->maillist = 0;
- return;
- }
- l->maillist = 2;
- output_mlist(id, l);
-
- if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
- save_mlist(0, l1, 1);
-
- for (m = l->m; m; m = m->next) {
- if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
- save_mlist(0, l1, 1);
- }
-}
-
-
-int lwid, bol, awid;
-
-output_mlist(id, l)
-int id;
-register struct list *l;
-{
- struct list *l1;
- register struct member *m;
- struct user *u;
-
- put_fill(out, l->description);
- if (l->acl_t == 'L') {
- if (l1 = (struct list *) hash_lookup(lists, l->acl_id))
- fprintf(out, "owner-%s: %s\n", l->name, l1->name);
- } else if (l->acl_t == 'U') {
- if (u = (struct user *) hash_lookup(users, l->acl_id))
- fprintf(out, "owner-%s: %s\n", l->name, u->login);
- }
-
- fprintf(out, "%s: ", l->name);
- lwid = strlen(l->name) + 2;
- bol = 1;
- for (m = l->m; m; m = m->next)
- do_member(out, m->name);
- if (l->m == (struct member *)NULL)
- fprintf(out, "/dev/null");
- fprintf(out, "\n\n");
-}
-
-
-/* Extract mailing lists. Make a list of all mailinglists, then
- * process them, adding any sub-lists or acl lists to the list of lists
- * to be processed. If further sublists are encountered, repeat...
- */
-
-do_mlists(out)
-FILE *out;
-{
- fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
- hash_step(lists, save_mlist, 0);
-}
-
-
-/* print out strings separated by commas, doing line breaks as appropriate */
-
-do_member(out, s)
-FILE *out;
-register char *s;
-{
- register wwid;
- static int cont = 1;
-
- wwid = strlen(s);
-
- if (!bol && awid + wwid + 2 > AL_MAX_WID) {
- fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
- cont++;
- awid = lwid = 17 + wwid;
- fputs(s, out);
- return;
- }
-
- if (bol) {
- lwid += wwid;
- awid = lwid;
- fputs(s, out);
- 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);
-}
-
-do_pobox(id, u, out)
-int id;
-register struct user *u;
-FILE *out;
-{
- if (u->pobox)
- fprintf(out, "%s: %s\n", u->login, u->pobox);
-}
-
-
-/* Do user poboxes. Just step through the users table, and print any
- * we extracted earlier.
- */
-
-do_poboxes(out)
-FILE *out;
-{
- fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
-
- hash_step(users, do_pobox, out);
-}
-
-
-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);
-}