]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/bnet.c
Fix reporting jobs from state file + misc
[bacula/bacula] / bacula / src / lib / bnet.c
index c319f7c2cc656e5dd6d197d673dc5f94fc415708..a95d1e5cb44bfb1157b15c9f8fad5770e7980d59 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "bacula.h"
 #include "jcr.h"
+#include <netdb.h>
 
 extern time_t watchdog_time;
 
@@ -42,7 +43,13 @@ extern time_t watchdog_time;
 #define ENODATA EPIPE
 #endif
 
-
+#ifdef HAVE_WIN32
+#define socketRead(fd, buf, len) recv(fd, buf, len, 0)
+#define socketWrite(fd, buf, len) send(fd, buf, len, 0)
+#else
+#define socketRead(fd, buf, len) read(fd, buf, len)
+#define socketWrite(fd, buf, len) write(fd, buf, len)
+#endif
 
 
 /*
@@ -59,9 +66,8 @@ static int32_t read_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
    while (nleft > 0) {
       do {
         errno = 0;
-        nread = read(bsock->fd, ptr, nleft);    
+        nread = socketRead(bsock->fd, ptr, nleft);      
         if (bsock->timed_out || bsock->terminated) {
-            Dmsg1(000, "timed_out = %d\n", bsock->timed_out);
            return nread;
         }
       } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
@@ -96,7 +102,7 @@ static int32_t write_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
    while (nleft > 0) {
       do {
         errno = 0;
-        nwritten = write(bsock->fd, ptr, nleft);
+        nwritten = socketWrite(bsock->fd, ptr, nleft);
         if (bsock->timed_out || bsock->terminated) {
            return nwritten;
         }
@@ -273,9 +279,9 @@ bnet_suppress_error_messages(BSOCK *bsock, int flag)
 
 
 /*
- * Transmit spooled data now
+ * Transmit spooled data now to a BSOCK
  */
-int bnet_despool(BSOCK *bsock)
+int bnet_despool_to_bsock(BSOCK *bsock)
 {
    int32_t pktsiz;
    size_t nbytes;
@@ -285,7 +291,7 @@ int bnet_despool(BSOCK *bsock)
       bsock->msglen = ntohl(pktsiz);
       if (bsock->msglen > 0) {
         if (bsock->msglen > (int32_t)sizeof_pool_memory(bsock->msg)) {
-           bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen);
+           bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
         }
         nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
         if (nbytes != (size_t)bsock->msglen) {
@@ -319,11 +325,10 @@ bnet_send(BSOCK *bsock)
    int32_t pktsiz;
    int32_t msglen;
 
-   if (bsock->errors || bsock->terminated) {
+   if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
       return 0;
    }
    msglen = bsock->msglen;
-   ASSERT(bsock->msglen < 1000000);
    pktsiz = htonl((int32_t)bsock->msglen);
    /* send int32_t containing size of data packet */
    bsock->timer_start = watchdog_time; /* start timer */
@@ -355,7 +360,6 @@ bnet_send(BSOCK *bsock)
 
    bsock->out_msg_no++;              /* increment message number */
    if (bsock->msglen <= 0) {         /* length only? */
-      ASSERT(msglen == bsock->msglen);
       return 1;                      /* yes, no data */
    }
 
@@ -382,7 +386,6 @@ bnet_send(BSOCK *bsock)
       }
       return 0;
    }
-   ASSERT(msglen == bsock->msglen);
    return 1;
 }
 
@@ -494,12 +497,10 @@ bnet_wait_data_intr(BSOCK *bsock, int sec)
 #define NO_DATA        4       /* Valid name, no data record of requested type. */
 #endif
 
-extern int h_errno;            /* On error has one of the above */
-
 /*
  * Get human readable error for gethostbyname()
  */
