/[monit]/monit/socket.c
ViewVC logotype

Diff of /monit/socket.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.44 by hauk, Wed Jun 8 22:54:17 2005 UTC revision 1.45 by hauk, Tue Oct 18 20:37:10 2005 UTC
# Line 57  Line 57 
57    
58  /* ------------------------------------------------------------- Definitions */  /* ------------------------------------------------------------- Definitions */
59    
60  #define TYPE_LOCAL  0  #define TYPE_LOCAL   0
61  #define TYPE_ACCEPT 1  #define TYPE_ACCEPT 1
62    #define RBUFFER_SIZE 1024
63    
64  struct Socket_T {  struct Socket_T {
65    int port;     int port;
66    int type;     int type;
67    int socket;     int socket;
68    char *host;     char *host;
69    Port_T Port;     Port_T Port;
70    int timeout;     int timeout;
71    int connection_type;     int connection_type;
72    ssl_connection *ssl;     ssl_connection *ssl;
73    ssl_server_connection *sslserver;     ssl_server_connection *sslserver;
74       int length;
75       int offset;
76       unsigned char buffer[RBUFFER_SIZE+1];
77  };  };
78    
79    
80    /* -------------------------------------------------------------- Prototypes */
81    
82    
83    static int fill(Socket_T S);
84    
85    
86  /* ------------------------------------------------------------------ Public */  /* ------------------------------------------------------------------ Public */
87    
88    
# Line 91  struct Socket_T { Line 101  struct Socket_T {
101   * @return The connected Socket or NULL if an error occurred   * @return The connected Socket or NULL if an error occurred
102   */   */
103  Socket_T socket_new(const char *host, int port, int type, int use_ssl,  Socket_T socket_new(const char *host, int port, int type, int use_ssl,
104                      int timeout) {                                         int timeout) {
105    
106    Ssl_T ssl= {use_ssl, SSL_VERSION_AUTO, NULL};     Ssl_T ssl= {use_ssl, SSL_VERSION_AUTO, NULL};
107    
108    return socket_create_t(host, port, type, ssl, timeout);     return socket_create_t(host, port, type, ssl, timeout);
109        
110  }  }
111    
112    
# Line 107  Socket_T socket_new(const char *host, in Line 117  Socket_T socket_new(const char *host, in
117   */   */
118  Socket_T socket_create(void *port) {  Socket_T socket_create(void *port) {
119    
120    int s;     int s;
121    Port_T p= port;     Port_T p= port;
122    
123    ASSERT(port);     ASSERT(port);
124    
125    if((s= create_generic_socket(p)) != -1) {     if((s= create_generic_socket(p)) != -1) {
126    
127      Socket_T S= NULL;         Socket_T S= NULL;
128    
129      NEW(S);         NEW(S);
130      S->socket= s;         S->socket= s;
131      S->type= p->type;         S->length= 0;
132      S->port= p->port;         S->offset= 0;
133      S->timeout= p->timeout;         S->type= p->type;
134      S->connection_type= TYPE_LOCAL;         S->port= p->port;
135               S->timeout= p->timeout;
136      if(p->family==AF_UNIX) {         S->connection_type= TYPE_LOCAL;
137        S->host= xstrdup(LOCALHOST);        
138      } else {         if(p->family==AF_UNIX) {
139        S->host= xstrdup(p->hostname);             S->host= xstrdup(LOCALHOST);
140      }         } else {
141               S->host= xstrdup(p->hostname);
142      if(p->SSL.use_ssl) {         }
143        if(! (S->ssl= new_ssl_connection(NULL, p->SSL.version))) {  
144          goto ssl_error;         if(p->SSL.use_ssl) {
145        }             if(! (S->ssl= new_ssl_connection(NULL, p->SSL.version))) {
146        if(! embed_ssl_socket(S->ssl, S->socket)) {               goto ssl_error;
147          goto ssl_error;             }
148        }             if(! embed_ssl_socket(S->ssl, S->socket)) {
149        if(p->SSL.certmd5) {               goto ssl_error;
150          if(! check_ssl_md5sum(S->ssl, p->SSL.certmd5)) {             }
151            goto ssl_error;             if(p->SSL.certmd5) {
152          }               if(! check_ssl_md5sum(S->ssl, p->SSL.certmd5)) {
153        }                 goto ssl_error;
154      }                 }
155               }
156      S->Port= port;         }
157    
158      return S;         S->Port= port;
159    
160      ssl_error:         return S;
161      socket_free(&S);  
162      return NULL;         ssl_error:
163           socket_free(&S);
164           return NULL;
165    
166    }     }
167    
168    return NULL;     return NULL;
169    
170  }  }
171    
# Line 170  Socket_T socket_create(void *port) { Line 182  Socket_T socket_create(void *port) {
182   * @return The connected Socket or NULL if an error occurred   * @return The connected Socket or NULL if an error occurred
183   */   */
184  Socket_T socket_create_t(const char *host, int port, int type, Ssl_T ssl,  Socket_T socket_create_t(const char *host, int port, int type, Ssl_T ssl,
185                           int timeout) {         int timeout) {
   
   int s;  
   int proto= type==SOCKET_UDP?SOCK_DGRAM:SOCK_STREAM;  
     
   ASSERT(host);  
   ASSERT((type==SOCKET_UDP)||(type==SOCKET_TCP));  
   if(ssl.use_ssl) {  
     ASSERT(type==SOCKET_TCP);  
   }  
   ASSERT(timeout>0);  
186    
187    if((s= create_socket(host, port, proto, timeout)) != -1) {     int s;
188           int proto= type==SOCKET_UDP?SOCK_DGRAM:SOCK_STREAM;
189      Socket_T S= NULL;    
190       ASSERT(host);
191       ASSERT((type==SOCKET_UDP)||(type==SOCKET_TCP));
192       if(ssl.use_ssl) {
193           ASSERT(type==SOCKET_TCP);
194       }
195       ASSERT(timeout>0);
196    
197       if((s= create_socket(host, port, proto, timeout)) != -1) {
198          
199           Socket_T S= NULL;
200    
201      NEW(S);         NEW(S);
202      S->socket= s;         S->socket= s;
203      S->port= port;         S->length= 0;
204      S->type= proto;         S->offset= 0;
205      S->timeout= timeout;         S->port= port;
206      S->host= xstrdup(host);         S->type= proto;
207      S->connection_type= TYPE_LOCAL;         S->timeout= timeout;
208               S->host= xstrdup(host);
209      if(ssl.use_ssl) {         S->connection_type= TYPE_LOCAL;
210        if(! (S->ssl= new_ssl_connection(NULL, ssl.version))) {        
211          goto ssl_error;         if(ssl.use_ssl) {
212        }             if(! (S->ssl= new_ssl_connection(NULL, ssl.version))) {
213        if(! embed_ssl_socket(S->ssl, S->socket)) {               goto ssl_error;
214          goto ssl_error;             }
215        }             if(! embed_ssl_socket(S->ssl, S->socket)) {
216        if(ssl.certmd5) {               goto ssl_error;
217          if(! check_ssl_md5sum(S->ssl, ssl.certmd5)) {             }
218            goto ssl_error;             if(ssl.certmd5) {
219          }               if(! check_ssl_md5sum(S->ssl, ssl.certmd5)) {
220        }                 goto ssl_error;
221      }                 }
222                   }
223      return S;         }
224              
225      ssl_error:         return S;
226      socket_free(&S);        
227      return NULL;         ssl_error:
228           socket_free(&S);
229    }         return NULL;
230      
231    return NULL;     }
232      
233       return NULL;
234    
235  }  }
236    
# Line 235  Socket_T socket_create_t(const char *hos Line 249  Socket_T socket_create_t(const char *hos
249   * @return A Socket or NULL if an error occurred   * @return A Socket or NULL if an error occurred
250   */   */
251  Socket_T socket_create_a(int socket, const char *remote_host,  Socket_T socket_create_a(int socket, const char *remote_host,
252                           int port, void *sslserver) {         int port, void *sslserver) {
253    
254    Socket_T S;     Socket_T S;
255    
256    ASSERT(socket>=0);     ASSERT(socket>=0);
257    ASSERT(remote_host);     ASSERT(remote_host);
258    
259    NEW(S);     NEW(S);
260    S->port= port;     S->length= 0;
261    S->socket= socket;     S->offset= 0;
262    S->type= SOCK_STREAM;     S->port= port;
263    S->timeout= NET_TIMEOUT;     S->socket= socket;
264    S->host= xstrdup(remote_host);     S->type= SOCK_STREAM;
265    S->connection_type= TYPE_ACCEPT;     S->timeout= NET_TIMEOUT;
266         S->host= xstrdup(remote_host);
267    if(sslserver) {     S->connection_type= TYPE_ACCEPT;
268      S->sslserver= sslserver;    
269      if(! (S->ssl= insert_accepted_ssl_socket(S->sslserver))) {     if(sslserver) {
270        goto ssl_error;         S->sslserver= sslserver;
271      }         if(! (S->ssl= insert_accepted_ssl_socket(S->sslserver))) {
272      if(! embed_accepted_ssl_socket(S->ssl, S->socket)) {             goto ssl_error;
273        goto ssl_error;         }
274      }         if(! embed_accepted_ssl_socket(S->ssl, S->socket)) {
275    }             goto ssl_error;
276             }
277    return S;     }
278        
279    ssl_error:     return S;
280    socket_free(&S);    
281    return NULL;     ssl_error:
282         socket_free(&S);
283       return NULL;
284      
285  }  }
286    
287    
# Line 276  Socket_T socket_create_a(int socket, con Line 292  Socket_T socket_create_a(int socket, con
292   */   */
293  void socket_free(Socket_T *S) {  void socket_free(Socket_T *S) {
294    
295    ASSERT(S && *S);     ASSERT(S && *S);
296    
297  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
298    if((*S)->ssl && (*S)->ssl->handler) {     if((*S)->ssl && (*S)->ssl->handler) {
299      if((*S)->connection_type==TYPE_LOCAL) {         if((*S)->connection_type==TYPE_LOCAL) {
300        close_ssl_socket((*S)->ssl);             close_ssl_socket((*S)->ssl);
301        delete_ssl_socket((*S)->ssl);             delete_ssl_socket((*S)->ssl);
302      } else if((*S)->connection_type==TYPE_ACCEPT && (*S)->sslserver) {         } else if((*S)->connection_type==TYPE_ACCEPT && (*S)->sslserver) {
303        close_accepted_ssl_socket((*S)->sslserver, (*S)->ssl);             close_accepted_ssl_socket((*S)->sslserver, (*S)->ssl);
304      }         }
305    }     }
306  #endif  #endif
307    
308    close_socket((*S)->socket);     close_socket((*S)->socket);
309    FREE((*S)->host);     FREE((*S)->host);
310    FREE(*S);     FREE(*S);
311        
312  }  }
313    
314    
# Line 306  void socket_free(Socket_T *S) { Line 322  void socket_free(Socket_T *S) {
322   */   */
323  int socket_is_ready(Socket_T S) {  int socket_is_ready(Socket_T S) {
324    
325    ASSERT(S);     ASSERT(S);
326        
327    switch(S->type) {     switch(S->type) {
328    
329      case SOCK_STREAM:         case SOCK_STREAM:
330        return check_socket(S->socket);             return check_socket(S->socket);
331    
332      case SOCK_DGRAM:         case SOCK_DGRAM:
333        return check_udp_socket(S->socket);             return check_udp_socket(S->socket);
334    
335      default:         default:
336        break;             break;
337    }     }
338    
339    return FALSE;     return FALSE;
340    
341  }  }
342    
# Line 332  int socket_is_ready(Socket_T S) { Line 348  int socket_is_ready(Socket_T S) {
348   */   */
349  int socket_get_socket(Socket_T S) {  int socket_get_socket(Socket_T S) {
350    
351    ASSERT(S);     ASSERT(S);
352        
353    return S->socket;     return S->socket;
354    
355  }  }
356    
# Line 346  int socket_get_socket(Socket_T S) { Line 362  int socket_get_socket(Socket_T S) {
362   */   */
363  int socket_get_type(Socket_T S) {  int socket_get_type(Socket_T S) {
364    
365    ASSERT(S);     ASSERT(S);
366        
367    return S->type;     return S->type;
368    
369  }  }
370    
# Line 361  int socket_get_type(Socket_T S) { Line 377  int socket_get_type(Socket_T S) {
377   */   */
378  void *socket_get_Port(Socket_T S) {  void *socket_get_Port(Socket_T S) {
379    
380    ASSERT(S);     ASSERT(S);
381        
382    return S->Port;     return S->Port;
383    
384  }  }
385    
# Line 375  void *socket_get_Port(Socket_T S) { Line 391  void *socket_get_Port(Socket_T S) {
391   */   */
392  int socket_get_remote_port(Socket_T S) {  int socket_get_remote_port(Socket_T S) {
393    
394    ASSERT(S);     ASSERT(S);
395        
396    return S->port;     return S->port;
397    
398  }  }
399    
# Line 389  int socket_get_remote_port(Socket_T S) { Line 405  int socket_get_remote_port(Socket_T S) {
405   * @return The remote host   * @return The remote host
406   */   */
407  const char *socket_get_remote_host(Socket_T S) {  const char *socket_get_remote_host(Socket_T S) {
408        
409    ASSERT(S);     ASSERT(S);
410        
411    return S->host;     return S->host;
412    
413  }  }
414    
# Line 409  const char *socket_get_remote_host(Socke Line 425  const char *socket_get_remote_host(Socke
425   */   */
426  int socket_print(Socket_T S, const char *m, ...) {  int socket_print(Socket_T S, const char *m, ...) {
427    
428    int n;     int n;
429    long l;     long l;
430    va_list ap;     va_list ap;
431    char *buf= NULL;     char *buf= NULL;
432    
433    ASSERT(S);     ASSERT(S);
434    ASSERT(m);     ASSERT(m);
435    
436    va_start(ap, m);     va_start(ap, m);
437    buf= Util_formatString(m, ap, &l);     buf= Util_formatString(m, ap, &l);
438    va_end(ap);     va_end(ap);
439        
440    n= socket_write(S, buf, l);     n= socket_write(S, buf, l);
441    FREE(buf);     FREE(buf);
442        
443    return n;     return n;
444    
445  }  }
446    
# Line 438  int socket_print(Socket_T S, const char Line 454  int socket_print(Socket_T S, const char
454   */   */
455  int socket_write(Socket_T S, void *b, int size) {  int socket_write(Socket_T S, void *b, int size) {
456    
457    int n= 0;     int n= 0;
458    void *p= b;     void *p= b;
459        
460    ASSERT(S);     ASSERT(S);
461    
462    while(size > 0) {     while(size > 0) {
463              
464      if(S->ssl) {         if(S->ssl) {
465        n= send_ssl_socket(S->ssl, p, size);             n= send_ssl_socket(S->ssl, p, size);
466      } else {         } else {
467        n= sock_write(S->socket,  p, size);             n= sock_write(S->socket,  p, size);
468      }         }
   
     if(n <= 0) break;  
     p+= n;  
     size-= n;  
469    
470    }         if(n <= 0) break;
471           p+= n;
472           size-= n;
473    
474    if(n < 0) {     }
475      /* No write or a partial write is an error */  
476      return -1;     if(n < 0) {
477    }         /* No write or a partial write is an error */
478             return -1;
479    return  (int)(p - b);     }
480      
481       return  (int)(p - b);
482    
483    }
484    
485    
486    /**
487     * Read a single byte. The byte is returned as an int in the range 0
488     * to 255.
489     * @param S A Socket_T object
490     * @return The byte read, or -1 if the end of the stream has been reached
491     */
492    int Socket_readByte(Socket_T S) {
493    
494       ASSERT(S);
495                  
496       if(S->offset >= S->length) {
497          if(fill(S) <= 0)
498            return -1;
499       }
500      
501       return S->buffer[S->offset++];
502      
503  }  }
504    
505    
# Line 476  int socket_write(Socket_T S, void *b, in Line 512  int socket_write(Socket_T S, void *b, in
512   */   */
513  int socket_read(Socket_T S, void *b, int size) {  int socket_read(Socket_T S, void *b, int size) {
514    
515    int n= 0;    int c;
516    void *p= b;    unsigned char *p= (unsigned char*)b;
   int timeout= 0;  
517        
518    ASSERT(S);    ASSERT(S);
519        
520    timeout= S->timeout;    while((size-- > 0) && ((c= Socket_readByte(S)) >= 0)) {
521              *p++= c;
   while(size > 0) {  
     if(S->ssl) {  
       n= recv_ssl_socket(S->ssl, p, size, timeout);  
     } else {  
       n= sock_read(S->socket, p, size, timeout);  
     }  
     if(n <= 0) break;  
     p+= n;  
     size-= n;  
     /* We managed to read some bytes and we only keep on reading  
      * available data, otherwise we return with what we have read  
      */  
     timeout= 0;  
522    }    }
523        
524      return  (int)p - (int)b;
525    
   if(n < 0 && p==b) {  
     return -1;  
   }  
     
   return (int)(p - b);  
   
526  }  }
527    
528    
# Line 512  int socket_read(Socket_T S, void *b, int Line 530  int socket_read(Socket_T S, void *b, int
530   * Reads in at most one less than size <code>characters</code> and   * Reads in at most one less than size <code>characters</code> and
531   * stores them into the buffer pointed to by s. Reading stops after   * stores them into the buffer pointed to by s. Reading stops after
532   * an EOF or a newline.  If a newline is read, it is stored into the   * an EOF or a newline.  If a newline is read, it is stored into the
533   * buffer.  A '\0' is stored after the last character in the buffer.   * buffer.   A '\0' is stored after the last character in the buffer.
534   * @unnecessary S A Socket_T object   * @unnecessary S A Socket_T object
535   * @unnecessary s A character buffer to store the string in   * @unnecessary s A character buffer to store the string in
536   * @param size The size of the string buffer, s   * @param size The size of the string buffer, s
# Line 521  int socket_read(Socket_T S, void *b, int Line 539  int socket_read(Socket_T S, void *b, int
539   */   */
540  char *socket_readln(Socket_T S, char *s, int size) {  char *socket_readln(Socket_T S, char *s, int size) {
541    
542    char *p= s;     char *p= s;
543        
544    ASSERT(S);     ASSERT(S);
545    
546       while(--size && ((*s= Socket_readByte(S)) > 0)) {
547           if(*s++ == 10)
548              break;
549       }
550      
551       *s= 0;
552      
553       if(*p)
554         return p;
555      
556       return NULL;
557      
558    }
559    
560    /*  
561     * TODO: We should use an internal buffer and read a large chunk  /* ----------------------------------------------------------------- Private */
562     * from the socket not just one by one byte.  
563     */  
564    while(--size && ((socket_read(S, s, 1)) > 0)) {  /*
565      if(*s++ == 10)   * Fill the internal buffer. If an error occurs or if the read
566          break;   * operation timed out -1 is returned.
567    }   * @param S An InputStream object
568       * @return TRUE (the length of data read) or -1 if an error occured
569    *s= 0;   */
570      static int fill(Socket_T S) {
   if(*p)  
       return p;  
     
   return NULL;  
571        
572        int n;
573        int timeout= S->timeout;
574        
575        S->offset= 0;
576        S->length= 0;
577      
578       /* Read as much as we can and only block  on the first read */
579       while(TRUE) {
580          
581           if(S->ssl) {
582             n= recv_ssl_socket(S->ssl, &S->buffer[S->length],
583                                RBUFFER_SIZE-S->length, timeout);
584           } else {
585             n= sock_read(S->socket, &S->buffer[S->length],
586                          RBUFFER_SIZE-S->length, timeout);
587           }
588          
589           timeout= 0;
590          
591           if(n > 0) {
592              S->length+= n;
593              continue;
594           }
595          
596           if(n<=0) break;
597          
598       }
599      
600       return S->length;
601      
602  }  }

Legend:
Removed from v.1.44  
changed lines
  Added in v.1.45

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26