/*
  
Title:	MsgEd
  
File:   config.c
  
Author:	Jim Nutt
	
Copr:	1988 by Jim Nutt
  
Description:
	
    handles all message maintenance
  
Revision History:
  
	0.00	6 July 1988
	
Support Files:
  
	msged.h
  
*/

#define TEXTLEN 128

#include "msged.h"
#include "editmail.h"
#include "maincmds.h"

static void checkareas(char *cpath);
static void set_colors(char *keyword,char *value);
static FILE *fileopen(char *env, char *cpath);
static void init(void);
static void parsemail(char *keyword, char *value);
static void parseconfig(FILE *fp);
static void setkeys(void);

ADDRESS parsenode(char *t)
{
	ADDRESS tmp;
	char   *s = NULL, *str = NULL;

	memset(&tmp, 0, sizeof tmp);

	if ((s = strrchr(t,'@')) != NULL)
		tmp.domain = strlwr(strdup(s + 1));
	else
		tmp.domain = NULL;

	str = s = strdup(t);

	if (strchr(t, ':')) {
		tmp.zone = (int) strtol(strtok(s, ":"),NULL,0);
		if (strchr(t, '/')) {
			tmp.net = (int) strtol(s = strtok(NULL, "/"),NULL,0);
			if (strchr(t, '.')) {
				tmp.node = (int) strtol(s = strtok(NULL, "."),NULL,0);
				tmp.point = (int) strtol(strtok(NULL, "\0"),NULL,0);
			}
			else {
				tmp.point = 0;
				tmp.node = (int) strtol(strtok(NULL, "\0"),NULL,0);
			}
		}
		else {
			tmp.net = thisnode.net;
			if (strchr(t, '.')) {
				tmp.node = (int) strtol(strtok(s, "."),NULL,0);
				tmp.point = (int) strtol(strtok(NULL, "\0"),NULL,0);
			}
			else {
				tmp.point = 0;
				tmp.node = (int) strtol(s,NULL,0);
			}
		}
	}
	else {
		tmp.zone = thisnode.zone;
		if (strchr(t, '/')) {
			tmp.net = (int) strtol(strtok(s, "/"),NULL,0);
			if (strchr(t, '.')) {
				tmp.node = (int) strtol(strtok(NULL, "."),NULL,0);
				tmp.point = (int) strtol(strtok(NULL, "\0"),NULL,0);
			}
			else {
				tmp.point = 0;
				tmp.node = strtol(strtok(NULL, '\0'),NULL,0);
			}
		}
		else {
			tmp.net = thisnode.net;
			if (strchr(t, '.')) {
				tmp.node = (int) strtol(s = strtok(s, "."),NULL,0);
				tmp.point = (int) strtol(s = strtok(NULL, "\0"),NULL,0);
			}
			else {
				tmp.point = 0;
				tmp.node = (int) strtol(s,NULL,0);
			}
		}
	}
	free(str);
	return (tmp);
}

static void checkareas(char *areafile)

