4.3BSD/usr/contrib/mh/conf/mhconfig.c

Compare this file to the similar file:
Show the results in this format:

/* mhconfig.c - configure MH */

#include "../h/strings.h"
#include <ctype.h>
#include <stdio.h>


#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);
}