-static char *gethost_strerror() 
+static const char *gethost_strerror() 
 {
    switch (h_errno) {
    case NETDB_INTERNAL:
@@ -541,7 +542,7 @@ static uint32_t *bget_host_ip(JCR *jcr, char *host)
    } else {
       P(ip_mutex);
       if ((hp = gethostbyname(host)) == NULL) {
-         Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for %s failed: ERR=%s\n", 
+         Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n", 
               host, gethost_strerror());
         V(ip_mutex);
         return NULL;
@@ -576,7 +577,7 @@ Wanted %d got %d bytes for s_addr.\n"), sizeof(inaddr.s_addr), hp->h_length);
  *  ***FIXME*** implement service from /etc/services
  */
 static BSOCK *
-bnet_open(JCR *jcr, char *name, char *host, char *service, int port, int *fatal)
+bnet_open(JCR *jcr, const char *name, char *host, char *service, int port, int *fatal)
 {
    int sockfd;
    struct sockaddr_in tcp_serv_addr;    /* socket information */
@@ -626,14 +627,14 @@ bnet_open(JCR *jcr, char *name, char *host, char *service, int port, int *fatal)
       close(sockfd);
       return NULL;
    }
-   return init_bsock(jcr, sockfd, name, host, port);
+   return init_bsock(jcr, sockfd, name, host, port, &tcp_serv_addr);
 }
 
 /*
  * Try to connect to host for max_retry_time at retry_time intervals.
  */
 BSOCK *
-bnet_connect(JCR *jcr, int retry_interval, int max_retry_time, char *name,
+bnet_connect(JCR *jcr, int retry_interval, int max_retry_time, const char *name,
             char *host, char *service, int port, int verbose)
 {
    int i;
@@ -679,11 +680,14 @@ char *bnet_strerror(BSOCK *bsock)
  *          1 on success
  */
 int
-bnet_fsend(BSOCK *bs, char *fmt, ...)
+bnet_fsend(BSOCK *bs, const char *fmt, ...)
 {
    va_list arg_ptr;
    int maxlen;
 
+   if (bs->errors || bs->terminated) {
+      return 0;
+   }
    /* This probably won't work, but we vsnprintf, then if we
     * get a negative length or a length greater than our buffer
     * (depending on which library is used), the printf was truncated, so
@@ -695,10 +699,10 @@ again:
    bs->msglen = bvsnprintf(mp_chr(bs->msg), maxlen, fmt, arg_ptr);
    va_end(arg_ptr);
    if (bs->msglen < 0 || bs->msglen >= maxlen) {
-      bs->msg = realloc_pool_memory(bs->msg, maxlen + 200);
+      bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
       goto again;
    }
-   return bnet_send(bs) < 0 ? 0 : 1;
+   return bnet_send(bs);
 }
 
 /* 
@@ -710,7 +714,7 @@ again:
  */
 int bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw)
 {
-   uint32_t dbuf_size;
+   uint32_t dbuf_size, start_size;
 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
    int opt;
 
@@ -718,7 +722,12 @@ int bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw)
     setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
 #endif
 
-   dbuf_size = size;
+   if (size != 0) {
+      dbuf_size = size;
+   } else {
+      dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
+   }
+   start_size = dbuf_size;
    if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size+100)) == NULL) {
       Jmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
       return 0;
@@ -730,14 +739,20 @@ int bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw)
         dbuf_size -= TAPE_BSIZE;
       }
       Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
-      if (dbuf_size != MAX_NETWORK_BUFFER_SIZE)
+      if (dbuf_size != start_size) {
          Jmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
+      }
       if (dbuf_size % TAPE_BSIZE != 0) {
          Jmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
              dbuf_size);
       }
    }
-   dbuf_size = size;
+   if (size != 0) {
+      dbuf_size = size;
+   } else {
+      dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
+   }
+   start_size = dbuf_size;
    if (rw & BNET_SETBUF_WRITE) {
       while ((dbuf_size > TAPE_BSIZE) &&
         (setsockopt(bs->fd, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t)&dbuf_size, sizeof(dbuf_size)) < 0)) {
@@ -745,8 +760,9 @@ int bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw)
         dbuf_size -= TAPE_BSIZE;
       }
       Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
-      if (dbuf_size != MAX_NETWORK_BUFFER_SIZE)
+      if (dbuf_size != start_size) {
          Jmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
+      }
       if (dbuf_size % TAPE_BSIZE != 0) {
          Jmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
              dbuf_size);
@@ -805,7 +821,8 @@ char *bnet_sig_to_ascii(BSOCK *bs)
  *  This probably should be done in net_open
  */
 BSOCK *
-init_bsock(JCR *jcr, int sockfd, char *who, char *host, int port) 
+init_bsock(JCR *jcr, int sockfd, const char *who, char *host, int port, 
+          struct sockaddr_in *client_addr) 
 {
    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
    memset(bsock, 0, sizeof(BSOCK));
@@ -816,6 +833,7 @@ init_bsock(JCR *jcr, int sockfd, char *who, char *host, int port)
    bsock->who = bstrdup(who);
    bsock->host = bstrdup(host);
    bsock->port = port;
+   memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
    /*
     * ****FIXME**** reduce this to a few hours once   
     *  heartbeats are implemented