/*
 *  MBFWD.C -  Autoforwarding.
 *
 *  The target port mode is set to idle if not connected,
 *  set to remote if connected. It is set to disconnect or timeout
 *  by getdat(), but this is checked and fixed up in getln().
 *  All port input is through getln().
 *  All file input is through nxtin().
 */
/*
 *  History of Modifiy
 *  Port assigned D,P,< at FWD.MBX                      Mar.23,1991
 *  Bug fixed. setports()                               871216
 */

#include "mb.h"
#include "mbexp.h"

#if (XENIX|UNIX|BSD)	/* AY-881125 */
#define FLOW_YES()	flow_yes()
#define FLOW_NO()	flow_no()
#define FLUSHPORT(n)	flushport(n)
#else
#define FLOW_YES()
#define FLOW_NO()
#define FLUSHPORT(n)
#endif

#define deepmax    5

#if !DOMAIN_NO	/* AY-880903 */
extern char domain[], mblmode2[];
extern int domainok, extfwdok;
#endif

extern char rfwd, rfwdok;   /* AY-1 */
extern char *rdstrnl();     /* AY-871209 */
extern word do_announce;	/* AY-881127 */

int   in_dofilecmd;			/* AY-880303 */
char  *mailingfile;         /* AY-880106 */
char  *script;
int   dohfwd;               /* AY-870107 */
char  *fwdfile;
FILE  *ifl[deepmax];
short deep;
/*static char  path[80];       path[] to static char AY-871204 */
char fwdpath[80] ;      /* feb.11,90 */
char  fcall[10];
short onebbs;
char  igtime;
short skipit;	/* If true, abort the forwarding */


/*
 *  YF command: change the name of the forwarding file.
 */

newfwd()
{
	XEPARSE();
	free(fwdfile);
	if ((fwdfile = (char *)malloc(strlen(port->fld[1]) + 1)) is NULL)
		errall();
	strcpy(fwdfile, port->fld[1]);
}

/*
 *  Add a call to one of the lists of calls of
 *  stations that have messages to be forwarded to them.
 */

addfwd(cp, lp, n, m)
char *cp, *lp;
short n, m;
{
	register short i;

	for (i = 0; i < n; i++, lp += ln_call) if (matchn(cp, lp, ln_call)) return n;
	if (n < m) { 
		strncpy(lp, cp, ln_call); 
		return n + 1; 
	}
	return n;
}

/*
 *  Check if a call has a message to be forwarded to it.
 */

findfwd(cp, lp, n)
char *cp, *lp;
short n;
{
	register short i;

	for (i = 0; i < n; i++, lp += ln_call) if (wcm(cp, lp)) return true;
	return false;
}

/*
 *  Build the two lists of calls of stations that have
 *  messages to be forwarded to them.
 *  ufwd - Calls to put in beacon line.
 *  bfwd - Calls that have message TO or AT.
 */

bldfwd()
{
register short i;
register word  h;
char *ptr, *ptr2, buf[ln_call + 1], *strchr();

    DBGMSG((stderr, "bldfwd()\n\r"));
    DB_LOCK(mfl);
#if SEM_NO
    SETMFHS();
#endif

    ufwdn = bfwdn = 0;
    for (h = mfhs->last; h; h = port->mmhs->prev) {
        read_rec(mfl, h, (char *)port->mmhs);

        if (!(port->mmhs->stat & (m_read | m_fwd))) {
            if (*port->mmhs->bbs is ' ') {
                ufwdn = addfwd(port->mmhs->to, ufwd, ufwdn, ufwdm);
                bfwdn = addfwd(port->mmhs->to, bfwd, bfwdn, bfwdm);
            } else {
                if (port->mmhs->ext) {
                    read_rec(mfl, port->mmhs->ext, (char *)mmes);
                    for (i = 0; i < mmes->count; i++) if (mmes->flag[i])
                        bfwdn = addfwd(mmes->call[i], bfwd, bfwdn, bfwdm);
                } else {
#if 0 /* Feb.11,90   !DOMAIN_NO */
                    if (port->mmhs->unu2)
                        read_rec(mfl, port->mmhs->unu2, (char *)msgbid);
                    if (msgbid->domain[0]) {
                        strcpy(domain, msgbid->domain);
                        ptr = ptr2 = domain;
                        while (*ptr) {
                            if (ptr2 = strchr(ptr, '.'))
                                *ptr2 = '\0';
                            pcall(buf, ptr);
                            bfwdn = addfwd(buf, bfwd, bfwdn, bfwdm);
                            if (ptr2 != NULL)
                                ptr = ++ptr2;
                            else
                                break;
                        }
                        msgbid->domain[0] = '\0';
                    } else {
#endif
                        if (matchn(port->mmhs->bbs, cport->user->call, ln_call)) 
                            ufwdn = addfwd(port->mmhs->to, ufwd, ufwdn, ufwdm);
                        else
                            bfwdn = addfwd(port->mmhs->bbs, bfwd, bfwdn, bfwdm);
                    }
#if 0 /* !DOMAIN_NO   Feb.11,90 */
                }
#endif
            }
        }
    }
    DBGMSG((stderr, "bldfwd()\n\r"));
    DB_UNLOCK(mfl);
    s_param clrbit s_mchange;
}

