/*
 *  MBINIT.C - 6/15/87 - Read configuration file.
 */
/*
 *  History of Modifiy(from V3.3J5.8 on PC-DOS) - By A.Yamada(JA3JWI)
 *
 *  3. Flash I/O port for corectory changing TNC State                87/11/27
 *  2. Read Boud Rate from config.mb                                  87/11/26
 *  1. Implement to Xenix                                             87/11/20
 */

#include "mb.h"
#include "mbexp.h"
#if	(XENIX|UNIX|BSD)
#include <sgtty.h>
#endif
#if !SWAP_NO			/* AY-880920 */
#include "mbswap.h"
AT_SWAP *at_swaproot;
TO_SWAP *to_swaproot;
DISARP *disarproot;
char *atmark = "@" ;
#endif

char *hfwdfile ;
extern char *ready_bbs;		/* AY-881005 */
word do_announce;		/* AY-881005 */

/*
**	Read swaping information.
*/
#if !SWAP_NO			/* AY-880920 */
rdswaps()
{
register char *st;
AT_SWAP	*at_swaptemp;
TO_SWAP	*to_swaptemp;
DISARP	*disarptemp;

	at_swaproot = (AT_SWAP *)NULL;
	to_swaproot = (TO_SWAP *)NULL;
	disarproot = (DISARP *)NULL;

	st = fgets(port->line, linelen, port->fl);
	while (!iseof(port->line) and (st isnt NULL))
	{
		if (port->line[0] == '#') {	/* AY-881030 */
			st = fgets(port->line, linelen, port->fl);
			continue;
		}

#if (XENIX|UNIX|BSD)
		xeparse();
#else
		pparse();
#endif

		switch(port->opt1) {
		case 'T':
			to_swaptemp = (TO_SWAP *) malloc(sizeof(TO_SWAP));
			if (to_swaptemp == NULL)
				errall();
			pcall(to_swaptemp->to, port->fld[1]);
                        pcall(to_swaptemp->new_to, port->fld[2]);
			to_swaptemp->next = to_swaproot;
			to_swaproot = to_swaptemp;
			break;
		case '@': 
			at_swaptemp = (AT_SWAP *) malloc(sizeof(AT_SWAP));
			if (at_swaptemp == NULL)
				errall();
			pcall(at_swaptemp->at, port->fld[1]);
                        if (port->flds < 3)
                        /*then*/  pcall(at_swaptemp->new_at, atmark) ;
                        else      pcall(at_swaptemp->new_at, port->fld[2]);
			at_swaptemp->next = at_swaproot;
			at_swaproot = at_swaptemp;
			break;
		case 'D': 
			disarptemp = (DISARP *) malloc(sizeof(DISARP));
			if (disarptemp == NULL)
				errall();
			pcall(disarptemp->to, port->fld[1]);
			pcall(disarptemp->at, port->fld[2]);
			strcpy(disarptemp->disfile, port->fld[3]);
			disarptemp->next = disarproot;
			disarproot = disarptemp;
			break;
		default:
			break;
		}

		st = fgets(port->line, linelen, port->fl);
	}
}
#endif

/*
 *  Read one line from the configuration file.
 *  The first field is a number. Return it.
 */

#if	(XENIX|UNIX|BSD)
unsigned short boud[];
extern int errno;
#endif

rdnumb()
{
/*	fgets (port->line, linelen, port->fl);	AY-881030 */

	while (fgets (port->line, linelen, port->fl))	/* AY-881030 */
		if (port->line[0] != '#') break;

	pparse ();
	return atoi (port->fld[0]);
}

/*
 *  Read one line from the configuration file.
 *  The first field is a YES / NO keyword.
 *  Return true if Y, false if N.
 */

kw()
{
/*	fgets(port->line, linelen, port->fl);	AY-881030 */

	while (fgets(port->line, linelen, port->fl))	/* AY-881030 */
		if (port->line[0] != '#') break;

	return(*port->line is 'Y');
}

