home *** CD-ROM | disk | FTP | other *** search
/ What PC? 1996 April / WHAT_PC_APR_96.ISO / internet / twinsock / src / tshost.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-24  |  8.6 KB  |  466 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 license in the file LICENSE.TXT included
  8.  *  with the TwinSock distribution.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
  13.  */
  14.  
  15. #include <sys/types.h>
  16. #include <sys/time.h>
  17. #include <stdio.h>
  18. #include <netinet/in.h>
  19. #include <errno.h>
  20. #ifdef NEED_SELECT_H
  21. #include <sys/select.h>
  22. #endif
  23. #include "twinsock.h"
  24. #include "tx.h"
  25.  
  26. extern    enum Encoding eLine;
  27.  
  28. extern    void    PacketTransmitData(void *pvData, int iDataLen, int iStream);
  29.  
  30. #define    BUFFER_SIZE    1024
  31.  
  32. static    fd_set    fdsActive;
  33. static    fd_set    fdsListener;
  34. static    int    nLargestFD;
  35. static    char    achBuffer[BUFFER_SIZE];
  36. static    int    bFlushing = 0;
  37. void    FlushInput(void);
  38.  
  39. int    GetNextExpiry(struct timeval *ptvValue);
  40. void    CheckTimers(void);
  41. extern    char    *sys_errlist[];
  42.  
  43. #define    TIMER_ID_SEND        0
  44. #define    TIMER_ID_RECEIVE    1
  45. #define    TIMER_ID_FLUSH        2
  46.  
  47. int    BumpLargestFD(int iValue)
  48. {
  49.     if (iValue > nLargestFD)
  50.         nLargestFD = iValue;
  51.     FD_SET(iValue, &fdsActive);
  52. };
  53.  
  54. int    SetListener(int iValue)
  55. {
  56.     FD_SET(iValue, &fdsListener);
  57. }
  58.  
  59. int    SetClosed(int iValue)
  60. {
  61.     FD_CLR(iValue, &fdsListener);
  62.     FD_CLR(iValue, &fdsActive);
  63. }
  64.  
  65. main(int argc, char **argv)
  66. {
  67.     fd_set    fdsRead, fdsWrite, fdsExcept, fdsDummy;
  68.     int    nRead;
  69.     int    i;
  70.     int    iResult;
  71.     struct    sockaddr_in saSource;
  72.     int    nSourceLen;
  73.     int    s;
  74.     struct    timeval tvZero;
  75.     struct    timeval tv;
  76.  
  77.     while (argc-- > 1)
  78.     {
  79.         argv++;
  80.         if (**argv =='-')
  81.         {
  82.             while (*++*argv)
  83.             {
  84.                 switch(**argv)
  85.                 {
  86.                 case '8':
  87.                     eLine = E_8Bit;
  88.                     break;
  89.  
  90.                 case 'n':
  91.                     eLine = E_8NoCtrl;
  92.                     break;
  93.  
  94.                 case 'N':
  95.                     eLine = E_8NoHiCtrl;
  96.                     break;
  97.  
  98.                 case 'x':
  99.                     eLine = E_8NoX;
  100.                     break;
  101.  
  102.                 case 'X':
  103.                     eLine = E_8NoHiX;
  104.                     break;
  105.  
  106.                 case 'e':
  107.                     eLine = E_Explicit;
  108.                     break;
  109.                 }
  110.             }
  111.         }
  112.     }
  113.  
  114.     fprintf(stderr, "TwinSock Host 1.4\n");
  115.     fprintf(stderr, "Copyright 1994-1995 Troy Rollo\n");
  116.     fprintf(stderr, "This program is free software\n");
  117.     fprintf(stderr, "See the file COPYING for details\n");
  118.     fprintf(stderr, "\nStart your TwinSock client now\n");
  119.  
  120.     if (isatty(0))
  121.         InitTerm();
  122.  
  123.     InitProtocol();
  124.     fprintf(stdout, "!@$TSStart%d$@", (int) eLine);
  125.     fflush(stdout);
  126.  
  127.     nLargestFD = 0;
  128.     FD_ZERO(&fdsActive);
  129.     FD_ZERO(&fdsWrite);
  130.     FD_ZERO(&fdsExcept);
  131.  
  132.     FD_SET(0, &fdsActive);
  133.  
  134.     while(1)
  135.     {
  136.         fdsRead = fdsActive;
  137.         iResult = select(nLargestFD + 1,
  138.                 &fdsRead,
  139.                 &fdsWrite,
  140.                 &fdsExcept,
  141.                 GetNextExpiry(&tv) ? &tv : 0);
  142.         CheckTimers();
  143.         if (iResult <= 0)
  144.             continue;
  145.         if (FD_ISSET(0, &fdsRead))
  146.         {
  147.             nRead = read(0, achBuffer, BUFFER_SIZE);
  148.             if (nRead > 0)
  149.             {
  150.                 if (bFlushing)
  151.                     FlushInput();
  152.                 else
  153.                     PacketReceiveData(achBuffer, nRead);
  154.             }
  155.             else if (nRead == 0 && !isatty(0))
  156.             {
  157.                 exit(0);
  158.             }
  159.         }
  160.         for (i = 3; i <= nLargestFD; i++)
  161.         {
  162.             if (FD_ISSET(i, &fdsRead))
  163.             {
  164.                 FD_ZERO(&fdsDummy);
  165.                 FD_SET(i, &fdsDummy);
  166.                 tvZero.tv_sec = tvZero.tv_usec = 0;
  167.                 if (select(i + 1,
  168.                         &fdsDummy,
  169.                         &fdsWrite,
  170.                         &fdsExcept,
  171.                         &tvZero) != 1)
  172.                     continue; /* Select lied */
  173.  
  174.                 nSourceLen = sizeof(saSource);
  175.                 if (FD_ISSET(i, &fdsListener))
  176.                 {
  177.                     s = accept(i,
  178.                         &saSource,
  179.                         &nSourceLen);
  180.                     if (s == -1)
  181.                         continue;
  182.                     s = htonl(s);
  183.                     BumpLargestFD(s);
  184.                     SendSocketData(i,
  185.                         &s,
  186.                         sizeof(s),
  187.                         &saSource,
  188.                         nSourceLen,
  189.                         FN_Accept);
  190.                 }
  191.                 else
  192.                 {
  193.                     nRead = recvfrom(i,
  194.                             achBuffer,
  195.                             BUFFER_SIZE,
  196.                             0,
  197.                             &saSource,
  198.                             &nSourceLen);
  199.                     if (nRead < 0 &&
  200.                         errno == ENOTCONN)
  201.                     {
  202.                         /* Was a datagram socket */
  203.                         SetClosed(i);
  204.                         continue;
  205.                     }
  206.                     if (nRead >= 0)
  207.                         SendSocketData(i,
  208.                             achBuffer,
  209.                             nRead,
  210.                             &saSource,
  211.                             nSourceLen,
  212.                             FN_Data);
  213.                     if (nRead == 0)
  214.                         SetClosed(i);
  215.                 }
  216.             }
  217.         }
  218.     }
  219. }
  220.  
  221.  
  222. void
  223. SetTransmitTimeout(void)
  224. {
  225.     KillTimer(TIMER_ID_SEND);
  226.     SetTimer(TIMER_ID_SEND, 10000);
  227. }
  228.  
  229. void
  230. KillTransmitTimeout(void)
  231. {
  232.     KillTimer(TIMER_ID_SEND);
  233. }
  234.  
  235. void    SetReceiveTimeout(void)
  236. {
  237.     KillTimer(TIMER_ID_RECEIVE);
  238.     SetTimer(TIMER_ID_RECEIVE, 1500);
  239. }
  240.  
  241. void    KillReceiveTimeout(void)
  242. {
  243.     KillTimer(TIMER_ID_RECEIVE);
  244. }
  245.  
  246. static    struct    timeval atvTimers[3];
  247. static    int    iTimersOn;
  248. static    int    iTimerRunning;
  249. static    int    iInTimer = 0;
  250.  
  251.  
  252. int    FireTimer(int iTimer)
  253. {
  254.     switch(iTimer)
  255.     {
  256.     case TIMER_ID_SEND:
  257.         TimeoutReceived();
  258.         break;
  259.  
  260.     case TIMER_ID_RECEIVE:
  261.         PacketReceiveData(0, 0);
  262.         break;
  263.  
  264.     case TIMER_ID_FLUSH:
  265.         bFlushing = 0;
  266.         break;
  267.     }
  268. }
  269.  
  270. int    GetNextExpiry(struct timeval *ptvValue)
  271. {
  272.     struct    timeval    tvNow;
  273.     struct    timezone tzDummy;
  274.     struct    timeval    tvGo;
  275.     int    i;
  276.  
  277.     if (!iTimersOn)
  278.         return 0;
  279.  
  280.     tvGo.tv_sec = 0x7fffffff;
  281.     tvGo.tv_usec = 0;
  282.     for (i = 0; i < 3; i++)
  283.     {
  284.         if (!(iTimersOn & (1 << i)))
  285.             continue;
  286.         if (atvTimers[i].tv_sec < tvGo.tv_sec ||
  287.             (atvTimers[i].tv_sec == tvGo.tv_sec &&
  288.              atvTimers[i].tv_usec < tvGo.tv_usec))
  289.         {
  290.             tvGo = atvTimers[i];
  291.             iTimerRunning = i;
  292.         }
  293.     }
  294.     gettimeofday(&tvNow, &tzDummy);
  295.     ptvValue->tv_sec = tvGo.tv_sec - tvNow.tv_sec;
  296.     ptvValue->tv_usec = tvGo.tv_usec - tvNow.tv_usec;
  297.     while (ptvValue->tv_usec < 0)
  298.     {
  299.         ptvValue->tv_usec += 1000000l;
  300.         ptvValue->tv_sec--;
  301.     }
  302.     while (ptvValue->tv_usec >= 1000000l)
  303.     {
  304.         ptvValue->tv_usec -= 1000000l;
  305.         ptvValue->tv_sec++;
  306.     }
  307.     if (ptvValue->tv_sec < 0)
  308.     {
  309.         ptvValue->tv_sec = 0;
  310.         ptvValue->tv_usec = 100;
  311.     }
  312.     if (!ptvValue->tv_sec &&
  313.         ptvValue->tv_usec < 100)
  314.         ptvValue->tv_usec = 100;
  315.     return 1;
  316. }
  317.  
  318. void    CheckTimers(void)
  319. {
  320.     struct    timeval    tvNow;
  321.     struct    timezone tzDummy;
  322.     int    i;
  323.  
  324.     gettimeofday(&tvNow, &tzDummy);
  325.     for (i = 0; i < 3; i++)
  326.     {
  327.         if (!(iTimersOn & (1 << i)))
  328.             continue;
  329.         if (atvTimers[i].tv_sec < tvNow.tv_sec ||
  330.             (atvTimers[i].tv_sec == tvNow.tv_sec &&
  331.              atvTimers[i].tv_usec < tvNow.tv_usec))
  332.         {
  333.             KillTimer(i);
  334.             FireTimer(i);
  335.         }
  336.     }
  337. }
  338.  
  339. int    SetTimer(int idTimer, int iTime)
  340. {
  341.     struct    timeval        tvNow;
  342.     struct    timezone    tzDummy;
  343.  
  344.     gettimeofday(&tvNow, &tzDummy);
  345.     atvTimers[idTimer] = tvNow;
  346.     atvTimers[idTimer].tv_usec += (long) iTime % 1000l * 1000l;
  347.     atvTimers[idTimer].tv_sec += iTime / 1000;
  348.     while (atvTimers[idTimer].tv_usec > 1000000l)
  349.     {
  350.         atvTimers[idTimer].tv_sec++;
  351.         atvTimers[idTimer].tv_usec -= 1000000l;
  352.     }
  353.     iTimersOn |= (1 << idTimer);
  354. }
  355.  
  356. int    KillTimer(int idTimer)
  357. {
  358.     iTimersOn &= ~(1 << idTimer);
  359. }
  360.  
  361. void    Shutdown(void)
  362. {
  363.     if (isatty(0))
  364.         UnInitTerm();
  365.     fprintf(stderr, "\nTwinSock Host Finished\n");
  366.     exit(0);
  367. }
  368.  
  369. int
  370. SendData(void *pvData, int iDataLen)
  371. {
  372.     int    iLen;
  373.     int    nWritten;
  374.  
  375.     if (bFlushing)
  376.         return iDataLen; /* Lie */
  377.     iLen = iDataLen;
  378.  
  379.     while (iLen > 0)
  380.     {
  381.         nWritten = write(1, pvData, iDataLen);
  382.         if (nWritten > 0)
  383.         {
  384.             pvData = (char *) pvData + nWritten;
  385.             iLen -= nWritten;
  386.         }
  387.     }
  388.     return iDataLen;
  389. }
  390.  
  391. void
  392. FlushInput(void)
  393. {
  394.     bFlushing = 1;
  395.     SetTimer(TIMER_ID_FLUSH, 1500);
  396. }
  397.  
  398. static void
  399. SendInitResponse(void)
  400. {
  401.     struct    tx_request txr;
  402.  
  403.     txr.iType = htons(FN_Init);
  404.     txr.nArgs = 0;
  405.     txr.nLen = htons(10);
  406.     txr.id = -1;
  407.     txr.nError = 0;
  408.     PacketTransmitData(&txr, 10, -2);
  409. }
  410.  
  411. void
  412. DataReceived(void *pvData, int iLen)
  413. {
  414.     static    struct tx_request *ptxr = 0;
  415.     static    struct tx_request txrHeader;
  416.     static    int    nBytes = 0;
  417.     short    nPktLen;
  418.     enum Functions ft;
  419.     int    nCopy;
  420.  
  421.     while (iLen)
  422.     {
  423.         if (nBytes < 10)
  424.         {
  425.             nCopy = 10 - nBytes;
  426.             if (nCopy > iLen)
  427.                 nCopy = iLen;
  428.             memcpy((char *) &txrHeader + nBytes, pvData, nCopy);
  429.             nBytes += nCopy;
  430.             pvData = (char *) pvData + nCopy;
  431.             iLen -= nCopy;
  432.             if (nBytes == 10)
  433.             {
  434.                 nPktLen = ntohs(txrHeader.nLen);
  435.                 ptxr = (struct tx_request *) malloc(sizeof(struct tx_request) + nPktLen - 10);
  436.                 memcpy(ptxr, &txrHeader, 10);
  437.             }
  438.         }
  439.         if (nBytes >= 10)
  440.         {
  441.             nPktLen = ntohs(txrHeader.nLen);
  442.             ft = (enum Functions) ntohs(txrHeader.iType);
  443.             nCopy = nPktLen - nBytes;
  444.             if (nCopy > iLen)
  445.                 nCopy = iLen;
  446.             if (nCopy)
  447.             {
  448.                 memcpy((char *) ptxr + nBytes, pvData, nCopy);
  449.                 nBytes += nCopy;
  450.                 pvData = (char *) pvData + nCopy;
  451.                 iLen -= nCopy;
  452.             }
  453.             if (nBytes == nPktLen)
  454.             {
  455.                 if (ft == FN_Init)
  456.                     SendInitResponse();
  457.                 else
  458.                     ResponseReceived(ptxr);
  459.                 free(ptxr);
  460.                 ptxr = 0;
  461.                 nBytes = 0;
  462.             }
  463.         }
  464.     }
  465. }
  466.