home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * DNET.C
- *
- * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
- */
-
- #include "dnet.h"
- #include <local/deemu.h>
- #include <local/ipc.h>
-
- short Deemu[] = {
- DMSTRT, 0, 0,
- DMNW , 0,10, 50, 50, 320, 100, 0xFFFF,
- DMEND , 0, 0
- };
-
-
- extern int Enable_Abort;
- long DResBase;
- char PortName[sizeof(DNETPORTNAME)+32];
-
- main(ac,av)
- char *av[];
- {
- long sink_mask, dnet_mask, ipc_mask;
- long baud = 0;
- char *netdevice = "serial.device";
- long netunit = 0;
- char *autoclient = "FTERM";
-
- unlink("ENV:DNET_NORUNCLIENT");
- Enable_Abort = 0;
- bzero(Pkts,sizeof(Pkts));
- if ((DResBase = (long)OpenLibrary("dres.library", 0)) == NULL) {
- puts("Unable to open DRES.LIBRARY");
- exit(1);
- }
- ac = DoOption(ac, av, "p,b%ld,d%d,n%s,s%s,a,h%d,U%ld,D%s,N%d,8X%d,B%ld",
- &PDebug, &baud, &DDebug, &HostName, &autoclient, &AutoAnswer,
- &AutoHangup, &netunit, &netdevice, &NetworkNum, &Master8, &DialOut,
- &TOBaud
- );
- if (ac < 0) {
- puts("Unknown option, valid options:\n");
- puts("dnet -pb#B#d#n<hostname>s<autorunclient>aU#D<device>N<netid>8");
- dneterror("Unknown switch");
- }
- if (AutoAnswer) {
- AutoHangup = 1;
- DialOut = 0;
- }
- sprintf(PortName, "%s%d", DNETPORTNAME, NetworkNum);
- {
- PORT *port;
- if (port = (PORT *)FindPort(PortName)) {
- puts("DNET: Network number in use");
- CloseLibrary(DResBase);
- exit(1);
- }
- }
- DNetPort = (PORT *)CreatePort(PortName, 0);
- IOSink = (PORT *)CreatePort(NULL,0);
- IPCPort = (PORT *)OpenIPC("dnet.CMD", 0);
- if (!DNetPort || !IOSink)
- dneterror("CreatePort");
-
- NewList(&TxList);
- NewList(&SvList);
- Rto_act = Wto_act = Cto_act = 0;
- NetOpen(IOSink, netdevice, netunit, &baud);
- TimerOpen(&Rto, IOSink);
- TimerOpen(&Wto, IOSink);
- TimerOpen(&Cto, IOSink);
-
- if (TOBaud)
- SetTimeouts(TOBaud);
- else
- SetTimeouts(Baud);
-
- NetStartRead(&Raux->sync, 3);
-
- do_dnetwindow(baud);
- if (Quit)
- 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;
- Cto.tr_node.io_Message.mn_Node.ln_Name = (char *)CTO_REQ;
-
- sink_mask = 1 << IOSink->mp_SigBit;
- dnet_mask = 1 << DNetPort->mp_SigBit;
- ipc_mask = 1 << IPCPort->mp_SigBit;
-
- do_netreset();
- loop:
- if (strcmp(autoclient, "-") != 0) {
- char buf[64];
- char *tmp;
-
- if ((tmp = GetDEnv("DNET_NORUNCLIENT")) == NULL) {
- sprintf(buf, "RUN <NIL: >NIL: %s -N%ld", autoclient, NetworkNum);
- if (Execute(buf, NULL, NULL) == 0) {
- puts("Unable to RUN FTERM (path not setup?)");
- puts("You can do it yourself");
- }
- } else {
- free(tmp);
- }
- }
- NetWrite(RestartPkt, 3, 1);
- Restart = 1;
- OnLine = 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().
- */
-
- /*
- * Immediate return from initial Wait() ... due to looping it is
- * possible one or more requests is ready but the signal bit has
- * already been cleared.
- */
-
- Signal(FindTask(NULL), ipc_mask|sink_mask|dnet_mask);
-
- while (!Quit && OnLine) {
- long mask = Wait(ipc_mask|sink_mask|dnet_mask|SIGBREAKF_CTRL_C);
-
- if (mask & ipc_mask)
- handle_ipc();
-
- 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 CTO_REQ: /* Only when line idle */
- Cto_act = 0;
- do_cto(ior);
- if (Cd == 0 && AutoHangup)
- OnLine = 0;
- 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 */
- NetReadReturned();
- do_rnet(ior);
- if (Cd == 0 && AutoHangup)
- OnLine = 0;
- 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);
- 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;
- }
- 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;
- }
- 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);
- }
- break;
- case DNCMD_QUIT:
- {
- char dummy;
-
- WriteStream(SCMD_QUIT, &dummy, 1, -1);
- }
- break;
- case DNCMD_INFO:
- {
- char *ptr = (char *)ior->io_Data;
- sprintf(ptr, " Bytes Packets Errors\n");
- ptr += strlen(ptr);
- sprintf(ptr, "OUT: %8ld %8ld %8ld\n", BytesOut, PacketsOut, PacketsResent);
- ptr += strlen(ptr);
- sprintf(ptr, "IN : %8ld %8ld %8ld\n", BytesIn, PacketsIn, PacketsNakd);
- ptr += strlen(ptr);
- sprintf(ptr, "Garbage Bytes In: %ld\n", GarbageIn);
- }
- 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;
- }
- 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;
- }
- }
- break;
- }
- if (ior)
- ReplyMsg(ior);
- }
- }
- if (mask & SIGBREAKF_CTRL_C)
- OnLine = 0;
- do_wupdate();
- }
- do_netreset();
- if (!Cd) {
- ResetConnect();
- ResetIdle();
- }
- if (!Quit)
- do_dnetwindow(baud);
- if (!Cd) {
- ResetConnect();
- ResetIdle();
- }
- if (!Quit)
- 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;
- if (!Cto_act) {
- Cto.tr_time.tv_secs = 1;
- Cto.tr_time.tv_micro= 0;
- SendIO(&Cto);
- Cto_act = 1;
- }
- }
-
-