home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
142.lha
/
DNet
/
dnet
/
dnet.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-21
|
9KB
|
369 lines
/*
* DNET.C
*
* DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
*
* V <1.05 Alpha Release
* V <1.10 Beta Release (Internal)
* V1.10 First Release
*/
#include "dnet.h"
extern int Enable_Abort;
main(ac,av)
char *av[];
{
long sink_mask, dnet_mask;
long baud = 0;
short networknum = 0;
char *netdevice = "serial.device";
long netunit = 0;
ubyte notdone;
ubyte autofterm = 1;
char buf[sizeof(DNETPORTNAME)+32];
Enable_Abort = 0;
bzero(Pkts,sizeof(Pkts));
{
register short i;
register char *ptr;
for (i = 1; i < ac; ++i) {
if (*(ptr = av[i]) == '-') {
while (*++ptr) {
switch(*ptr) {
case 'b':
baud = atoi(ptr+1);
ptr = "\0\0";
break;
case 'd':
DDebug = 1;
puts("Debugger on");
break;
case 'n':
HostName = ptr+1;
ptr = "\0\0";
break;
case 's':
autofterm = 0;
break;
case 'h':
AutoHangup = 1;
break;
case 'U':
netunit = atoi(ptr+1);
ptr = "\0\0";
break;
case 'D':
netdevice = ptr + 1;
ptr = "\0\0";
break;
case 'N':
networknum = atoi(ptr+1);
ptr = "\0\0";
break;
default:
printf("Unknown option: %c\n", *ptr);
dneterror("Unknown switch");
break; /* not reached */
}
}
}
}
}
sprintf(buf, "%s%d", DNETPORTNAME, networknum);
{
PORT *port;
if (port = (PORT *)FindPort(buf)) {
puts("DNET: Network number in use");
exit(1);
}
}
DNetPort = (PORT *)CreatePort(buf, 0);
IOSink = (PORT *)CreatePort(NULL,0);
if (!DNetPort || !IOSink)
dneterror("CreatePort");
NewList(&TxList);
NewList(&SvList);
Rto_act = Wto_act = 0;
NetOpen(&RNet,&WNet, IOSink, netdevice, netunit, baud);
TimerOpen(&Rto, IOSink);
TimerOpen(&Wto, IOSink);
WTimeoutVal = ((MAXPKT * 2) * 1000 / (Baud / 10 + 1));
RTimeoutVal = ((MAXPKT + 50) * 1000 / (Baud / 10 + 1));
WTimeoutVal *= 1000;
RTimeoutVal *= 1000;
RNet->io_Data = (APTR)&Raux->sync; /* Startup the network read */
RNet->io_Length = 3;
SendIO(RNet);
if (do_dnetwindow() < 0)
dneterror(NULL);
Rto.tr_node.io_Message.mn_Node.ln_Name = (char *)RTO_REQ;
Wto.tr_node.io_Message.mn_Node.ln_Name = (char *)WTO_REQ;
sink_mask = 1 << IOSink->mp_SigBit;
dnet_mask = 1 << DNetPort->mp_SigBit;
do_netreset();
loop:
if (autofterm) {
char buf[32];
sprintf(buf, "RUN <NIL: >NIL: FTERM -N%ld", networknum);
if (Execute(buf, NULL, NULL) == 0) {
puts("Unable to RUN FTERM (path not setup?)");
puts("You can do it yourself");
}
}
NetWrite(RestartPkt, 3, 1);
Restart = 1;
/*
* NOTE: Routines must be particularly careful not to clear the
* signal mask unless it doesn't matter. Specifically,
* routines in the dnet_mask section cannot arbitrarily
* clear the signal associated with the sink_mask section.
*
* If you look at NetWrite(), you will note that the signal
* is restored if it must do a WaitIO().
*/
notdone = 1;
while (notdone) {
long mask = Wait(sink_mask|dnet_mask|SIGBREAKF_CTRL_C);
if (mask & sink_mask) { /* IOSink returns */
register IOR *ior;
while (ior = (IOR *)GetMsg(IOSink)) {
switch((long)ior->io_Message.mn_Node.ln_Name) {
case PKT_REQ:
--NumCon;
if (ior->io_Length)
FreeMem(ior->io_Data, ior->io_Length);
FreeMem(ior, sizeof(IOR));
break;
case RTO_REQ: /* Read timeout, reset READ state */
Rto_act = 0;
do_rto(ior);
break;
case WTO_REQ: /* Write-Ack timeout, send CHECK */
Wto_act = 0;
do_wto(ior);
break;
case RNET_REQ: /* Receive data ready, interpret */
if (do_rnet(ior) < 0 && AutoHangup) /* handle receive data */
notdone = 0;
SendIO(ior); /* restart receive */
break;
case WNET_REQ: /* Write data sent, start WTO */
NetClWrite(ior);
do_wnet(ior);
break;
case IGWNET_REQ:
NetClWrite(ior);
break;
}
}
}
if (mask & dnet_mask) { /* Receive commands */
register IOR *ior;
while (ior = (IOR *)GetMsg(DNetPort)) {
ior->io_Actual = 0;
switch(ior->io_Command) {
case DNCMD_WRITE: /* write data to net */
{
uword chan = (ulong)ior->io_Unit;
if (Chan[chan].state != CHAN_OPEN) {
ior->io_Error = 1;
break;
}
ior->io_Error = 0;
ior->io_Command = SCMD_DATA;
ior->io_Message.mn_Node.ln_Pri = Chan[chan].pri;
Enqueue(&TxList, ior);
do_wupdate();
ior = NULL;
}
break;
case DNCMD_SOPEN: /* Reply from server port on remote */
/* open request */
{
CACKCMD ack;
uword chan = (ulong)ior->io_Unit;
ack.chanh = chan >> 8;
ack.chanl = chan;
ack.error = ior->io_Error;
WriteStream(SCMD_ACKCMD, &ack, sizeof(ack), chan);
if (ack.error) {
Chan[chan].state = CHAN_FREE;
--NumCon;
} else {
if (Chan[chan].state == CHAN_CLOSE && !ack.error) {
WritePort(Chan[chan].port, DNCMD_CLOSE, NULL, 0, PKT_REQ, chan);
goto sopenbrk;
}
Chan[chan].state = CHAN_OPEN;
Chan[chan].port = (PORT *)ior->io_Offset;
Chan[chan].flags = CHANF_ROK|CHANF_WOK;
}
do_wupdate();
sopenbrk:
if (ior->io_Length)
FreeMem(ior->io_Data, ior->io_Length);
FreeMem(ior, sizeof(IOR));
ior = NULL;
}
break;
case DNCMD_EOF:
{
CEOFCMD eof;
uword chan = (ulong)ior->io_Unit;
ior->io_Error = 0;
eof.chanh = chan >> 8;
eof.chanl = chan;
eof.flags = CHANF_ROK;
WriteStream(SCMD_EOFCMD, &eof, sizeof(CEOFCMD), chan);
Chan[chan].flags &= ~CHANF_WOK;
do_wupdate();
}
break;
case DNCMD_IOCTL:
{
CIOCTL cio;
uword chan = (ulong)ior->io_Unit;
ior->io_Error = 0;
cio.chanh = chan >> 8;
cio.chanl = chan;
cio.valh = (ubyte)((ulong)ior->io_Data >> 24);
cio.vall = (ubyte)((ulong)ior->io_Data >> 16);
cio.valaux = (ubyte)((ulong)ior->io_Data >> 8);
cio.cmd = (ubyte)(ulong)ior->io_Data;
WriteStream(SCMD_IOCTL, &cio, sizeof(CIOCTL), chan);
do_wupdate();
}
break;
case DNCMD_QUIT:
{
char dummy;
DeldQuit = 1;
WriteStream(SCMD_QUIT, &dummy, 1, -1);
do_wupdate();
}
break;
case DNCMD_OPEN:
ior->io_Error = 0;
{
uword chan = alloc_channel();
COPEN co;
if (chan >= MAXCHAN) {
ior->io_Error = 1;
break;
}
co.chanh = chan >> 8;
co.chanl = chan;
co.porth = (ulong)ior->io_Unit >> 8; /* port # */
co.portl = (ulong)ior->io_Unit;
co.error= 0;
co.pri = (char)(long)ior->io_Message.mn_Node.ln_Name;
Chan[chan].ior = ior;
Chan[chan].port= (PORT *)ior->io_Offset;
Chan[chan].state = CHAN_LOPEN;
Chan[chan].flags = 0;
Chan[chan].pri = ior->io_Message.mn_Node.ln_Pri;
WriteStream(SCMD_OPEN, &co, sizeof(COPEN), chan);
ior = NULL;
do_wupdate();
}
break;
case DNCMD_CLOSE: /* same io_Command for CCTL_? */
ior->io_Error = 0;
{
CCLOSE cc;
uword chan = (ulong)ior->io_Unit;
cc.chanh = chan >> 8;
cc.chanl = chan;
WriteStream(SCMD_CLOSE, &cc, sizeof(CCLOSE), chan);
Chan[chan].ior = ior;
Chan[chan].state = CHAN_CLOSE;
Chan[chan].flags |= CHANF_LCLOSE;
if (Chan[chan].flags & CHANF_RCLOSE) {
Chan[chan].state = CHAN_FREE;
Chan[chan].ior = NULL;
} else {
ior = NULL;
}
do_wupdate();
}
break;
}
if (ior)
ReplyMsg(ior);
}
}
if (mask & SIGBREAKF_CTRL_C)
notdone = 0;
}
do_netreset();
if (do_dnetwindow() > 0)
goto loop;
dneterror(NULL);
}
do_netreset()
{
register short i;
register CHAN *ch;
register IOR *ior;
while (ior = RemHead(&TxList)) {
ior->io_Error = 1;
ReplyMsg(ior);
}
for (i = 0, ch = Chan; i < MAXCHAN; ++i, ++ch) {
switch(ch->state) {
case CHAN_OPEN:
WritePort(Chan[i].port, DNCMD_CLOSE, NULL, 0, PKT_REQ, i);
case CHAN_ROPEN: /* pending on listen port */
ch->state = CHAN_CLOSE;
ch->flags = CHANF_RCLOSE;
ch->ior = NULL;
break;
case CHAN_LOPEN: /* pending on network */
ch->ior->io_Error = 1;
ReplyMsg(ch->ior);
ch->ior = NULL;
ch->state = CHAN_FREE;
ch->flags = 0;
--NumCon;
break;
case CHAN_CLOSE:
if (!(ch->flags & CHANF_LCLOSE))
break;
ch->ior->io_Error = 1;
ReplyMsg(ch->ior);
ch->ior = NULL;
ch->state = CHAN_FREE;
ch->flags = 0;
--NumCon;
}
}
RPStart = 0;
WPStart = 0;
WPUsed = 0;
RState = 0;
RChan = 0;
WChan = 0;
}