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>
-
- void do_netreset();
- char *GetDEnv();
-
- 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];
-
- #ifdef LATTICE
-
- int __stdargs CXBRK(void); /* get around a bug in lcr.lib : onbreak() */
-
- int __stdargs
- CXBRK(void)
- {
- return(0);
- }
-
- #endif
-
- void main ARGS((int, char **));
-
- void
- main(ac,av)
- int ac;
- char *av[];
- {
- long sink_mask, dnet_mask/*, ipc_mask*/;
- long baud = 0;
- char *netdevice = "serial.device";
- long netunit = 0;
- char *autoclient = "FTERM";
- short i;
-
- unlink("ENV:DNET_NORUNCLIENT");
- #ifndef LATTICE
- Enable_Abort = 0;
- #endif
- BZero(Pkts,sizeof(Pkts));
- InitServers();
-
- for (i = 1; i < ac; ++i) {
- if (strcmp(av[i], "-Getty") == 0) {
- Getty = 1;
- AutoHangup = 1;
- av[i] = "";
- }
- if (strcmp(av[i], "-DEVICE") == 0) {
- netdevice = av[i + 1];
- av[i] = "";
- av[i+1] = "";
- }
- if (strcmp(av[i], "-UNIT") == 0) {
- netunit = atoi(av[i+1]);
- av[i] = "";
- av[i+1] = "";
- }
- }
-
- ac = DoOption(ac, av, "p,m%d,b%ld,d%d,n%s,s%s,a,h%d,U%ld,D%s,N%d,8X%d,B%ld,P%d",
- &PDebug, &Mode7, &baud, &DDebug, &HostName, &autoclient, &AutoAnswer,
- &AutoHangup, &netunit, &netdevice, &NetworkNum, &Master8, &DialOut,
- &TOBaud, &Protocol
- );
- 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((LIST *)&TxList);
- 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(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) {
- FILE *fi = fopen("T:dscr", "w");
- if (fi) {
- fprintf(fi, "Wait 5\n");
- fprintf(fi, "%s -N%ld\n", autoclient, NetworkNum);
- fclose(fi);
- Execute("RUN <NIL: >NIL: execute T:dscr", NULL, NULL);
- }
- }
-
- WriteRestart();
- 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 */
- IOSTD *ior;
- while (ior = (IOSTD *)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(IOSTD));
- break;
- case CTO_REQ: /* Only when line idle */
- Cto_act = 0;
- do_cto((IOT *)ior);
- if (Cd == 0 && AutoHangup)
- OnLine = 0;
- break;
- case RTO_REQ: /* Read timeout, reset READ state */
- Rto_act = 0;
- do_rto((IOT *)ior);
- break;
- case WTO_REQ: /* Write-Ack timeout, send CHECK */
- Wto_act = 0;
- do_wto((IOT *)ior);
- break;
- case RNET_REQ: /* Receive data ready, interpret */
- {
- char *ptr;
- long bytes = NetReadReturned(&ptr);
- do_rnet(ptr, bytes);
- }
- if (Cd == 0 && AutoHangup)
- OnLine = 0;
- break;
- case WNET_REQ:
- NetClWrite((IOSER *)ior);
- break;
- }
- }
- }
- if (mask & dnet_mask) { /* Receive commands */
- IOSTD *ior;
- while (ior = (IOSTD *)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, (NODE *)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(IOSTD));
- 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, (uword)-1);
- }
- break;
- case DNCMD_INFO:
- {
- char *ptr = (char *)ior->io_Data;
- sprintf(ptr, " Bytes Packets Errors\n"
- "OUT: %8ld %8ld %8ld\n"
- "IN : %8ld %8ld %8ld\n"
- "Garbage Bytes In: %ld\n\n"
- " 6-expn 7-comp 8-bin\n"
- "Packet Breakdown Send: %8ld %8ld %8ld\n"
- "Packet Breakdown Recv: %8ld %8ld %8ld\n",
-
- BytesOut, PacketsOut, PacketsResent,
- BytesIn, PacketsIn, PacketsNakd,
- GarbageIn,
- Packets6Out, Packets7Out, Packets8Out,
- Packets6In, Packets7In, Packets8In
- );
- }
- 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;
- case DNCMD_EXEC:
- Execute((char *)ior->io_Offset, NULL, NULL);
- break;
- }
- if (ior)
- ReplyMsg((MSG *)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);
- }
-
- void
- do_netreset()
- {
- short i;
- CHAN *ch;
- IOSTD *ior;
-
- while (ior = (IOSTD *)RemHead((LIST *)&TxList)) {
- ior->io_Error = 1;
- ReplyMsg((MSG *)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((MSG *)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((MSG *)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((IOR *)&Cto);
- Cto_act = 1;
- }
- }
-
-