build: Move python detection back into waf (instead of in configure and Makefile)
[vlendec/samba-autobuild/.git] / ctdb / protocol / protocol_basic.c
1 /*
2    CTDB protocol marshalling
3
4    Copyright (C) Amitay Isaacs  2015-2017
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "replace.h"
21 #include "system/network.h"
22
23 #include <talloc.h>
24
25 #include "protocol_basic.h"
26
27 /*
28  * Basic data types
29  */
30
31 size_t ctdb_uint8_len(uint8_t *in)
32 {
33         return sizeof(uint8_t);
34 }
35
36 void ctdb_uint8_push(uint8_t *in, uint8_t *buf, size_t *npush)
37 {
38         *buf = *in;
39         *npush = sizeof(uint8_t);
40 }
41
42 int ctdb_uint8_pull(uint8_t *buf, size_t buflen, uint8_t *out, size_t *npull)
43 {
44         if (buflen < sizeof(uint8_t)) {
45                 return EMSGSIZE;
46         }
47
48         *out = *buf;
49         *npull = sizeof(uint8_t);
50         return 0;
51 }
52
53 size_t ctdb_uint16_len(uint16_t *in)
54 {
55         return sizeof(uint16_t);
56 }
57
58 void ctdb_uint16_push(uint16_t *in, uint8_t *buf, size_t *npush)
59 {
60         memcpy(buf, in, sizeof(uint16_t));
61         *npush = sizeof(uint16_t);
62 }
63
64 int ctdb_uint16_pull(uint8_t *buf, size_t buflen, uint16_t *out, size_t *npull)
65 {
66         if (buflen < sizeof(uint16_t)) {
67                 return EMSGSIZE;
68         }
69
70         memcpy(out, buf, sizeof(uint16_t));
71         *npull = sizeof(uint16_t);
72         return 0;
73 }
74
75 size_t ctdb_int32_len(int32_t *in)
76 {
77         return sizeof(int32_t);
78 }
79
80 void ctdb_int32_push(int32_t *in, uint8_t *buf, size_t *npush)
81 {
82         memcpy(buf, in, sizeof(int32_t));
83         *npush = sizeof(int32_t);
84 }
85
86 int ctdb_int32_pull(uint8_t *buf, size_t buflen, int32_t *out, size_t *npull)
87 {
88         if (buflen < sizeof(int32_t)) {
89                 return EMSGSIZE;
90         }
91
92         memcpy(out, buf, sizeof(int32_t));
93         *npull = sizeof(int32_t);
94         return 0;
95 }
96
97 size_t ctdb_uint32_len(uint32_t *in)
98 {
99         return sizeof(uint32_t);
100 }
101
102 void ctdb_uint32_push(uint32_t *in, uint8_t *buf, size_t *npush)
103 {
104         memcpy(buf, in, sizeof(uint32_t));
105         *npush = sizeof(uint32_t);
106 }
107
108 int ctdb_uint32_pull(uint8_t *buf, size_t buflen, uint32_t *out, size_t *npull)
109 {
110         if (buflen < sizeof(uint32_t)) {
111                 return EMSGSIZE;
112         }
113
114         memcpy(out, buf, sizeof(uint32_t));
115         *npull = sizeof(uint32_t);
116         return 0;
117 }
118
119 size_t ctdb_uint64_len(uint64_t *in)
120 {
121         return sizeof(uint64_t);
122 }
123
124 void ctdb_uint64_push(uint64_t *in, uint8_t *buf, size_t *npush)
125 {
126         memcpy(buf, in, sizeof(uint64_t));
127         *npush = sizeof(uint64_t);
128 }
129
130 int ctdb_uint64_pull(uint8_t *buf, size_t buflen, uint64_t *out, size_t *npull)
131 {
132         if (buflen < sizeof(uint64_t)) {
133                 return EMSGSIZE;
134         }
135
136         memcpy(out, buf, sizeof(uint64_t));
137         *npull = sizeof(uint64_t);
138         return 0;
139 }
140
141 size_t ctdb_double_len(double *in)
142 {
143         return sizeof(double);
144 }
145
146 void ctdb_double_push(double *in, uint8_t *buf, size_t *npush)
147 {
148         memcpy(buf, in, sizeof(double));
149         *npush = sizeof(double);
150 }
151
152 int ctdb_double_pull(uint8_t *buf, size_t buflen, double *out, size_t *npull)
153 {
154         if (buflen < sizeof(double)) {
155                 return EMSGSIZE;
156         }
157
158         memcpy(out, buf, sizeof(double));
159         *npull = sizeof(double);
160         return 0;
161 }
162
163 size_t ctdb_bool_len(bool *in)
164 {
165         uint8_t u8 = *in;
166
167         return ctdb_uint8_len(&u8);
168 }
169
170 void ctdb_bool_push(bool *in, uint8_t *buf, size_t *npush)
171 {
172         size_t np;
173         uint8_t u8 = *in;
174
175         ctdb_uint8_push(&u8, buf, &np);
176         *npush = np;
177 }
178
179 int ctdb_bool_pull(uint8_t *buf, size_t buflen, bool *out, size_t *npull)
180 {
181         size_t np;
182         uint8_t u8;
183         int ret;
184
185         ret = ctdb_uint8_pull(buf, buflen, &u8, &np);
186         if (ret != 0) {
187                 return ret;
188         }
189
190         if (u8 == 0) {
191                 *out = false;
192         } else if (u8 == 1) {
193                 *out = true;
194         } else {
195                 return EINVAL;
196         }
197
198         *npull = np;
199         return 0;
200 }
201
202 size_t ctdb_chararray_len(char *in, size_t len)
203 {
204         return len;
205 }
206
207 void ctdb_chararray_push(char *in, size_t len, uint8_t *buf, size_t *npush)
208 {
209         memcpy(buf, in, len);
210         *npush = len;
211 }
212
213 int ctdb_chararray_pull(uint8_t *buf, size_t buflen, char *out, size_t len,
214                         size_t *npull)
215 {
216         if (buflen < len) {
217                 return EMSGSIZE;
218         }
219
220         memcpy(out, buf, len);
221         out[len-1] = '\0';
222         *npull = len;
223         return 0;
224 }
225
226 size_t ctdb_string_len(const char **in)
227 {
228         if (*in == NULL) {
229                 return 0;
230         }
231
232         return strlen(*in) + 1;
233 }
234
235 void ctdb_string_push(const char **in, uint8_t *buf, size_t *npush)
236 {
237         size_t len;
238
239         len = ctdb_string_len(in);
240         if (len > 0) {
241                 memcpy(buf, *in, len);
242         }
243
244         *npush = len;
245 }
246
247 int ctdb_string_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
248                      const char **out, size_t *npull)
249 {
250         const char *str;
251
252         if (buflen > UINT32_MAX) {
253                 return EMSGSIZE;
254         }
255
256         if (buflen == 0) {
257                 *out = NULL;
258                 *npull = 0;
259                 return 0;
260         }
261
262         str = talloc_strndup(mem_ctx, (char *)buf, buflen);
263         if (str == NULL) {
264                 return ENOMEM;
265         }
266
267         *out = str;
268         *npull = ctdb_string_len(&str);
269         return 0;
270 }
271
272 size_t ctdb_stringn_len(const char **in)
273 {
274         uint32_t u32 = ctdb_string_len(in);
275
276         return ctdb_uint32_len(&u32) + u32;
277 }
278
279 void ctdb_stringn_push(const char **in, uint8_t *buf, size_t *npush)
280 {
281         size_t offset = 0, np;
282         uint32_t u32 = ctdb_string_len(in);
283
284         ctdb_uint32_push(&u32, buf+offset, &np);
285         offset += np;
286
287         ctdb_string_push(in, buf+offset, &np);
288         offset += np;
289
290         *npush = offset;
291 }
292
293 int ctdb_stringn_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
294                       const char **out, size_t *npull)
295 {
296         size_t offset = 0, np;
297         uint32_t u32;
298         int ret;
299
300         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
301         if (ret != 0) {
302                 return ret;
303         }
304         offset += np;
305
306         if (buflen-offset < u32) {
307                 return EMSGSIZE;
308         }
309
310         ret = ctdb_string_pull(buf+offset, u32, mem_ctx, out, &np);
311         if (ret != 0) {
312                 return ret;
313         }
314         offset += np;
315
316         *npull = offset;
317         return 0;
318 }
319
320 /*
321  * System defined data types
322  */
323
324 size_t ctdb_pid_len(pid_t *in)
325 {
326         return sizeof(pid_t);
327 }
328
329 void ctdb_pid_push(pid_t *in, uint8_t *buf, size_t *npush)
330 {
331         memcpy(buf, in, sizeof(pid_t));
332         *npush = sizeof(pid_t);
333 }
334
335 int ctdb_pid_pull(uint8_t *buf, size_t buflen, pid_t *out, size_t *npull)
336 {
337         if (buflen < sizeof(pid_t)) {
338                 return EMSGSIZE;
339         }
340
341         memcpy(out, buf, sizeof(pid_t));
342         *npull = sizeof(pid_t);
343         return 0;
344 }
345
346 size_t ctdb_timeval_len(struct timeval *in)
347 {
348         return sizeof(struct timeval);
349 }
350
351 void ctdb_timeval_push(struct timeval *in, uint8_t *buf, size_t *npush)
352 {
353         memcpy(buf, in, sizeof(struct timeval));
354         *npush = sizeof(struct timeval);
355 }
356
357 int ctdb_timeval_pull(uint8_t *buf, size_t buflen, struct timeval *out,
358                       size_t *npull)
359 {
360         if (buflen < sizeof(struct timeval)) {
361                 return EMSGSIZE;
362         }
363
364         memcpy(out, buf, sizeof(struct timeval));
365         *npull = sizeof(struct timeval);
366         return 0;
367 }
368
369 /*
370  * Dummy type to tackle structure padding
371  */
372
373 size_t ctdb_padding_len(int count)
374 {
375         return count % SIZEOF_VOID_P;
376 }
377
378 void ctdb_padding_push(int count, uint8_t *buf, size_t *npush)
379 {
380         uint8_t padding[count];
381         size_t aligned_count = count % SIZEOF_VOID_P;
382
383         if (aligned_count > 0) {
384                 memset(padding, 0, aligned_count);
385                 memcpy(buf, padding, aligned_count);
386         }
387         *npush = aligned_count;
388 }
389
390 int ctdb_padding_pull(uint8_t *buf, size_t buflen, int count, size_t *npull)
391 {
392         size_t aligned_count = count % SIZEOF_VOID_P;
393
394         if (buflen < aligned_count) {
395                 return EMSGSIZE;
396         }
397
398         *npull = aligned_count;
399         return 0;
400 }