{
	FILE   *fp = NULL;
        char    buffer[TEXTLEN];
	char   *s = NULL;
        int     flag = 1;

        if ((fp = fopen(areafile,"rt")) == NULL)
          if ((fp = fopen("areas.bbs","rt")) == NULL)
              if ((fp = fileopen("BINKLEY",areafile)) == NULL)
                if ((fp = fileopen("BINKLEY","areas.bbs")) == NULL)
                    if ((fp = fileopen("OPUS",areafile)) == NULL)
                      if ((fp = fileopen("OPUS","areas.bbs")) == NULL)
                          if ((fp = fileopen("SEADOG",areafile)) == NULL)
                            if ((fp = fileopen("SEADOG","areas.bbs")) == NULL)
                                if ((fp = fileopen("BBS",areafile)) == NULL)
                                  if ((fp = fileopen("BBS","areas.bbs")) == NULL)
                                        return;
	
 	if (fp != NULL) {
 		
                while (fgets(buffer, TEXTLEN, fp) != NULL) {
			char *tag = NULL;
			char *path = NULL;
			int i = 0;
			
			if ((*buffer == '\r') || (*buffer == '\n'))
				continue;
				
			s = buffer;

			while (isspace(*s))
				s++;

			if ((*s == ';') || (*s == '-'))
				continue;

                        if ((strchr(buffer,'!')) || flag) {
                                char *p = strrchr(buffer,'!');
                                if (p != NULL) {
                                        *p = '\0';
                                        if (origin != NULL)
                                                free(origin);
                                        origin = strdup(buffer);
                                }
                                flag = 0;
				continue;
			}
				
			path = strlwr(strtok(s," \t"));
                        tag = strlwr(strtok(NULL," \t\n"));
                        flag = 0;
			
			for (;i < areas; i++)
				if (strcmp(tag,arealist[i].tag) == 0)
					break;
						
			if (i == areas) {
				areas++;
				area = areas - 1;
				checkmem(arealist = (struct _area *)
					realloc(arealist,
					areas * sizeof(struct _area)));

                                memset(&(arealist[area]),0,sizeof(struct _area));

				arealist[area].echomail = 1;
                                arealist[area].description = strdup(tag);
                                arealist[area].tag = arealist[area].description;
				arealist[area].path = strdup(path);
                                if (*(arealist[area].path + strlen(arealist[area].path) - 1) == '\\')
                                        *(arealist[area].path + strlen(arealist[area].path) - 1) = '\0';
			}
		}
	}

	if (fp != NULL)
		fclose(fp);
}

static void set_colors(char *keyword,char *value)

{
        int     color = 0;
        char   *s = NULL;

        s = strtok(value, " +\0");
        strlwr(s);
        if (strcmp("black", s) == 0)
                color = 0;
        else if (strcmp("blue", s) == 0)
                color = 1;
        else if (strcmp("green", s) == 0)
                color = 2;
        else if (strcmp("cyan", s) == 0)
                color = 3;
        else if (strcmp("red", s) == 0)
                color = 4;
        else if (strcmp("magenta", s) == 0)
                color = 5;
        else if (strcmp("yellow", s) == 0)
                color = 6;
        else if (strcmp("white", s) == 0)
                color = 7;

        s = strlwr(strtok(NULL, "\0"));
        while ((s != NULL) && isspace(*s))
                s++;
        if ((s != NULL) && (strcmp(s, "intense") == 0))
                color |= 8;

        if (strcmp("foreground", keyword) == 0)
                normfore = color;
        if (strcmp("background", keyword) == 0)
                normback = color;
        if (strcmp("hifore", keyword) == 0)
                statfore = color;
        if (strcmp("hiback", keyword) == 0)
                statback = color;
}

static FILE *fileopen(char *env,char *cfn)

{
        char    pathname[PATHLEN];
        char   *cpath;

        if (cfn == NULL)
                return(NULL);

        if ((cpath = getenv(env)) == NULL)
                return(NULL);

        strcpy(pathname, cpath);

        if (*(pathname + strlen(pathname) - 1) != '\\')
                strcat(pathname,"\\");

        strcat(pathname,cfn);

        return(fopen(pathname,"rt"));
}

static void init()

{
	seenbys = YES;
	shownotes = NO;
	kludgelines = NO;
	gate = 7;
	thisnode.zone = 0;
	thisnode.net = 0;
	thisnode.node = 0;
	thisnode.point = 0;
        thisnode.domain = NULL;
	confmail = strdup("confmail.out");
	outfile = strdup("prn");
	domains = 0;
	domain_list = NULL;
	tabsize = 8;
        pointnet = 0;
        softcr = NO;
        override = FALSE;
        tearline = YES;
        readthread = NO;
	quotestr = ">";
	quotestyle = USENET;
        areas = 0;
        fidolist = NULL;
        userlist = NULL;
        origin = NULL;
        confirmations = YES;
        flashhelp = NO;
        videomethod = DIRECT;
        memset(&msgbits,0,sizeof(msgbits));
        msgbits.local = 1;
        vbase = 0;
        maxx = maxy = 0;
        rm = 300;        /* an unreasonable value */
}