/*
 *  Read one line from the configuration file.
 *  The first field is a letter.
 *  Return the control character corresponding to that letter.
 */

char cchr()
{
/*	fgets (port->line, linelen, port->fl); AY-881030 */

    while (fgets (port->line, linelen, port->fl))   /* AY-881030 */
		if (port->line[0] != '#') break;

	return (*port->line - 64);
}

/*
 *  Read one line from the configuration file.
 *  Squirrel it away in allocated memory.
 *  Return a pointer to it.
 */

char *rdstr()
{
	register char *t;

/*	fgets (port->line, linelen, port->fl); AY-881030 */

	while (fgets (port->line, linelen, port->fl))	/* AY-881030 */
		if (port->line[0] != '#') break;

	t = (char *) malloc (strlen(port->line) + 1);
#if	(XENIX|UNIX|BSD)
	if (t == NULL) syserr("MB: Can't get memory", errno);
#endif
	strcpy (t, port->line);
	return t;
}

/*
 *  Read a line from the configuration file.
 *  Remove the new line at end.
 *  Squirrel it away in allocated memory.
 *  Return a pointer to it.
 */

char *rdstrnl()
{
	register char *t;

	t = rdstr();
	remnl(t);
	return t;
}

/*
 *  Read multiple lines from the configuration file, until "*** EOF".
 *  Squirrel them away in allocated memory.
 *  Return a pointer to the start of the first line.
 */

char *rdmstr()
{
	register short i;
	register char *t;

	t = port->line; 
	i = linelen;
/*	fgets (t, i, port->fl);	AY-881030 */

	while (fgets (t, i, port->fl))	/* AY-881030 */
		if (*t != '#') break;

	while (!iseof(t)) {
		i -= strlen(t); 
		t += strlen(t); 
		fgets(t, i, port->fl); 
	}
	*t = '\0';
	t = (char *) malloc (linelen - i + 1);
	strcpy (t, port->line);
	return t;
}

/*
 *  Read the directory path section of the configuration file.
 */

rdpaths()
{
	register DIRPATH *p, *path;
	register char *st;

	dphd = NULL;
	st = fgets(port->line, linelen, port->fl);
	while (!iseof(port->line) and (st isnt NULL)) {
		if (port->line[0] == '#') {		/* AY-881030 */
			st = fgets(port->line, linelen, port->fl);
			continue;
		}
		path = (DIRPATH *) malloc(sizeof(DIRPATH));
		path->next = NULL;
		if (dphd is NULL) dphd = path; 
		else p->next = path;
		p = path;

		pparse();
		st = port->fld[0];
		path->flags = 0;
		path->id = *st++;
		while(*st)
		{
			switch(*st)
			{
			case 'D': 
				path->flags setbit dp_dnload; 
				break;
			case 'U': 
				path->flags setbit dp_upload; 
				break;
			default : 
				;
			}
			st++;
		}
		path->path = rdstrnl();
		path->name = rdstrnl();

		st = fgets(port->line, linelen, port->fl);
	}
}

/*
 *  Read the port definition section of the configuration file.
 */

