Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndml_nmb.c
1 /*
2  * Copyright (c) 1998,1999,2000
3  *      Traakan, Inc., Los Altos, CA
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *
35  */
36
37
38 #include "ndmlib.h"
39
40
41
42 xdrproc_t
43 ndmnmb_find_xdrproc (struct ndmp_msg_buf *nmb)
44 {
45         struct ndmp_xdr_message_table * xmte;
46
47         xmte = ndmp_xmt_lookup (nmb->protocol_version, nmb->header.message);
48
49         if (!xmte) {
50                 return 0;
51         }
52
53         if (nmb->header.message_type == NDMP0_MESSAGE_REQUEST) {
54                 return (xdrproc_t) xmte->xdr_request;
55         }
56
57         if (nmb->header.message_type == NDMP0_MESSAGE_REPLY) {
58                 return (xdrproc_t) xmte->xdr_reply;
59         }
60
61         return 0;
62 }
63
64 void
65 ndmnmb_free (struct ndmp_msg_buf *nmb)
66 {
67         xdrproc_t xdr_body = ndmnmb_find_xdrproc (nmb);
68
69         if (nmb->flags & NDMNMB_FLAG_NO_FREE)
70                 return;
71
72         if (xdr_body) {
73                 xdr_free (xdr_body, (void*) &nmb->body);
74         }
75 }
76
77 void
78 ndmnmb_snoop (
79   struct ndmlog *log,
80   char *tag,
81   int level,
82   struct ndmp_msg_buf *nmb,
83   char *whence)
84 {
85         int             rc, nl, i;
86         char            buf[2048];
87         int             (*ndmpp)();
88         int             level5 = 5;
89         int             level6 = 6;
90
91          if (level < 6 && nmb->protocol_version == 4) {
92                 ndmp4_header *header = (ndmp4_header *)&nmb->header;
93                 if ((header->message_code == NDMP4_NOTIFY_DATA_HALTED &&
94                      header->error_code == NDMP4_DATA_HALT_SUCCESSFUL) ||
95                     (header->message_code == NDMP4_NOTIFY_MOVER_HALTED &&
96                      header->error_code == NDMP4_MOVER_HALT_CONNECT_CLOSED)) {
97                         level = 6;
98                         level5 = 0;
99                         level6 = 0;
100                 }
101         }
102
103         if (!log || level < 5) {
104                 return;
105         }
106
107         rc = ndmp_pp_header (nmb->protocol_version, &nmb->header, buf);
108 #if 0
109         ndmlogf (log, tag, level5, "%s %s", buf, whence);
110 #else
111         {
112                 char combo[3];
113
114                 if (*whence == 'R') {
115                         combo[0] = '>';
116                         combo[1] = buf[0];
117                 } else {
118                         combo[0] = buf[0];
119                         combo[1] = '>';
120                 }
121                 combo[2] = 0;
122
123                 ndmlogf (log, tag, level5, "%s %s", combo, buf+2);
124         }
125 #endif
126
127         if (level < 6) {
128                 return;
129         }
130         if (rc <= 0) {          /* no body */
131                 return;
132         }
133
134         if (nmb->header.message_type == NDMP0_MESSAGE_REQUEST) {
135                 ndmpp = ndmp_pp_request;
136         } else if (nmb->header.message_type == NDMP0_MESSAGE_REPLY) {
137                 ndmpp = ndmp_pp_reply;
138         } else {
139                 return;         /* should not happen */
140         }
141
142         nl = 1;
143         for (i = 0; i < nl; i++) {
144                 nl = (*ndmpp)(nmb->protocol_version,
145                         nmb->header.message, &nmb->body, i, buf);
146                 if (nl == 0)
147                         break;          /* no printable body (void) */
148
149                 ndmlogf (log, tag, level6, "   %s", buf);
150         }
151 }
152
153 unsigned
154 ndmnmb_get_reply_error_raw (struct ndmp_msg_buf *nmb)
155 {
156         unsigned        protocol_version = nmb->protocol_version;
157         unsigned        msg = nmb->header.message;
158         unsigned        raw_error;
159
160         if (NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(protocol_version, msg)) {
161                 raw_error = nmb->body.unf3_error.error;
162         } else {
163                 raw_error = nmb->body.error;
164         }
165
166         return raw_error;
167 }
168
169 ndmp9_error
170 ndmnmb_get_reply_error (struct ndmp_msg_buf *nmb)
171 {
172         unsigned        protocol_version = nmb->protocol_version;
173         unsigned        raw_error = ndmnmb_get_reply_error_raw (nmb);
174         ndmp9_error     error;
175
176         switch (protocol_version) {
177         default:
178                 /* best effort */
179                 error = (ndmp9_error) raw_error;
180                 break;
181
182 #ifndef NDMOS_OPTION_NO_NDMP2
183         case NDMP2VER:
184                 {
185                         ndmp2_error     error2 = raw_error;
186
187                         ndmp_2to9_error (&error2, &error);
188                 }
189                 break;
190 #endif /* !NDMOS_OPTION_NO_NDMP2 */
191
192 #ifndef NDMOS_OPTION_NO_NDMP3
193         case NDMP3VER:
194                 {
195                         ndmp3_error     error3 = raw_error;
196
197                         ndmp_3to9_error (&error3, &error);
198                 }
199                 break;
200 #endif /* !NDMOS_OPTION_NO_NDMP3 */
201
202 #ifndef NDMOS_OPTION_NO_NDMP4
203         case NDMP4VER:
204                 {
205                         ndmp4_error     error4 = raw_error;
206
207                         ndmp_4to9_error (&error4, &error);
208                 }
209                 break;
210 #endif /* !NDMOS_OPTION_NO_NDMP4 */
211         }
212
213         return error;
214 }
215
216 int
217 ndmnmb_set_reply_error_raw (struct ndmp_msg_buf *nmb, unsigned raw_error)
218 {
219         unsigned        protocol_version = nmb->protocol_version;
220         unsigned        msg = nmb->header.message;
221
222         if (NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(protocol_version, msg)) {
223                 nmb->body.unf3_error.error = raw_error;
224         } else {
225                 nmb->body.error = raw_error;
226         }
227
228         return 0;
229 }
230
231 int
232 ndmnmb_set_reply_error (struct ndmp_msg_buf *nmb, ndmp9_error error)
233 {
234         unsigned        protocol_version = nmb->protocol_version;
235         unsigned        raw_error;
236
237         switch (protocol_version) {
238         default:
239                 /* best effort */
240                 raw_error = (unsigned) error;
241                 break;
242
243 #ifndef NDMOS_OPTION_NO_NDMP2
244         case NDMP2VER:
245                 {
246                         ndmp2_error     error2;
247
248                         ndmp_9to2_error (&error, &error2);
249                         raw_error = (unsigned) error2;
250                 }
251                 break;
252 #endif /* !NDMOS_OPTION_NO_NDMP2 */
253
254 #ifndef NDMOS_OPTION_NO_NDMP3
255         case NDMP3VER:
256                 {
257                         ndmp3_error     error3;
258
259                         ndmp_9to3_error (&error, &error3);
260                         raw_error = (unsigned) error3;
261                 }
262                 break;
263 #endif /* !NDMOS_OPTION_NO_NDMP3 */
264
265 #ifndef NDMOS_OPTION_NO_NDMP4
266         case NDMP4VER:
267                 {
268                         ndmp4_error     error4;
269
270                         ndmp_9to4_error (&error, &error4);
271                         raw_error = (unsigned) error4;
272                 }
273                 break;
274 #endif /* !NDMOS_OPTION_NO_NDMP4 */
275         }
276
277         return ndmnmb_set_reply_error_raw (nmb, raw_error);
278 }