home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 March / CMCD0304.ISO / Software / Freeware / Programare / nullsoft / nsis20.exe / Contrib / NSISdl / connection.cpp < prev    next >
C/C++ Source or Header  |  2002-12-04  |  11KB  |  446 lines

  1. /*
  2. ** JNetLib
  3. ** Copyright (C) 2000-2001 Nullsoft, Inc.
  4. ** Author: Justin Frankel
  5. ** File: connection.cpp - JNL TCP connection implementation
  6. ** License: see jnetlib.h
  7. */
  8.  
  9. #include "netinc.h"
  10. #include "util.h"
  11. #include "connection.h"
  12.  
  13.  
  14. JNL_Connection::JNL_Connection(JNL_AsyncDNS *dns, int sendbufsize, int recvbufsize)
  15. {
  16.   m_errorstr="";
  17.   if (dns == JNL_CONNECTION_AUTODNS)
  18.   {
  19.     m_dns=new JNL_AsyncDNS();
  20.     m_dns_owned=1;
  21.   }
  22.   else
  23.   {
  24.     m_dns=dns;
  25.     m_dns_owned=0;
  26.   }
  27.   m_recv_buffer_len=recvbufsize;
  28.   m_send_buffer_len=sendbufsize;
  29.   m_recv_buffer=(char*)malloc(m_recv_buffer_len);
  30.   m_send_buffer=(char*)malloc(m_send_buffer_len);
  31.   m_socket=-1;
  32.   m_remote_port=0;
  33.   m_state=STATE_NOCONNECTION;
  34.   m_recv_len=m_recv_pos=0;
  35.   m_send_len=m_send_pos=0;
  36.   m_host[0]=0;
  37.   memset(&m_saddr,0,sizeof(m_saddr));
  38. }
  39.  
  40. void JNL_Connection::connect(int s, struct sockaddr_in *loc)
  41. {
  42.   close(1);
  43.   m_socket=s;
  44.   m_remote_port=0;
  45.   m_dns=NULL;
  46.   if (loc) m_saddr=*loc;
  47.   else memset(&m_saddr,0,sizeof(m_saddr));
  48.   if (m_socket != -1)
  49.   {
  50.     SET_SOCK_BLOCK(m_socket,0);
  51.     m_state=STATE_CONNECTED;
  52.   }
  53.   else 
  54.   {
  55.     m_errorstr="invalid socket passed to connect";
  56.     m_state=STATE_ERROR;
  57.   }
  58. }
  59.  
  60. void JNL_Connection::connect(char *hostname, int port)
  61. {
  62.   close(1);
  63.   m_remote_port=(short)port;
  64.   m_socket=::socket(AF_INET,SOCK_STREAM,0);
  65.   if (m_socket==-1)
  66.   {
  67.     m_errorstr="creating socket";
  68.     m_state=STATE_ERROR;
  69.   }
  70.   else
  71.   {
  72.     SET_SOCK_BLOCK(m_socket,0);
  73.     strncpy(m_host,hostname,sizeof(m_host)-1);
  74.     m_host[sizeof(m_host)-1]=0;
  75.     memset(&m_saddr,0,sizeof(m_saddr));
  76.     if (!m_host[0])
  77.     {
  78.       m_errorstr="empty hostname";
  79.       m_state=STATE_ERROR;
  80.     }
  81.     else
  82.     {
  83.       m_state=STATE_RESOLVING;
  84.           m_saddr.sin_family=AF_INET;
  85.       m_saddr.sin_port=htons((unsigned short)port);
  86.       m_saddr.sin_addr.s_addr=inet_addr(hostname);
  87.     }
  88.   }
  89. }
  90.  
  91. JNL_Connection::~JNL_Connection()
  92. {
  93.   if (m_socket >= 0)
  94.   {
  95.     ::shutdown(m_socket, SHUT_RDWR);
  96.     ::closesocket(m_socket);
  97.     m_socket=-1;
  98.   }
  99.   free(m_recv_buffer);
  100.   free(m_send_buffer);
  101.   if (m_dns_owned) 
  102.   {
  103.     delete m_dns;
  104.   }
  105. }
  106.  
  107. void JNL_Connection::run(int max_send_bytes, int max_recv_bytes, int *bytes_sent, int *bytes_rcvd)
  108. {
  109.   int bytes_allowed_to_send=(max_send_bytes<0)?m_send_buffer_len:max_send_bytes;
  110.   int bytes_allowed_to_recv=(max_recv_bytes<0)?m_recv_buffer_len:max_recv_bytes;
  111.  
  112.   if (bytes_sent) *bytes_sent=0;
  113.   if (bytes_rcvd) *bytes_rcvd=0;
  114.  
  115.   switch (m_state)
  116.   {
  117.     case STATE_RESOLVING:
  118.       if (m_saddr.sin_addr.s_addr == INADDR_NONE)
  119.       {
  120.         int a=m_dns?m_dns->resolve(m_host,(unsigned long int *)&m_saddr.sin_addr.s_addr):-1;
  121.         if (!a) { m_state=STATE_CONNECTING; }
  122.         else if (a == 1)
  123.         {
  124.           m_state=STATE_RESOLVING; 
  125.           break;
  126.         }
  127.         else
  128.         {
  129.           m_errorstr="resolving hostname"; 
  130.           m_state=STATE_ERROR; 
  131.           return;
  132.         }
  133.       }
  134.       if (!::connect(m_socket,(struct sockaddr *)&m_saddr,16)) 
  135.       {
  136.         m_state=STATE_CONNECTED;
  137.       }
  138.       else if (ERRNO!=EINPROGRESS)
  139.       {
  140.         m_errorstr="connecting to host";
  141.         m_state=STATE_ERROR;
  142.       }
  143.       else { m_state=STATE_CONNECTING; }
  144.     break;
  145.     case STATE_CONNECTING:
  146.       {        
  147.         fd_set f[3];
  148.         FD_ZERO(&f[0]);
  149.         FD_ZERO(&f[1]);
  150.         FD_ZERO(&f[2]);
  151.         FD_SET(m_socket,&f[0]);
  152.         FD_SET(m_socket,&f[1]);
  153.         FD_SET(m_socket,&f[2]);
  154.         struct timeval tv;
  155.         memset(&tv,0,sizeof(tv));
  156.         if (select(m_socket+1,&f[0],&f[1],&f[2],&tv)==-1)
  157.         {
  158.           m_errorstr="connecting to host (calling select())";
  159.           m_state=STATE_ERROR;
  160.         }
  161.         else if (FD_ISSET(m_socket,&f[1])) 
  162.         {
  163.           m_state=STATE_CONNECTED;
  164.         }
  165.         else if (FD_ISSET(m_socket,&f[2]))
  166.         {
  167.           m_errorstr="connecting to host";
  168.           m_state=STATE_ERROR;
  169.         }
  170.       }
  171.     break;
  172.     case STATE_CONNECTED:
  173.     case STATE_CLOSING:
  174.       if (m_send_len>0 && bytes_allowed_to_send>0)
  175.       {
  176.         int len=m_send_buffer_len-m_send_pos;
  177.         if (len > m_send_len) len=m_send_len;
  178.         if (len > bytes_allowed_to_send) len=bytes_allowed_to_send;
  179.         if (len > 0)
  180.         {
  181.           int res=::send(m_socket,m_send_buffer+m_send_pos,len,0);
  182.           if (res==-1 && ERRNO != EWOULDBLOCK)
  183.           {            
  184. //            m_state=STATE_CLOSED;
  185. //            return;
  186.           }
  187.           if (res>0)
  188.           {
  189.             bytes_allowed_to_send-=res;
  190.             if (bytes_sent) *bytes_sent+=res;
  191.             m_send_pos+=res;
  192.             m_send_len-=res;
  193.           }
  194.         }
  195.         if (m_send_pos>=m_send_buffer_len) 
  196.         {
  197.           m_send_pos=0;
  198.           if (m_send_len>0)
  199.           {
  200.             len=m_send_buffer_len-m_send_pos;
  201.             if (len > m_send_len) len=m_send_len;
  202.             if (len > bytes_allowed_to_send) len=bytes_allowed_to_send;
  203.             int res=::send(m_socket,m_send_buffer+m_send_pos,len,0);
  204.             if (res==-1 && ERRNO != EWOULDBLOCK)
  205.             {
  206. //              m_state=STATE_CLOSED;
  207.             }
  208.             if (res>0)
  209.             {
  210.               bytes_allowed_to_send-=res;
  211.               if (bytes_sent) *bytes_sent+=res;
  212.               m_send_pos+=res;
  213.               m_send_len-=res;
  214.             }
  215.           }
  216.         }
  217.       }
  218.       if (m_recv_len<m_recv_buffer_len)
  219.       {
  220.         int len=m_recv_buffer_len-m_recv_pos;
  221.         if (len > m_recv_buffer_len-m_recv_len) len=m_recv_buffer_len-m_recv_len;
  222.         if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv;
  223.         if (len>0)
  224.         {
  225.           int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0);
  226.           if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK))
  227.           {        
  228.             m_state=STATE_CLOSED;
  229.             break;
  230.           }
  231.           if (res > 0)
  232.           {
  233.             bytes_allowed_to_recv-=res;
  234.             if (bytes_rcvd) *bytes_rcvd+=res;
  235.             m_recv_pos+=res;
  236.             m_recv_len+=res;
  237.           }
  238.         }
  239.         if (m_recv_pos >= m_recv_buffer_len)
  240.         {
  241.           m_recv_pos=0;
  242.           if (m_recv_len < m_recv_buffer_len)
  243.           {
  244.             len=m_recv_buffer_len-m_recv_len;
  245.             if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv;
  246.             if (len > 0)
  247.             {
  248.               int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0);
  249.               if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK))
  250.               {        
  251.                 m_state=STATE_CLOSED;
  252.                 break;
  253.               }
  254.               if (res > 0)
  255.               {
  256.                 bytes_allowed_to_recv-=res;
  257.                 if (bytes_rcvd) *bytes_rcvd+=res;
  258.                 m_recv_pos+=res;
  259.                 m_recv_len+=res;
  260.               }
  261.             }
  262.           }
  263.         }
  264.       }
  265.       if (m_state == STATE_CLOSING)
  266.       {
  267.         if (m_send_len < 1) m_state = STATE_CLOSED;
  268.       }
  269.     break;
  270.     default: break;
  271.   }
  272. }
  273.  
  274. void JNL_Connection::close(int quick)
  275. {
  276.   if (quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING)
  277.   {
  278.     m_state=STATE_CLOSED;
  279.     if (m_socket >= 0)
  280.     {
  281.       ::shutdown(m_socket, SHUT_RDWR);
  282.       ::closesocket(m_socket);
  283.     }
  284.     m_socket=-1;
  285.     memset(m_recv_buffer,0,m_recv_buffer_len);
  286.     memset(m_send_buffer,0,m_send_buffer_len);
  287.     m_remote_port=0;
  288.     m_recv_len=m_recv_pos=0;
  289.     m_send_len=m_send_pos=0;
  290.     m_host[0]=0;
  291.     memset(&m_saddr,0,sizeof(m_saddr));
  292.   }
  293.   else
  294.   {
  295.     if (m_state == STATE_CONNECTED) m_state=STATE_CLOSING;
  296.   }
  297. }
  298.  
  299. int JNL_Connection::send_bytes_in_queue(void)
  300. {
  301.   return m_send_len;
  302. }
  303.  
  304. int JNL_Connection::send_bytes_available(void)
  305. {
  306.   return m_send_buffer_len-m_send_len;
  307. }
  308.  
  309. int JNL_Connection::send(char *data, int length)
  310. {
  311.   if (length > send_bytes_available())
  312.   {
  313.     return -1;
  314.   }
  315.   
  316.   int write_pos=m_send_pos+m_send_len;
  317.   if (write_pos >= m_send_buffer_len) 
  318.   {
  319.     write_pos-=m_send_buffer_len;
  320.   }
  321.  
  322.   int len=m_send_buffer_len-write_pos;
  323.   if (len > length) 
  324.   {
  325.     len=length;
  326.   }
  327.  
  328.   memcpy(m_send_buffer+write_pos,data,len);
  329.   if (length > len)
  330.   {
  331.     memcpy(m_send_buffer,data+len,length-len);
  332.   }
  333.   m_send_len+=length;
  334.   return 0;
  335. }
  336.  
  337. int JNL_Connection::send_string(char *line)
  338. {
  339.   return send(line,strlen(line));
  340. }
  341.  
  342. int JNL_Connection::recv_bytes_available(void)
  343. {
  344.   return m_recv_len;
  345. }
  346.  
  347. int JNL_Connection::peek_bytes(char *data, int maxlength)
  348. {
  349.   if (maxlength > m_recv_len)
  350.   {
  351.     maxlength=m_recv_len;
  352.   }
  353.   int read_pos=m_recv_pos-m_recv_len;
  354.   if (read_pos < 0) 
  355.   {
  356.     read_pos += m_recv_buffer_len;
  357.   }
  358.   int len=m_recv_buffer_len-read_pos;
  359.   if (len > maxlength)
  360.   {
  361.     len=maxlength;
  362.   }
  363.   memcpy(data,m_recv_buffer+read_pos,len);
  364.   if (len < maxlength)
  365.   {
  366.     memcpy(data+len,m_recv_buffer,maxlength-len);
  367.   }
  368.  
  369.   return maxlength;
  370. }
  371.  
  372. int JNL_Connection::recv_bytes(char *data, int maxlength)
  373. {
  374.   
  375.   int ml=peek_bytes(data,maxlength);
  376.   m_recv_len-=ml;
  377.   return ml;
  378. }
  379.  
  380. int JNL_Connection::getbfromrecv(int pos, int remove)
  381. {
  382.   int read_pos=m_recv_pos-m_recv_len + pos;
  383.   if (pos < 0 || pos > m_recv_len) return -1;
  384.   if (read_pos < 0) 
  385.   {
  386.     read_pos += m_recv_buffer_len;
  387.   }
  388.   if (read_pos >= m_recv_buffer_len)
  389.   {
  390.     read_pos-=m_recv_buffer_len;
  391.   }
  392.   if (remove) m_recv_len--;
  393.   return m_recv_buffer[read_pos];
  394. }
  395.  
  396. int JNL_Connection::recv_lines_available(void)
  397. {
  398.   int l=recv_bytes_available();
  399.   int lcount=0;
  400.   int lastch=0;
  401.   int pos;
  402.   for (pos=0; pos < l; pos ++)
  403.   {
  404.     int t=getbfromrecv(pos,0);
  405.     if (t == -1) return lcount;
  406.     if ((t=='\r' || t=='\n') &&(
  407.          (lastch != '\r' && lastch != '\n') || lastch==t
  408.         )) lcount++;
  409.     lastch=t;
  410.   }
  411.   return lcount;
  412. }
  413.  
  414. int JNL_Connection::recv_line(char *line, int maxlength)
  415. {
  416.   if (maxlength > m_recv_len) maxlength=m_recv_len;
  417.   while (maxlength--)
  418.   {
  419.     int t=getbfromrecv(0,1);
  420.     if (t == -1) 
  421.     {
  422.       *line=0;
  423.       return 0;
  424.     }
  425.     if (t == '\r' || t == '\n')
  426.     {
  427.       int r=getbfromrecv(0,0);
  428.       if ((r == '\r' || r == '\n') && r != t) getbfromrecv(0,1);
  429.       *line=0;
  430.       return 0;
  431.     }
  432.     *line++=(char)t;
  433.   }
  434.   return 1;
  435. }
  436.  
  437. unsigned long JNL_Connection::get_interface(void)
  438. {
  439.   if (m_socket==-1) return 0;
  440.   struct sockaddr_in sin;
  441.   memset(&sin,0,sizeof(sin));
  442.   socklen_t len=16;
  443.   if (::getsockname(m_socket,(struct sockaddr *)&sin,&len)) return 0;
  444.   return (unsigned long) sin.sin_addr.s_addr;
  445. }
  446.