/* mhconfig.c - configure MH */ #include "../h/strings.h" #include #include #define BANNER "This is %s, for generic UNIX (MH.6 configuration program)\n\n" #define SED "config.sed" #define SEDOC "doc/config.sed" #define MFIL(f) "makefiles/f", "f" #define MMFIL(f,g) "makefiles/f", "g" #define MAKE "../%s/Makefile" #define WARNING "This file is automatically generated. Do not edit!" #define NOTOK (-1) #define NULLCP ((char *) 0) #define SVAL(s) (s ? s : "") #define QUOTE '\\' /* */ static int smtp = 0; static int sedP = 1; static int filesP = 1; static int docP = 1; static int makeP = 1; static char *myname = "mhconfig"; static char *myopts = NULL; static char *binpath = "/usr/local"; static char *bbhome = "/usr/spool/bboards"; static char *bboards = "off"; static char *ccoptions = NULL; static char *chownpath = "/etc/chown"; static char *curses = "-lcurses -ltermlib"; static char *debug = "off"; static char *editor = "prompter"; static char *etcpath = "/usr/local/lib/mh"; static char *ldoptions = NULL; static char *ldoptlibs = NULL; static char *mailpath = "/usr/spool/mail"; static char *maildir = NULL; static char *mailfile = NULL; static char *mandir = "/usr/man"; static char *manuals = "standard"; static char *mf = "off"; static char *mts = "sendmail"; static char *remove = "mv -f"; static char *oldload = "off"; static char *options = NULL; static char *pop = "off"; static char *popbboards = "off"; static char *ranlib = "on"; static char *tma = "off"; #define unknown 0 #define mmdf 1 #define mmdf2 2 #define mh 3 #define sendmail 4 static int mtsnum = unknown; static struct mtsopt { char *mtskey; char *optval; int code; int mtsflags; #define NOFLAGS 0x00 #define DOSMTP 0x01 #define NOMF 0x02 } mtsopts[] = { "mmdf", "MMDFMTS MMDFI", mmdf, NOFLAGS, "mmdf/smtp", "SENDMTS SMTP", mmdf, DOSMTP, "mmdf2", "MMDFMTS MMDFII", mmdf2, NOFLAGS, "mmdf2/smtp", "SENDMTS MMDFII SMTP", mmdf2, DOSMTP, "mh", "MHMTS", mh, NOFLAGS, "sendmail", "SENDMTS", sendmail, NOMF, "sendmail/smtp", "SENDMTS SMTP", sendmail, NOMF, NULL, NULL, unknown, NOFLAGS }; static struct bind { char *keyword; char **value; int flags; #define BD_NIL 0x00 #define BD_ADD 0x01 } binds[] = { "bin", &binpath, BD_NIL, "bbhome", &bbhome, BD_NIL, "bboards", &bboards, BD_NIL, "ccoptions", &ccoptions, BD_ADD, "chown", &chownpath, BD_NIL, "curses", &curses, BD_NIL, "debug", &debug, BD_NIL, "editor", &editor, BD_NIL, "etc", &etcpath, BD_NIL, "ldoptions", &ldoptions, BD_ADD, "ldoptlibs", &ldoptlibs, BD_ADD, "mail", &mailpath, BD_NIL, "mandir", &mandir, BD_NIL, "manuals", &manuals, BD_NIL, "mf", &mf, BD_NIL, "mts", &mts, BD_NIL, "oldload", &oldload, BD_NIL, "options", &options, BD_ADD, "pop", &pop, BD_NIL, "popbboards", &popbboards, BD_NIL, "ranlib", &ranlib, BD_NIL, "remove", &remove, BD_NIL, "tma", &tma, BD_NIL, NULL }; char *files[] = { "../support/bboards/bboards.daily", "../support/bboards/bboards.weekly", "../support/bboards/crontab", "../support/bboards/MakeBBoards", "../config/config.c", "../zotnet/mts/mts.c", "../zotnet/mts/mtstailor", "../support/general/MailAliases", "../mts/sendmail/bboardsMH.m4", "../mts/sendmail/popMH.m4", NULL }; static struct pair { char *infile; char *outfile; } makefiles[] = { MFIL (config), MFIL (dist), MFIL (doc), MMFIL (mtsM,mts), MFIL (mts/mh), MFIL (mts/mmdf), MFIL (mts/sendmail), MFIL (papers), MFIL (sbr), MMFIL (supportM,support), MFIL (support/bboards), MFIL (support/general), MFIL (support/pop), MFIL (uip), MMFIL (zotnetM,zotnet), MFIL (zotnet/bboards), MFIL (zotnet/mf), MFIL (zotnet/mts), MFIL (zotnet/tws), NULL }; char *stradd (), *strdup (), *tail (); long time (); /* */ /* ARGSUSED */ main (argc, argv, envp) int argc; char **argv, **envp; { arginit (argv); if (sedP) do_sed (); if (filesP) do_files (); if (docP) do_doc (); if (makeP) do_make (); if (filesP || makeP) printf ("Don't forget to run \"make clean\" before proceeding\n"); exit (0); } /* */ static do_sed () { do_sedfile (SED, 0); do_sedfile (SEDOC, smtp); } static do_sedfile (sed, flag) char *sed; int flag; { int i; FILE * fp; if ((fp = fopen (sed, "w")) == NULL) adios (sed, "unable to write"); printf ("generating %s\n", sed); fprintf (fp, "s%%@(MHWARNING)%%%s%%g\n", WARNING); fprintf (fp, "s%%@(MHBINPATH)%%%s%%g\n", SVAL (binpath)); fprintf (fp, "s%%@(MHETCPATH)%%%s%%g\n", SVAL (etcpath)); fprintf (fp, "s%%@(MHCHOWNPATH)%%%s%%g\n", SVAL (chownpath)); fprintf (fp, "s%%@(MHDROPATH)%%%s%%g\n", SVAL (maildir)); fprintf (fp, "s%%@(MHDROPFIL)%%%s%%g\n", SVAL (mailfile)); if (maildir) fprintf (fp, "s%%@(MHDROPLOC)%%%s/$USER%%g\n", SVAL (maildir)); else fprintf (fp, "s%%@(MHDROPLOC)%%$HOME/%s%%g\n", SVAL (mailfile)); fprintf (fp, "s%%@(MHDROPHAK)%%%s%%g\n",/* HACK */ maildir ? maildir : "/usr/spool/mail"); fprintf (fp, "s%%@(MHMANDIR)%%%s%%g\n", mandir); if (strcmp (manuals, "standard") == 0 || strcmp (manuals, "gen") == 0) for (i = 1; i <= 8; i++) { fprintf (fp, "s%%@(MHMANDIR%d)%%man%d%%g\n", i, i); fprintf (fp, "s%%@(MHMANEXT%d)%%%d%%g\n", i, i); } else for (i = 1; i <= 8; i++) { fprintf (fp, "s%%@(MHMANDIR%d)%%man%c%%g\n", i, strcmp (manuals, "new") == 0 ? 'n' : strcmp (manuals, "old") == 0 ? 'o' : 'l'); fprintf (fp, "s%%@(MHMANEXT%d)%%%c%%g\n", i, strcmp (manuals, "new") == 0 ? 'n' : strcmp (manuals, "old") == 0 ? 'o' : 'l'); } if (strcmp (manuals, "gen") == 0) fprintf (fp, "s%%@(MHMANGEN)%%%s%%g\n", "#"); /* comment char */ else fprintf (fp, "s%%@(MHMANGEN)%%%s%%g\n", ""); fprintf (fp, "s%%@(MHEDITOR)%%%s%%g\n", SVAL (editor)); fprintf (fp, "s%%@(MHCONFIG)%%%s%%g\n", SVAL (myopts)); if (ccoptions) fprintf (fp, "s%%@(MHOPTIONS)%%%s %s%%g\n", SVAL (options), SVAL (ccoptions)); else fprintf (fp, "s%%@(MHOPTIONS)%%%s%%g\n", SVAL (options)); fprintf (fp, "s%%@(LDOPTIONS)%%%s%%g\n", SVAL (ldoptions)); fprintf (fp, "s%%@(LDOPTLIB)%%%s%%g\n", SVAL (ldoptlibs)); fprintf (fp, "s%%@(LDCURSES)%%%s%%g\n", SVAL (curses)); if (strcmp (bboards, "on") == 0) fprintf (fp, "/^@BEGIN: BBOARDS$/d\n/^@END: BBOARDS$/d\n"); else fprintf (fp, "/^@BEGIN: BBOARDS$/,/^@END: BBOARDS$/d\n"); fprintf (fp, "s%%@(BBHOME)%%%s%%g\n", SVAL (bbhome)); if (strcmp (debug, "on") == 0) { fprintf (fp, "/^@BEGIN: DEBUG$/d\n/^@END: DEBUG$/d\n"); fprintf (fp, "/^@BEGIN: OPTIM$/,/^@END: OPTIM$/d\n"); } else { fprintf (fp, "/^@BEGIN: DEBUG$/,/^@END: DEBUG$/d\n"); fprintf (fp, "/^@BEGIN: OPTIM$/d\n/^@END: OPTIM$/d\n"); } if (strcmp (oldload, "on") == 0) { fprintf (fp, "/^@BEGIN: OLDLOAD$/d\n/^@END: OLDLOAD$/d\n"); fprintf (fp, "/^@BEGIN: NEWLOAD$/,/^@END: NEWLOAD$/d\n"); } else { fprintf (fp, "/^@BEGIN: NEWLOAD$/d\n/^@END: NEWLOAD$/d\n"); fprintf (fp, "/^@BEGIN: OLDLOAD$/,/^@END: OLDLOAD$/d\n"); } if (strcmp (ranlib, "on") == 0) { fprintf (fp, "/^@BEGIN: RANLIB$/d\n/^@END: RANLIB$/d\n"); fprintf (fp, "/^@BEGIN: LORDER$/,/^@END: LORDER$/d\n"); } else { fprintf (fp, "/^@BEGIN: LORDER$/d\n/^@END: LORDER$/d\n"); fprintf (fp, "/^@BEGIN: RANLIB$/,/^@END: RANLIB$/d\n"); } if (strcmp (tma, "on") == 0) fprintf (fp, "/^@BEGIN: TMA$/d\n/^@END: TMA$/d\n"); else fprintf (fp, "/^@BEGIN: TMA$/,/^@END: TMA$/d\n"); if (flag || ((mtsnum == mmdf || mtsnum == mmdf2) && !smtp)) { fprintf (fp, "/^@BEGIN: MMDFMTS$/d\n/^@END: MMDFMTS$/d\n"); if (mtsnum == mmdf) fprintf (fp, "/^@BEGIN: MMDFIMTS$/d\n/^@END: MMDFIMTS$/d\n"); else fprintf (fp, "/^@BEGIN: MMDFIMTS$/,/^@END: MMDFIMTS$/d\n"); if (mtsnum == mmdf2) fprintf (fp, "/^@BEGIN: MMDFIIMTS$/d\n/^@END: MMDFIIMTS$/d\n"); else fprintf (fp, "/^@BEGIN: MMDFIIMTS$/,/^@END: MMDFIIMTS$/d\n"); } else { fprintf (fp, "/^@BEGIN: MMDFMTS$/,/^@END: MMDFMTS$/d\n"); fprintf (fp, "/^@BEGIN: MMDFIMTS$/,/^@END: MMDFIMTS$/d\n"); fprintf (fp, "/^@BEGIN: MMDFIIMTS$/,/^@END: MMDFIIMTS$/d\n"); } if (mtsnum == mh) fprintf (fp, "/^@BEGIN: MHMTS$/d\n/^@END: MHMTS$/d\n"); else fprintf (fp, "/^@BEGIN: MHMTS$/,/^@END: MHMTS$/d\n"); if (!flag && (mtsnum == sendmail || smtp)) fprintf (fp, "/^@BEGIN: SENDMTS$/d\n/^@END: SENDMTS$/d\n"); else fprintf (fp, "/^@BEGIN: SENDMTS$/,/^@END: SENDMTS$/d\n"); switch (mtsnum) { case mh: case sendmail: case mmdf: fprintf (fp, "/^@BEGIN: SENDMTSHACK$/d\n/^@END: SENDMTSHACK$/d\n"); break; default: fprintf (fp, "/^@BEGIN: SENDMTSHACK$/,/^@END: SENDMTSHACK$/d\n"); break; } if (smtp) fprintf (fp, "/^@BEGIN: SMTP$/d\n/^@END: SMTP$/d\n"); else fprintf (fp, "/^@BEGIN: SMTP$/,/^@END: SMTP$/d\n"); if (strcmp (pop, "on") == 0) fprintf (fp, "/^@BEGIN: POP$/d\n/^@END: POP$/d\n"); else fprintf (fp, "/^@BEGIN: POP$/,/^@END: POP$/d\n"); if (strcmp (popbboards, "on") == 0) fprintf (fp, "/^@BEGIN: BPOP$/d\n/^@END: BPOP$/d\n"); else fprintf (fp, "/^@BEGIN: BPOP$/,/^@END: BPOP$/d\n"); if (strcmp (mf, "on") == 0) fprintf (fp, "/^@BEGIN: MF$/d\n/^@END: MF$/d\n"); else fprintf (fp, "/^@BEGIN: MF$/,/^@END: MF$/d\n"); fprintf (fp, "s%%@(MHREMOVE)%%%s%%g\n", SVAL (remove)); (void) fclose (fp); } /* */ static do_files () { char **pp; for (pp = files; *pp; pp++) shell ("rm -f %s; sed -f %s < config/%s > %s", *pp, SED, tail (*pp), *pp); } static do_doc () { shell ("mhdoc"); } static do_make () { char buffer[BUFSIZ]; struct pair *pp; for (pp = makefiles; pp -> infile; pp++) { (void) sprintf (buffer, MAKE, pp -> outfile); shell ("rm -f %s; sed -f %s < %s > %s", buffer, SED, pp -> infile, buffer); } } /* */ /* VARARGS */ static shell (fmt, a, b, c, d) char *fmt, *a, *b, *c, *d; { char buffer[BUFSIZ]; (void) sprintf (buffer, fmt, a, b, c, d); printf ("%s\n", buffer); (void) fflush (stdout); if (system (buffer)) adios (NULLCP, "failed"); } /* */ static arginit (vec) char **vec; { int i; char *ap, *cp, *dp, *config, buffer[BUFSIZ]; struct bind *bp; FILE * fp; myname = tail (*vec); printf (BANNER, myname); (void) fflush (stdout); for (vec++;; vec++) { if (strcmp (*vec, "-s") == 0) { sedP = !sedP; continue; } if (strcmp (*vec, "-f") == 0) { filesP = !filesP; continue; } if (strcmp (*vec, "-d") == 0) { docP = !docP; continue; } if (strcmp (*vec, "-m") == 0) { makeP = !makeP; continue; } break; } if ((config = *vec++) == NULL || *vec != NULL) adios (NULLCP, "usage: %s file", myname); if ((fp = fopen (config, "r")) == NULL) adios (config, "unable to read"); while (fgets (buffer, sizeof buffer, fp)) { if (ap = index (buffer, '\n')) *ap-- = NULL; else ap = &buffer[strlen (buffer) - 1]; while (ap >= buffer) if (isspace (*ap)) *ap = NULL; else break; for (cp = buffer; isspace (*cp); cp++) continue; if (*cp == NULL || *cp == '#') continue; for (ap = cp; *ap; ap++) if (isspace (*ap)) { *ap++ = NULL; while (isspace (*ap)) ap++; break; } for (bp = binds; bp -> keyword; bp++) if (strcmp (bp -> keyword, cp) == 0) break; if (bp -> keyword == NULL) adios (NULLCP, "unknown option %s in %s", cp, config); else if (*(bp -> value) == NULL || !(bp -> flags & BD_ADD)) *(bp -> value) = strdup (ap); else *(bp -> value) = stradd (ap, stradd (" ", *(bp -> value))); } (void) fclose (fp); /* */ if (binpath == NULL) adios (NULLCP, "bin must be specified in %s", config); trim (binpath); if (strcmp (bboards, "on") && strcmp (bboards, "off")) adios (NULLCP, "bboards should be either \"on\" or \"off\", not %s", bboards); if (bbhome == NULL) adios (NULLCP, "bbhome must be specified in %s", config); trim (bbhome); if (strcmp (debug, "on") && strcmp (debug, "off")) adios (NULLCP, "debug should be either \"on\" or \"off\", not %s", debug); if (etcpath == NULL) adios (NULLCP, "etc must be specified in %s", config); trim (etcpath); if (mailpath == NULL) adios (NULLCP, "mail must be specified in %s", config); trim (mailpath); if (*mailpath == '/') maildir = mailpath; else mailfile = mailpath; if (strcmp (manuals, "standard") && strcmp (manuals, "local") && strcmp (manuals, "new") && strcmp (manuals, "old") && strcmp (manuals, "gen") && strcmp (manuals, "none")) adios (NULLCP,"invalid manuals setting: %s",manuals); if (mts == NULL) adios (NULLCP, "mts must be specified in %s", config); for (i = 0; mtsopts[i].mtskey; i++) if (strcmp (mts, mtsopts[i].mtskey) == 0) break; if ((mtsnum = mtsopts[i].code) == unknown) adios (NULLCP, "invalid mts setting: %s", mts); add_option (mtsopts[i].optval); smtp = mtsopts[i].mtsflags & DOSMTP; if (mtsopts[i].mtsflags & NOMF) mf = "off"; /* hack... */ if (strcmp (pop, "on") && strcmp (pop, "off")) adios (NULLCP, "pop should be either \"on\" or \"off\", not %s", pop); if (strcmp (pop, "on") == 0) add_option ("POP"); if (strcmp (popbboards, "on") && strcmp (popbboards, "off")) adios (NULLCP, "popbboards should be either \"on\" or \"off\", not %s", popbboards); if (strcmp (popbboards, "on") == 0) { add_option ("BPOP"); if (strcmp (bboards, "on") || strcmp (pop, "on")) adios (NULLCP, "popbboards \"on\" requires both bboards and pop \"on\""); } if (strcmp (mf, "on") && strcmp (mf, "off")) adios (NULLCP, "mf should be either \"on\" or \"off\", not %s", mf); if (strcmp (mf, "on") == 0) add_option ("MF"); if (strcmp (tma, "on") && strcmp (tma, "off")) adios (NULLCP, "tma should be either \"on\" or \"off\", not %s", tma); if (strcmp (tma, "on") == 0) add_option ("TMA"); begin_myopt (); if (cp = options) { for (ap = cp; *ap; ap++) if (isspace (*ap)) *ap = ' '; options = NULL; for (ap = cp; dp = index (ap, ' '); ap = dp) { *dp++ = NULL; add_myopt (ap); (void) sprintf (buffer, "%s-D%s", options ? " " : "", ap); ap = buffer; options = stradd (ap, options); while (isspace (*dp)) dp++; } if (*ap) { add_myopt (ap); (void) sprintf (buffer, "%s-D%s", options ? " " : "", ap); ap = buffer; options = stradd (ap, options); } free (cp); } end_myopt (); } /* */ static add_option (s) char *s; { options = options ? stradd (s, stradd (" ", options)) : strdup (s); } begin_myopt () { myopts = strdup ("char *options[] = {"); } add_myopt (s) char *s; { int len; char *bp, buffer[BUFSIZ]; static int nameoutput = 0; static int linepos = 0; static int outputlinelen = 72; if (!nameoutput) { printf ("%s: ", bp = "options"); linepos += (nameoutput = strlen (bp) + 2); } len = strlen (s); if (linepos != nameoutput) if (len + linepos + 3 > outputlinelen) printf ("\n%*s", linepos = nameoutput, ""); else printf (" "), linepos++; printf ("[%s]", s); linepos += len + 2; (void) fflush (stdout); bp = buffer; *bp++ = '"'; while (*s) { if (*s == '"') *bp++ = QUOTE, *bp++ = QUOTE; *bp++ = *s++; } (void) strcpy (bp, "\", "); myopts = stradd (buffer, myopts); } end_myopt () { printf ("\n"); (void) fflush (stdout); myopts = stradd ("NULL};", myopts); } /* */ static trim (s) char *s; { char *p; if (s == NULL || (p = rindex (s, '/')) == NULL) return; if (*++p == NULL) *--p = NULL; } static char *tail (s) char *s; { char *p; if (p = rindex (s, '/')) p++; return ((p == NULL || *p == NULL) ? s : p); } /* */ static char *stradd (s1, s2) char *s1, *s2; { char *p; if (s1 == NULL || *s1 == NULL) return s2; if (s2 == NULL) return strdup (s1); if ((p = malloc ((unsigned) (strlen (s1) + strlen (s2) + 2))) == NULL) adios (NULLCP, "insufficient memory"); (void) sprintf (p, "%s%s", s2, s1); if (s2) free (s2); return p; } static char *strdup (s) char *s; { char *p; if ((p = malloc ((unsigned) (strlen (s) + 1))) == NULL) adios (NULLCP, "insufficient memory"); (void) strcpy (p, s); return p; } /* */ static char *index (s, c) char *s, c; { char i; while (i = *s++) if (i == c) return (s - 1); return NULL; } static char *rindex (s, c) char *s, c; { char i, *t; t = NULL; while (i = *s++) if (i == c) t = s - 1; return t; } /* */ /* VARARGS */ adios (what, fmt, a, b, c) char *what, *fmt, *a, *b, *c; { (void) fflush (stdout); fprintf (stderr, "%s: ", myname); fprintf (stderr, fmt, a, b, c); if (what) { (void) fputc (' ', stderr); perror (what); } else (void) fputc ('\n', stderr); exit (1); }