/*
 *    Copyright 1988 by Rayan S. Zachariassen, all rights reserved.
 *      This will be free software, but only when it is finished.
 */
/*
 *    Several extensive changes by Matti Aarnio <mea@nic.funet.fi>
 *      Copyright 1991-1997.
 */

/*
 * ZMailer SMTP server.
 */

#include "smtpserver.h"

/* as in: SKIPWHILE(isascii,cp) */
#define SKIPWHILE(X,Y)  while (*Y != '\0' && isascii(*Y) && X(*Y)) { ++Y; }

int is_in_toplevel(str)
     const char *str;
{
}

void add_to_toplevels(str)
     char *str;
{
}


static void cfparam __((char *));
static void cfparam(str)
char *str;
{
    char *name, *param1, *param2;

    name = strchr(str, '\n');	/* The trailing newline chopper ... */
    if (name)
	*name = 0;

    SKIPWHILE(!isspace, str);
    SKIPWHILE(isspace, str);
    name = str;
    SKIPWHILE(!isspace, str);
    if (*str != 0)
	*str++ = 0;

    if (cistrcmp(name, "help") == 0) {
	int i = 0, helpmax = HELPMAX;
	while (helplines[i] != NULL && i < helpmax)
	    ++i;
	param2 = strchr(str, '\n');
	if (param2)
	    *param2 = 0;
	helplines[i] = strdup(str);
	helplines[i + 1] = NULL;	/* This will always stay within the array... */
	return;
    }
    if (cistrcmp(name, "toplevels") == 0) {
      add_to_toplevels(str);
      return;
    }

    SKIPWHILE(isspace, str);
    param1 = str;

    SKIPWHILE(!isspace, str);
    if (*str != 0)
	*str++ = 0;
    SKIPWHILE(isspace, str);
    param2 = str;
    SKIPWHILE(!isspace, str);
    if (*str != 0)
	*str++ = 0;

    if (cistrcmp(name, "maxsize") == 0) {
	sscanf(param1, "%ld", &maxsize);
	return;
    }
    if (cistrcmp(name, "max-error-recipients") == 0) {
	sscanf(param1, "%d", &MaxErrorRecipients);
	return;
    }
    if (cistrcmp(name, "same-ip-source-parallel-max") == 0) {
	sscanf(param1, "%d", &MaxSameIpSource);
	return;
    }
    if (cistrcmp(name, "MaxSameIpSource") == 0) {
	sscanf(param1, "%d", &MaxSameIpSource);
	return;
    }
    if (cistrcmp(name, "accept-percent-kludge") == 0) {
	percent_accept = 1;
	return;
    }
    if (cistrcmp(name, "reject-percent-kludge") == 0) {
	percent_accept = -1;
	return;
    }
    /* Following have two parameters:  DBTYPE and DBPATH */
    if (cistrcmp(name, "policydb") == 0) {
	policydefine(&policydb, param1, param2);
	return;
    }
    if (cistrcmp(name, "tcprcvbuffersize") == 0) {
	sscanf(param1, "%d", &TcpRcvBufferSize);
    }
    if (cistrcmp(name, "tcpxmitbuffersize") == 0) {
	sscanf(param1, "%d", &TcpXmitBufferSize);
    }
}

struct smtpconf *
 readcffile(name)
const char *name;
{
    FILE *fp;
    struct smtpconf scf, *head, *tail = NULL;
    char c, *cp, buf[1024], *s, *s0;
    const char *toplevels = "ad ae af ag ai al am an ao aq ar as at au aw az ba bb bd be bf bg bh bi bj bm bn bo br bs bt bv bw by bz ca cc cf cg ch ci ck cl cm cn co com cr cu cv cx cy cz de dj dk dm do dz ec edu ee eg eh es et fi fj fk fm fo fr ga gb gd ge gf gh gi gl gm gn gov gp gq gr gt gu gw gy hk hm hn hr ht hu id ie il in int io iq ir is it jm jo jp ke kg kh ki km kn kp kr kw ky kz la lb lc li lk lr ls lt lu lv ly ma mc md mg mh mil ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nc ne net nf ng ni nl no np nr nt nu nz om org pa pe pf pg ph pk pl pm pn pr pt pw py qa re ro ru rw sa sb sc sd se sg sh si sj sk sl sm sn so sr st sv sy sz tc td tf tg th tj tk tm tn to tp tr tt tv tw tz ua ug uk um us uy uz va vc ve vg vi vn vu wf ws ye yu za zm zr zw";

    strcpy(buf,toplevels);
    add_to_toplevels(buf);

    if ((fp = fopen(name, "r")) == NULL)
	return NULL;
    head = NULL;
    buf[sizeof(buf) - 1] = 0;
    while (fgets(buf, sizeof buf, fp) != NULL) {
	c = buf[0];
	if (c == '#' || (isascii(c) && isspace(c)))
	    continue;
	if (buf[sizeof(buf) - 1] != 0 &&
	    buf[sizeof(buf) - 1] != '\n') {
	    int cc;
	    while ((cc = getc(fp)) != '\n' &&
		   cc != EOF);	/* Scan until end-of-line */
	}
	buf[sizeof(buf) - 1] = 0;	/* Trunc, just in case.. */

	if (strncmp(buf, "PARAM", 5) == 0) {
	    cfparam(buf);
	    continue;
	}
	scf.flags = "";
	scf.next = NULL;
	cp = buf;
	SKIPWHILE(!isspace, cp);
	c = *cp;
	*cp = '\0';
	s0 = s = strdup(buf);
	for (s = s0; *s; ++s)
	    if (isascii(*s & 0xFF) && isupper(*s & 0xFF))
		*s = tolower(*s & 0xFF);
	scf.pattern = s0;
	scf.maxloadavg = 999;
	if (c != '\0') {
	    ++cp;
	    SKIPWHILE(isspace, cp);
	    if (*cp && isascii(*cp) && isdigit(*cp)) {
		/* Sanity-check -- 2 is VERY LOW */
		if ((scf.maxloadavg = atoi(cp)) < 2)
		    scf.maxloadavg = 2;
		SKIPWHILE(isdigit, cp);
		SKIPWHILE(isspace, cp);
	    }
	    scf.flags = strdup(cp);
	    if ((cp = strchr(scf.flags, '\n')) != NULL)
		*cp = '\0';
	}
	if (head == NULL) {
	    head = tail = (struct smtpconf *) emalloc(sizeof scf);
	    *head = scf;
	} else {
	    tail->next = (struct smtpconf *) emalloc(sizeof scf);
	    *(tail->next) = scf;
	    tail = tail->next;
	}
    }
    fclose(fp);
    return head;
}

struct smtpconf *
 findcf(h)
const char *h;
{
    struct smtpconf *scfp;
    register char *cp, *s;
    int c;

#ifndef	USE_ALLOCA
    cp = emalloc(strlen(h) + 1);
#else
    cp = alloca(strlen(h) + 1);
#endif
    for (s = cp; *h != '\0'; ++h) {
	c = (*h) & 0xFF;
	if (isascii(c) && isalpha(c) && isupper(c))
	    *s++ = tolower(c);
	else
	    *s++ = c;
    }
    *s = '\0';
    for (scfp = cfhead; scfp != NULL; scfp = scfp->next) {
	if (strmatch(scfp->pattern, cp)) {
#ifndef USE_ALLOCA
	    free(cp);
#endif
	    return scfp;
	}
    }
#ifndef USE_ALLOCA
    free(cp);
#endif
    return NULL;
}