/*
 *  Read the next input line from FWD.MB,
 *  or from a file referenced from FWD.MB.
 *  Return NULL if no more lines to read.
 */

char *nxtin(p)
char *p;
{
	register char *st;

	while (deep >= 0) {
		st = fgets(p, 80, ifl[deep]);
		if (st is NULL) {
			fclose(ifl[deep]);
			deep--;
		} else {
			if (*p == '#') continue;	/* AY-881030 */
			if (*p isnt '@') return st;
#if	!(XENIX|UNIX|BSD)	/* AY-880410 */
			uc(p);
#endif
			remnl(p);
			deep++;
			if ((ifl[deep] = fopen(p + 1, "r")) is NULL) deep--;
		}
	}
	return NULL;
}

/*
 *  The entry to fowarding.
 *  X and XI commands.
 *  Also called when the MailBox is idle and any ports forwarding time occurs.
 *  Port always set to cport on entry, options and args in cport buffer.
 */

fwd()
{
	PORTS *p;
/*	char  buf[BUFSIZ];  /* AY-881106 */

/*
**  If remote sysop did the command, just remember it for later.
*/

	if (port->mode & sysop) { 
		savecmd(); 
		return; 
	}

	/*
 *  If no fwd.mb file, then do nothing.
 */

	deep = 0;
	if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) return;

/*
**  X and XI commands. Do it for all ports.
*/

	if (cport->flds)
	{
		for (p = porthd; p isnt NULL; p = p->next) p->flags setbit p_dofwd;
		onebbs = (cport->flds is 2);
		if (onebbs) strncpy (fcall, cport->fld[1], 9);
		igtime = cport->opt2;
	}

/*
 *  Automatic forwarding. Do it only for ports with p_dofwd set.
 */

	else
	{
		onebbs = false;
		igtime = ' ';
	}

#if SHARE	/* AY-880601 */
	bldfwd();
#else
	if (s_param & s_mchange) bldfwd();