rdports()
{
	register char *st;
	register PORTS *p, *pt;
	short first = true;
#if	(XENIX|UNIX|BSD)
	long t;
#endif

	pt = porthd;
	st = fgets (port->line, linelen, port->fl);
	while (!iseof(port->line) and (st isnt NULL)) {
		if (port->line[0] == '#') {			/* AY-881030 */
			st = fgets(port->line, linelen, port->fl);
			continue;
		}
		pparse();

		if (!first)
		{
			pt = (PORTS *) malloc(sizeof(PORTS));
			pt->cmd  = (char *)malloc(cmdlen);
			pt->line = (char *)malloc(linelen);
			p->next = pt;
		}

		first = false;
		p = pt;
		pt->next = NULL;

		pt->user = (USER *)malloc(sizeof(USER));
		pt->user->rn = 0;
		pt->mmhs = (MSG_HDR *)malloc(sizeof(MSG_HDR));
		pt->mmhs->rn = 0;
		pt->cmdcnt = 0;
		pt->msg = NULL;

		st = port->fld[0];
		pt->dev  = 0;
		pt->priv = 0;
		pt->flags  = (p_fwdok | p_give | p_dotmr);
		pt->id = *st++;
		pt->idn =(int)(pt->id - 'A');
		while(*st)
		{
			switch(*st)
			{
			case 'A':	/* AY-881127 */
				pt->priv setbit p_mailfor;
				do_announce setbit 2;
				break;
			case 'N':	/* AY-881127 */
				pt->priv setbit p_mbready;
				do_announce setbit 1;
				break;
			case 'C': 
				pt->dev = p_console; 
				cport = pt; 
				break;
			case 'H': 
				pt->dev = p_hayes;   
				break;
			case 'S': 
				pt->dev = p_serial;  
				break;
			case 'T': 
				pt->dev = p_tnc;     
				break;
			case 'Z': 
				pt->dev = p_memory;  
				break;

			case 'E': 
				pt->flags setbit p_echo;    
				break;
			case 'L': 
				pt->flags setbit p_lf;      
				break;

			case 'B': 
				pt->priv setbit p_bbs;     
				break;
			case 'D': 
				pt->priv setbit p_dnload;  
				break;
			case 'G': 
				pt->priv setbit p_gate;    
				break;
			case 'I': 
				pt->priv setbit p_ilcal;   
				break;
			case 'M': 
				pt->priv setbit p_mon;     
				break;
			case 'R': 
				pt->priv setbit p_sysop;   
				break;
			case 'U': 
				pt->priv setbit p_upload;  
				break;
			default: break;
			}
			st++;
		}
		pt->mode   = idle;
		pt->ctime  = atoi(port->fld[1]);
		pt->dtime  = atoi(port->fld[2]);
		pt->mtime  = atoi(port->fld[3]);
		pt->mcount = atoi(port->fld[4]);
		pt->maxhrd = atoi(port->fld[5]);
		pt->ndigi  = atoi(port->fld[6]);
		pt->fwdmin = atoi(port->fld[7]);
		pt->errmax = atoi(port->fld[8]);
#if	(XENIX|UNIX|BSD)
		if (port->flds >= 9) {
			if (matchn(port->fld[9], "B300", 4))
				boud[pt->idn] = B300; else
			if (matchn(port->fld[9], "B1200", 5))
				boud[pt->idn] = B1200; else
			if (matchn(port->fld[9], "B2400", 5))
				boud[pt->idn] = B2400; else
			if (matchn(port->fld[9], "B4800", 5))
				boud[pt->idn] = B4800; else
			if (matchn(port->fld[9], "B9600", 5))
				boud[pt->idn] = B9600;
			else
				boud[pt->idn] = B2400; /* default */
		}
		else
			boud[pt->idn] = B2400;            /* default */
#endif
		pt->nhrd   = 0;
		pt->heard  = (char *) malloc(13 * pt->maxhrd);
		pt->name   = rdstrnl();

	/* Reading this port messages AY-881126 */
		pt->mready = (char *)malloc(linelen);	/* AY-881126 */
		pt->mready[0] = '\0';
		st = fgets(port->line, linelen, port->fl);
		while (!iseof(port->line) && st != NULL) {
DBGMSG((stdout, "get:%s", port->line));
			strcat(pt->mready, port->line);
			st = fgets(port->line, linelen, port->fl);
		}
	/* ------------------------------------ */
		st = fgets(port->line, linelen, port->fl);
	}

	ioinit();

/*
 *  Drain any garbage from the port.
 */

	for (p = porthd; p isnt NULL; p = p->next)
	{
		p->lport = cport;
		if (p->dev is p_tnc)
		{
			ioport(p);
#if	(XENIX|UNIX|BSD)
			outchar(ctl_c);
			outchar('\n');
			mbsleep(1);
#else
                        p->mode = remote ;      /* discon check CHANGED SMC */
			distnc () ;             /* 1988-12-31   */
			p->mode = idle ;        /* JH1NAI       */
                    /*     outchar('\n');
                             wait(1);      */
#endif
			while(instat()) inchar();
		}
	}
	ioport(porthd);
}

