home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
packet
/
cbbs60so.arc
/
MBFWD.C
< prev
next >
Wrap
Text File
|
1989-02-20
|
21KB
|
980 lines
/*
* MBFWD.C - 1/31/89 - 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().
*/
#include "mb.h"
#define deepmax 5 /* Max nesting depth of indirection in fwd.mb */
#define fw_one 0x01 /* Forward to only one MailBox, given in fcall*/
#define fw_anytime 0x02 /* Ignore the times in the "G" item */
#define fw_abort 0x04 /* Abort forwarding as soon as possible */
#define fw_tried 0x08 /* Attempted to forward to this MailBox */
#define fw_tiout 0x10 /* Forward timeout flag */
#define fw_forced 0x20 /* Forced forward flag */
#define fw_pass 0x40 /* Bypass forward sub file */
char *script; /* Pointer to where the connect script is */
byte fopts; /* Options, see defines above. */
char fwdtyp;
char *fwdfile; /* The file name of fwd.mb root file */
FILE *ifl[deepmax]; /* File variables for fwd.mb */
short deep; /* Current depth within fwd.mb */
char path[80]; /* "G" item saved here, for logging */
char fcall[10]; /* Call of the MailBox to forward to */
/*
* YF command: change the name of the forwarding root file.
*/
newfwd()
{
if (*port->fld[1])
{
free(fwdfile);
fwdfile = strdup(port->fld[1]);
}
sprintf(tmp->scr, "is %s\n", fwdfile);
outstr(tmp->scr);
}
/*
* Add a call to the list of BBS that have messages to be forwarded to them.
*/
addbfwd(cp)
char *cp;
{
register short i;
register char *lp;
for (i = 0, lp = bfwd; i < bfwdn; i++, lp += ln_call)
if (matchn(cp, lp, ln_call)) return;
if (bfwdn < bfwdm) { strncpy(lp, cp, ln_call); bfwdn++; }
}
/*
* Add a call to the list of users that have unread messges.
*/
addufwd(cp)
char *cp;
{
register short i;
register char *lp;
for (i = 0, lp = ufwd; i < ufwdn; i++, lp += ln_call)
if (matchn(cp, lp, ln_call)) return;
if (ufwdn < ufwdm) { strncpy(lp, cp, ln_call); ufwdn++; }
}
/*
* 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;
}
/*
* Add the info from one message header to the 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.
*/
addfwd()
{
register short i;
char *p, hcall[6];
if (!(port->mmhs->stat & (m_busy | m_kill | m_read | m_fwd | m_hold)))
{
if (*port->mmhs->bbs is ' ')
{
addufwd(port->mmhs->to);
addbfwd(port->mmhs->to);
}
else
{
if (port->mmhs->ext is 1)
{
for (i = 0; i < port->mmhs->count; i++) if (port->mmhs->flag[i])
addbfwd(port->mmhs->call[i]);
}
else
{
if (matchn(port->mmhs->bbs, cport->user->call, ln_call))
addufwd(port->mmhs->to);
else addbfwd(port->mmhs->bbs);
if (port->mmhs->ext is 2)
{
p = port->mmhs->call[0];
while((p = strchr(p, '.')) isnt NULL)
{
p++;
fill(hcall, ' ', ln_call);
pcall(hcall, p);
addbfwd(hcall);
}
}
}
}
}
}
/*
* Build the two lists of calls of stations that have
* messages to be forwarded to them.
*/
bldfwd()
{
register word h;
ufwdn = 0;
bfwdn = 0;
read_rec(mfl, 0, (char *)mfhs);
for (h = mfhs->last; h; h--)
{
read_rec(mfl, h, (char *)port->mmhs);
if (!(port->mmhs->stat & (m_busy | m_kill | m_read | m_fwd | m_hold)))
addfwd();
}
}
/*
* Return true if the current time is within
* the time window for forwarding to this MailBox.
*/
chktime()
{
register short c, en, st;
if (fopts & fw_anytime) 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));
}
/*
* Check if it is ok to forward using this list.
* Return a pointer to the port to use for forwarding, or NULL.
*/
PORTS *chkfwd()
{
register PORTS *p;
if (fopts & fw_one)
if (!match (fcall, cport->fld[1])) { passlst(); return NULL; }
if (!chktime()) { passlst(); return NULL; }
if ((p = findport(cport->opt2)) is NULL) { passlst(); return NULL; }
if (!(p->flags & p_dofwd)) { passlst(); return NULL; }
if (fopts & fw_abort) { passlst(); return NULL; }
p->mode = idle;
return p;
}
/*
* Check if a disconnect happened.
*/
chkdis()
{
if (instat()) if (getdat()) if (isdis(port->line))
{ cmdtnc(); port->mode = idle; return true; }
if (port->flags & p_trans) if (!isdcd())
{ cmdtnc(); port->mode = idle; return true; }
return false;
}
/*
* 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, i;
while (deep >= 0)
{
i = 1;
if ((st = fgets(p, 80, ifl[deep])) is NULL)
{
fclose(ifl[deep]);
deep--;
}
else
{
if (*p isnt '@') return st;
if (fopts & fw_pass) return st;
if (*(p+1) is ' ')
{
if (!chktime()) return st;
i = 6;
}
if (deep < (deepmax - 1))
{
strupr(p);
remnl(p);
deep++;
if ((ifl[deep] = fopen(p + i, "r")) is NULL) deep--;
}
}
}
return NULL;
}
/*
* Do some DOS commands.
*/
dofdos()
{
register PORTS *p;
if ((p = findport(cport->opt2)) is NULL) { passlst(); return; }
if (strlen(cport->fld[0]) > 3) if (!chktime()) { passlst(); return; }
if (fopts)
if (!((fopts & fw_one) and (match(fcall, cport->fld[1]))))
{ passlst(); return; }
/*
* Just in case, flush whatever might be currently open.
*/
clnuser();
clnmsg();
clnlog();
while (nxtin(cport->line) isnt NULL)
{
if (iseof(cport->line)) return;
remnl(cport->line);
printf("\nRunning: %s\n", cport->line);
if (system(cport->line)) perror("Error");
}
}
/*
* The entry to fowarding.
*/
fwd()
{
register PORTS *p;
/*
* If no fwd.mb file, then do nothing.
*/
deep = 0;
if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) return;
bldfwd();
script = tmp->scr;
*script = '\0';
while(nxtin(cport->line) isnt NULL)
{
bidok = false;
hidok = false;
ioport(cport);
strupr(cport->line);
parse();
fwdtyp = cport->opt1;
switch (fwdtyp)
{
case 'E':
passlst();
script = tmp->scr;
*script = '\0';
break;
case 'D':
case 'F':
case 'G':
case 'H':
if ((p = chkfwd()) isnt NULL)
{
fopts clrbit fw_tried;
/*
* Save tail of list header for logging.
*/
strcpy(path, cport->line + 6);
remnl(path);
script = tmp->scr;
if (!*script)
{
*script = 'C';
strcpy(script + 1, cport->line + 6);
*(script + strlen(script) + 1) = '\0';
}
dofwd(p);
dorev(p);
distnc();
p->mode = idle;
ioport(cport);
}
script = tmp->scr;
*script = '\0';
break;
case 'P':
dopar();
break;
case '!':
dofdos();
break;
case 'C':
case 'R':
case 'S':
strcpy(script, cport->line);
script += (strlen(cport->line) + 1);
*script = '\0';
break;
default: break;
}
}
/*
* Put us back on the port we were on when we got here.
*/
ioport(cport);
bidok = false;
hidok = false;
}
/*
* A and AI commands.
*/
all_fwd()
{
byte pflg;
port->opt1 = 'X';
putcomd( port->opt1, port->opt2 );
pflg = getp_flag();
putc_flag (pflg);
port->mode = logout;
}
/*
* X and XI commands.
*/
sfwd()
{
register PORTS *p;
/*
* If remote sysop did the command, just remember it for later.
*/
if (port->mode & sysop) { savecmd(); return; }
/*
* Set up parameters for fwd()
*/
fopts = fw_forced;
for (p = porthd; p isnt NULL; p = p->next)
{
p->ec = p->ecuser;
p->flags setbit p_dofwd;
}
if (cport->flds is 2)
{
fopts setbit fw_one;
strncpy (fcall, cport->fld[1], ln_callp);
}
if (cport->opt2 is 'I') fopts setbit fw_anytime;
fwd();
/*
* Reset the port flags.
*/
for (p = porthd; p isnt NULL; p = p->next)
{
p->ec = p->ecmon;
p->flags clrbit p_dofwd;
}
}
/*
* Automatic forwarding.
* Called once each minute when the MailBox is idle.
*/
afwd(curmin)
int curmin;
{
register PORTS *p;
register short anyfwd;
/*
* Mark the ports that should forward at this minute.
*/
fopts = 0;
anyfwd = false;
for (p = porthd; p isnt NULL; p = p->next) if (p->fwdmin is curmin)
{
p->flags setbit p_dofwd;
p->ec = p->ecuser;
anyfwd = true;
}
/*
* If any ports forward at this minute, do the forwarding.
*/
if (anyfwd)
{
setbusy();
alloff(); /* Turn off connects and monitoring */
if (s_flag & s_dv) begin_lock();
readmsg();
readusr();
/*
* Write out mon and calls heard files
*/
clsmon();
/*
* Once a day, do wp and stale
*/
if (!matchn(ufhs->wpdate, l_date, ln_date))
{
port->opt1 = '\0';
port->flds = 1;
dwuser();
stale();
strncpy(ufhs->wpdate, l_date, ln_date);
write_rec(ufl, 0, (char *)ufhs);
}
if (s_flag & s_dv) end_lock();
/*
* Check and see if the mailfile should be compressed
*/
if (s_param & s_unt)
if (!matchn(mfhs->date, l_date, ln_date))
if (unt_hr <= (10 *(l_time[0] - '0') + (l_time[1] - '0')))
{
port->opt2 = 'A';
setunt();
}
fwd();
clnlog();
setfwd();
clsmsg();
clsusr();
allon(); /* Turn on monitoring and connects */
clrbusy();
}
/*
* Reset the port flags.
*/
for (p = porthd; p isnt NULL; p = p->next)
{
p->ec = p->ecmon;
p->flags clrbit p_dofwd;
}
}
/*
* Reverse forwarding.
* Accept messages from the remote MailBox after forwarding to it.
*/
dorev(p)
PORTS *p;
{
ioport(p);
if (fwdtyp is 'G') return;
if (fwdtyp is 'D') return;
if (p->mode & idle)
{
if (fwdtyp is 'F') return;
if (fwdtyp is 'H') if (fopts & fw_tried) return;
cmb();
if (p->mode & idle) return;
}
pcall(fcall, path + 2);
rduser(fcall, p->user);
log ('M', 'F', 'R', path); /* Log start of reverse forward */
if (p->tmode)
{
cmdtnc();
trantnc();
}
while(true)
{
outstr("F>\n");
getln();
if (p->mode & idle) return;
parse();
if (p->opt1 isnt 'S') return;
{
sndmsg();
if (p->mode & gone) return;
addfwd();
}
}
}
/*
* F> command: do reverse forward to logged user.
*/
fwdcmd()
{
register PORTS *p;
register short ok;
/*
* If no fwd.mb file, then do nothing.
*/
p = port;
deep = 0;
if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) { p->mode = forced; return; }
ioport(cport);
/*
* Find the users E, F, G, or H list in the fwd.mb file.
*/
ok = false;
while(!ok and (nxtin(cport->line) isnt NULL))
{
strupr(cport->line);
parse();
fwdtyp = cport->opt1;
switch(fwdtyp)
{
case 'D' :
case 'E' :
case 'F' :
case 'G' :
case 'H' :
pcall(fcall, cport->fld[1]);
ok = matchn(fcall, p->user->call, ln_call);
if (!ok) passlst();
break;
case '!' :
case 'P' :
passlst();
break;
default : ; /* 'C', 'R', 'S' */
}
}
ioport(p);
if (ok)
{
log ('M', 'F', 'S', nullstr); /* Log start of forwarding */
bldfwd();
remnl(cport->line);
strcpy( path, cport->line+6 );
dofwd(p);
log ('M', 'F', 'E', nullstr); /* Log end of forwarding */
}
while (deep >= 0) { fclose(ifl[deep]); deep--; }
if(p->mode is idle) return;
outstr("*** Done.\n");
}
/*
* Pass a sublist in the forwarding file.
*/
passlst()
{
fopts setbit fw_pass;
while (true)
{
if (nxtin(cport->line) is NULL) {fopts clrbit fw_pass; return;}
if (iseof(cport->line)) {fopts clrbit fw_pass; return;}
}
}
/*
* Set tnc parameters.
*/
dopar()
{
register PORTS *p;
if ((p = findport(cport->opt2)) is NULL) { 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 & forced) fopts setbit fw_abort;
if (port->mode & gone) { distnc(); port->mode = idle; }
}
/*
* Eat the remote MailBox prompt.
*/
eat()
{
register char c;
if (fwdtyp is 'D') c = ':'; else c = '>';
while(true) {
getln();
if (!(port->mode & remote)) return;
if (port->line[0] is '[') isbid();
if ((port->mode & remote) and (port->line[strlen(port->line) - 2] is c)) {
return;
}
}
}
/*
* Connect to a remote Mailox.
* Port mode idle at entry.
* On return, port mode is remote if the connect worked, else idle.
*/
cmb()
{
port->flags setbit p_dotmr;
port->mode = remote;
/*
* Execute the connect script.
*/
while(*script)
{
switch (*script++)
{
case 'C' :
contnc(script);
if (port->mode & idle) return;
if (port->dev is p_tnc) do
{
getln();
if (port->mode & idle) return;
}
while (!iscon(port->line));
break;
case 'S' :
outstr(script);
break;
case 'R' :
getln();
if (port->mode & idle) return;
strupr(port->line);
if (*script isnt '!')
if (!search(port->line, script, strlen(script)-1))
{ distnc(); port->mode = idle; return; }
break;
default: ;
}
while(*script++); /* Move to next script line */
}
/*
* In theory, now connected to MailBox. Eat login messge.
*/
eat();
if (!(port->mode & remote)) return;
if (bidok) {
outstr("[CBBS-6.0-H$]\n");
eat();
}
}
/*
* Forward whatever messages go to this MailBox.
*/
dofwd(p)
PORTS *p;
{
register char *st;
st = nxtin(cport->line);
while (!iseof(cport->line) and (st isnt NULL))
{
ioport(cport);
parse();
ioport(p);
pcall (tcall, cport->fld[0]);
if (findfwd(tcall, bfwd, bfwdn))
{
fmsg();
if (fopts & fw_tried) if (p->mode & idle)
{
p->mmhs->stat clrbit m_busy;
wt_mmhs();
passlst();
return;
}
}
st = nxtin(cport->line);
}
}
/*
* Send the message text.
*/
xmtmsg()
{
register FILE *fl;
sprintf(port->line, "%s%u", msgdir, port->mmhs->number);
if ((fl = fopen(port->line, "r")) is NULL) nofile(port->line); else
{
fseek(fl, (long)RECSIZE, 0);
while(fgets(tmp->scr, scrmax, fl) isnt NULL)
{
if (chkdis()) { fclose(fl); return false; }
outstr(tmp->scr);
}
fclose (fl);
}
if (fwdtyp is 'D')
{
outstr(".\n");
outstr("y\n");
}
else
{
outchar (cpmeof);
outchar ('\n');
}
return true;
}
/*
* Forward all messages TO or AT tcall
* to the MailBox we are connected to.
*/
fmsg()
{
char *a, *b, *c;
char hcall[6];
register PORTS *p;
register word h;
register short i, ok, kill, extnr, kok, hasit;
hasit = true; /* just initialize it to something */
p = port;
for (h = mfhs->last; h; h--)
{
if (s_flag & s_dv) begin_lock();
read_rec(mfl, h, (char *)p->mmhs);
ok = (!(p->mmhs->stat & (m_kill | m_read | m_fwd | m_hold | m_busy)));
/*
* Decide whether to forward this one.
*/
if (ok)
{
if (p->mmhs->ext is 1)
{
ok = false;
for (i = 0; !ok and (i < p->mmhs->count); i++) if (p->mmhs->flag[i])
if (wcm(tcall, p->mmhs->call[i])) { ok = true; extnr = i; }
}
else if (*p->mmhs->bbs isnt ' ')
{
ok = wcm(tcall, p->mmhs->bbs);
if (!ok) if (p->mmhs->ext is 2)
{
c = p->mmhs->call[0];
while(!ok and ((c=strchr(c, '.')) isnt NULL))
{
c++;
fill(hcall, ' ', ln_call);
pcall(hcall, c);
ok = wcm(tcall, hcall);
}
}
}
else ok = wcm(tcall, p->mmhs->to);
}
if (ok)
{
p->mmhs->stat setbit m_busy;
wt_mmhs();
}
if (s_flag & s_dv) end_lock();
/*
* If we DO forward this one, forward this one.
*/
if (ok)
{
if (fopts & fw_tiout) { wait (p->ftime); fopts clrbit fw_tiout; }
fopts setbit fw_tried;
if (p->mode & idle) cmb();
if (p->mode & idle) return;
if (fwdtyp is 'D') prtx("mail $G\n");
if (*p->mmhs->bbs is ' ') prtx("S$B $G < $P");
else if((hidok)and(p->mmhs->ext is 2)) prtx("S$B $G @ $h < $P");
else prtx("S$B $G @ $A < $P");
if (bidok) if (*p->mmhs->bid isnt ' ') {
outstr(" $");
a = p->line;
b = p->mmhs->bid;
unbl(a, b, ln_bid);
outstr(p->line);
}
outchar('\n');
getln(); if (p->mode & idle) return;
if (bidok)
{
if(*p->line < ' ') { getln(); if(p->mode & idle) return; }
switch(*p->line)
{
case 'O': hasit = false;
outstr(p->mmhs->title);
outchar('\n'); break;
case 'N': hasit = true; break;
default : p->mmhs->stat clrbit m_busy;
wt_mmhs();
return;
}
}
else
{
hasit = false; /* you'll want to send msg */
outstr(p->mmhs->title); outchar('\n');
if (fwdtyp isnt 'D')
{
getln(); if (p->mode & idle) return;
}
}
if (!hasit)
{
curtim();
if (port->dev is p_tnc) prtx(mm[4]);
if (!xmtmsg()) { fopts setbit fw_tiout; return;}
}
eat(); if (p->mode & idle){ fopts setbit fw_tiout; return; }
/*
* The message actually forwarded.
* Kill it, mark it, or whatever.
*/
sprintf(p->line, "%u %s", p->mmhs->number, path);
log ('M', 'F', ' ', p->line);
kill = false;
kok = false;
/*
* If cc: list exists, mark this call as forwarded.
*/
if (p->mmhs->ext is 1)
{
p->mmhs->flag[extnr] = false;
for (i = 0; i < p->mmhs->count; i++) if (p->mmhs->flag[i]) kok = true;
}
if (!kok)
{
if ((p->mmhs->type is 'F') or (p->mmhs->type is 'B'))
kill = s_param & s_fkill;
else kill = s_param & s_kill;
}
if (kill) p->mmhs->stat setbit m_kill;
else
if (!kok) p->mmhs->stat setbit m_fwd;
p->mmhs->stat clrbit m_busy;
write_rec(mfl, p->mmhs->rn, (char *)p->mmhs);
makehdr2();
}
}
}