home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / winsock / twnsck10 / tshost.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  7.6 KB  |  407 lines

  1. /*
  2.  *  TwinSock - "Troy's Windows Sockets"
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <sys/types.h>
  22. #include <sys/time.h>
  23. #include <stdio.h>
  24. #include <netinet/in.h>
  25. #include <errno.h>
  26. #include "twinsock.h"
  27. #include "tx.h"
  28.  
  29. #define    BUFFER_SIZE    1024
  30.  
  31. static    fd_set    fdsActive;
  32. static    fd_set    fdsListener;
  33. static    int    nLargestFD;
  34. static    char    achBuffer[BUFFER_SIZE];
  35. static    int    bFlushing = 0;
  36. void    FlushInput(void);
  37.  
  38. int    GetNextExpiry(struct timeval *ptvValue);
  39. void    CheckTimers(void);
  40. extern    char    *sys_errlist[];
  41.  
  42. #define    TIMER_ID_SEND        0
  43. #define    TIMER_ID_RECEIVE    1
  44. #define    TIMER_ID_FLUSH        2
  45.  
  46. int    BumpLargestFD(int iValue)
  47. {
  48.     if (iValue > nLargestFD)
  49.         nLargestFD = iValue;
  50.     FD_SET(iValue, &fdsActive);
  51. };
  52.  
  53. int    SetListener(int iValue)
  54. {
  55.     FD_SET(iValue, &fdsListener);
  56. }
  57.  
  58. int    SetClosed(int iValue)
  59. {
  60.     FD_CLR(iValue, &fdsListener);
  61.     FD_CLR(iValue, &fdsActive);
  62. }
  63.  
  64. main(int argc, char **argv)
  65. {
  66.     fd_set    fdsRead, fdsWrite, fdsExcept, fdsDummy;
  67.     int    nRead;
  68.     int    i;
  69.     int    iResult;
  70.     struct    sockaddr_in saSource;
  71.     int    nSourceLen;
  72.     int    s;
  73.     struct    timeval tvZero;
  74.     struct    timeval tv;
  75.  
  76.     fprintf(stderr, "TwinSock Host 1.0\n");
  77.     fprintf(stderr, "Copyright 1994 Troy Rollo\n");
  78.     fprintf(stderr, "This program is free software\n");
  79.     fprintf(stderr, "See the file COPYING for details\n");
  80.     fprintf(stderr, "\nStart your TwinSock client now\n");
  81.  
  82.     InitTerm();
  83.     nLargestFD = 0;
  84.     FD_ZERO(&fdsActive);
  85.     FD_ZERO(&fdsWrite);
  86.     FD_ZERO(&fdsExcept);
  87.  
  88.     FD_SET(0, &fdsActive);
  89.  
  90.     while(1)
  91.     {
  92.         fdsRead = fdsActive;
  93.         iResult = select(nLargestFD + 1,
  94.                 &fdsRead,
  95.                 &fdsWrite,
  96.                 &fdsExcept,
  97.                 GetNextExpiry(&tv) ? &tv : 0);
  98.         CheckTimers();
  99.         if (iResult <= 0)
  100.             continue;
  101.         if (FD_ISSET(0, &fdsRead))
  102.         {
  103.             nRead = read(0, achBuffer, BUFFER_SIZE);
  104.             if (nRead > 0)
  105.             {
  106.                 if (bFlushing)
  107.                     FlushInput();
  108.                 else
  109.                     PacketReceiveData(achBuffer, nRead);
  110.             }
  111.         }
  112.         for (i = 3; i <= nLargestFD; i++)
  113.         {
  114.             if (FD_ISSET(i, &fdsRead))
  115.             {
  116.                 FD_ZERO(&fdsDummy);
  117.                 FD_SET(i, &fdsDummy);
  118.                 tvZero.tv_sec = tvZero.tv_usec = 0;
  119.                 if (select(i + 1,
  120.                         &fdsDummy,
  121.                         &fdsWrite,
  122.                         &fdsExcept,
  123.                         &tvZero) != 1)
  124.                     continue; /* Select lied */
  125.  
  126.                 nSourceLen = sizeof(saSource);
  127.                 if (FD_ISSET(i, &fdsListener))
  128.                 {
  129.                     s = accept(i,
  130.                         &saSource,
  131.                         &nSourceLen);
  132.                     if (s == -1)
  133.                         continue;
  134.                     s = htonl(s);
  135.                     BumpLargestFD(s);
  136.                     SendSocketData(i,
  137.                         &s,
  138.                         sizeof(s),
  139.                         &saSource,
  140.                         nSourceLen,
  141.                         FN_Accept);
  142.                 }
  143.                 else
  144.                 {
  145.                     nRead = recvfrom(i,
  146.                             achBuffer,
  147.                             BUFFER_SIZE,
  148.                             0,
  149.                             &saSource,
  150.                             &nSourceLen);
  151.                     if (nRead >= 0)
  152.                         SendSocketData(i,
  153.                             achBuffer,
  154.                             nRead,
  155.                             &saSource,
  156.                             nSourceLen,
  157.                             FN_Data);
  158.                     if (nRead == 0)
  159.                         SetClosed(i);
  160.                 }
  161.             }
  162.         }
  163.     }
  164. }
  165.  
  166.  
  167. void
  168. SetTransmitTimeout(void)
  169. {
  170.     KillTimer(TIMER_ID_SEND);
  171.     SetTimer(TIMER_ID_SEND, 3000);
  172. }
  173.  
  174. void
  175. KillTransmitTimeout(void)
  176. {
  177.     KillTimer(TIMER_ID_SEND);
  178. }
  179.  
  180. void    SetReceiveTimeout(void)
  181. {
  182.     KillTimer(TIMER_ID_RECEIVE);
  183.     SetTimer(TIMER_ID_RECEIVE, 1500);
  184. }
  185.  
  186. void    KillReceiveTimeout(void)
  187. {
  188.     KillTimer(TIMER_ID_RECEIVE);
  189. }
  190.  
  191. static    struct    timeval atvTimers[3];
  192. static    int    iTimersOn;
  193. static    int    iTimerRunning;
  194. static    int    iInTimer = 0;
  195.  
  196.  
  197. int    FireTimer(int iTimer)
  198. {
  199.     switch(iTimer)
  200.     {
  201.     case TIMER_ID_SEND:
  202.         TimeoutReceived();
  203.         break;
  204.  
  205.     case TIMER_ID_RECEIVE:
  206.         PacketReceiveData(0, 0);
  207.         break;
  208.  
  209.     case TIMER_ID_FLUSH:
  210.         bFlushing = 0;
  211.         break;
  212.     }
  213. }
  214.  
  215. int    GetNextExpiry(struct timeval *ptvValue)
  216. {
  217.     struct    timeval    tvNow;
  218.     struct    timezone tzDummy;
  219.     struct    timeval    tvGo;
  220.     int    i;
  221.  
  222.     if (!iTimersOn)
  223.         return 0;
  224.  
  225.     tvGo.tv_sec = 0x7fffffff;
  226.     tvGo.tv_usec = 0;
  227.     for (i = 0; i < 3; i++)
  228.     {
  229.         if (!(iTimersOn & (1 << i)))
  230.             continue;
  231.         if (atvTimers[i].tv_sec < tvGo.tv_sec ||
  232.             (atvTimers[i].tv_sec == tvGo.tv_sec &&
  233.              atvTimers[i].tv_usec < tvGo.tv_usec))
  234.         {
  235.             tvGo = atvTimers[i];
  236.             iTimerRunning = i;
  237.         }
  238.     }
  239.     gettimeofday(&tvNow, &tzDummy);
  240.     ptvValue->tv_sec = tvGo.tv_sec - tvNow.tv_sec;
  241.     ptvValue->tv_usec = tvGo.tv_usec - tvNow.tv_usec;
  242.     while (ptvValue->tv_usec < 0)
  243.     {
  244.         ptvValue->tv_usec += 1000000l;
  245.         ptvValue->tv_sec--;
  246.     }
  247.     while (ptvValue->tv_usec >= 1000000l)
  248.     {
  249.         ptvValue->tv_usec -= 1000000l;
  250.         ptvValue->tv_sec++;
  251.     }
  252.     if (ptvValue->tv_sec < 0)
  253.     {
  254.         ptvValue->tv_sec = 0;
  255.         ptvValue->tv_usec = 100;
  256.     }
  257.     if (!ptvValue->tv_sec &&
  258.         ptvValue->tv_usec < 100)
  259.         ptvValue->tv_usec = 100;
  260.     return 1;
  261. }
  262.  
  263. void    CheckTimers(void)
  264. {
  265.     struct    timeval    tvNow;
  266.     struct    timezone tzDummy;
  267.     int    i;
  268.  
  269.     gettimeofday(&tvNow, &tzDummy);
  270.     for (i = 0; i < 3; i++)
  271.     {
  272.         if (!(iTimersOn & (1 << i)))
  273.             continue;
  274.         if (atvTimers[i].tv_sec < tvNow.tv_sec ||
  275.             (atvTimers[i].tv_sec == tvNow.tv_sec &&
  276.              atvTimers[i].tv_usec < tvNow.tv_usec))
  277.         {
  278.             KillTimer(i);
  279.             FireTimer(i);
  280.         }
  281.     }
  282. }
  283.  
  284. int    SetTimer(int idTimer, int iTime)
  285. {
  286.     struct    timeval        tvNow;
  287.     struct    timezone    tzDummy;
  288.  
  289.     gettimeofday(&tvNow, &tzDummy);
  290.     atvTimers[idTimer] = tvNow;
  291.     atvTimers[idTimer].tv_usec += (long) iTime % 1000l * 1000l;
  292.     atvTimers[idTimer].tv_sec += iTime / 1000;
  293.     while (atvTimers[idTimer].tv_usec > 1000000l)
  294.     {
  295.         atvTimers[idTimer].tv_sec++;
  296.         atvTimers[idTimer].tv_usec -= 1000000l;
  297.     }
  298.     iTimersOn |= (1 << idTimer);
  299. }
  300.  
  301. int    KillTimer(int idTimer)
  302. {
  303.     iTimersOn &= ~(1 << idTimer);
  304. }
  305.  
  306. void    Shutdown(void)
  307. {
  308.     UnInitTerm();
  309.     fprintf(stderr, "\nTwinSock Host Finished\n");
  310.     exit(0);
  311. }
  312.  
  313. int
  314. SendData(void *pvData, int iDataLen)
  315. {
  316.     int    iLen;
  317.     int    nWritten;
  318.  
  319.     if (bFlushing)
  320.         return iDataLen; /* Lie */
  321.     iLen = iDataLen;
  322.  
  323.     while (iLen > 0)
  324.     {
  325.         nWritten = write(1, pvData, iDataLen);
  326.         if (nWritten > 0)
  327.             iLen -= nWritten;
  328.     }
  329.     return iDataLen;
  330. }
  331.  
  332. void
  333. FlushInput(void)
  334. {
  335.     bFlushing = 1;
  336.     SetTimer(TIMER_ID_FLUSH, 1500);
  337. }
  338.  
  339. static void
  340. SendInitResponse(void)
  341. {
  342.     struct    tx_request txr;
  343.  
  344.     txr.iType = htons(FN_Init);
  345.     txr.nArgs = 0;
  346.     txr.nLen = htons(10);
  347.     txr.id = -1;
  348.     txr.nError = 0;
  349.     PacketTransmitData(&txr, 10, -2);
  350. }
  351.  
  352. void
  353. DataReceived(void *pvData, int iLen)
  354. {
  355.     static    struct tx_request *ptxr = 0;
  356.     static    struct tx_request txrHeader;
  357.     static    int    nBytes = 0;
  358.     short    nPktLen;
  359.     enum Functions ft;
  360.     int    nCopy;
  361.  
  362.     while (iLen)
  363.     {
  364.         if (nBytes < 10)
  365.         {
  366.             nCopy = 10 - nBytes;
  367.             if (nCopy > iLen)
  368.                 nCopy = iLen;
  369.             memcpy((char *) &txrHeader + nBytes, pvData, nCopy);
  370.             nBytes += nCopy;
  371.             pvData = (char *) pvData + nCopy;
  372.             iLen -= nCopy;
  373.             if (nBytes == 10)
  374.             {
  375.                 nPktLen = ntohs(txrHeader.nLen);
  376.                 ptxr = (struct tx_request *) malloc(sizeof(struct tx_request) + nPktLen - 10);
  377.                 memcpy(ptxr, &txrHeader, 10);
  378.             }
  379.         }
  380.         if (nBytes >= 10)
  381.         {
  382.             nPktLen = ntohs(txrHeader.nLen);
  383.             ft = (enum Functions) ntohs(txrHeader.iType);
  384.             nCopy = nPktLen - nBytes;
  385.             if (nCopy > iLen)
  386.                 nCopy = iLen;
  387.             if (nCopy)
  388.             {
  389.                 memcpy((char *) ptxr + nBytes, pvData, nCopy);
  390.                 nBytes += nCopy;
  391.                 pvData = (char *) pvData + nCopy;
  392.                 iLen -= nCopy;
  393.             }
  394.             if (nBytes == nPktLen)
  395.             {
  396.                 if (ft == FN_Init)
  397.                     SendInitResponse();
  398.                 else
  399.                     ResponseReceived(ptxr);
  400.                 free(ptxr);
  401.                 ptxr = 0;
  402.                 nBytes = 0;
  403.             }
  404.         }
  405.     }
  406. }
  407.