2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
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.
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.
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
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.
29 * Network Utility Routines
33 * Version $Id: bnet.c 3670 2006-11-21 16:13:58Z kerns $
41 #ifndef ENODATA /* not defined on BSD systems */
46 #define socketRead(fd, buf, len) ::recv(fd, buf, len, 0)
47 #define socketWrite(fd, buf, len) ::send(fd, buf, len, 0)
48 #define socketClose(fd) ::closesocket(fd)
50 #define socketRead(fd, buf, len) ::read(fd, buf, len)
51 #define socketWrite(fd, buf, len) ::write(fd, buf, len)
52 #define socketClose(fd) ::close(fd)
56 * Send a message over the network. The send consists of
57 * two network packets. The first is sends a 32 bit integer containing
58 * the length of the data packet which follows.
60 * Returns: false on failure
69 if (errors || terminated || msglen > 1000000) {
72 /* Compute total packet length */
74 pktsiz = sizeof(pktsiz); /* signal, no data */
76 pktsiz = msglen + sizeof(pktsiz); /* data */
78 /* Store packet length at head of message -- note, we
79 * have reserved an int32_t just before msg, so we can
82 hdr = (int32_t *)(msg - (int)sizeof(pktsiz));
83 *hdr = htonl(msglen); /* store signal/length */
85 out_msg_no++; /* increment message number */
87 /* send data packet */
88 timer_start = watchdog_time; /* start timer */
90 /* Full I/O done in one write */
91 rc = write_nbytes(this, (char *)hdr, pktsiz);
92 timer_start = 0; /* clear timer */
101 if (!suppress_error_msgs) {
102 Qmsg5(m_jcr, M_ERROR, 0,
103 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
105 m_host, m_port, bnet_strerror(this));
108 Qmsg5(m_jcr, M_ERROR, 0,
109 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
110 msglen, m_who, m_host, m_port, rc);
118 * Format and send a message
119 * Returns: false on error
122 bool BSOCK::fsend(const char *fmt, ...)
127 if (errors || terminated) {
130 /* This probably won't work, but we vsnprintf, then if we
131 * get a negative length or a length greater than our buffer
132 * (depending on which library is used), the printf was truncated, so
133 * get a bigger buffer and try again.
136 maxlen = sizeof_pool_memory(msg) - 1;
137 va_start(arg_ptr, fmt);
138 msglen = bvsnprintf(msg, maxlen, fmt, arg_ptr);
140 if (msglen > 0 && msglen < (maxlen - 5)) {
143 msg = realloc_pool_memory(msg, maxlen + maxlen / 2);
149 * Receive a message from the other end. Each message consists of
150 * two packets. The first is a header that contains the size
151 * of the data that follows in the second packet.
152 * Returns number of bytes read (may return zero)
153 * Returns -1 on signal (BNET_SIGNAL)
154 * Returns -2 on hard end of file (BNET_HARDEOF)
155 * Returns -3 on error (BNET_ERROR)
157 * Unfortunately, it is a bit complicated because we have these
160 * 2. Signal including end of data stream
161 * 3. Hard end of file
163 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
165 int32_t BSOCK::recv()
172 if (errors || terminated) {
176 read_seqno++; /* bump sequence number */
177 timer_start = watchdog_time; /* set start wait time */
179 /* get data size -- in int32_t */
180 if ((nbytes = read_nbytes(this, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
181 timer_start = 0; /* clear timer */
182 /* probably pipe broken because client died */
189 return BNET_HARDEOF; /* assume hard EOF received */
191 timer_start = 0; /* clear timer */
192 if (nbytes != sizeof(int32_t)) {
195 Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
196 sizeof(int32_t), nbytes, m_who, m_host, m_port);
200 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
202 if (pktsiz == 0) { /* No data transferred */
203 timer_start = 0; /* clear timer */
206 return 0; /* zero bytes read */
209 /* If signal or packet size too big */
210 if (pktsiz < 0 || pktsiz > 1000000) {
211 if (pktsiz > 0) { /* if packet too big */
212 Qmsg3(m_jcr, M_FATAL, 0,
213 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
214 m_who, m_host, m_port);
215 pktsiz = BNET_TERMINATE; /* hang up */
217 if (pktsiz == BNET_TERMINATE) {
220 timer_start = 0; /* clear timer */
222 msglen = pktsiz; /* signal code */
223 return BNET_SIGNAL; /* signal */
226 /* Make sure the buffer is big enough + one byte for EOS */
227 if (pktsiz >= (int32_t) sizeof_pool_memory(msg)) {
228 msg = realloc_pool_memory(msg, pktsiz + 100);
231 timer_start = watchdog_time; /* set start wait time */
233 /* now read the actual data */
234 if ((nbytes = read_nbytes(this, msg, pktsiz)) <= 0) {
235 timer_start = 0; /* clear timer */
242 Qmsg4(m_jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
243 m_who, m_host, m_port, bnet_strerror(this));
246 timer_start = 0; /* clear timer */
249 if (nbytes != pktsiz) {
252 Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
253 pktsiz, nbytes, m_who, m_host, m_port);
256 /* always add a zero by to properly terminate any
257 * string that was send to us. Note, we ensured above that the
258 * buffer is at least one byte longer than the message length.
260 msg[nbytes] = 0; /* terminate in case it is a string */
261 sm_check(__FILE__, __LINE__, false);
262 return nbytes; /* return actual length of message */
269 bool BSOCK::signal(int signal)
272 if (signal == BNET_TERMINATE) {
273 suppress_error_msgs = true;
279 * Despool spooled attributes
281 bool BSOCK::despool(void update_attr_spool_size(ssize_t size), ssize_t tsize)
285 ssize_t last = 0, size = 0;
289 while (fread((char *)&pktsiz, 1, sizeof(int32_t), spool_fd) ==
291 size += sizeof(int32_t);
292 msglen = ntohl(pktsiz);
294 if (msglen > (int32_t) sizeof_pool_memory(msg)) {
295 msg = realloc_pool_memory(msg, msglen + 1);
297 nbytes = fread(msg, 1, msglen, spool_fd);
298 if (nbytes != (size_t) msglen) {
300 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, msglen);
301 Qmsg1(jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
303 update_attr_spool_size(tsize - last);
307 if ((++count & 0x3F) == 0) {
308 update_attr_spool_size(size - last);
314 update_attr_spool_size(tsize - last);
315 if (ferror(spool_fd)) {
317 Qmsg1(jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
330 for (; bsock; bsock = next) {
331 next = bsock->m_next; /* get possible pointer to next before destoryed */
334 /* Shutdown tls cleanly. */
336 tls_bsock_shutdown(bsock);
337 free_tls_connection(bsock->tls);
340 #endif /* HAVE_TLS */
341 if (bsock->timed_out) {
342 shutdown(bsock->fd, 2); /* discard any pending I/O */
344 socketClose(bsock->fd); /* normal close */
346 destroy(); /* free the packet */
351 void BSOCK::destroy()
354 free_pool_memory(msg);
357 ASSERT(1 == 0); /* double close */
360 free_pool_memory(errmsg);