]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bget_msg.c
Tweak leave SQL library links in rpm
[bacula/bacula] / bacula / src / lib / bget_msg.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2016 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *  Subroutines to receive network data and handle
21  *   network signals for the FD and the SD.
22  *
23  *   Kern Sibbald, May MMI previously in src/stored/fdmsg.c
24  *
25  */
26
27 #include "bacula.h"
28 #include "jcr.h"
29
30 static char OK_msg[]   = "2000 OK\n";
31 static char TERM_msg[] = "2999 Terminate\n";
32
33 #define msglvl 500
34
35 /*
36  * This routine does a bnet_recv(), then if a signal was
37  *   sent, it handles it.  The return codes are the same as
38  *   bne_recv() except the BNET_SIGNAL messages that can
39  *   be handled are done so without returning.
40  *
41  * Returns number of bytes read (may return zero)
42  * Returns -1 on signal (BNET_SIGNAL)
43  * Returns -2 on hard end of file (BNET_HARDEOF)
44  * Returns -3 on error  (BNET_ERROR)
45  * Returns -4 on Command (BNET_COMMAND)
46  */
47 int bget_msg(BSOCK *sock)
48 {
49    int n;
50    for ( ;; ) {
51       n = sock->recv();
52       if (n >= 0) {                  /* normal return */
53          return n;
54       }
55       if (sock->is_stop()) {         /* error return */
56          return n;
57       }
58
59       /* BNET_SIGNAL (-1) return from bnet_recv() => network signal */
60       switch (sock->msglen) {
61       case BNET_EOD:               /* end of data */
62          Dmsg0(msglvl, "Got BNET_EOD\n");
63          return n;
64       case BNET_EOD_POLL:
65          Dmsg0(msglvl, "Got BNET_EOD_POLL\n");
66          if (sock->is_terminated()) {
67             sock->fsend(TERM_msg);
68          } else {
69             sock->fsend(OK_msg); /* send response */
70          }
71          return n;                 /* end of data */
72       case BNET_TERMINATE:
73          Dmsg0(msglvl, "Got BNET_TERMINATE\n");
74          sock->set_terminated();
75          return n;
76       case BNET_POLL:
77          Dmsg0(msglvl, "Got BNET_POLL\n");
78          if (sock->is_terminated()) {
79             sock->fsend(TERM_msg);
80          } else {
81             sock->fsend(OK_msg); /* send response */
82          }
83          break;
84       case BNET_HEARTBEAT:
85       case BNET_HB_RESPONSE:
86          break;
87       case BNET_STATUS:
88          /* *****FIXME***** Implement BNET_STATUS */
89          Dmsg0(msglvl, "Got BNET_STATUS\n");
90          sock->fsend(_("Status OK\n"));
91          sock->signal(BNET_EOD);
92          break;
93       default:
94          Emsg1(M_ERROR, 0, _("bget_msg: unknown signal %d\n"), sock->msglen);
95          break;
96       }
97    }
98 }
99
100 bmessage::bmessage(int bufsize)
101 {
102    msg = get_pool_memory(PM_BSOCK);
103    msg = realloc_pool_memory(msg, bufsize);
104    status = bmessage::bm_busy;
105    jobbytes = 0;
106 }
107
108 bmessage::~bmessage()
109 {
110    free_pool_memory(msg);
111 }
112
113 void bmessage::swap(BSOCK *sock)
114 {
115    POOLMEM *swap = sock->msg;
116    sock->msg = msg;
117    msg = swap;
118 }
119
120 GetMsg::GetMsg(JCR *a_jcr, BSOCK *a_bsock, const char *a_rec_header, int32_t a_bufsize):
121       jcr(a_jcr),
122       bsock(a_bsock),
123       rec_header(a_rec_header),
124       bufsize(a_bufsize),
125       m_is_stop(false),
126       m_is_done(false),
127       m_is_error(false),
128       m_use_count(1)
129 {
130    jcr->inc_use_count();        /* We own a copy of the JCR */
131    bmsg_aux = New(bmessage(bufsize));
132    bmsg = bmsg_aux;
133    pthread_mutex_init(&mutex, 0);
134    pthread_cond_init(&cond, NULL);
135 };
136
137 GetMsg::~GetMsg()
138 {
139    free_jcr(jcr);               /* Release our copy of the JCR */
140    delete bmsg_aux;
141    pthread_mutex_destroy(&mutex);
142    pthread_cond_destroy(&cond);
143 };
144
145 int GetMsg::bget_msg(bmessage **pbmsg)
146 {
147    // Get our own local copy of the socket
148
149    if (pbmsg == NULL) {
150       pbmsg = &bmsg_aux;
151    }
152    bmessage *bmsg = *pbmsg;
153    bmsg->ret = ::bget_msg(bsock);
154    bmsg->status = bmessage::bm_ready;
155    bmsg->rbuflen = bmsg->msglen = bmsg->origlen = bsock->msglen;
156 /*   bmsg->is_header = !bmsg->is_header; ALAIN SAYS: I think this line is useless */
157    /* swap msg instead of copying */
158    bmsg->swap(bsock);
159    bmsg->rbuf = bmsg->msg;
160
161    msglen = bmsg->msglen;
162    msg = bmsg->msg;
163    return bmsg->ret;
164 }