#endif
	script = tmp->scr;
	*script = '\0';
	skipit = false;

	dohfwd = rfwdok = rfwd = false;              /* AY-871007 */
	while(nxtin(cport->line) isnt NULL)
	{
		ioport(cport);
		if (instat()) if (inchar() is achar) skipit = true;

#if	(XENIX|UNIX|BSD)
		xeparse();
#else
		uc(cport->line);
		pparse();
#endif
		switch (cport->opt1)
		{
		case 'G': 
			if (!skipit) { 
				rfwd = false; 
				dofwd(); 
			} /* AY-1 */
			script = tmp->scr;
			*script = '\0';
			break;
		case 'H': 
			dohfwd = true;                          /* AY-871007 */
		case 'F': 
                        if (!skipit) {
				rfwd = true; 
				dofwd(); 
			}  /* AY-871007 */
			script = tmp->scr;
			*script = '\0';
			break;
		case 'D': 
                        if (!chktime()) break;          /* AY-881124 */
                        if (cport->opt2 != ' ') {       /* Mar.23,91 */
                                if ((p=findport(cport->opt2)) is NULL) break ;
                                if (!(p->flags & p_dofwd)) break ;
                        }
                        remnl (cport->line) ;        /* add jh1nai 3/14 */
                        system(&cport->line[6]);
			break;
		case 'P': 
			dopar();
                        script = tmp->scr ;       /* add jh1nai 3/15  */
                        *script = '\0' ;          /*                  */
			break;
		case 'Q': 
                        setports();               /* AY-871127 */
                        script = tmp->scr ;       /* add jh1nai 3/15  */
                        *script = '\0' ;          /*                  */
			break;
                case '<':
                        if (cport->opt2 != ' ') {       /* Mar.23,91 */
                                if ((p=findport(cport->opt2)) is NULL) break ;
                                if (!(p->flags & p_dofwd)) break ;
                        }
			dofilecmd();
                        script = tmp->scr ;       /* add jh1nai 3/15  */
                        *script = '\0'  ;         /*                  */
			break;                                  /* AY-880104 */
#if  IO_REDIR                                      /* Nov13,89 */
		case '>': 
			if (!chktime()) break;			/* AY-881124 */
                        remnl (cport->line)  ;    /* Nov13,89 */
                        strcpy (cport->line, cport->line + 6 ) ;
                        redir_out(); 
                        script = tmp->scr  ;
                        *script = '\0'     ;
                        break;                     /* AY-880105 */
#endif
                case 'R':
                        remnl (cport->line) ;     /* Nov13,89 */
                case 'C':
		case 'S': 
			strcpy(script, cport->line);
			script += (strlen(cport->line) + 1);
			*script = '\0';
			break;

		default:	
			break;
		}
	}

/*
 *  Reset the port flags.
 */

	for (p = porthd; p isnt NULL; p = p->next) {
		p->flags clrbit p_dofwd;
		p->flags clrbit p_fwdok;
	}

/*
 *  Put us back on the port we were on when we got here.
 */

	ioport(cport);
#if SHARE			/* AY-880617 */
	setfwd();
#endif
}

/*
 *  Pass a sublist in the forwarding file.
 */

passlst()
{
	while (true)
	{
		if (nxtin(cport->line) is NULL) return;
		if (iseof(cport->line)) return;
	}
}

/*
 *  Set tnc parameters.
 */

dopar()
{
	register PORTS *p;

	if ((p = findport(cport->opt2)) is NULL) { 
		passlst(); 
		return; 
	}
        if (!(p->flags & p_dofwd)) {            /* Mar.23,91 */
                passlst() ;
                return    ;
        }
	if (strlen(cport->fld[0]) > 3) if (!chktime()) { 
		passlst(); 
		return; 
	}
        ioport(p);
	while (nxtin(cport->line) isnt NULL)
	{
		if (iseof(cport->line)) { 
			ioport(cport); 
			return; 
		}
		onetnc(cport->line);
	}
	ioport(cport);
}

/*
 *  Get a line from the current port.
 *  Handle disconnect, timeout, and ^F.
 */

getln()
{
	while (!getdat())
		;

	if (port->mode & gone)
	{
		distnc();
		port->mode = idle;
	}
}

/*
 *  Eat the remote MailBox prompt.
 */
#if !DOMAIN_NO	/* AY-880903 */
eat()
{
char *strchr(), *strrchr();
register char *tempptr;

	do {
		getln();
		if ((port->line[0] == '[') && (tempptr = strchr(port->line, ']')))
		if (*(--tempptr) == '$') {
			rfwdok = true;
			tempptr = strrchr(port->line, '-'); tempptr++;
			while (*tempptr && (*tempptr != '$')) {
				switch(*tempptr) {
				case 'H': domainok |= 2; break;
				case 'D': domainok |= 1; break;
				case 'E': extfwdok = 1; break;
				default: break;
				}
				tempptr++;
			}
		}
	} while ((port->mode & remote)
	    and (port->line[strlen(port->line) - 2] isnt '>'));
	FLUSHPORT(2);	/* AY-880913 */
}
#else
eat()
{
char *strchr(), *strrchr();
register char *tempptr;

	do {
		getln();
		if (*(port->line) == '[')
		{
			if (tempptr = strchr(port->line, ']'))
			{
				if ((*(--tempptr) == '$') or (matchn(port->line, "[MBL", 4)))
					rfwdok = true;
			}
		}
	} while ((port->mode & remote)
	    and (port->line[strlen(port->line) - 2] isnt '>'));
	FLUSHPORT(2);	/* AY-880913 */
}
#endif

