home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
packet
/
cbbs60so.arc
/
MBGATE.C
< prev
next >
Wrap
Text File
|
1989-01-26
|
9KB
|
425 lines
/*
* MBGATE.C - 1/26/88 - Gateway routines.
* - by David B. Toth, VE3GYQ
* - if it doesn't work, you can blame it on
* somebody else
*
*/
#include "mb.h"
char *gm[num_gm];
static char *lm = "*** LINKED to $S\n";
PORTS *okport(id)
char id;
{
register PORTS *p;
if ((p = findport(id)) is NULL) { port->msg = mnport; return NULL; }
if (p is port) { port->msg = mcant; return NULL; }
if (p->mode isnt idle) { port->msg = minuse; return NULL; }
return p;
}
/*
* C Command: connect to someone in the user file.
* tcall is passed as the eventual target station, with its
* user record in tuser.
*/
connuser()
{
register PORTS *s;
register short link;
char gatecall[ln_call];
pcall(tcall, port->fld[1]);
if (!rduser(tcall, tuser)) { port->msg = mfind; return; }
/*
* If user linked thru a GateWay, connect to the gateway.
*/
link = false;
if (tuser->port is 'L')
{
if (!*tuser->path) { port->msg = mcant; return; }
pcall(gatecall, tuser->path);
/*
* Read GateWay's call into a user record.
*/
if (!rduser(gatecall, tuser)) { port->msg = mfind; return; }
link = true;
}
if ((s = okport(tuser->port)) is NULL) return;
if (port->mode & remote) if (!(s->priv & p_gate))
{ port->msg = gm[0]; return; }
if (link) rduser(gatecall, s->user); else rduser(tcall, s->user);
/*
* Build the connect line to send to the tnc.
*/
unbl(port->line, tuser->call, ln_call);
if (*tuser->path)
sprintf(tmp->scr, "C %s-%d V %s\n", port->line, tuser->ssid, tuser->path);
else
sprintf(tmp->scr, "C %s-%d\n", port->line, tuser->ssid);
s->ec = s->ecuser;
ctnc(s, link);
s->ec = s->ecmon;
log ('G', 'E', ' ', nullstr);
}
/*
* C Command: make the connection between the master and slave ports
* when the user specifies the port and connect path.
*/
ctncv()
{
register PORTS *s;
if ((s = okport(port->opt2)) is NULL) return;
if (!(s->priv & p_gate)) { port->msg = gm[0]; return; }
pcall(tcall, port->fld[1]);
rduser(tcall, s->user);
if (port->flds > 2)
sprintf(tmp->scr,"C %s V %s\n", port->fld[1], port->fld[3]);
else sprintf(tmp->scr, "C %s\n", port->fld[1]);
s->ec = s->ecuser;
ctnc(s, false);
s->ec = s->ecmon;
log ('G', 'E', ' ', nullstr);
}
ctnc(s, link)
PORTS *s;
short link;
{
register PORTS *m;
int open_gate;
m = port;
m->lport = s;
s->lport = m;
/*
* Send the connect string to the tnc.
*/
s->mode = remote;
ioport(s);
contnc(tmp->scr);
/*
* Tell the user "attempting connect".
*/
ioport(m);
prtx(gm[2]);
/*
* Special case for in-memory link, in case contnc failed.
*/
if (s->mode is idle)
{
m->msg = gm[3];
return;
}
/*
* Wait for the connection.
*/
settmr(&m->expire, 60);
while (chktmr(m->expire))
{
/*
* User wants to give up?
*/
ioport(m);
open_gate = false;
if (instat()) if(getdat()) if (*m->line is ctl_w) open_gate = true;
if (!isdcd()) open_gate = true;
if (open_gate)
{
log ('G', 'A', m->opt2, m->fld[1]);
ioport(s); distnc();
s->mode = idle;
ioport(m);
m->msg = gm[5];
return;
}
/*
* Something from the slave tnc.
*/
ioport(s);
if (instat()) if (getdat())
{
if (isdis(s->line))
{
waitcmd(0);
s->mode = idle;
ioport(m);
log ('G', 'A', m->opt2, m->fld[1]);
m->msg = gm[3];
return;
}
else if (iscon(s->line) or (s->dev is p_serial))
{
log ('G', 'C', m->opt2, m->fld[1]);
if (m isnt cport)
{
ioport(m); prtx(gm[4]); prtx(lm);
ioport(s); wait(10); prtx(lm); /* wait 10 sec. to send msg */
}
if (link)
{
outstr("G\nC "); outnb(tcall, ln_call); outchar('\n');
}
/*
* Special case of connecting
* from the console.
*/
if (m is cport)
{
m->fl = NULL;
term(s);
ioport(s);
tncstate();
if (s->mode is discon)
{
s->mode = idle;
m->lport = cport; s->lport = cport;
ioport(m);
return;
}
else /* just go back to cmd line and leave slave connected */
{
convtnc();
s->mode = idle;
ioport(m);
return;
}
}
else tncslinked(m, s);
ioport(s);
distnc();
s->mode = idle;
m->lport = cport; s->lport = cport;
ioport(m);
return;
}
}
}
/*
* Fall through if timer times out.
*/
ioport(s);
distnc();
s->mode = idle;
ioport(m);
log ('G', 'A', port->opt2, port->fld[1]);
port->msg = gm[3];
}
/*
* M command: Monitor the slave port from the master port.
* return if anything from the master port.
*/
mtncv()
{
register PORTS *m, *s;
register int linecount;
if (port->opt2 is ' ') { shports(); return; }
if ((s = okport(port->opt2)) is NULL) return;
if (!(s->priv & p_mon)) { port->msg = gm[0]; return; }
m = port;
m->lport = s;
s->lport = m;
log ('G', 'M', port->opt2, nullstr);
prtx(gm[6]);
ioport(s);
onecmd(t_mon);
settmr(&s->expire, s->mtime);
linecount = s->mcount;
s->ec = s->ecuser;
while (linecount and chktmr(s->expire))
{
ioport(s);
if (instat()) if (getdat())
{
ioport(m);
outstr(s->line);
linecount--;
}
ioport(m);
if (m->flags & p_trans) if(!isdcd()) linecount = 0;
if (instat()) if (getdat()) linecount = 0;
}
s->ec = s->ecmon;
ioport(s);
onecmd(t_moff);
ioport(m);
m->lport = cport;
s->lport = cport;
log ('G', 'E', ' ', nullstr);
}
/*
* U Command: master port sends unproto frames through the
* selected slave port. Sets slave port CONOK ON to allow a
* connect to occur from the slave port.
*/
utncv()
{
register PORTS *m, *s;
if (port->opt2 is ' ') { shports(); return; }
if ((s = okport (port->opt2)) is NULL) return;
if (!(s->priv & p_mon)) { port->msg = gm[0]; return; }
m = port;
log ('G', 'U', m->opt2, nullstr);
m->lport = s;
s->lport = m;
s->ec = s->ecuser;
utnc (m, s);
s->ec = s->ecmon;
s->mode = idle;
m->lport = cport;
s->lport = cport;
ioport(m);
log ('G', 'E', ' ', nullstr);
}
utnc(m, s)
PORTS *m, *s;
{
prtx(gm[1]);
ioport(s);
onecmd(t_con);
convtnc();
settmr(&m->expire, m->ctime);
while(chktmr(m->expire))
{
if (xtalk(m, s))
{
if ((*m->line is ctl_w) or (m->mode & discon))
{
ioport(s); cmdtnc(); onecmd(t_coff);
return;
}
}
ioport(s);
if (instat())
{
getcmd();
if (iscon(s->line))
{
s->mode = remote;
pcall(tcall, port->fld[3]);
rduser(tcall, s->user);
ioport(m); prtx(lm); ioport(s); prtx(lm);
tncslinked(m, s);
ioport(s); cmdtnc(); onecmd(t_coff);
return;
}
}
}
m->mode = timeout;
}
/*
* xtalk: handles the cross-connection of data between tncs.
* fails with loss of tnc on either side ... lets calling fn
* clean up the tncs.
*/
xtalk(pf, pt)
PORTS *pf, *pt;
{
ioport(pf);
if (instat()) if (getdat())
{
if (!(pf->mode & discon)) if (!isdis(pf->line) and (*pf->line isnt ctl_w))
{ ioport(pt); outstr(pf->line); }
return true;
}
if (pf->flags & p_trans)
if (!isdcd())
{
pf->mode = discon;
return true;
}
return false;
}
/*
* tncslinked: always disconnects slave and sets it to idle before
* returning ... lets calling routine take care of master port
*/
tncslinked(m, s)
PORTS *m, *s;
{
settmr(&m->expire, m->ctime);
while(chktmr(m->expire))
{
if (xtalk(s, m))
{
if (s->mode & discon)
{
ioport(s); cmdtnc(); s->mode = idle; return;
}
else
{
settmr(&m->expire, m->ctime);
}
}
if (xtalk(m, s))
{
if ((m->mode & discon) or (*m->line is ctl_w))
{
ioport(s); distnc(); s->mode=idle; return;
}
else
{
settmr(&m->expire, m->ctime);
}
}
}
/*
* On timeout, fall thru, let caller say timeout and dump user.
*/
ioport(s); distnc(); s->mode = idle;
ioport(m); m->mode = timeout;
}