]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bsock.c
kes Expand new BSOCK class adding signal() and new BNET signals.
[bacula/bacula] / bacula / src / lib / bsock.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation plus additions
11    that are listed in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Network Utility Routines
30  *
31  *  by Kern Sibbald
32  *
33  *   Version $Id: bnet.c 3670 2006-11-21 16:13:58Z kerns $
34  */
35
36
37 #include "bacula.h"
38 #include "jcr.h"
39 #include <netdb.h>
40
41 /*
42  * Send a message over the network. The send consists of
43  * two network packets. The first is sends a 32 bit integer containing
44  * the length of the data packet which follows.
45  *
46  * Returns: false on failure
47  *          true  on success
48  */
49 bool BSOCK::send()
50 {
51    int32_t rc;
52    int32_t pktsiz;
53    int32_t *hdr;
54
55    if (errors || terminated || msglen > 1000000) {
56       return false;
57    }
58    /* Compute total packet length */
59    if (msglen <= 0) {
60       pktsiz = sizeof(pktsiz);               /* signal, no data */
61    } else {
62       pktsiz = msglen + sizeof(pktsiz);      /* data */
63    }
64    /* Store packet length at head of message -- note, we
65     *  have reserved an int32_t just before msg, so we can
66     *  store there 
67     */
68    hdr = (int32_t *)(msg - (int)sizeof(pktsiz));
69    *hdr = htonl(msglen);                     /* store signal/length */
70
71    out_msg_no++;            /* increment message number */
72
73    /* send data packet */
74    timer_start = watchdog_time;  /* start timer */
75    timed_out = 0;
76    /* Full I/O done in one write */
77    rc = write_nbytes(this, (char *)hdr, pktsiz);
78    timer_start = 0;         /* clear timer */
79    if (rc != pktsiz) {
80       errors++;
81       if (errno == 0) {
82          b_errno = EIO;
83       } else {
84          b_errno = errno;
85       }
86       if (rc < 0) {
87          if (!suppress_error_msgs) {
88             Qmsg5(jcr, M_ERROR, 0,
89                   _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), 
90                   msglen, who,
91                   host, port, bnet_strerror(this));
92          }
93       } else {
94          Qmsg5(jcr, M_ERROR, 0,
95                _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
96                msglen, who, host, port, rc);
97       }
98       return false;
99    }
100    return true;
101 }
102
103 /*
104  * Format and send a message
105  *  Returns: false on error
106  *           true  on success
107  */
108 bool BSOCK::fsend(const char *fmt, ...)
109 {
110    va_list arg_ptr;
111    int maxlen;
112
113    if (errors || terminated) {
114       return false;
115    }
116    /* This probably won't work, but we vsnprintf, then if we
117     * get a negative length or a length greater than our buffer
118     * (depending on which library is used), the printf was truncated, so
119     * get a bigger buffer and try again.
120     */
121    for (;;) {
122       maxlen = sizeof_pool_memory(msg) - 1;
123       va_start(arg_ptr, fmt);
124       msglen = bvsnprintf(msg, maxlen, fmt, arg_ptr);
125       va_end(arg_ptr);
126       if (msglen > 0 && msglen < (maxlen - 5)) {
127          break;
128       }
129       msg = realloc_pool_memory(msg, maxlen + maxlen / 2);
130    }
131    return send();
132 }
133
134 /*
135  * Send a signal
136  */
137 bool BSOCK::signal(int signal)
138 {
139    msglen = signal;
140    if (signal == BNET_TERMINATE) {
141       suppress_error_msgs = true;
142    }
143    return send();
144 }