static void parsemail(char *keyword, char *value)

{
        char    delimiter = *value;
        char    t[64];
        char   *s = NULL, *d = t;

        memset(t, 0, PATHLEN);
        areas++;
        area = areas - 1;
        if (arealist == NULL)
                arealist = (struct _area *) malloc(areas * sizeof(struct _area));
        else
                arealist = (struct _area *) realloc(arealist, areas * sizeof(struct _area));

        if (arealist == NULL)
                outamemory();

        memset(&(arealist[area]),0,sizeof(struct _area));

        if (strcmp("local", keyword) == 0)
                arealist[area].local = 1;
        else if (strcmp("mail", keyword) == 0)
                arealist[area].netmail = 1;
        else if (strcmp("echo", keyword) == 0)
                arealist[area].echomail = 1;

        if (strchr("\'\"", delimiter) == NULL) {
                s = value;
                delimiter = ' ';
        }
        else
                s = value + 1;

        while ((*s != NULL) && (*s != delimiter))
                *d++ = *s++;
        *d = '\0';
        s++;
        arealist[area].description = strdup(t);
        memset(t, 0, PATHLEN);
        d = t;

        while ((*s != NULL) && isspace(*s)) s++;

        if (*s == NULL) {
                fputs("error in configuration file\n", stderr);
                fprintf(stderr, "check %s statements for path\n", keyword);
                exit(255);
        }
        else {
                while ((*s != NULL) && !isspace(*s))
                        *d++ = *s++;
                *d = '\0';
                arealist[area].path = strdup(t);
                if (*(arealist[area].path + strlen(arealist[area].path) - 1) == '\\')
                        *(arealist[area].path + strlen(arealist[area].path) - 1) = '\0';

                while ((*s != NULL) && isspace(*s)) s++;

                if (*s != NULL) {
                        memset(t, 0, PATHLEN);
                        d = t;
                        while ((*s != NULL) && !isspace(*s))
                                *d++ = *s++;
                        *d = '\0';
                        arealist[area].tag = strlwr(strdup(t));
                }
        }
}

static void parseconfig(FILE *fp)