/*
 *  Do the initialization. Called from mainline.
 */

init(file)
char *file ;
{
char *nullstr = "" ;
/*
 *  Default system params.
 */

	s_param = (s_mchange | s_page);

	porthd       = (PORTS *) malloc(sizeof(PORTS));
	porthd->cmd  = (char *)  malloc(cmdlen);
	porthd->line = (char *)  malloc(linelen);
	ioport(porthd);

	if ((port->fl = fopen(file, "r")) is NULL)
	{
		printf("Cannot open %s\n", file); 
		exit(0);
	}
	rdports();
#if !SWAP_NO			/* AY-880920 */
	rdswaps();
#endif
	rdpaths();
	rdcnf();
	fclose(port->fl);
	ioport(cport);
	opnmon();
	opnmsg();
	opnusr();
	rduser(tcall, cport->user);

/*
 *  If owners record did not exist, make him right kind.
 */

	if (!cport->user->rn) {
		cport->user->options = u_bbs | u_sysop | u_local;
		strncpy(cport->user->home_bbs, tcall, ln_call);
                upduser (cport->user ) ;  /* Nov11,89 */
	}

	opnlog();
        log ('C','I',' ',nullstr);       /* Nov11,89 */

/*
 *  Grab a mess of memory.
 */
#if SCO386
	scrmax = 16;
#else
	if ((scrmax = (_memavl() / 1024)) > 16) scrmax = 16;
#endif
	scrmax *= 1024;
	tmp = (TMP *) malloc(scrmax);
	printf("%u free space at %x\n\r", scrmax, (int)tmp);
	dirmax = scrmax / sizeof(DIRENT);
}

/*
 *  Read the rest of the configuration file,
 *  after the port and path definitions.
 */

