From: mar Date: Fri, 5 Aug 1988 19:17:06 +0000 (+0000) Subject: New algorighm: extract stuff first, then dump everything. X-Git-Tag: KREL1~266 X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/commitdiff_plain/39b944109afb574805e490431be52fa33ff3dfc5?hp=70c18c181fc2e4fddae942d417ff4a28b0057a5a New algorighm: extract stuff first, then dump everything. --- diff --git a/gen/aliases.qc b/gen/aliases.qc index 61244a88..eff025c7 100644 --- a/gen/aliases.qc +++ b/gen/aliases.qc @@ -5,11 +5,11 @@ * user pobox entries * maillist expansions * sublists of maillists - * mail alias entries */ #include +#include #include #include #include @@ -31,8 +31,9 @@ char **argv; { long tm = time(NULL); FILE *out= stdout; + char filename[64], *targetfile; struct stat sb; -## int error, flag1, flag2, flag3; +## int flag1, flag2, flag3; ## char *filetime; ## ingres sms @@ -49,113 +50,232 @@ char **argv; if (flag1 < 0 && flag2 < 0 && flag3 < 0) { fprintf(stderr, "File %s does not need to be rebuilt.\n", argv[1]); - exit(0); + exit(SMS_NO_CHANGE); } } - if ((out = fopen(argv[1], "w")) == NULL) { - fprintf(stderr, "unable to open %s for output\n", argv[1]); - exit(errno); + targetfile = argv[1]; + sprintf(filename, "%s~", targetfile); + if ((out = fopen(filename, "w")) == NULL) { + fprintf(stderr, "unable to open %s for output\n", filename); + exit(SMS_OCONFIG); } } else if (argc != 1) { fprintf(stderr, "usage: %s [outfile]\n", argv[0]); - exit(-1); + exit(SMS_ARGS); } -## 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); +## begin transaction + get_info(); +## end transaction +## exit + + fprintf(stderr, "Dumping information\n"); 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(SMS_CCONFIG); } - exit(0); + + if (argc == 2) + fix_file(targetfile); + exit(SMS_SUCCESS); } -/* 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... +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[33]; + char maillist; + char acl_t; + char description[256]; + int acl_id; + struct member *m; +}; + + +get_info() +##{ +## int id, maillistp, acl, pid, bid, mid; +## char name[129], type[9], buf[257]; + char *s; + register struct user *u; + register struct list *l; + register struct member *m; + + fprintf(stderr, "Loading machines\n"); + machines = create_hash(1000); +## retrieve (id = machine.mach_id, name = machine.#name) { + if (s = index(name, '.')) + *s = 0; + sprintf(buf, "%s.LOCAL", name); + hash_store(machines, id, strsave(buf)); +## } + + fprintf(stderr, "Loading strings\n"); + strings = create_hash(2000); +## retrieve (id = strings.string_id, name = strings.string) { + hash_store(strings, id, strsave(strtrim(name))); +## } + + fprintf(stderr, "Loading users\n"); + users = create_hash(15000); +## range of u is users +## retrieve (id = u.users_id, name = u.login, type = u.potype, +## pid = u.pop_id, bid = u.box_id) where u.status = 1 { + u = (struct user *) malloc(sizeof(struct user)); + strcpy(u->login, strtrim(name)); + u->pobox = (char *) NULL; + if (type[0] == 'P') { + if (s = hash_lookup(machines, pid)) { + sprintf(buf, "%s@%s", name, s); + u->pobox = strsave(buf); + } else { + 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) + fprintf(stderr, "User %s's pobox string is missing!\n", u->login); + } + hash_store(users, id, u); +## } + + fprintf(stderr, "Loading lists\n"); + lists = create_hash(15000); +## range of l is list +## retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist, +## buf = l.desc, type = l.acl_type, acl = l.acl_id) +## where l.active != 0 { + l = (struct list *) malloc(sizeof(struct list)); + strcpy(l->name, strtrim(name)); + l->maillist = maillistp; + strcpy(l->description, strtrim(buf)); + l->acl_t = type[0]; + l->acl_id = acl; + l->m = (struct member *) NULL; + hash_store(lists, id, l); +## } + + + fprintf(stderr, "Loading members\n"); +## range of m is members +## retrieve (id = m.list_id, type = m.member_type, mid = m.member_id) { + if (l = (struct list *) hash_lookup(lists, id)) { + m = (struct member *) malloc(sizeof(struct member)); + m->name = (char *) NULL; + if (type[0] == 'U') { + m->list_id = 0; + if (u = (struct user *) hash_lookup(users, mid)) + m->name = u->login; + } else if (type[0] == 'L') { + m->list_id = mid; + if (l = (struct list *) hash_lookup(lists, mid)) + m->name = l->name; + } else if (type[0] == 'S') { + m->list_id = 0; + if (s = hash_lookup(strings, mid)) + m->name = s; + } + if (m->name != (char *) NULL) { + m->next = l->m; + l->m = m; + } + } +## } +##} + + +void save_mlist(id, l, sq) +int id; +struct list *l; +struct save_queue *sq; +{ + if (l->maillist) + sq_save_unique_data(sq, id); +} + + +/* Determine if a list, given by list_id, is a user group. + * We really need to figure out a way to do this right. + */ + +int user_group(id) +int id; +{ + return(0); +} + + +/* 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... */ 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(); +{ + register struct list *l; + struct list *l1; + register struct member *m; + struct user *u; + register struct save_queue *sq; + struct save_queue *sq_create(); + int id; 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); -## } + hash_step(lists, save_mlist, sq); -## 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); + l = (struct list *) hash_lookup(lists, id); + if (l->m && /* there's at least one member */ + l->m->next == NULL && /* there's only one member */ + !strcmp(l->name, l->m->name)) /* the member is same as list */ + continue; + 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); + if (!user_group(l->acl_id)) + sq_save_unique_data(sq, l->acl_id); + } + } 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: ", name); - lwid = strlen(name) + 2; + fprintf(out, "%s: ", l->name); + lwid = strlen(l->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); -## } + for (m = l->m; m; m = m->next) { + if (m->list_id != 0 && user_group(m->list_id)) + sq_save_unique_data(sq, m->list_id); + do_member(out, m->name); + } fprintf(out, "\n\n"); } sq_destroy(sq); -##} +} /* print out strings separated by commas, doing line breaks as appropriate */ @@ -168,7 +288,7 @@ register char *s; static int awid; static int cont = 1; - trim(s); + strtrim(s); wwid = strlen(s); if (awid + wwid + 2 > AL_MAX_WID) { @@ -194,55 +314,30 @@ register char *s; 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); +} + -/* 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 user poboxes. Just step through the users table, and print any + * we extracted earlier. */ do_poboxes(out) FILE *out; -##{ -## char login[9], name[33], box[129]; +{ + register char *p; + char *index(); 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); -## } -##} + hash_step(users, do_pobox, out); +} put_fill(aliases, string)