--- /dev/null
+/* $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 <stdio.h>
+#include <sms.h>
+#include <sms_app.h>
+
+#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;
+ }
+}