modules/sk/cd_socket.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. SK_cd_make
  2. SK_cd_free
  3. SK_cd_puts
  4. SK_cd_gets
  5. SK_cd_close
  6. SK_cd_printf

   1 /***************************************
   2   $Revision: 1.2 $
   3 
   4   Socket module - cd_socket.c - basic read/write socket routines defined
   5                                 in terms of connection data structures
   6                                 with timeouts and storing information about
   7                                 broken connections.
   8 
   9   Status: NOT REVUED, TESTED
  10 
  11   Design and implementation by Marek Bukowy.
  12 
  13   ******************/ /******************
  14   Copyright (c) 1999, 2000                           RIPE NCC
  15  
  16   All Rights Reserved
  17   
  18   Permission to use, copy, modify, and distribute this software and its
  19   documentation for any purpose and without fee is hereby granted,
  20   provided that the above copyright notice appear in all copies and that
  21   both that copyright notice and this permission notice appear in
  22   supporting documentation, and that the name of the author not be
  23   used in advertising or publicity pertaining to distribution of the
  24   software without specific, written prior permission.
  25   
  26   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  27   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  28   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  29   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  30   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  31   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  32   ***************************************/
  33 #include "sk.h"
  34 #include "stubs.h"
  35 #include "memwrap.h"
  36 /*+
  37  * -------------------------------------------------------------------
  38  * CD (connection data structure) varieties of the functions: 
  39  *   broken connections get registered in the connection structure
  40  *   as side effects.
  41  * by marek
  42  * -----------------------------------------------------------------
  43 +*/
  44 
  45 /* SK_cd_make */
  46 /*++++++++++++++++++++++++++++++++++++++
  47   
  48   Construct a connection data given the socket or file descriptor.
  49   Also performs the getpeername check and stores the IP in an allocated
  50   string.
  51 
  52   sk_conn_st *condat    pointer to where the data is to be stored.
  53 
  54   int  sock             The socket or file descriptor.
  55 
  56   unsigned timeout      Read timeout (used in SK_cd_gets) in seconds.
  57                         Value of 0 disables the timeout.
  58   ++++++++++++++++++++++++++++++++++++++*/
  59 void SK_cd_make(sk_conn_st *condat, int  sock, unsigned timeout)
     /* [<][>][^][v][top][bottom][index][help] */
  60 {
  61   memset(condat, 0, sizeof(sk_conn_st));
  62 
  63   condat->sock = sock;
  64 
  65   condat->ip = SK_getpeername(sock); 
  66   dieif(condat->ip == NULL);
  67 
  68   SK_getpeerip(sock, &(condat->rIP));
  69   condat->eIP =  condat->rIP;
  70 
  71   condat->rd_timeout.tv_sec = timeout;
  72 }
  73 
  74 
  75 /*++++++++++++++++++++++++++++++++++++++
  76   Destroys the data allocated and anchored by the connection data structure.
  77 
  78   sk_conn_st *condat   Pointer to the connection data structure.
  79 
  80   ++++++++++++++++++++++++++++++++++++++*/
  81 void SK_cd_free(sk_conn_st *condat)
     /* [<][>][^][v][top][bottom][index][help] */
  82 {
  83   wr_free(condat->ip);
  84 }
  85 
  86 /* SK_cd_puts() */
  87 /*++++++++++++++++++++++++++++++++++++++
  88 
  89    This function writes a character string out to a socket, unless 
  90    the connection is broken. 
  91 
  92    int SK_cd_puts         Returns the total_count of bytes written, 
  93                           or inverted error codes (negative numbers):
  94                           (- SK_DISCONNECT) on broken connection,
  95                           (- SK_INTERRUPT)  on control-c received,
  96                           (- SK_TIMEOUT)    on timeout.
  97 
  98    sk_conn_st *condat     Pointer to the connection data structure.
  99 
 100    char   *str            The buffer to be written to the socket.
 101 
 102   More:
 103        if the connection structure has bad status for this connection
 104        from previous calls, no write will be attempted.
 105 
 106   +html+ <PRE>
 107   Author:
 108         marek
 109 
 110   Side Effects:
 111        broken connections get registered in the connection structure 
 112         
 113   +html+ </PRE>
 114 
 115   ++++++++++++++++++++++++++++++++++++++*/
 116 int SK_cd_puts(sk_conn_st *condat, const char *str) 
     /* [<][>][^][v][top][bottom][index][help] */
 117 {
 118   int res;
 119   
 120   if( condat->rtc != 0 ) {
 121     return (-condat->rtc);
 122   }
 123 
 124   res = SK_puts(condat->sock, str);
 125 
 126   if( res < 0 ){
 127     /* set the corresponding rtc flag */
 128     condat->rtc |= (-res);
 129 
 130     switch( - res ) {
 131       /* dont know what to do and how to log */
 132     case SK_DISCONNECT:
 133     case SK_INTERRUPT:
 134       /*("Thread received a control-c\n");*/
 135     case SK_TIMEOUT:
 136       /*("Reading timed out\n");*/
 137       break;
 138     default:
 139       /* unexpected error code. bail out */
 140       die;
 141     }
 142   }
 143   return res;
 144 } /* SK_cd_puts() */
 145 
 146 /* SK_cd_gets() */
 147 /*++++++++++++++++++++++++++++++++++++++
 148 
 149   Read from a socket, until a linefeed character is received or the buffer
 150   fills up to the maximum size "count". If the connection data has non-zero
 151   timeout value for reading, it is used here between calls to read 
 152   the next 1 character.
 153 
 154    int SK_cd_gets      Returns the total_count of bytes read, 
 155                        or inverted error codes (negative numbers):
 156                        (- SK_DISCONNECT) on broken connection,
 157                        (- SK_TIMEOUT)    on timeout.
 158 
 159    sk_conn_st *condat  connection data
 160 
 161    char   *str         The buffer to store the data received from
 162                        the socket.
 163 
 164    size_t count        size of the buffer.
 165 
 166   More:
 167        if the connection structure has bad status for this connection
 168        from previous calls, no read will be attempted.
 169 
 170   +html+ <PRE>
 171   Author:
 172         marek
 173         
 174   Side Effects:
 175        broken connections get registered in the connection structure.
 176        
 177   +html+ </PRE>
 178 
 179   ++++++++++++++++++++++++++++++++++++++*/
 180 int SK_cd_gets(sk_conn_st *condat, char *str, size_t count) 
     /* [<][>][^][v][top][bottom][index][help] */
 181 {
 182   fd_set rset;
 183   struct timeval *ptm = & condat->rd_timeout;
 184   int readcount = 0;
 185     
 186   memset( str, 0, count);
 187   /* leave space for \0 */
 188   count--;
 189 
 190   FD_ZERO( &rset );
 191   FD_SET( condat->sock, &rset );
 192 
 193   if( ptm->tv_sec == 0 && ptm->tv_usec == 0) { /* if timeout undefined, 
 194                                                   do blocking I/O */
 195     ptm = NULL;
 196   }
 197 
 198   do {
 199     char buf[2];
 200     int sel = select( (condat->sock)+1, &rset, NULL, NULL, ptm);
 201     int ern = errno;
 202 
 203     dieif(sel < 0); /* we don't expect problems */
 204       
 205     if( sel == 0 ) {      
 206       condat->rtc |= SK_TIMEOUT;
 207       break;
 208     }
 209 
 210     else { 
 211       if(read( condat->sock, buf, 1) == 0 ) {
 212         condat->rtc |= SK_DISCONNECT;
 213         break;
 214       }
 215       str[readcount] = buf[0];
 216       readcount++;
 217       if( buf[0] == '\n' ) {
 218         break;
 219       }
 220     } 
 221   } while( readcount < count );
 222          
 223   return readcount;
 224 
 225 } /* SK_cd_gets() */
 226 
 227 
 228 /*++++++++++++++++++++++++++++++++++++++
 229   Wrapper around the close(2) system call, 
 230 
 231   int SK_cd_close         returns the error codes of close(2).
 232 
 233   sk_conn_st *condat      Pointer to the connection data structure.
 234 
 235     +html+ <PRE>
 236   Author:
 237         marek
 238     +html+ </PRE>
 239   ++++++++++++++++++++++++++++++++++++++*/
 240 int SK_cd_close(sk_conn_st *condat) {
     /* [<][>][^][v][top][bottom][index][help] */
 241   return SK_close(condat->sock);
 242 } /* SK_cd_close() */
 243 
 244 
 245 /* SK_cd_printf() */
 246 /*++++++++++++++++++++++++++++++++++++++
 247 
 248   Printf-like function to print to socket/file specified by connection
 249   data structure. First writes the text to a temporary buffer, then
 250   uses SK_cd_puts to print it. Maintains a 2K static buffer, and allocates
 251   more memory if this is not enough.
 252 
 253   int SK_cd_printf       Returns the SK_cd_puts error code/return value.
 254 
 255   sk_conn_st *condat     Pointer to the connection data structure.
 256 
 257   char *txt              Format text to be written
 258 
 259   ...                    more arguments (like printf)
 260 
 261   
 262     +html+ <PRE>
 263   Author:
 264         marek
 265     +html+ </PRE>
 266   ++++++++++++++++++++++++++++++++++++++*/
 267 int SK_cd_printf(sk_conn_st *condat, char *txt, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 268 {
 269 #define SKBUFLEN 2047
 270   va_list   ap;
 271   char      buffer[SKBUFLEN+1];
 272   unsigned  len;
 273   char      *newbuf = NULL;
 274   char      *finalbuf = buffer; /* points to where the text REALLY is */
 275  
 276   /* vsnprintf returns the number of character it WOULD write if it could.
 277      So we assume the buffer to be of adequate size for most cases,
 278      and if it isn't, then we allocate to newbuf and call v*printf again 
 279   */
 280   va_start(ap, txt);
 281   len = vsnprintf(buffer, SKBUFLEN, txt, ap);
 282   va_end(ap);
 283   
 284   if( len > SKBUFLEN ) {
 285     dieif(!NOERR(wr_malloc( (void **)& newbuf, len+1)));
 286     
 287     va_start(ap, txt);
 288     vsnprintf(newbuf, len, txt, ap);
 289     va_end(ap);   
 290     
 291     finalbuf = newbuf;
 292   }  
 293   /* terminate */
 294   finalbuf[len] = 0;
 295 
 296   /* reuse len */
 297   len = SK_cd_puts(condat, finalbuf);
 298 
 299   if(newbuf != NULL) {
 300     wr_free(newbuf);
 301   }
 302 
 303   return len;
 304 } /* SK_cd_printf() */

/* [<][>][^][v][top][bottom][index][help] */