home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff294.lzh / DNet / amiga / dnet / dnet.c < prev    next >
C/C++ Source or Header  |  1989-12-11  |  10KB  |  446 lines

  1.  
  2. /*
  3.  *  DNET.C
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  */
  7.  
  8. #include "dnet.h"
  9. #include <local/deemu.h>
  10.  
  11. void do_netreset();
  12. char *GetDEnv();
  13.  
  14. short Deemu[] = {
  15.     DMSTRT, 0, 0,
  16.     DMNW  , 0,10, 50, 50, 320, 100, 0xFFFF,
  17.     DMEND , 0, 0
  18. };
  19.  
  20. extern int Enable_Abort;
  21. /*long DResBase;*/
  22. char PortName[sizeof(DNETPORTNAME)+32];
  23.  
  24. #ifdef LATTICE
  25.  
  26. int __stdargs CXBRK(void);      /*  get around a bug in lcr.lib : onbreak() */
  27.  
  28. int __stdargs
  29. CXBRK(void)
  30. {
  31.     return(0);
  32. }
  33.  
  34. #endif
  35.  
  36. void main ARGS((int, char **));
  37.  
  38. void
  39. main(ac,av)
  40. int ac;
  41. char *av[];
  42. {
  43.     long sink_mask, dnet_mask/*, ipc_mask*/;
  44.     long baud = 0;
  45.     char *netdevice = "serial.device";
  46.     long netunit = 0;
  47.     char *autoclient = "FTERM";
  48.     short i;
  49.  
  50.     unlink("ENV:DNET_NORUNCLIENT");
  51. #ifndef LATTICE
  52.     Enable_Abort = 0;
  53. #endif
  54.     BZero(Pkts,sizeof(Pkts));
  55.     InitServers();
  56.  
  57.     for (i = 1; i < ac; ++i) {
  58.     if (strcmp(av[i], "-Getty") == 0) {
  59.         Getty = 1;
  60.         AutoHangup = 1;
  61.         av[i] = "";
  62.     }
  63.     if (strcmp(av[i], "-DEVICE") == 0) {
  64.         netdevice = av[i + 1];
  65.         av[i] = "";
  66.         av[i+1] = "";
  67.     }
  68.     if (strcmp(av[i], "-UNIT") == 0) {
  69.         netunit = atoi(av[i+1]);
  70.         av[i] = "";
  71.         av[i+1] = "";
  72.     }
  73.     }
  74.  
  75.     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",
  76.     &PDebug, &Mode7, &baud, &DDebug, &HostName, &autoclient, &AutoAnswer,
  77.     &AutoHangup, &netunit, &netdevice, &NetworkNum, &Master8, &DialOut,
  78.     &TOBaud, &Protocol
  79.     );
  80.     if (ac < 0) {
  81.     puts("Unknown option, valid options:\n");
  82.     puts("dnet -pb#B#d#n<hostname>s<autorunclient>aU#D<device>N<netid>8");
  83.     dneterror("Unknown switch");
  84.     }
  85.     if (AutoAnswer) {
  86.     AutoHangup = 1;
  87.     DialOut = 0;
  88.     }
  89.     sprintf(PortName, "%s%d", DNETPORTNAME, NetworkNum);
  90.     {
  91.     PORT *port;
  92.     if (port = (PORT *)FindPort(PortName)) {
  93.         puts("DNET: Network number in use");
  94.         /*
  95.         CloseLibrary(DResBase);
  96.         */
  97.         exit(1);
  98.     }
  99.     }
  100.     DNetPort = (PORT *)CreatePort(PortName, 0);
  101.     IOSink   = (PORT *)CreatePort(NULL,0);
  102.     /*
  103.     IPCPort  = (PORT *)OpenIPC("dnet.CMD", 0);
  104.     */
  105.     if (!DNetPort || !IOSink)
  106.     dneterror("CreatePort");
  107.  
  108.     NewList((LIST *)&TxList);
  109.     Rto_act = Wto_act = Cto_act = 0;
  110.     NetOpen(IOSink, netdevice, netunit, &baud);
  111.     TimerOpen(&Rto, IOSink);
  112.     TimerOpen(&Wto, IOSink);
  113.     TimerOpen(&Cto, IOSink);
  114.  
  115.     if (TOBaud)
  116.     SetTimeouts(TOBaud);
  117.     else
  118.     SetTimeouts(Baud);
  119.  
  120.     NetStartRead(3);
  121.  
  122.     do_dnetwindow(baud);
  123.  
  124.     if (Quit)
  125.     dneterror(NULL);
  126.  
  127.     Rto.tr_node.io_Message.mn_Node.ln_Name = (char *)RTO_REQ;
  128.     Wto.tr_node.io_Message.mn_Node.ln_Name = (char *)WTO_REQ;
  129.     Cto.tr_node.io_Message.mn_Node.ln_Name = (char *)CTO_REQ;
  130.  
  131.     sink_mask = 1 << IOSink->mp_SigBit;
  132.     dnet_mask = 1 << DNetPort->mp_SigBit;
  133.     /*
  134.     ipc_mask = 1 << IPCPort->mp_SigBit;
  135.     */
  136.  
  137.     do_netreset();
  138. loop:
  139.     if (strcmp(autoclient, "-") != 0) {
  140.     FILE *fi = fopen("T:dscr", "w");
  141.     if (fi) {
  142.         fprintf(fi, "Wait 5\n");
  143.         fprintf(fi, "%s -N%ld\n", autoclient, NetworkNum);
  144.         fclose(fi);
  145.         Execute("RUN <NIL: >NIL: execute T:dscr", NULL, NULL);
  146.     }
  147.     }
  148.  
  149.     WriteRestart();
  150.     Restart = 1;
  151.     OnLine = 1;
  152.  
  153.     /*
  154.      *    NOTE:    Routines must be particularly careful not to clear the
  155.      *        signal mask unless it doesn't matter.  Specifically,
  156.      *        routines in the dnet_mask section cannot arbitrarily
  157.      *        clear the signal associated with the sink_mask section.
  158.      *
  159.      *        If you look at NetWrite(), you will note that the signal
  160.      *        is restored if it must do a WaitIO().
  161.      */
  162.  
  163.     /*
  164.      *    Immediate return from initial Wait() ... due to looping it is
  165.      *    possible one or more requests is ready but the signal bit has
  166.      *    already been cleared.
  167.      */
  168.  
  169.     Signal(FindTask(NULL), /*ipc_mask|*/sink_mask|dnet_mask);
  170.  
  171.     while (!Quit && OnLine) {
  172.     long mask = Wait(/*ipc_mask|*/sink_mask|dnet_mask|SIGBREAKF_CTRL_C);
  173.  
  174.     /*
  175.     if (mask & ipc_mask)
  176.         handle_ipc();
  177.     */
  178.  
  179.     if (mask & sink_mask) {     /*  IOSink returns      */
  180.         IOSTD *ior;
  181.         while (ior = (IOSTD *)GetMsg(IOSink)) {
  182.         switch((long)ior->io_Message.mn_Node.ln_Name) {
  183.         case PKT_REQ:
  184.             --NumCon;
  185.             if (ior->io_Length)
  186.             FreeMem(ior->io_Data, ior->io_Length);
  187.             FreeMem(ior, sizeof(IOSTD));
  188.             break;
  189.         case CTO_REQ:    /*  Only when line idle         */
  190.             Cto_act = 0;
  191.             do_cto((IOT *)ior);
  192.             if (Cd == 0 && AutoHangup)
  193.             OnLine = 0;
  194.             break;
  195.         case RTO_REQ:    /*  Read timeout, reset READ state  */
  196.             Rto_act = 0;
  197.             do_rto((IOT *)ior);
  198.             break;
  199.         case WTO_REQ:    /*  Write-Ack timeout, send CHECK   */
  200.             Wto_act = 0;
  201.             do_wto((IOT *)ior);
  202.             break;
  203.         case RNET_REQ:    /*  Receive data ready, interpret   */
  204.             {
  205.             char *ptr;
  206.             long bytes = NetReadReturned(&ptr);
  207.             do_rnet(ptr, bytes);
  208.             }
  209.             if (Cd == 0 && AutoHangup)
  210.             OnLine = 0;
  211.             break;
  212.         case WNET_REQ:
  213.             NetClWrite((IOSER *)ior);
  214.             break;
  215.         }
  216.         }
  217.     }
  218.     if (mask & dnet_mask) {     /*  Receive commands    */
  219.         IOSTD *ior;
  220.         while (ior = (IOSTD *)GetMsg(DNetPort)) {
  221.         ior->io_Actual = 0;
  222.         switch(ior->io_Command) {
  223.         case DNCMD_WRITE:    /*  write data to net        */
  224.             {
  225.             uword chan = (ulong)ior->io_Unit;
  226.             if (Chan[chan].state != CHAN_OPEN) {
  227.                 ior->io_Error = 1;
  228.                 break;
  229.             }
  230.             ior->io_Error = 0;
  231.             ior->io_Command = SCMD_DATA;
  232.             ior->io_Message.mn_Node.ln_Pri = Chan[chan].pri;
  233.             Enqueue(&TxList, (NODE *)ior);
  234.             ior = NULL;
  235.             }
  236.             break;
  237.         case DNCMD_SOPEN:   /*    Reply from server port on remote    */
  238.                     /*    open request                */
  239.             {
  240.             CACKCMD ack;
  241.             uword chan = (ulong)ior->io_Unit;
  242.  
  243.  
  244.             ack.chanh = chan >> 8;
  245.             ack.chanl = chan;
  246.             ack.error = ior->io_Error;
  247.             WriteStream(SCMD_ACKCMD, &ack, sizeof(ack), chan);
  248.             if (ack.error) {
  249.                 Chan[chan].state = CHAN_FREE;
  250.                 --NumCon;
  251.             } else {
  252.                 if (Chan[chan].state == CHAN_CLOSE && !ack.error) {
  253.                 WritePort(Chan[chan].port, DNCMD_CLOSE, NULL, 0, PKT_REQ, chan);
  254.                 goto sopenbrk;
  255.                 }
  256.                 Chan[chan].state = CHAN_OPEN;
  257.                 Chan[chan].port  = (PORT *)ior->io_Offset;
  258.                 Chan[chan].flags = CHANF_ROK|CHANF_WOK;
  259.             }
  260. sopenbrk:
  261.             if (ior->io_Length)
  262.                 FreeMem(ior->io_Data, ior->io_Length);
  263.             FreeMem(ior, sizeof(IOSTD));
  264.             ior = NULL;
  265.             }
  266.             break;
  267.         case DNCMD_EOF:
  268.             {
  269.             CEOFCMD eof;
  270.             uword chan = (ulong)ior->io_Unit;
  271.  
  272.             ior->io_Error = 0;
  273.             eof.chanh = chan >> 8;
  274.             eof.chanl = chan;
  275.             eof.flags = CHANF_ROK;
  276.             WriteStream(SCMD_EOFCMD, &eof, sizeof(CEOFCMD), chan);
  277.             Chan[chan].flags &= ~CHANF_WOK;
  278.             }
  279.             break;
  280.         case DNCMD_IOCTL:
  281.             {
  282.             CIOCTL cio;
  283.             uword chan = (ulong)ior->io_Unit;
  284.  
  285.             ior->io_Error = 0;
  286.             cio.chanh = chan >> 8;
  287.             cio.chanl = chan;
  288.             cio.valh   = (ubyte)((ulong)ior->io_Data >> 24);
  289.             cio.vall   = (ubyte)((ulong)ior->io_Data >> 16);
  290.             cio.valaux = (ubyte)((ulong)ior->io_Data >> 8);
  291.             cio.cmd = (ubyte)(ulong)ior->io_Data;
  292.             WriteStream(SCMD_IOCTL, &cio, sizeof(CIOCTL), chan);
  293.             }
  294.             break;
  295.         case DNCMD_QUIT:
  296.             {
  297.             char dummy;
  298.  
  299.             WriteStream(SCMD_QUIT, &dummy, 1, (uword)-1);
  300.             }
  301.             break;
  302.         case DNCMD_INFO:
  303.             {
  304.             char *ptr = (char *)ior->io_Data;
  305.             sprintf(ptr, "         Bytes  Packets   Errors\n"
  306.                      "OUT:  %8ld %8ld %8ld\n"
  307.                      "IN :  %8ld %8ld %8ld\n"
  308.                      "Garbage Bytes In: %ld\n\n"
  309.                      "                        6-expn   7-comp   8-bin\n"
  310.                      "Packet Breakdown Send: %8ld %8ld %8ld\n"
  311.                      "Packet Breakdown Recv: %8ld %8ld %8ld\n",
  312.  
  313.                     BytesOut, PacketsOut, PacketsResent,
  314.                     BytesIn,  PacketsIn,  PacketsNakd,
  315.                     GarbageIn,
  316.                     Packets6Out, Packets7Out, Packets8Out,
  317.                     Packets6In,  Packets7In,  Packets8In
  318.             );
  319.             }
  320.             break;
  321.         case DNCMD_OPEN:
  322.             ior->io_Error = 0;
  323.             {
  324.             uword chan = alloc_channel();
  325.             COPEN co;
  326.             if (chan >= MAXCHAN) {
  327.                 ior->io_Error = 1;
  328.                 break;
  329.             }
  330.             co.chanh = chan >> 8;
  331.             co.chanl = chan;
  332.             co.porth = (ulong)ior->io_Unit >> 8;  /* port #   */
  333.             co.portl = (ulong)ior->io_Unit;
  334.             co.error= 0;
  335.             co.pri = (char)(long)ior->io_Message.mn_Node.ln_Name;
  336.             Chan[chan].ior = ior;
  337.             Chan[chan].port= (PORT *)ior->io_Offset;
  338.             Chan[chan].state = CHAN_LOPEN;
  339.             Chan[chan].flags = 0;
  340.             Chan[chan].pri = ior->io_Message.mn_Node.ln_Pri;
  341.             WriteStream(SCMD_OPEN, &co, sizeof(COPEN), chan);
  342.             ior = NULL;
  343.             }
  344.             break;
  345.         case DNCMD_CLOSE:    /*  same io_Command for CCTL_?    */
  346.             ior->io_Error = 0;
  347.             {
  348.             CCLOSE cc;
  349.             uword chan = (ulong)ior->io_Unit;
  350.  
  351.             cc.chanh = chan >> 8;
  352.             cc.chanl = chan;
  353.             WriteStream(SCMD_CLOSE, &cc, sizeof(CCLOSE), chan);
  354.             Chan[chan].ior = ior;
  355.             Chan[chan].state = CHAN_CLOSE;
  356.             Chan[chan].flags |= CHANF_LCLOSE;
  357.             if (Chan[chan].flags & CHANF_RCLOSE) {
  358.                 Chan[chan].state = CHAN_FREE;
  359.                 Chan[chan].ior = NULL;
  360.             } else {
  361.                 ior = NULL;
  362.             }
  363.             }
  364.             break;
  365.         case DNCMD_EXEC:
  366.             Execute((char *)ior->io_Offset, NULL, NULL);
  367.             break;
  368.         }
  369.         if (ior)
  370.             ReplyMsg((MSG *)ior);
  371.         }
  372.     }
  373.     if (mask & SIGBREAKF_CTRL_C)
  374.         OnLine = 0;
  375.     do_wupdate();
  376.     }
  377.     do_netreset();
  378.     if (!Cd) {
  379.     ResetConnect();
  380.     ResetIdle();
  381.     }
  382.     if (!Quit)
  383.     do_dnetwindow(baud);
  384.     if (!Cd) {
  385.     ResetConnect();
  386.     ResetIdle();
  387.     }
  388.     if (!Quit)
  389.     goto loop;
  390.     dneterror(NULL);
  391. }
  392.  
  393. void
  394. do_netreset()
  395. {
  396.     short i;
  397.     CHAN *ch;
  398.     IOSTD *ior;
  399.  
  400.     while (ior = (IOSTD *)RemHead((LIST *)&TxList)) {
  401.     ior->io_Error = 1;
  402.     ReplyMsg((MSG *)ior);
  403.     }
  404.     for (i = 0, ch = Chan; i < MAXCHAN; ++i, ++ch) {
  405.     switch(ch->state) {
  406.     case CHAN_OPEN:
  407.         WritePort(Chan[i].port, DNCMD_CLOSE, NULL, 0, PKT_REQ, i);
  408.     case CHAN_ROPEN:    /*  pending on listen port  */
  409.         ch->state = CHAN_CLOSE;
  410.         ch->flags = CHANF_RCLOSE;
  411.         ch->ior = NULL;
  412.         break;
  413.     case CHAN_LOPEN:    /*  pending on network        */
  414.         ch->ior->io_Error = 1;
  415.         ReplyMsg((MSG *)ch->ior);
  416.         ch->ior = NULL;
  417.         ch->state = CHAN_FREE;
  418.         ch->flags = 0;
  419.         --NumCon;
  420.         break;
  421.     case CHAN_CLOSE:
  422.         if (!(ch->flags & CHANF_LCLOSE))
  423.         break;
  424.         ch->ior->io_Error = 1;
  425.         ReplyMsg((MSG *)ch->ior);
  426.         ch->ior = NULL;
  427.         ch->state = CHAN_FREE;
  428.         ch->flags = 0;
  429.         --NumCon;
  430.     }
  431.     }
  432.     RPStart = 0;
  433.     WPStart = 0;
  434.     WPUsed  = 0;
  435.     RState  = 0;
  436.     RChan = 0;
  437.     WChan = 0;
  438.     if (!Cto_act) {
  439.     Cto.tr_time.tv_secs = 1;
  440.     Cto.tr_time.tv_micro= 0;
  441.     SendIO((IOR *)&Cto);
  442.     Cto_act = 1;
  443.     }
  444. }
  445.  
  446.