{
        char    buffer[TEXTLEN];
	char   *keyword = NULL;
	char   *value = NULL;
	char   *s = NULL;
	ADDRESS tdom;

        memset(buffer, 0, TEXTLEN);

        while (!feof(fp)) {

                if (fgets(buffer, TEXTLEN, fp) == NULL)
                        return;

		keyword = strlwr(strtok(buffer, " \t"));
		if ((*keyword) == ';')
                        continue;

		if ((value = strtok(NULL, ";\n\r")) == NULL)
                                continue;

		while (isspace(*value) &&
		       !((*value == '\n') || (*value == ';')))
			value++;

		if ((strcmp("application",keyword) == 0) &&
		    (strcmp("msged",strlwr(strtok(value," \t"))) == 0)) {
			strcpy(buffer,strtok(NULL,"\n\r"));
			keyword = strlwr(strtok(buffer, " \t"));

			if ((value = strtok(NULL, "\n\r")) == NULL)
				continue;

			while (isspace(*value) && (*value != '\n'))
				value++;
		}
			

		if ((strcmp("username", keyword) == 0) ||
                    (strcmp("name",keyword) == 0) ||
		    (strcmp("sysop",keyword) == 0))
			username = strdup(value);

                else if (strcmp("include", keyword) == 0) {
                        FILE *ifp;
                        if ((ifp = fopen(value,"rt")) != NULL) {
                                parseconfig(ifp);
                                fclose(ifp);
                        }
                }

		else if (strcmp("outfile", keyword) == 0) {
			free(outfile);
			outfile = strdup(value);
                }

                else if (strcmp("tosslog", keyword) == 0) {
                        free(confmail);
                        confmail = strdup(value);
                }

		else if (strcmp("video",keyword) == 0) {
			strlwr(value);
                        if (strncmp(value,"direct",6) == 0)
                                videomethod = DIRECT;
                        else if (strncmp(value,"bios",4) == 0)
                                videomethod = BIOS;
                        else if (strncmp(value,"fossil",6) == 0) {
                                videomethod = FOSSIL;
#if defined(__ZTC__)
                                fputs("video fossil not supported by ZTC msged\n",stderr);
                                exit(255);
#endif
                        }
		}

		else if (strcmp("quotestyle",keyword) == 0) {
			strlwr(value);
			if (strncmp(value,"fidonet",7) == 0)
				quotestyle = FIDONET;
			else if (strncmp(value,"usenet",6) == 0)
				quotestyle = USENET;
		}

		else if (strcmp("gate",keyword) == 0) {
			if (gate == 7)
				gate = 0;
			strlwr(value);
			if (strncmp(value,"zones",5) == 0)
				gate |= GZONES;
			else if (strncmp(value,"domains",7) == 0)
				gate |= GDOMAINS;
			else if (strncmp(value,"both",4) == 0)
				gate = GDOMAINS | GZONES;
			else if (strncmp(value,"none",4) == 0)
				gate = 0;
                }

		else if (strcmp("colors",keyword) == 0) {
			int color;
			s = strtok(value," \t");
			s = strtok(NULL," \t");
			s = strtok(NULL," \t");
			s = strtok(NULL," \t");
			s = strtok(NULL," \t");
			color = (int) strtol(s,NULL,0);
			normfore = (0xf & color);
			normback = (0xf & (color >> 4));
			s = strtok(NULL," \t\n\r");
			color = (int) strtol(s,NULL,0);
			statfore = (0xf & color);
			statback = (0xf & (color >> 4));
		}

		else if (strcmp("domain", keyword) == 0) {
			s = strlwr(strdup(strtok(value," \t")));
			tdom = parsenode(strtok(NULL,"\n\0"));
			tdom.domain = s;
			checkmem(domain_list = (ADDRESS *) realloc(domain_list,++domains * sizeof(ADDRESS)));
			domain_list[domains - 1] = tdom;
		}

		else if (strcmp("mydomain", keyword) == 0)
			thisnode.domain = strlwr(strdup(value));

                else if (strcmp("userlist", keyword) == 0) {
			fidolist = strdup(strtok(value,",\n"));
			if ((userlist = strtok(NULL,",\n")) != NULL)
                                userlist = strdup(userlist);
                }

		else if (strcmp("node", keyword) == 0)
			thisnode = parsenode(value);

		else if (strcmp("boss", keyword) == 0)
			thisnode = parsenode(value);

		else if (strcmp("point", keyword) == 0) {
			tdom = parsenode(value);
			if ((thisnode.net != tdom.net) && (thisnode.net != 0)) {
				thisnode.point = tdom.node;
				pointnet = tdom.net;
			}
			else {
				thisnode.node = tdom.node;
				thisnode.net = tdom.net;
			}
		}

                else if (strcmp("videoseg", keyword) == 0)
			vbase = (int) strtol(value,NULL,0);

		else if (strcmp("pointnet", keyword) == 0)
			pointnet = (int) strtol(value,NULL,0);

		else if (strcmp("maxx", keyword) == 0)
			maxx = (int) strtol(value,NULL,0);

		else if (strcmp("maxy", keyword) == 0)
			maxy = (int) strtol(value,NULL,0);

		else if (strcmp("zone", keyword) == 0)
			thisnode.zone = (int) strtol(value,NULL,0);

		else if (strcmp("tabsize", keyword) == 0)
			tabsize = (int) strtol(value,NULL,0);

		else if (strcmp("right", keyword) == 0)
			rm = (int) strtol(value,NULL,0);

                else if (strcmp("flashhelp",keyword) == 0) {
                        flashhelp = (strcmp("yes", strlwr(value)) == 0);
		}

                else if (strcmp("softcr",keyword) == 0) {
			strlwr(value);
                        softcr = (strcmp("yes", value) == 0);
		}

		else if (strcmp("seen-bys", keyword) == 0) {
			strlwr(value);
                        seenbys = (strcmp("yes", value) == 0);
		}

                else if (strcmp("threads", keyword) == 0) {
			strlwr(value);
                        readthread = (strcmp("yes", value) == 0);
                }

                else if (strcmp("privileged", keyword) == 0)
                        msgbits.private = (strcmp("yes", strlwr(value)) == 0);

                else if (strcmp("kill/sent", keyword) == 0)
                        msgbits.killsent = (strcmp("yes", strlwr(value)) == 0);

                else if (strcmp("crash", keyword) == 0)
                        msgbits.crash = (strcmp("yes", strlwr(value)) == 0);

                else if (strcmp("hold", keyword) == 0)
                        msgbits.hold = (strcmp("yes", strlwr(value)) == 0);

                else if (strcmp("tearline", keyword) == 0)
                        tearline = (strcmp("yes", strlwr(value)) == 0);

		else if (strcmp("shownotes", keyword) == 0) {
			strlwr(value);
                        shownotes = (strcmp("yes", value) == 0);
		}

		else if (strcmp("editkey", keyword) == 0) {
			int scancode;
			int i = 0;

			strlwr(value);
			scancode = (int) strtol(value,&value,0);
			while (*value && isspace(*value)) value++;
			while (editcmds[i].label != NULL) {
				if (strncmp(editcmds[i].label,value,strlen(editcmds[i].label)) == 0) {
					if (scancode & 0xff)
						editckeys[scancode & 0xff] = editcmds[i].action;
					else
						editakeys[scancode >> 8] = editcmds[i].action;
					break;
				}
				i++;
			}
		}

		else if (strcmp("readkey", keyword) == 0) {
			int scancode;
			int i = 0;

			strlwr(value);
			scancode = (int) strtol(value,&value,0);
			while (*value && isspace(*value)) value++;
			while (maincmds[i].label != NULL) {
				if (strncmp(maincmds[i].label,value,strlen(maincmds[i].label)) == 0) {
					if (scancode & 0xff)
						mainckeys[scancode & 0xff] = maincmds[i].action;
					else
						mainakeys[scancode >> 8] = maincmds[i].action;
					break;
				}
				i++;
			}
		}

		else if (strcmp("confirm", keyword) == 0) {
			strlwr(value);
                        confirmations = (strcmp("yes", value) == 0);
		}

		else if (strcmp("kludge-lines", keyword) == 0) {
			strlwr(value);
                        kludgelines = (strcmp("yes", value) == 0);
		}

		else if (strcmp("quote", keyword) == 0)
			quotestr = strdup(value);

                else if ((strcmp("system", keyword) == 0) ||
                         (strcmp("origin", keyword) == 0)) {
                        if (origin != NULL)
                                free(origin);
                        origin = strdup(value);
                }

		else if (strcmp("netmail",keyword) == 0) {
			areas++;
			area = areas - 1;
			if (arealist == NULL)
				arealist = (struct _area *) malloc(areas * sizeof(struct _area));
			else
				arealist = (struct _area *) realloc(arealist, areas * sizeof(struct _area));

			if (arealist == NULL)
				outamemory();

			memset(&(arealist[area]),0,sizeof(struct _area));

			arealist[area].netmail = 1;
			arealist[area].description = "netmail";
                        arealist[area].path = strdup(value);
                        if (*(arealist[area].path + strlen(arealist[area].path) - 1) == '\\')
                                *(arealist[area].path + strlen(arealist[area].path) - 1) = '\0';

		}

		else if ((strcmp("echo", keyword) == 0) ||
			 (strcmp("mail", keyword) == 0) ||
                         (strcmp("local", keyword) == 0))
                        parsemail(keyword,value);

		else if ((strcmp("foreground", keyword) == 0) ||
			 (strcmp("background", keyword) == 0) ||
			 (strcmp("hifore", keyword) == 0) ||
                         (strcmp("hiback", keyword) == 0))
                        set_colors(keyword,value);

                memset(buffer, 0, TEXTLEN);
	}
}