/*
 *  Connect to a remote Mailox.
 *  Port mode idle at entry.
 *  On return, port mode is remote if the connect worked.
 */

cmb()
{
	register char *p;

	port->mode = remote;
	script = tmp->scr;
        port->flags setbit p_dotmr ; /* May5,1990 */
/*
 *  There is a connect script, execute it.
 */

	if (*script)
	{
		while(*script)
		{
			switch (*script++)
			{
			case 'C' :
				contnc(script);
				do
				{
					getln();
					if (port->mode & idle) return;
                                } while (!iscon(port->line));
				break;

			case 'S' :
                           /*     onetnc(script);      Nov23,89 */
                                outstr(script) ;
				break;

			case 'R' :
                                getln();
                                if (port->mode & idle) return;
                                uc(port->line);
                                remnl (port->line) ;     /* Nov13,89 */
				if (*script isnt '!')
                      /*                  if (!matchn(port->line, script, strlen(port->line) - 1))  */
                                        if (!matchn(port->line, script,strlen(script))) /* Nov17,89 */
                                        {
						distnc(); 
						port->mode = idle; 
						return; 
					}
				break;

			default: 
				;
			}
			while(*script++);
		}
	}

/*
 *  No connect script, so just connect.
 */

	else
	{
                contnc(fwdpath);
		if (port->mode & idle) return;

		if (port->dev is p_tnc) do
		{
			getln();
			if (port->mode & idle) return;
		}    while (!iscon(port->line));
	}

  /*
 *  In theory, now connected to MailBox. Eat login messge.
 */

	eat();
        if (port->mode & idle) return ;  /* Jun24,1990 */
	if (rfwdok) {
                outstr(mblmode);
		eat();
	}
        remnl(fwdpath);    /* Logging needs the new line gone. */
}

/*
 *  batch file proceser
 *  Usage(in fwd.mb)
 *  "< 0023 File_name"
 *  00 & 23 are same as G,F,H etc
 */

dofilecmd()  /* do comannd file port -> cport */
{
/*    if (cport->flds < 2) return;      */
        remnl (cport->line) ;
        if (strlen(cport->line) < 8 ) return ;
	if (!chktime()) { 
		dohfwd = rfwdok = rfwd = false; 
		return; 
	}
        in_dofilecmd = 1;
        strcpy(tmp->scr, "< ");
/*        strcat(tmp->scr, cport->fld[cport->flds -1]); */
        strcat (tmp->scr, cport->line + 6) ;     /* Mar.23,91 */
        strncpy(port->line, tmp->scr, linelen);

        docmd_file();
        in_dofilecmd = 0;
}

/*
 *  Forward whatever messages go to this MailBox.
 */

dofwd()
{
	register PORTS *p;
	register char *st;

#if !DOMAIN_NO	/* AY-880903 */
	domainok = extfwdok = 0;
#endif

	if (onebbs) if (!match (fcall, cport->fld[1])) { 
		dohfwd = rfwdok = rfwd = false; 
		passlst(); 
		return; 
	} /* AY-871007 */
	if (!chktime()) { 
		dohfwd = rfwdok = rfwd = false; 
		passlst(); 
		return; 
	} /* AY-871007 */

	if ((p = findport(cport->opt2)) is NULL) { 
		dohfwd = rfwdok = rfwd = false; 
		passlst(); 
		return; 
	} /* AY-871007 */

	if (!(p->flags & p_dofwd)) { 
		dohfwd = rfwdok = rfwd = false; 
		passlst(); 
		return; 
	} /* AY-871007 */

        strcpy(fwdpath, cport->line + 6);
        st = nxtin(cport->line);
	while (!iseof(cport->line) and (st isnt NULL)) {
		ioport(cport);
		pparse ();
		ioport(p);
		pcall (tcall, cport->fld[0]);

		if (findfwd(tcall, bfwd, bfwdn))
		if (fmsg()) if (port->mode & idle) {
            /* onecmd(RESTART);  del V46.xx xx-880531 */
			dohfwd = rfwdok = rfwd = false;
			passlst();
			return;
		} /* AY-871007 */

		st = nxtin(cport->line);
	}

	if (dohfwd and (port->mode & idle)) {
		if (port->mode & idle)
			cmb();
		if (port->mode & idle) { 
			dohfwd = rfwdok = rfwd = false; 
			return; 
		}
	}
	if (rfwd and rfwdok) {
		outstr("F>\n");
		port->errors = 0;

		while (!(port->mode & gone)) {   /* (true) AY-870915 */
			getln();
			if(port->mode & idle)
				break;

			if (!(port->mode & gone)) {
				if (matchn("*** Done.", port->line, 8)) {
					eat();
					break;
				} else if (port->line[0] isnt 'S') {
				/* allow S commnd only AY */
					port->mode = forced;
					break;
				} else
					docmd();

                                if (port->mode & gone) break;
				if (port->errors > 0 ) { 
					port->mode = forced; 
					break; 
				}
				outstr("F>\n");
				continue;
			}
			break;
		}
	}
	dohfwd = rfwdok = rfwd = false;
/*        if (port->mode & (remote | timeout | forced )) distnc(); Feb.18,90*/
        if ( port->mode & (gone | remote) ) distnc () ;
	port->mode = idle;
}

