home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / stg_v4.lzh / stgxfr.c < prev    next >
C/C++ Source or Header  |  1994-11-11  |  9KB  |  534 lines

  1. /*
  2.  * stgxfr - version 4, third (or is it fourth?) rewrite
  3.  *
  4. */
  5.  
  6. #include "stgnet.h"
  7.  
  8. #include "dump.c"
  9.  
  10. #include <time.h>
  11.  
  12. #define MAX_SIZE 1024        /* max data block */
  13. #define MAX_RECV MAX_SIZE*2
  14.  
  15. /* packet types */
  16. #define NAK_PKT 0x00    /* request repeat of pkt */
  17. #define ERR_PKT 0x01    /* fail request with err # */
  18. #define RQ_INIT 0x08    /* initialize connection */
  19. #define RP_INIT 0x09
  20. #define RQ_PASS 0x0A    /* security check */
  21. #define RP_PASS 0x0B
  22. #define RQ_OPEN 0x10    /* open file */
  23. #define RP_OPEN 0x11
  24. #define RQ_CREA 0x12    /* create file */
  25. #define RP_CREA 0x13
  26. #define RQ_DELE 0x14    /* delete file */
  27. #define RP_DELE 0x15
  28. #define RQ_RENA 0x16    /* rename file */
  29. #define RP_RENA 0x17
  30. #define RQ_SEEK 0x20    /* seek in file */
  31. #define RP_SEEK 0x21
  32. #define RQ_READ 0x22    /* read fm file */
  33. #define RP_READ 0x23
  34. #define RQ_WRIT 0x24    /* write to file */
  35. #define RP_WRIT 0x25
  36. #define RQ_CLOS 0x2E    /* close file (chn 0=close connection) */
  37. #define RP_CLOS 0x2F
  38. #define RQ_NOP  0xFE    /* no operation */
  39.  
  40. #define PKT_HDR 6        /* packet header length */
  41. #define PKT_OVR PKT_HDR+3    /* plus crc bytes */
  42.  
  43. #define CHEK(x) ((B)(x^0xA5))    /* header check code calculation */
  44.  
  45. #ifdef _MS
  46. #define SWAPW(x) ( ((x&0xFF00)>>8) | ((x&0x00FF)<<8) )
  47. #define SWAPWO(x) ( ((x&0xFF00)>>8) | ((x&0x00FF)<<8) )
  48. #else
  49. #define SWAPW(x) (x)
  50. #define SWAPWO(x) ( (((B*)(&x))[0]<<8) | ((B*)(&x))[1] )
  51. #endif
  52.  
  53. struct packet
  54. {
  55.     B type;        /* packet type code */
  56.     B chek;        /* header check code */
  57.     B chan;        /* channel number */
  58.     B seq;        /* sequence number */
  59.     W len;        /* data length (+6+3=pkt len) */
  60.     B dat[MAX_SIZE+3];
  61. };
  62.  
  63. struct Q
  64. {
  65.     struct Q *Qnext;
  66.     struct packet *pkt;
  67. };
  68.  
  69. struct Q *Qsend=0;    /* waiting to be sent */
  70. struct Q *Qrecv=0;    /* waiting to be processed */
  71. struct Q *Qwait=0;    /* requests waiting for an answer */
  72.  
  73. struct Stat
  74. {
  75.     long tx;        /* bytes transmitted */
  76.     long rx;        /* bytes received */
  77.     long lost;        /* bytes receiver lost */
  78.     long sqerr;        /* # of sequence errors (old seq #) */
  79.     long txerr;        /* # of transmit errors */
  80.     long rxerr;        /* # of receive errors */
  81.     long cycle;        /* # of cyles */
  82. } Sec,Tot;
  83.  
  84. int iTestMode=0;        /* test mode flag */
  85. int iDebug=0;            /* internal debug flag */
  86. int iMaxSend=1;            /* maximum bytes to send at once */
  87. time_t Now;                /* time now */
  88.  
  89. struct packet *
  90. NewPacket(size)
  91. int size;
  92. {
  93.     struct packet *new;
  94.  
  95.     size+=PKT_OVR;
  96.     new=(struct packet *)malloc(size);
  97.     if (!new)
  98.     {
  99.         syslog(LOG_ERR,"malloc(%d): %m",size);
  100.         exit(errno);
  101.     }
  102.     memset((B*)new,0,size);
  103.     return(new);
  104. }
  105.  
  106. struct Q *
  107. AddQ(pQ,old)
  108. struct Q **pQ;
  109. struct Q *old;
  110. {
  111.     struct Q *end;
  112.  
  113.     if (!*pQ)
  114.         *pQ=old;
  115.     else
  116.     {
  117.         end=*pQ;
  118.         while (end->Qnext)
  119.             end=end->Qnext;
  120.         end->Qnext=old;
  121.     }
  122.     return(old);
  123. }
  124.  
  125. struct Q *
  126. NewQ(pQ,pkt)
  127. struct Q **pQ;
  128. struct packet *pkt;
  129. {
  130.     struct Q *new;
  131.  
  132.     new=(struct Q*)malloc(sizeof(*new));
  133.     if (!new)
  134.     {
  135.         syslog(LOG_ERR,"malloc(%d): %m",sizeof(*new));
  136.         exit(errno);
  137.     }
  138.  
  139.     new->Qnext=0;
  140.     new->pkt=pkt;
  141.  
  142.     return(AddQ(pQ,new));
  143. }
  144.  
  145. pktcrc(buf,len,set)
  146. B* buf;
  147. int len,set;
  148. {
  149.     B c[4];
  150.  
  151.     c[0]=c[1]=c[2]=c[3]=0xFF;
  152.  
  153.     crc(buf,len,c);
  154.     c[1]=~c[1];
  155.     c[2]=~c[2];
  156.     c[3]=~c[3];
  157.  
  158.     if (set)
  159.     {
  160.         buf[len+0]=c[1];
  161.         buf[len+1]=c[2];
  162.         buf[len+2]=c[3];
  163.         return(0);
  164.     }
  165.  
  166.     if
  167.     (
  168.         buf[len+0]!=c[1] ||
  169.         buf[len+1]!=c[2] ||
  170.         buf[len+2]!=c[3]
  171.     )
  172.         return(ERR);
  173.  
  174.     return(0);
  175. }
  176.  
  177. Sender()
  178. {
  179.     static struct packet *Pnop=0;    /* nop packet */
  180.     static W nopseq=0;                /* nop sequence */
  181.     static struct Q *Qsending=0;    /* currently sending */
  182.     static B *pcur=0;        /* pointer to unsent */
  183.     static B *pend=0;        /* pointer to pkt end */
  184.     int bytes;
  185.  
  186. /*    if (!Qsending && !Qsend) */
  187.  
  188.     if (!pcur)
  189.     {
  190.         /* nothing to do, send a nop */
  191.         if (!Pnop)
  192.         {
  193.             Pnop=NewPacket(0);
  194.             Pnop->type=RQ_NOP;
  195.             Pnop->chek=CHEK(Pnop->type);
  196.             Pnop->seq=-1;
  197.         }
  198.  
  199.         Pnop->chan=(nopseq&0xFF00)>>8;
  200.         Pnop->seq=(nopseq&0x00FF);
  201.         nopseq++;
  202.  
  203.         pktcrc((B*)Pnop,PKT_HDR,1);
  204.  
  205.         pcur=(B*)Pnop;
  206.         pend=pcur+PKT_OVR;
  207.     }
  208.  
  209.     bytes=pend-pcur;
  210.     if (bytes>iMaxSend)
  211.         bytes=iMaxSend;
  212.  
  213.     if (write(1,pcur,bytes)!=bytes)
  214.     {
  215.         /* should attempt to rewind pcur to Qsending->pkt here */
  216.         Sec.txerr++;
  217.         pcur=pend=0;
  218.     }
  219.     else
  220.     {
  221.         Sec.tx+=bytes;
  222.         pcur+=bytes;
  223.         if (pcur==pend)
  224.             pcur=pend=0;
  225.     }
  226.  
  227.     if (!pcur && Qsending)
  228.     {
  229.         /* free packet & queue */
  230.         free(Qsending->pkt);
  231.         free(Qsending);
  232.         Qsending=0;
  233.     }
  234.  
  235.     return(0);
  236. }
  237.  
  238. Sync(p,l)
  239. unsigned char *p;
  240. int l;
  241. {
  242.     unsigned char *o=p;
  243.  
  244.     if (l<2)
  245.         return(0);
  246.  
  247.     l--;
  248.  
  249.     while (l--)
  250.     {
  251.         if (p[1]==CHEK(p[0]))
  252.             break;
  253.         p++;
  254.     }
  255.     return(p-o);
  256. }
  257.  
  258. Receiver()
  259. {
  260.     static struct packet *pkt=0;    /* current packet */
  261.     static int have=0;                /* bytes we have in pkt */
  262.     static W nopseq=0;                /* nop sequence check */
  263.     W noptmp,nopoff;
  264.     struct packet *ptr;                /* movable ptr to scan pkt */
  265.     struct packet *new;                /* new packet */
  266.     int bytes;
  267.  
  268.     if (!pkt)
  269.     {
  270.         pkt=(struct packet *)malloc(MAX_RECV);
  271.         if (!pkt)
  272.         {
  273.             syslog(LOG_ERR,"malloc(%d): %m",MAX_RECV);
  274.             exit(errno);
  275.         }
  276.     }
  277.  
  278.     bytes=_gs_rdy(0);
  279.     if (bytes==ERR)
  280.     {
  281.         return(0);
  282.     }
  283.  
  284.     if (have+bytes>MAX_RECV)
  285.         bytes=MAX_RECV-have;
  286.  
  287.     errno=EEOF;
  288.     if (read(0,(B*)pkt+have,bytes)!=bytes)
  289.     {
  290. if (iDebug) wstringf(2,"read: %m\n");
  291.         Sec.rxerr++;
  292.         Sec.lost+=have;
  293.         have=0;
  294.         return(0);
  295.     }
  296.     have+=bytes;
  297.  
  298. if (iDebug)
  299. {
  300.     wstringf(2,"Adding %d bytes, now %d:\n",bytes,have);
  301.     dump(2,pkt,have);
  302. }
  303.  
  304.     /* scan through pkt for valid packets using ptr */
  305.     ptr=pkt;
  306.     while (have>=PKT_OVR)
  307.     {
  308.         /* check header sync code */
  309.         if (ptr->chek!=CHEK(ptr->type))
  310.         {
  311.             bytes=Sync((B*)ptr,have);
  312. if (iDebug) wstringf(2,"Throwing out %d bytes\n",bytes);
  313.             Sec.lost+=bytes;
  314.             ((B*)ptr)+=bytes;
  315.             have-=bytes;
  316.             continue;
  317.         }
  318.  
  319.         /* is the size kosher? */
  320.         bytes=SWAPWO(ptr->len);
  321.         if (bytes>MAX_SIZE)
  322.         {
  323. if (iDebug) wstringf(2,"Impossible length value: %d\n",bytes);
  324.             ptr->type++;
  325.             continue;
  326.         }
  327.  
  328.         /* do we have the entire packet? */
  329.         bytes+=PKT_OVR;
  330.         if (bytes>have)
  331.         {
  332.             break;
  333.         }
  334.  
  335.         /* is the crc correct? */
  336.         if (pktcrc((B*)ptr,bytes-3,0))
  337.         {
  338. if (iDebug) wstringf(2,"Bad CRC\n");
  339.             ptr->type++;
  340.             continue;
  341.         }
  342.  
  343.         /* is it a nop packet? */
  344.         if (ptr->type==RQ_NOP)
  345.         {
  346.             noptmp=(ptr->chan<<8)|ptr->seq;
  347.  
  348.             if (noptmp!=nopseq)
  349.             {
  350. /*wstringf(2,"[%04X-%04X]",nopseq,noptmp);*/
  351.                 nopoff=noptmp-nopseq;
  352.                 if (nopoff>=0x8000)
  353.                 {
  354. if (iDebug) wstringf(2,"Packet out of sequence: %04X (current=%04X)\n",
  355.     noptmp,nopseq);
  356.                     Sec.sqerr++;
  357.                 }
  358.                 else
  359.                 {
  360.                     Sec.lost+=PKT_OVR*nopoff;
  361. nopoff=noptmp-1;
  362.                     nopseq=noptmp;
  363. if (iDebug) wstringf(2,"Lost packets: %04X - %04X\n",nopseq,nopoff);
  364.                 }
  365.                 Sec.rx+=bytes;
  366.             }
  367.             else 
  368.             {
  369. /*                write(2,".",1); */
  370.                 Sec.rx+=bytes;
  371.             }
  372.             nopseq++;
  373.     
  374.             /* throw it away */
  375. if (iDebug) wstringf(2,"Nop Packet: skipping %d bytes\n",bytes);
  376.             ((B*)ptr)+=bytes;
  377.             have-=bytes;
  378.             continue;
  379.         }
  380.  
  381.         /* put packet on queue */
  382.         new=NewPacket(bytes);
  383.         memcpy((B*)new,(B*)ptr,bytes);
  384.         AddQ(&Qrecv,new);
  385.  
  386. if (iDebug) wstringf(2,"Other Packet: skipping %d bytes\n",bytes);
  387.         Sec.rx+=bytes;
  388.         ((B*)ptr)+=bytes;
  389.         have-=bytes;
  390.     }
  391.  
  392. if (iDebug)
  393. {
  394.     wstringf(2,"Left is %d bytes:\n",have);
  395.     dump(2,ptr,have);
  396. }
  397.  
  398.     /* move remainder (ptr through pkt+have) back to beginning of pkt */
  399.     if (ptr!=pkt)
  400.         memcpy((B*)pkt,(B*)ptr,have);
  401.  
  402.     return(0);
  403. }
  404.  
  405. Second()
  406. {
  407.     int baud;
  408.     int perf;
  409.     
  410.         
  411.     if (Sec.rx)
  412.     if (Sec.lost+Sec.sqerr)
  413.     {
  414.         /* are receiving bytes, but have lost some */
  415.         if (iMaxSend>1)
  416.         {
  417.             iMaxSend--;
  418.             if (iTestMode)
  419.                 wstringf(2,"MaxSend now %d\n",iMaxSend);
  420.         }
  421.     }
  422.     else
  423.     {
  424.         /* no loss, increase it */
  425.         iMaxSend++;
  426.         if (iTestMode)
  427.             wstringf(2,"MaxSend now %d\n",iMaxSend);
  428.     }
  429.  
  430.     if (iTestMode)
  431.     {
  432.         baud=(Sec.tx+Sec.rx)*10;
  433.         if ((Sec.lost+Sec.sqerr) && Sec.rx)
  434.             perf=100*Sec.rx/(Sec.rx+Sec.lost+Sec.sqerr*PKT_OVR);
  435.         else if (Sec.rx)
  436.             perf=100;
  437.         else
  438.             perf=0;
  439.  
  440.         wstringf(2,"T=%5d R=%5d L=%5d S=%5d E=%5d C=%5d B=%5d P=%3d%%\n",
  441.             Sec.tx,
  442.             Sec.rx,
  443.             Sec.lost,
  444.             Sec.sqerr,
  445.             Sec.txerr+Sec.rxerr,
  446.             Sec.cycle,
  447.             baud,
  448.             perf);
  449.     }
  450.  
  451.     memset(&Sec,0,sizeof(Sec));
  452. }
  453.  
  454. Running()
  455. {
  456.     static time_t Last;
  457.  
  458.     Now=time(0);
  459.     if (Now!=Last)
  460.     {
  461.         Second();
  462.         Last=Now;
  463.     }
  464.  
  465.     Sec.cycle++;
  466.  
  467.     Sender();
  468.     Receiver();
  469.  
  470.     return(1);
  471. }
  472.  
  473. TestMode()
  474. {
  475.     struct Q *Qtemp;
  476.  
  477.     iTestMode=1;
  478.  
  479.     wstringf(2,"TEST MODE\n");
  480.  
  481.     if (isatty(0))
  482.         _ss_mode(0,-1);
  483.  
  484.     if (isatty(1))
  485.         _ss_mode(1,-1);
  486.  
  487.     while (Running())
  488.     {
  489.         if (Qrecv)
  490.         {
  491.             wstringf(2,"recv: %02X %02X %02X %04X\n",
  492.                 Qrecv->pkt->type,
  493.                 Qrecv->pkt->chan,
  494.                 Qrecv->pkt->seq,
  495.                 SWAPW(Qrecv->pkt->len));
  496.             Qtemp=Qrecv;
  497.             Qrecv=Qrecv->Qnext;
  498.             free(Qtemp->pkt);
  499.             free(Qtemp);
  500.         }
  501.     }
  502. }
  503.  
  504. void
  505. Help()
  506. {
  507.     wstringf(1,"stgxfr - StG-Net Transfer Protocol\n");
  508.     wstringf(1,"  ** FOR INTERNAL USE ONLY **\n");
  509.     STGVER;
  510.     exit(1);
  511. }
  512.  
  513. void
  514. main(argc,argv)
  515. char **argv;
  516. {
  517.     openlog(*argv,0,LOG_STGNET);
  518.  
  519.     dash(argv)
  520.     {
  521.     case '#':
  522.         wstringf(2,"stgxfr: %s\n",STG_VER);
  523.         exit(0);
  524.  
  525.     case 'd': iDebug++; break;
  526.  
  527.     case 't': TestMode();
  528.  
  529.     case '?':
  530.     default:
  531.         Help();
  532.     }
  533. }
  534.