void	opening(char *cfgfile, char *areafile)
{
        FILE   *fp = NULL;

        /* start looking for the config file... */

        if ((fp = fopen(cfgfile,"rt")) == NULL)
          if ((fp = fopen("binkley.cfg","rt")) == NULL)
            if ((fp = fopen("msged.cfg","rt")) == NULL)
              if ((fp = fileopen("BINKLEY",cfgfile)) == NULL)
                if ((fp = fileopen("BINKLEY","binkley.cfg")) == NULL)
                  if ((fp = fileopen("BINKLEY","msged.cfg")) == NULL)
                    if ((fp = fileopen("OPUS",cfgfile)) == NULL)
                      if ((fp = fileopen("OPUS","binkley.cfg")) == NULL)
                        if ((fp = fileopen("OPUS","msged.cfg")) == NULL)
                          if ((fp = fileopen("SEADOG",cfgfile)) == NULL)
                            if ((fp = fileopen("SEADOG","binkley.cfg")) == NULL)
                              if ((fp = fileopen("SEADOG","msged.cfg")) == NULL)
                                if ((fp = fileopen("BBS",cfgfile)) == NULL)
                                  if ((fp = fileopen("BBS","binkley.cfg")) == NULL)
                                    if ((fp = fileopen("BBS","msged.cfg")) == NULL) {
                                      fputs("cannot find a configuration file\n",stderr);
                                      exit(255);
                                    }

        init();

        parseconfig(fp);

	if (fp != NULL)
                fclose(fp);

	if ((normfore == 0) && (normback == 0))
		normfore = 7;

	if ((statback == 0) || (statfore == 0))
		statback = 7;

        checkareas(areafile);

        video_init();

        if (rm > maxx)
                rm = maxx - 1;

        if (flashhelp) {
                system("flrun >nul");
                fputs("~L=HELP/",stderr);
        }

        foreground(normfore);
	background(normback);
	cls();
        gotoxy(6, 9);
	intense(ON);
	bputs("msged FTS Compatible Mail Editor");
        intense(OFF);
        gotoxy(6, 11);
	bputs("version " VERSION " Copyright 1988,89 by Jim Nutt");
        gotoxy(6,13);
        bprintf("%d by %d ",maxx,maxy);
        if (videomethod == DIRECT)
                bputs("direct video");
        else if (videomethod == BIOS)
                bputs("bios video");
        else
                bputs("fossil video");

        if (flashhelp)
                bputs(" -- help system installed");

	gotoxy(6, 15);
	bprintf("%s at %d:%d/%d", username, thisnode.zone,
		thisnode.net, thisnode.node);
	if (thisnode.point)
		bprintf(".%d",thisnode.point);

	if (thisnode.domain != NULL)
		bprintf("@%s",thisnode.domain);
		
	if (thisnode.point)
		bprintf(" (private net %d/%d)", pointnet,
			thisnode.point);

	if (origin != NULL) {
		gotoxy(6,16);
		bputs(origin);
		gotoxy(6,18);
	}
	else
		gotoxy(6,17);
		
	bprintf("%d message areas found", areas);
}