/*
 *  Return true if the current time is within
 *  the time window for forwarding to this MailBox.
 */

chktime()
{
	register short c, en, st;

	if (igtime is 'I') return true;
	curtim();
	st = 10 * (int)(cport->line[2] - '0') + (int)(cport->line[3] - '0');
	en = 10 * (int)(cport->line[4] - '0') + (int)(cport->line[5] - '0');
	c  = 10 * (int)(l_time[0] - '0') + (int)(l_time[1] - '0');
	if (st <= en) return ((c >= st) and (c <= en));
	return ((c >= st) or (c <= en));
}

/*
 *  Wild card match with ? and * in first arg.
 */

wcm(s1, s2)
char *s1, *s2;
{
	register short l;

	for (l = 0; l < ln_call; l++, s1++, s2++)
	{
		if (*s1 is '*') return true;
		if (*s1 isnt '?') if (*s1 isnt *s2) return false;
	}
	return true;
}

/*
 *  Check if a disconnect happened.
 */

ckdis()
{
	if (instat())
		if (getdat())
		{
			if (isdis(port->line))
			{ 
				cmdtnc(); 
				port->mode = idle; 
				return true; 
			}
			else if (port->mode is timeout)
			{ 
				cmdtnc(); 
				port->mode = idle; 
				return true; 
			}
		}
	return false;
}

/*
 *  Send the message text.
 */

xmtmsg()
{
	FILE *fl;

	FLOW_YES();
	sprintf(port->line, "%s%u", msgdir, port->mmhs->number);
	if ((fl = fopen(port->line, "r")) is NULL) {
		nofile(port->line);
	} else {
		while(fgets(tmp->scr, scrmax, fl) isnt NULL) {
			outstr(tmp->scr);
			if (ckdis())
			{
                    /*            onecmd(RESTART);    del Feb11,90 */
				fclose(fl);
				FLOW_NO();
				return false;
			}
		}
		fclose (fl);
	}
	sprintf(tmp->scr, "%c%c", cpmeof, '\n');
	outstr(tmp->scr);
	FLOW_NO();
	FLUSHPORT(1);
	return true;
}

/*
 *  Forward all messages TO or AT tcall
 *  to the MailBox we are connected to.
 */

