home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d145 / dnet.lha / Dnet / amiga / dnet / dnet.c < prev    next >
C/C++ Source or Header  |  1988-05-26  |  9KB  |  369 lines

  1.  
  2. /*
  3.  *  DNET.C
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  V <1.05 Alpha Release
  8.  *  V <1.10 Beta  Release (Internal)
  9.  *  V1.10   First Release
  10.  */
  11.  
  12. #include "dnet.h"
  13.  
  14. extern int Enable_Abort;
  15.  
  16. main(ac,av)
  17. char *av[];
  18. {
  19.     long sink_mask, dnet_mask;
  20.     long baud = 0;
  21.     short networknum = 0;
  22.     char *netdevice = "serial.device";
  23.     long netunit = 0;
  24.     ubyte notdone;
  25.     ubyte autofterm = 1;
  26.     char buf[sizeof(DNETPORTNAME)+32];
  27.  
  28.     Enable_Abort = 0;
  29.     bzero(Pkts,sizeof(Pkts));
  30.     {
  31.     register short i;
  32.     register char *ptr;
  33.     for (i = 1; i < ac; ++i) {
  34.         if (*(ptr = av[i]) == '-') {
  35.         while (*++ptr) {
  36.             switch(*ptr) {
  37.             case 'b':
  38.             baud = atoi(ptr+1);
  39.             ptr = "\0\0";
  40.             break;
  41.             case 'd':
  42.             DDebug = 1;
  43.             puts("Debugger on");
  44.             break;
  45.             case 'n':
  46.             HostName = ptr+1;
  47.             ptr = "\0\0";
  48.             break;
  49.             case 's':
  50.             autofterm = 0;
  51.             break;
  52.             case 'h':
  53.             AutoHangup = 1;
  54.             break;
  55.             case 'U':
  56.             netunit = atoi(ptr+1);
  57.             ptr = "\0\0";
  58.             break;
  59.             case 'D':
  60.             netdevice = ptr + 1;
  61.             ptr = "\0\0";
  62.             break;
  63.             case 'N':
  64.             networknum = atoi(ptr+1);
  65.             ptr = "\0\0";
  66.             break;
  67.             default:
  68.             printf("Unknown option: %c\n", *ptr);
  69.             dneterror("Unknown switch");
  70.             break;    /*  not reached */
  71.             }
  72.         }
  73.         }
  74.     }
  75.     }
  76.     sprintf(buf, "%s%d", DNETPORTNAME, networknum);
  77.     {
  78.     PORT *port;
  79.     if (port = (PORT *)FindPort(buf)) {
  80.         puts("DNET: Network number in use");
  81.         exit(1);
  82.     }
  83.     }
  84.     DNetPort = (PORT *)CreatePort(buf, 0);
  85.     IOSink   = (PORT *)CreatePort(NULL,0);
  86.     if (!DNetPort || !IOSink)
  87.     dneterror("CreatePort");
  88.     NewList(&TxList);
  89.     NewList(&SvList);
  90.     Rto_act = Wto_act = 0;
  91.     NetOpen(&RNet,&WNet, IOSink, netdevice, netunit, baud);
  92.     TimerOpen(&Rto, IOSink);
  93.     TimerOpen(&Wto, IOSink);
  94.  
  95.     WTimeoutVal = ((MAXPKT * 2) * 1000 / (Baud / 10 + 1));
  96.     RTimeoutVal = ((MAXPKT + 50) * 1000 / (Baud / 10 + 1));
  97.     WTimeoutVal *= 1000;
  98.     RTimeoutVal *= 1000;
  99.  
  100.     RNet->io_Data   = (APTR)&Raux->sync; /*  Startup the network read    */
  101.     RNet->io_Length = 3;
  102.     SendIO(RNet);
  103.  
  104.     if (do_dnetwindow() < 0)
  105.     dneterror(NULL);
  106.     Rto.tr_node.io_Message.mn_Node.ln_Name = (char *)RTO_REQ;
  107.     Wto.tr_node.io_Message.mn_Node.ln_Name = (char *)WTO_REQ;
  108.  
  109.     sink_mask = 1 << IOSink->mp_SigBit;
  110.     dnet_mask = 1 << DNetPort->mp_SigBit;
  111.  
  112.     do_netreset();
  113. loop:
  114.     if (autofterm) {
  115.     char buf[32];
  116.     sprintf(buf, "RUN <NIL: >NIL: FTERM -N%ld", networknum);
  117.     if (Execute(buf, NULL, NULL) == 0) {
  118.         puts("Unable to RUN FTERM (path not setup?)");
  119.         puts("You can do it yourself");
  120.     }
  121.     }
  122.     NetWrite(RestartPkt, 3, 1);
  123.     Restart = 1;
  124.  
  125.     /*
  126.      *    NOTE:    Routines must be particularly careful not to clear the
  127.      *        signal mask unless it doesn't matter.  Specifically,
  128.      *        routines in the dnet_mask section cannot arbitrarily
  129.      *        clear the signal associated with the sink_mask section.
  130.      *
  131.      *        If you look at NetWrite(), you will note that the signal
  132.      *        is restored if it must do a WaitIO().
  133.      */
  134.  
  135.     notdone = 1;
  136.     while (notdone) {
  137.     long mask = Wait(sink_mask|dnet_mask|SIGBREAKF_CTRL_C);
  138.     if (mask & sink_mask) {     /*  IOSink returns      */
  139.         register IOR *ior;
  140.         while (ior = (IOR *)GetMsg(IOSink)) {
  141.         switch((long)ior->io_Message.mn_Node.ln_Name) {
  142.         case PKT_REQ:
  143.             --NumCon;
  144.             if (ior->io_Length)
  145.             FreeMem(ior->io_Data, ior->io_Length);
  146.             FreeMem(ior, sizeof(IOR));
  147.             break;
  148.         case RTO_REQ:    /*  Read timeout, reset READ state  */
  149.             Rto_act = 0;
  150.             do_rto(ior);
  151.             break;
  152.         case WTO_REQ:    /*  Write-Ack timeout, send CHECK   */
  153.             Wto_act = 0;
  154.             do_wto(ior);
  155.             break;
  156.         case RNET_REQ:    /*  Receive data ready, interpret   */
  157.             if (do_rnet(ior) < 0 && AutoHangup) /*  handle receive data */
  158.             notdone = 0;
  159.             SendIO(ior);            /*  restart receive     */
  160.             break;
  161.         case WNET_REQ:    /*  Write data sent, start WTO        */
  162.             NetClWrite(ior);
  163.             do_wnet(ior);
  164.             break;
  165.         case IGWNET_REQ:
  166.             NetClWrite(ior);
  167.             break;
  168.         }
  169.         }
  170.     }
  171.     if (mask & dnet_mask) {     /*  Receive commands    */
  172.         register IOR *ior;
  173.         while (ior = (IOR *)GetMsg(DNetPort)) {
  174.         ior->io_Actual = 0;
  175.         switch(ior->io_Command) {
  176.         case DNCMD_WRITE:    /*  write data to net        */
  177.             {
  178.             uword chan = (ulong)ior->io_Unit;
  179.             if (Chan[chan].state != CHAN_OPEN) {
  180.                 ior->io_Error = 1;
  181.                 break;
  182.             }
  183.             ior->io_Error = 0;
  184.             ior->io_Command = SCMD_DATA;
  185.             ior->io_Message.mn_Node.ln_Pri = Chan[chan].pri;
  186.             Enqueue(&TxList, ior);
  187.             do_wupdate();
  188.             ior = NULL;
  189.             }
  190.             break;
  191.         case DNCMD_SOPEN:   /*    Reply from server port on remote    */
  192.                     /*    open request                */
  193.             {
  194.             CACKCMD ack;
  195.             uword chan = (ulong)ior->io_Unit;
  196.  
  197.  
  198.             ack.chanh = chan >> 8;
  199.             ack.chanl = chan;
  200.             ack.error = ior->io_Error;
  201.             WriteStream(SCMD_ACKCMD, &ack, sizeof(ack), chan);
  202.             if (ack.error) {
  203.                 Chan[chan].state = CHAN_FREE;
  204.                 --NumCon;
  205.             } else {
  206.                 if (Chan[chan].state == CHAN_CLOSE && !ack.error) {
  207.                 WritePort(Chan[chan].port, DNCMD_CLOSE, NULL, 0, PKT_REQ, chan);
  208.                 goto sopenbrk;
  209.                 }
  210.                 Chan[chan].state = CHAN_OPEN;
  211.                 Chan[chan].port  = (PORT *)ior->io_Offset;
  212.                 Chan[chan].flags = CHANF_ROK|CHANF_WOK;
  213.             }
  214.             do_wupdate();
  215. sopenbrk:
  216.             if (ior->io_Length)
  217.                 FreeMem(ior->io_Data, ior->io_Length);
  218.             FreeMem(ior, sizeof(IOR));
  219.             ior = NULL;
  220.             }
  221.             break;
  222.         case DNCMD_EOF:
  223.             {
  224.             CEOFCMD eof;
  225.             uword chan = (ulong)ior->io_Unit;
  226.  
  227.             ior->io_Error = 0;
  228.             eof.chanh = chan >> 8;
  229.             eof.chanl = chan;
  230.             eof.flags = CHANF_ROK;
  231.             WriteStream(SCMD_EOFCMD, &eof, sizeof(CEOFCMD), chan);
  232.             Chan[chan].flags &= ~CHANF_WOK;
  233.             do_wupdate();
  234.             }
  235.             break;
  236.         case DNCMD_IOCTL:
  237.             {
  238.             CIOCTL cio;
  239.             uword chan = (ulong)ior->io_Unit;
  240.  
  241.             ior->io_Error = 0;
  242.             cio.chanh = chan >> 8;
  243.             cio.chanl = chan;
  244.             cio.valh   = (ubyte)((ulong)ior->io_Data >> 24);
  245.             cio.vall   = (ubyte)((ulong)ior->io_Data >> 16);
  246.             cio.valaux = (ubyte)((ulong)ior->io_Data >> 8);
  247.             cio.cmd = (ubyte)(ulong)ior->io_Data;
  248.             WriteStream(SCMD_IOCTL, &cio, sizeof(CIOCTL), chan);
  249.             do_wupdate();
  250.             }
  251.             break;
  252.         case DNCMD_QUIT:
  253.             {
  254.             char dummy;
  255.  
  256.             DeldQuit = 1;
  257.             WriteStream(SCMD_QUIT, &dummy, 1, -1);
  258.             do_wupdate();
  259.             }
  260.             break;
  261.         case DNCMD_OPEN:
  262.             ior->io_Error = 0;
  263.             {
  264.             uword chan = alloc_channel();
  265.             COPEN co;
  266.             if (chan >= MAXCHAN) {
  267.                 ior->io_Error = 1;
  268.                 break;
  269.             }
  270.             co.chanh = chan >> 8;
  271.             co.chanl = chan;
  272.             co.porth = (ulong)ior->io_Unit >> 8;  /* port #   */
  273.             co.portl = (ulong)ior->io_Unit;
  274.             co.error= 0;
  275.             co.pri = (char)(long)ior->io_Message.mn_Node.ln_Name;
  276.             Chan[chan].ior = ior;
  277.             Chan[chan].port= (PORT *)ior->io_Offset;
  278.             Chan[chan].state = CHAN_LOPEN;
  279.             Chan[chan].flags = 0;
  280.             Chan[chan].pri = ior->io_Message.mn_Node.ln_Pri;
  281.             WriteStream(SCMD_OPEN, &co, sizeof(COPEN), chan);
  282.             ior = NULL;
  283.             do_wupdate();
  284.             }
  285.             break;
  286.         case DNCMD_CLOSE:    /*  same io_Command for CCTL_?    */
  287.             ior->io_Error = 0;
  288.             {
  289.             CCLOSE cc;
  290.             uword chan = (ulong)ior->io_Unit;
  291.  
  292.             cc.chanh = chan >> 8;
  293.             cc.chanl = chan;
  294.             WriteStream(SCMD_CLOSE, &cc, sizeof(CCLOSE), chan);
  295.             Chan[chan].ior = ior;
  296.             Chan[chan].state = CHAN_CLOSE;
  297.             Chan[chan].flags |= CHANF_LCLOSE;
  298.             if (Chan[chan].flags & CHANF_RCLOSE) {
  299.                 Chan[chan].state = CHAN_FREE;
  300.                 Chan[chan].ior = NULL;
  301.             } else {
  302.                 ior = NULL;
  303.             }
  304.             do_wupdate();
  305.             }
  306.             break;
  307.         }
  308.         if (ior)
  309.             ReplyMsg(ior);
  310.         }
  311.     }
  312.     if (mask & SIGBREAKF_CTRL_C)
  313.         notdone = 0;
  314.     }
  315.     do_netreset();
  316.     if (do_dnetwindow() > 0)
  317.     goto loop;
  318.     dneterror(NULL);
  319. }
  320.  
  321. do_netreset()
  322. {
  323.     register short i;
  324.     register CHAN *ch;
  325.     register IOR *ior;
  326.  
  327.     while (ior = RemHead(&TxList)) {
  328.     ior->io_Error = 1;
  329.     ReplyMsg(ior);
  330.     }
  331.     for (i = 0, ch = Chan; i < MAXCHAN; ++i, ++ch) {
  332.     switch(ch->state) {
  333.     case CHAN_OPEN:
  334.         WritePort(Chan[i].port, DNCMD_CLOSE, NULL, 0, PKT_REQ, i);
  335.     case CHAN_ROPEN:    /*  pending on listen port  */
  336.         ch->state = CHAN_CLOSE;
  337.         ch->flags = CHANF_RCLOSE;
  338.         ch->ior = NULL;
  339.         break;
  340.     case CHAN_LOPEN:    /*  pending on network        */
  341.         ch->ior->io_Error = 1;
  342.         ReplyMsg(ch->ior);
  343.         ch->ior = NULL;
  344.         ch->state = CHAN_FREE;
  345.         ch->flags = 0;
  346.         --NumCon;
  347.         break;
  348.     case CHAN_CLOSE:
  349.         if (!(ch->flags & CHANF_LCLOSE))
  350.         break;
  351.         ch->ior->io_Error = 1;
  352.         ReplyMsg(ch->ior);
  353.         ch->ior = NULL;
  354.         ch->state = CHAN_FREE;
  355.         ch->flags = 0;
  356.         --NumCon;
  357.     }
  358.     }
  359.     RPStart = 0;
  360.     WPStart = 0;
  361.     WPUsed  = 0;
  362.     RState  = 0;
  363.     RChan = 0;
  364.     WChan = 0;
  365. }
  366.  
  367.  
  368.  
  369.