rdcnf()
{
	char *ptr, *skipsp(), *strchr();		/* AY-880521 */
	register int i;
        char myaddr[64] ;   /* FEB11,90 */
 /*
 *  Login message.
 */

	motd = rdmstr();

/*
 *  Prompts.
 */

	bbmenu = rdstr();  /* Menu for connected bbs */
	symenu = rdstr();  /* Remote sysop menu */
	rmenus = rdstr();  /* Remote menu */
	lmenus = rdstr();  /* Local menu */

/*
 *  Who are we?
 */

	while (fgets (port->line, linelen, port->fl))
		if (port->line[0] != '#') break;

        unbl (myaddr, port->line, 63) ; /* SET My Domain Address FEB11,90 */
        pcall (tcall, port->line);

/*
 *  Where are we?
 */

	qth = rdstrnl();

/*
 *  Who is our name server?
 */

    /*  HFWD.MBX June.2,1991
	while (fgets (port->line, cmdlen, port->fl))
		if (port->line[0] != '#') break;
        pcall (wpcall, port->line);
    */
        hfwdfile = rdstrnl();
/*
 *  File names and directory paths used by MailBox.
 */

	helpfile = rdstrnl();
	infofile = rdstrnl();
	fwdfile  = rdstrnl();
	rfwdfile = rdstrnl();
	lgfile   = rdstrnl();
	monfile  = rdstrnl();
	mbfile   = rdstrnl();
	mbbfile  = rdstrnl();
	usfile   = rdstrnl();
	usbfile  = rdstrnl();
	msgdir   = rdstrnl();

	hrdfile  = rdstrnl();
	hrdmax   = rdnumb();

/*
 *  Give time slice back to DoubleDOS?
 */

	if (kw()) s_param setbit s_dd;

/*
 *  Max # users in user file.
 */

	maxusers = rdnumb();

/*
 *  Logging
 */

	if (kw()) s_param setbit s_log_on;
	if (kw()) s_param setbit s_log_gate;
	if (kw()) s_param setbit s_log_file;
	if (kw()) s_param setbit s_log_msg;
	if (kw()) s_param setbit s_log_loc;

/*
 *  Control characters.
 */

	achar = cchr();
	rchar = cchr();
	tchar = cchr();
	wchar = cchr();

	pausemsg = rdstr();
	/* Text for local display of user call. */
	mumsg = rdstr();
	/* Text to send when get connect request. */
	reqmsg = rdstr();
	/* Various "talk to the owner" texts. */
	talkm1 = rdstr();
	talkm2 = rdstr();
	talkm3 = rdstr();
	talkm4 = rdstr();
	/* GateWay Messages. */
	for (i = 0; i < num_gm; i++) gm[i] = rdstr();
	/* MailBox messages. */
	for (i = 0; i < num_mm; i++) mm[i] = rdstr();

	/* Formatting Mail header AY-880521 */
	if (mm[4][0] == '\\')
	{
		ptr++;
                sprintf(port->line, "R:$J/$K%c $M@%s %s", mm[4][1], myaddr, &mm[4][2]);
	}
	else
                sprintf(port->line, "R:$J/$K $M@%s %s", myaddr, mm[4]);
                                                 /* Set My address Feb11,90 */
	free(mm[4]);
	if ((mm[4] = (char *) malloc (strlen(port->line) + 1)) == NULL)
		errall();

	strcpy(mm[4], port->line);
	/* End of Formatting AY-880521 */

	/* Max calls in unread mail list. */
	ufwdm = rdnumb();
	bfwdm = rdnumb();
	/* Kill regular message after forward? */
	if (kw()) s_param setbit s_kill;
	/* Kill F message after forward? */
	if (kw()) s_param setbit s_fkill;
	/* Generate service msg after KT? */
	if (kw()) s_param setbit s_svc;
	/* Enable ET command? */
	if (kw()) s_param setbit s_edtfc;
	/* Msgs @ SYSOP remove @ BBS? */
	if (kw()) s_param setbit s_nobbs;
	/* Upload/download prompts. */
	fm = rdstr();
	/* User file text. */
	for (i = 0; i < num_um; i++) um[i] = rdstr();
	remnl(um[0]);
	/* Error/status messages. */
	mcant  = rdstr();
	mfind  = rdstr();
	mprot  = rdstr();
	mexst  = rdstr();
	mtime  = rdstr();
	mwhat  = rdstr();
	mdone  = rdstr();
	mnport = rdstr();
	mndir  = rdstr();
	mnfile = rdstr();
	mnmsg  = rdstr();
	minuse = rdstr();

	/* Expanded messages. by A.Yamada */
	bidprompt= "BID:\n";             /* BID: */
	bid_toolong= "Too long\n";             /* Too long bid */
	bbsonly_msg = rdmstr();          /* Sorry, current time is bbs only.
					      *** EOF   */
	tomanydigi_msg = rdmstr();       /* Sorry, Too many digipeating
					      *** EOF   */
	abortby_usr = rdstr();           /* Proces aborted by usr */
	meantime = rdstrnl();            /* Read mean time */
	if (kw()) check_kanji_title setbit 1; /* Yes, no listing kanji title */
	else check_kanji_title clrbit 1;
#if	(XENIX|UNIX|BSD)
	can_t_do = rdstrnl();            /* Can't do : */
	mailingfile = rdstrnl();         /* File name of interface MB & Xenix */
	mailer = rdstrnl();              /* Mailer program name with opt */
	to_file = rdstrnl();             /* To: feeld check file name */
	at_file = rdstrnl();             /* At: feeld check file name */
	if (kw()) kill_after_m setbit 1; /* Erace after forwarded mail to Xenix */
	else kill_after_m clrbit 1;
#else
       if (kw()) trace_tnc setbit 1;    /* TRACE TNC Yes or No by PC-DOS SMC */
            else trace_tnc clrbit 1;
#endif
}