fmsg()
{
char *ptr;
register word prev, h;
register short anyok, i, ok, kill, extnr, kok;

register char *ptr2;
char tmpcall[ln_call];

#if !EXTFWD_NO	/* AY-881020 */
register char *tmpptr;
#endif

#if SEM_NO
    DBGMSG((stderr, "fmsg()\n\r"));
    DB_LOCK(mfl);
    SETMFHS();
    DB_UNLOCK(mfl);
#endif

    anyok = false;
    for (h = mfhs->last; h; h = prev) {
        read_rec(mfl, h, (char *)port->mmhs);

	domain[0] = '\0';
	fill (msgbid, '\0', sizeof(MSG_BID));
	ptr = ptr2 = NULL;

        /* Save previous, kill msg destroys hdr */
        prev = port->mmhs->prev;

        ok = (!(port->mmhs->stat & (m_read | m_fwd)));

/*
**  Decide whether to forward this one.
*/
        if (ok) {
            if (port->mmhs->unu2) {
                read_rec(mfl, port->mmhs->unu2, (char *)msgbid);
                if (msgbid->domain[0] != '\0') {
                    strcpy(domain, msgbid->domain);
                    ptr = ptr2 = domain;
                }
            }
	    if (port->mmhs->ext) {
                ok = false;
                read_rec(mfl, port->mmhs->ext, (char *)mmes);
                for (i = 0; !ok and (i < mmes->count); i++)
                    if (mmes->flag[i])
                if (wcm(tcall, mmes->call[i])) { ok = true; extnr = i; }
            } else if (*port->mmhs->bbs isnt ' ') {
                fill (tmpcall, '\0', sizeof(tmpcall));
                ok = wcm(tcall, port->mmhs->bbs);
#if 0    /* Feb.11,90   Delete  Domain Xfer */
                if (!ok && ptr) {
                    while (*ptr) {
                        if ((ptr2 = strchr(ptr, '.')) != NULL) {
		            *ptr2 = '\0';
                            pcall(tmpcall, ptr);
                            *ptr2 = '.';
                            ptr = ++ptr2;
                        } else {	/* This is the Top Domain Address!!!! */
                            pcall(tmpcall, ptr);
			    *ptr = '\0';
                        }
                        if (ok = matchn(tcall, tmpcall, ln_call)) break;
                    }	
                }
#endif
            } else ok = wcm(tcall, port->mmhs->to);
        }
/*
**  If we DO forward this one, forward this one.
*/
        if (ok) {
            anyok = true;
            if (port->mode & idle)
                cmb();
            if (port->mode & idle)
                return anyok;

            if (msgbid->domain[0]) {
                strcpy(domain, msgbid->domain);
/*                if (!(domainok & 1)) *(--ptr) = '\0';     Nov13,89 */
            }

            if (*port->mmhs->bbs is ' ')
                prtx("S$B $G < $P");
            else
                prtx("S$B $G @ $A < $P");

            if (rfwdok && (msgbid->bid[0] != '\0'))
                sprintf(tmp->scr, " $%s\n", msgbid->bid);
            else
                sprintf(tmp->scr, "\n");
            outstr(tmp->scr);

            getln();
            if (port->mode & idle)		/* AY-880505 */
                return anyok;
            if (isretry(port->line))	/* AY-880406 */
                getln();
            if (port->mode & idle)
                return anyok;
            if (*(port->line) != 'N') {
#if 0   /* !EXTFWD_NO   AY-881020 ==> Delete Dec.1,89 */
                if (!domainok)
                if(msgbid->domain[0] != '\0') {
                    sprintf(tmp->scr, "%!%s#", msgbid->domain);
                    tmpptr = tmp->scr;
                    while(*tmpptr) {
                        if (*tmpptr == '.')
                            *tmpptr++ = '!';
                        else
                            tmpptr++;
                    }
                    outstr(tmp->scr);
                }
#endif
                outstr(port->mmhs->title); 
                outchar('\n');
                curtim();
                prtx(mm[4]);
                FLOW_YES();
                if (!xmtmsg()) { FLOW_NO(); return anyok; }
                eat();
                if (port->mode & idle) { FLOW_NO(); return anyok; }
            } else {
                eat();
                if (port->mode & idle) return anyok;
            }
/*
 *  The message actually forwarded.
 *  Kill it, mark it, or whatever.
 */
            sprintf(port->line, "%u %s %s",
            port->mmhs->number, fwdpath, port->mmhs->title);
            log ('M', 'F', ' ', port->line);
            s_param setbit s_mchange;

            kill = false; 
            kok = false;
/*
 *  If cc: list exists, mark this call as forwarded.
 */
            if (port->mmhs->ext) {
                mmes->flag[extnr] = false;
                for (i = 0; i < mmes->count; i++)
                    if (mmes->flag[i]) kok = true;
            }

            if (!kok) {
                if (port->mmhs->type is 'F')
                    kill = s_param & s_fkill;
                else
                    kill = s_param & s_kill;
            }                       /* Del H-Addr check  Feb24,90 */
            if (kill && /*(!port->mmhs->unu2) &&*/ (msgbid->bid[0] == '\0'))
                kmsg();
            else {
                DBGMSG((stderr, "fmsg()\n\r"));
                DB_LOCK(mfl);
                if (!kok) {
                    port->mmhs->stat setbit m_fwd;
                    write_rec(mfl, port->mmhs->rn, (char *)port->mmhs);
                }
                if (port->mmhs->ext)
                    write_rec(mfl, port->mmhs->ext, (char *)mmes);
                DBGMSG((stderr, "fmsg()\n\r"));
                DB_UNLOCK(mfl);
            }
        }
        FLOW_NO();
    }
    return anyok;
}

