/*
** readconfig.c -- base routine to read nmh configuration files
**              -- such as nmh profile, context file, or mhn.defaults.
**
** This code is Copyright (c) 2002, by the authors of nmh.  See the
** COPYRIGHT file in the root directory of the nmh distribution for
** complete copyright information.
*/

#include <sysexits.h>
#include <h/mh.h>
#include <h/utils.h>

struct procstr {
	char *procname;
	char **procnaddr;
};

static struct procstr procs[] = {
	{ "attachment-header",  &attach_hdr },
	{ "sign-header",   &sign_hdr },
	{ "enc-header",    &enc_hdr },
	{ "context",       &context },
	{ "mh-sequences",  &mh_seq },
	{ "draft-folder",  &draftfolder },
	{ "listproc",      &listproc },
	{ "sendmail",      &sendmail },
	{ "trash-folder",  &trashfolder },
	{ "whatnowproc",   &whatnowproc },
	{ NULL, NULL }
};

static struct node **opp = NULL;


void
readconfig(struct node **npp, FILE *ib, char *file, int ctx)
{
	enum state state;
	struct field f = {{0}};
	struct node *np;
	struct procstr *ps;

	if (npp == NULL && (npp = opp) == NULL) {
		admonish(NULL, "bug: readconfig called but pump not primed");
		return;
	}

	for (state = FLD2;;) {
		switch (state = m_getfld2(state, &f, ib)) {
		case LENERR2:
			state = FLD2;
			/* FALL */
		case FLD2:
			np = mh_xcalloc(1, sizeof(*np));
			*npp = np;
			*(npp = &np->n_next) = NULL;
			np->n_name = mh_xstrdup(f.name);
			np->n_field = trimcpy(f.value);
			np->n_context = ctx;

			/*
			** Now scan the list of `procs' and link in
			** the field value to the global variable.
			*/
			for (ps = procs; ps->procname; ps++) {
				if (mh_strcasecmp(np->n_name,
						ps->procname) == 0) {
					*ps->procnaddr = np->n_field;
					break;
				}
			}
			continue;
		case FMTERR2:
			advise(NULL, "%s is poorly formatted", file);
			state = FLD2;
			continue;
		case BODY2:
			adios(EX_CONFIG, NULL, "no blank lines are permitted in %s",
					file);

		case FILEEOF2:
			break;

		case IOERR2:
			adios(EX_IOERR, NULL, "m_getfld2", "some error happened");
			break;

		default:
			adios(EX_CONFIG, NULL, "%s is poorly formatted", file);
		}
		break;
	}

	opp = npp;
}