/*
 *  Read the port definition section of the fwd.mb
 */
static char *cond[] ={
	"on", "off"};
setports()
{
	char *nxtin();
	register int tmptime;
	register PORTS *p;
	register char *st;
	register word privsv;
	int      ctimesv, dtimesv, mtimesv, mcountsv, fwdminsv,
	maxhrdsv, ndigisv, errmaxsv;

	if (!chktime()) { 
		passlst(); 
		return; 
	}

        if (cport->opt2 is 'N') { 
		passlst(); 
		return; 
	}
        if (cport->opt2 isnt ' '){      /* MAY2,1991 */
                if ((p = findport (cport->opt2)) is NULL ){
                        passlst();
                        return;
                }
                if (!(p->flags & p_dofwd)){
                        passlst();
                        return;
                }
        }

	if((st = nxtin(cport->line)) is NULL) return;
	while (!iseof(cport->line) and (st isnt NULL))
	{
		pparse();
		st = cport->fld[0];

		if ((p = findport(cport->opt1)) is NULL)
		{
                        sprintf(tmp->scr, "MB: port %c - not installed. check %s please\n\7",
			    cport->opt1, fwdfile);
			debugmsg(tmp->scr);
                        st = nxtin(cport->line);
			;
			continue;
		}
		st++;

		do_announce = 0;	/* AY-881127 */

		privsv = p->priv;   /* AY-871216 */
		ctimesv = p->ctime;
		dtimesv = p->dtime;
		mtimesv = p->mtime;
		mcountsv= p->mcount;
		maxhrdsv= p->maxhrd;
		ndigisv = p->ndigi;
		errmaxsv= p->errmax;
		fwdminsv= p->fwdmin;
		p->priv = (word)0;  /* AY-871215 */

		while(*st)
		{
			switch(*st)
			{
			case 'A':	/* AY-881127 */
				p->priv setbit p_mailfor;
				do_announce setbit 2;
				break;
			case 'N':	/* AY-881127 */
				p->priv setbit p_mbready;
				do_announce setbit 1;
				break;
			case 'B': 
				p->priv setbit p_bbs; 
				break;
			case 'D': 
				p->priv setbit p_dnload; 
				break;
			case 'U': 
				p->priv setbit p_upload; 
				break;
			case 'G': 
				p->priv setbit p_gate; 
				break;
			case 'I': 
				p->priv setbit p_ilcal; 
				break;
			case 'M': 
				p->priv setbit p_mon; 
				break;
			case 'R': 
				p->priv setbit p_sysop; 
				break;
			case '-': 
				break;
			default:  
				sprintf(tmp->scr,"%c: ignored.\n\r\7", *st);
				debugmsg(tmp->scr); 
				break;
			}
			st++;
		}
		p->ctime  = atoi(port->fld[1]);
		p->dtime  = atoi(port->fld[2]);
		p->mtime  = atoi(port->fld[3]);
		p->mcount = atoi(port->fld[4]);
		p->maxhrd = atoi(port->fld[5]);
		p->ndigi  = atoi(port->fld[6]);
		if (port->fld[7][0] is '+')
		{
			p->fwdmin += atoi(port->fld[7] + 1);
                        if (p->fwdmin >= 60) p->fwdmin -= 60;
		} else
			if (port->fld[7][0] is '-')
			{
				tmptime = (int)p->fwdmin;
				tmptime -= atoi(port->fld[7] + 1);
                                if (tmptime < 0)
					p->fwdmin = (byte)(tmptime +=60);
				else
					p->fwdmin = (byte)(tmptime);
			} 
			else
				p->fwdmin = atoi(port->fld[7]);
		p->errmax = atoi(port->fld[8]);

		if (privsv ^ p->priv)
		{
			sprintf(tmp->scr, "\n\r***** Status of port %c *****\n\r",
			    cport->opt1);
			debugmsg(tmp->scr);
			sprintf(tmp->scr, "%s\n\r", cport->line);
			debugmsg(tmp->scr);
		}
		if ((privsv & p_bbs) ^ (p->priv & p_bbs)) {
			sprintf(tmp->scr,"B:BBS only is %s.\n\r",
			    cond[!(p->priv & p_bbs)]);
			debugmsg(tmp->scr);
		}
		if ((privsv & p_dnload) ^ (p->priv & p_dnload)) {
			sprintf(tmp->scr,"D:Download allowed is %s.\n\r",
			    cond[!(p->priv & p_dnload)]);
			debugmsg(tmp->scr);
		}
		if ((privsv & p_upload) ^ (p->priv & p_upload)) {
			sprintf(tmp->scr,"U:Upload allowed is %s.\n\r",
			    cond[!(p->priv & p_upload)]);
			debugmsg(tmp->scr);
		}
		if ((privsv & p_gate) ^ (p->priv & p_gate)) {
			sprintf(tmp->scr,"G:Gateway allowed is %s.\n\r",
			    cond[!(p->priv & p_gate)]);
			debugmsg(tmp->scr);
		}
		if ((privsv & p_ilcal) ^ (p->priv & p_ilcal)) {
			sprintf(tmp->scr,"I:Exlude Illegal call is %s.\n\r",
			    cond[!(p->priv & p_ilcal)]);
			debugmsg(tmp->scr);
		}
		if ((privsv & p_mon) ^ (p->priv & p_mon)) {
			sprintf(tmp->scr,"M:Monitoring allowed is %s.\n\r",
			    cond[!(p->priv & p_mon)]);
			debugmsg(tmp->scr);
		}
		if ((privsv & p_sysop) ^ (p->priv & p_sysop)) {
			sprintf(tmp->scr,"R:Remote Sysop allowed is %s.\n\r",
			    cond[!(p_sysop)]);
			debugmsg(tmp->scr);
		}

		if (p->ctime isnt ctimesv) {
			sprintf(tmp->scr,"Timeout is %d to %d sec.\n\r", ctimesv, p->ctime);
			debugmsg(tmp->scr);
		}
		if (p->dtime isnt dtimesv) {
			sprintf(tmp->scr, "Changed force disconnect time, %d to %d sec.\n\r",
			    dtimesv, p->dtime);
			debugmsg(tmp->scr);
		}
		if (p->mtime isnt mtimesv) {
			sprintf(tmp->scr,"Allow monitoring %d to %d sec.\n\r",
			    mtimesv, p->mtime);
			debugmsg(tmp->scr);
		}
		if (p->mcount isnt mcountsv) {
			sprintf(tmp->scr,"Allow monitoring %d to %d lines.\n\r",
			    mcountsv,p->mcount);
			debugmsg(tmp->scr);
		}
		if (p->maxhrd isnt maxhrdsv) {
			sprintf(tmp->scr,"Allow J-list %d to %d Calls.\n\r",
			    maxhrdsv, p->maxhrd);
			debugmsg(tmp->scr);
		}
		if (p->ndigi isnt ndigisv) {
			sprintf(tmp->scr,"%d digipeats allow on connect.[%d]\n\r",
			    ndigisv, p->ndigi);
			debugmsg(tmp->scr);
		}
		if (p->fwdmin isnt fwdminsv) {
			sprintf(tmp->scr,
			    "Changed forwarding time, %d to %d min of each hours.\n\r",
			    fwdminsv, p->fwdmin);
			debugmsg(tmp->scr);
		}
		if (p->errmax isnt errmaxsv) {
			sprintf(tmp->scr,"Allowed command errors are %d to %d.\n\r\n\r",
			    errmaxsv, p->errmax);
			debugmsg(tmp->scr);
		}
		if (privsv ^ p->priv)
			debugmsg("\n\r");

		st = nxtin(cport->line);
	}
}
