1 /*
2 CTDB event daemon protocol
3
4 Copyright (C) Amitay Isaacs 2018
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
22 #include <talloc.h>
23
24 #include "protocol/protocol_basic.h"
25
26 #include "event_protocol.h"
27 #include "event_protocol_api.h"
28
ctdb_event_script_action_len(enum ctdb_event_script_action in)29 static size_t ctdb_event_script_action_len(enum ctdb_event_script_action in)
30 {
31 uint32_t u32 = in;
32
33 return ctdb_uint32_len(&u32);
34 }
35
ctdb_event_script_action_push(enum ctdb_event_script_action in,uint8_t * buf,size_t * npush)36 static void ctdb_event_script_action_push(enum ctdb_event_script_action in,
37 uint8_t *buf,
38 size_t *npush)
39 {
40 uint32_t u32 = in;
41
42 ctdb_uint32_push(&u32, buf, npush);
43 }
44
ctdb_event_script_action_pull(uint8_t * buf,size_t buflen,enum ctdb_event_script_action * out,size_t * npull)45 static int ctdb_event_script_action_pull(uint8_t *buf,
46 size_t buflen,
47 enum ctdb_event_script_action *out,
48 size_t *npull)
49 {
50 enum ctdb_event_script_action value;
51 uint32_t u32;
52 size_t np;
53 int ret;
54
55 ret = ctdb_uint32_pull(buf, buflen, &u32, &np);
56 if (ret != 0) {
57 return ret;
58 }
59
60 switch (u32) {
61 case 0:
62 value = CTDB_EVENT_SCRIPT_DISABLE;
63 break;
64
65 case 1:
66 value = CTDB_EVENT_SCRIPT_ENABLE;
67 break;
68
69 default:
70 return EINVAL;
71 }
72
73 *out = value;
74 *npull = np;
75
76 return 0;
77 }
78
ctdb_event_command_len(enum ctdb_event_command in)79 static size_t ctdb_event_command_len(enum ctdb_event_command in)
80 {
81 uint32_t u32 = in;
82
83 return ctdb_uint32_len(&u32);
84 }
85
ctdb_event_command_push(enum ctdb_event_command in,uint8_t * buf,size_t * npush)86 static void ctdb_event_command_push(enum ctdb_event_command in,
87 uint8_t *buf,
88 size_t *npush)
89 {
90 uint32_t u32 = in;
91
92 ctdb_uint32_push(&u32, buf, npush);
93 }
94
ctdb_event_command_pull(uint8_t * buf,size_t buflen,enum ctdb_event_command * out,size_t * npull)95 static int ctdb_event_command_pull(uint8_t *buf,
96 size_t buflen,
97 enum ctdb_event_command *out,
98 size_t *npull)
99 {
100 enum ctdb_event_command value;
101 uint32_t u32;
102 size_t np;
103 int ret;
104
105 ret = ctdb_uint32_pull(buf, buflen, &u32, &np);
106 if (ret != 0) {
107 return ret;
108 }
109
110 switch (u32) {
111 case 1:
112 value = CTDB_EVENT_CMD_RUN;
113 break;
114
115 case 2:
116 value = CTDB_EVENT_CMD_STATUS;
117 break;
118
119 case 3:
120 value = CTDB_EVENT_CMD_SCRIPT;
121 break;
122
123 default:
124 return EINVAL;
125 }
126
127 *out = value;
128 *npull = np;
129
130 return 0;
131 }
132
ctdb_event_script_len(struct ctdb_event_script * in)133 static size_t ctdb_event_script_len(struct ctdb_event_script *in)
134 {
135 return ctdb_stringn_len(&in->name) +
136 ctdb_timeval_len(&in->begin) +
137 ctdb_timeval_len(&in->end) +
138 ctdb_int32_len(&in->result) +
139 ctdb_stringn_len(&in->output);
140 }
141
ctdb_event_script_push(struct ctdb_event_script * in,uint8_t * buf,size_t * npush)142 static void ctdb_event_script_push(struct ctdb_event_script *in,
143 uint8_t *buf,
144 size_t *npush)
145 {
146 size_t offset = 0, np;
147
148 ctdb_stringn_push(&in->name, buf+offset, &np);
149 offset += np;
150
151 ctdb_timeval_push(&in->begin, buf+offset, &np);
152 offset += np;
153
154 ctdb_timeval_push(&in->end, buf+offset, &np);
155 offset += np;
156
157 ctdb_int32_push(&in->result, buf+offset, &np);
158 offset += np;
159
160 ctdb_stringn_push(&in->output, buf+offset, &np);
161 offset += np;
162
163 *npush = offset;
164 }
165
ctdb_event_script_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_script * value,size_t * npull)166 static int ctdb_event_script_pull_elems(uint8_t *buf,
167 size_t buflen,
168 TALLOC_CTX *mem_ctx,
169 struct ctdb_event_script *value,
170 size_t *npull)
171 {
172 size_t offset = 0, np;
173 int ret;
174
175 ret = ctdb_stringn_pull(buf+offset,
176 buflen-offset,
177 mem_ctx,
178 &value->name,
179 &np);
180 if (ret != 0) {
181 return ret;
182 }
183 offset += np;
184
185 ret = ctdb_timeval_pull(buf+offset,
186 buflen-offset,
187 &value->begin,
188 &np);
189 if (ret != 0) {
190 return ret;
191 }
192 offset += np;
193
194 ret = ctdb_timeval_pull(buf+offset,
195 buflen-offset,
196 &value->end,
197 &np);
198 if (ret != 0) {
199 return ret;
200 }
201 offset += np;
202
203 ret = ctdb_int32_pull(buf+offset,
204 buflen-offset,
205 &value->result,
206 &np);
207 if (ret != 0) {
208 return ret;
209 }
210 offset += np;
211
212 ret = ctdb_stringn_pull(buf+offset,
213 buflen-offset,
214 mem_ctx,
215 &value->output,
216 &np);
217 if (ret != 0) {
218 return ret;
219 }
220 offset += np;
221
222 *npull = offset;
223
224 return 0;
225 }
226
227 #ifdef EVENT_PROTOCOL_TEST
ctdb_event_script_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_script ** out,size_t * npull)228 static int ctdb_event_script_pull(uint8_t *buf,
229 size_t buflen,
230 TALLOC_CTX *mem_ctx,
231 struct ctdb_event_script **out,
232 size_t *npull)
233 {
234 struct ctdb_event_script *value;
235 int ret;
236
237 value = talloc(mem_ctx, struct ctdb_event_script);
238 if (value == NULL) {
239 return ENOMEM;
240 }
241
242 ret = ctdb_event_script_pull_elems(buf, buflen, value, value, npull);
243 if (ret != 0) {
244 talloc_free(value);
245 return ret;
246 }
247
248 *out = value;
249
250 return 0;
251 }
252 #endif
253
ctdb_event_script_list_len(struct ctdb_event_script_list * in)254 static size_t ctdb_event_script_list_len(struct ctdb_event_script_list *in)
255 {
256 size_t len;
257 int i;
258
259 len = ctdb_int32_len(&in->num_scripts);
260
261 for (i=0; i<in->num_scripts; i++) {
262 len += ctdb_event_script_len(&in->script[i]);
263 }
264
265 return len;
266 }
267
ctdb_event_script_list_push(struct ctdb_event_script_list * in,uint8_t * buf,size_t * npush)268 static void ctdb_event_script_list_push(struct ctdb_event_script_list *in,
269 uint8_t *buf,
270 size_t *npush)
271 {
272 size_t offset = 0, np;
273 int i;
274
275 ctdb_int32_push(&in->num_scripts, buf+offset, &np);
276 offset += np;
277
278 for (i=0; i<in->num_scripts; i++) {
279 ctdb_event_script_push(&in->script[i], buf+offset, &np);
280 offset += np;
281 }
282
283 *npush = offset;
284 }
285
ctdb_event_script_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_script_list ** out,size_t * npull)286 static int ctdb_event_script_list_pull(uint8_t *buf,
287 size_t buflen,
288 TALLOC_CTX *mem_ctx,
289 struct ctdb_event_script_list **out,
290 size_t *npull)
291 {
292 struct ctdb_event_script_list *value = NULL;
293 size_t offset = 0, np;
294 int num_scripts;
295 int ret, i;
296
297 ret = ctdb_int32_pull(buf+offset, buflen-offset, &num_scripts, &np);
298 if (ret != 0) {
299 return ret;
300 }
301 offset += np;
302
303 if (num_scripts < 0) {
304 return EINVAL;
305 }
306
307 value = talloc_zero(mem_ctx, struct ctdb_event_script_list);
308 if (value == NULL) {
309 return ENOMEM;
310 }
311
312 value->num_scripts = num_scripts;
313 if (num_scripts == 0) {
314 goto done;
315 }
316
317 value->script = talloc_array(value, struct ctdb_event_script,
318 num_scripts);
319 if (value->script == NULL) {
320 ret = ENOMEM;
321 goto fail;
322 }
323
324 for (i=0; i<num_scripts; i++) {
325 ret = ctdb_event_script_pull_elems(buf+offset,
326 buflen-offset,
327 value,
328 &value->script[i],
329 &np);
330 if (ret != 0) {
331 goto fail;
332 }
333 offset += np;
334 }
335
336 done:
337 *out = value;
338 *npull = offset;
339
340 return 0;
341
342 fail:
343 talloc_free(value);
344 return ret;
345 }
346
ctdb_event_request_run_len(struct ctdb_event_request_run * in)347 static size_t ctdb_event_request_run_len(struct ctdb_event_request_run *in)
348 {
349 return ctdb_stringn_len(&in->component) +
350 ctdb_stringn_len(&in->event) +
351 ctdb_stringn_len(&in->args) +
352 ctdb_uint32_len(&in->timeout) +
353 ctdb_uint32_len(&in->flags);
354 }
355
ctdb_event_request_run_push(struct ctdb_event_request_run * in,uint8_t * buf,size_t * npush)356 static void ctdb_event_request_run_push(struct ctdb_event_request_run *in,
357 uint8_t *buf,
358 size_t *npush)
359 {
360 size_t offset = 0, np;
361
362 ctdb_stringn_push(&in->component, buf+offset, &np);
363 offset += np;
364
365 ctdb_stringn_push(&in->event, buf+offset, &np);
366 offset += np;
367
368 ctdb_stringn_push(&in->args, buf+offset, &np);
369 offset += np;
370
371 ctdb_uint32_push(&in->timeout, buf+offset, &np);
372 offset += np;
373
374 ctdb_uint32_push(&in->flags, buf+offset, &np);
375 offset += np;
376
377 *npush = offset;
378 }
379
ctdb_event_request_run_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_request_run ** out,size_t * npull)380 static int ctdb_event_request_run_pull(uint8_t *buf,
381 size_t buflen,
382 TALLOC_CTX *mem_ctx,
383 struct ctdb_event_request_run **out,
384 size_t *npull)
385 {
386 struct ctdb_event_request_run *value;
387 size_t offset = 0, np;
388 int ret;
389
390 value = talloc(mem_ctx, struct ctdb_event_request_run);
391 if (value == NULL) {
392 return ENOMEM;
393 }
394
395 ret = ctdb_stringn_pull(buf+offset,
396 buflen-offset,
397 value,
398 &value->component,
399 &np);
400 if (ret != 0) {
401 goto fail;
402 }
403 offset += np;
404
405 ret = ctdb_stringn_pull(buf+offset,
406 buflen-offset,
407 value,
408 &value->event,
409 &np);
410 if (ret != 0) {
411 goto fail;
412 }
413 offset += np;
414
415 ret = ctdb_stringn_pull(buf+offset,
416 buflen-offset,
417 value,
418 &value->args,
419 &np);
420 if (ret != 0) {
421 goto fail;
422 }
423 offset += np;
424
425 ret = ctdb_uint32_pull(buf+offset,
426 buflen-offset,
427 &value->timeout,
428 &np);
429 if (ret != 0) {
430 goto fail;
431 }
432 offset += np;
433
434 ret = ctdb_uint32_pull(buf+offset,
435 buflen-offset,
436 &value->flags,
437 &np);
438 if (ret != 0) {
439 goto fail;
440 }
441 offset += np;
442
443 *out = value;
444 *npull = offset;
445
446 return 0;
447
448 fail:
449 talloc_free(value);
450 return ret;
451 }
452
ctdb_event_request_status_len(struct ctdb_event_request_status * in)453 static size_t ctdb_event_request_status_len(
454 struct ctdb_event_request_status *in)
455 {
456 return ctdb_stringn_len(&in->component) +
457 ctdb_stringn_len(&in->event);
458 }
459
ctdb_event_request_status_push(struct ctdb_event_request_status * in,uint8_t * buf,size_t * npush)460 static void ctdb_event_request_status_push(
461 struct ctdb_event_request_status *in,
462 uint8_t *buf,
463 size_t *npush)
464 {
465 size_t offset = 0, np;
466
467 ctdb_stringn_push(&in->component, buf+offset, &np);
468 offset += np;
469
470 ctdb_stringn_push(&in->event, buf+offset, &np);
471 offset += np;
472
473 *npush = offset;
474 }
475
ctdb_event_request_status_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_request_status ** out,size_t * npull)476 static int ctdb_event_request_status_pull(
477 uint8_t *buf,
478 size_t buflen,
479 TALLOC_CTX *mem_ctx,
480 struct ctdb_event_request_status **out,
481 size_t *npull)
482 {
483 struct ctdb_event_request_status *value;
484 size_t offset = 0, np;
485 int ret;
486
487 value = talloc(mem_ctx, struct ctdb_event_request_status);
488 if (value == NULL) {
489 return ENOMEM;
490 }
491
492 ret = ctdb_stringn_pull(buf+offset,
493 buflen-offset,
494 value,
495 &value->component,
496 &np);
497 if (ret != 0) {
498 goto fail;
499 }
500 offset += np;
501
502 ret = ctdb_stringn_pull(buf+offset,
503 buflen-offset,
504 value,
505 &value->event,
506 &np);
507 if (ret != 0) {
508 goto fail;
509 }
510 offset += np;
511
512 *out = value;
513 *npull = offset;
514
515 return 0;
516
517 fail:
518 talloc_free(value);
519 return ret;
520 }
521
ctdb_event_request_script_len(struct ctdb_event_request_script * in)522 static size_t ctdb_event_request_script_len(
523 struct ctdb_event_request_script *in)
524 {
525 return ctdb_stringn_len(&in->component) +
526 ctdb_stringn_len(&in->script) +
527 ctdb_event_script_action_len(in->action);
528 }
529
ctdb_event_request_script_push(struct ctdb_event_request_script * in,uint8_t * buf,size_t * npush)530 static void ctdb_event_request_script_push(
531 struct ctdb_event_request_script *in,
532 uint8_t *buf,
533 size_t *npush)
534 {
535 size_t offset = 0, np;
536
537 ctdb_stringn_push(&in->component, buf+offset, &np);
538 offset += np;
539
540 ctdb_stringn_push(&in->script, buf+offset, &np);
541 offset += np;
542
543 ctdb_event_script_action_push(in->action, buf+offset, &np);
544 offset += np;
545
546 *npush = offset;
547 }
548
ctdb_event_request_script_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_request_script ** out,size_t * npull)549 static int ctdb_event_request_script_pull(
550 uint8_t *buf,
551 size_t buflen,
552 TALLOC_CTX *mem_ctx,
553 struct ctdb_event_request_script **out,
554 size_t *npull)
555 {
556 struct ctdb_event_request_script *value;
557 size_t offset = 0, np;
558 int ret;
559
560 value = talloc(mem_ctx, struct ctdb_event_request_script);
561 if (value == NULL) {
562 return ENOMEM;
563 }
564
565 ret = ctdb_stringn_pull(buf+offset,
566 buflen-offset,
567 value,
568 &value->component,
569 &np);
570 if (ret != 0) {
571 goto fail;
572 }
573 offset += np;
574
575 ret = ctdb_stringn_pull(buf+offset,
576 buflen-offset,
577 value,
578 &value->script,
579 &np);
580 if (ret != 0) {
581 goto fail;
582 }
583 offset += np;
584
585 ret = ctdb_event_script_action_pull(buf+offset,
586 buflen-offset,
587 &value->action,
588 &np);
589 if (ret != 0) {
590 goto fail;
591 }
592 offset += np;
593
594 *out = value;
595 *npull = offset;
596
597 return 0;
598
599 fail:
600 talloc_free(value);
601 return ret;
602 }
603
ctdb_event_reply_status_len(struct ctdb_event_reply_status * in)604 static size_t ctdb_event_reply_status_len(
605 struct ctdb_event_reply_status *in)
606 {
607 return ctdb_int32_len(&in->summary) +
608 ctdb_event_script_list_len(in->script_list);
609 }
610
ctdb_event_reply_status_push(struct ctdb_event_reply_status * in,uint8_t * buf,size_t * npush)611 static void ctdb_event_reply_status_push(
612 struct ctdb_event_reply_status *in,
613 uint8_t *buf,
614 size_t *npush)
615 {
616 size_t offset = 0, np;
617
618 ctdb_int32_push(&in->summary, buf+offset, &np);
619 offset += np;
620
621 ctdb_event_script_list_push(in->script_list, buf+offset, &np);
622 offset += np;
623
624 *npush = offset;
625 }
626
ctdb_event_reply_status_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_reply_status ** out,size_t * npull)627 static int ctdb_event_reply_status_pull(
628 uint8_t *buf,
629 size_t buflen,
630 TALLOC_CTX *mem_ctx,
631 struct ctdb_event_reply_status **out,
632 size_t *npull)
633 {
634 struct ctdb_event_reply_status *value;
635 size_t offset = 0, np;
636 int ret;
637
638 value = talloc(mem_ctx, struct ctdb_event_reply_status);
639 if (value == NULL) {
640 return ENOMEM;
641 }
642
643 ret = ctdb_int32_pull(buf+offset, buflen-offset, &value->summary, &np);
644 if (ret != 0) {
645 goto fail;
646 }
647 offset += np;
648
649 ret = ctdb_event_script_list_pull(buf+offset,
650 buflen-offset,
651 value,
652 &value->script_list,
653 &np);
654 if (ret != 0) {
655 goto fail;
656 }
657 offset += np;
658
659 *out = value;
660 *npull = offset;
661
662 return 0;
663
664 fail:
665 talloc_free(value);
666 return ret;
667 }
668
ctdb_event_header_len(struct ctdb_event_header * in)669 static size_t ctdb_event_header_len(struct ctdb_event_header *in)
670 {
671 return ctdb_uint32_len(&in->length) +
672 ctdb_uint32_len(&in->version) +
673 ctdb_uint32_len(&in->reqid);
674 }
675
ctdb_event_header_push(struct ctdb_event_header * in,uint8_t * buf,size_t * npush)676 static void ctdb_event_header_push(struct ctdb_event_header *in,
677 uint8_t *buf,
678 size_t *npush)
679 {
680 size_t offset = 0, np;
681
682 ctdb_uint32_push(&in->length, buf+offset, &np);
683 offset += np;
684
685 ctdb_uint32_push(&in->version, buf+offset, &np);
686 offset += np;
687
688 ctdb_uint32_push(&in->reqid, buf+offset, &np);
689 offset += np;
690
691 *npush = offset;
692 }
693
ctdb_event_header_pull(uint8_t * buf,size_t buflen,struct ctdb_event_header * value,size_t * npull)694 static int ctdb_event_header_pull(uint8_t *buf,
695 size_t buflen,
696 struct ctdb_event_header *value,
697 size_t *npull)
698 {
699 size_t offset = 0, np;
700 int ret;
701
702 ret = ctdb_uint32_pull(buf+offset,
703 buflen-offset,
704 &value->length,
705 &np);
706 if (ret != 0) {
707 return ret;
708 }
709 offset += np;
710
711 ret = ctdb_uint32_pull(buf+offset,
712 buflen-offset,
713 &value->version,
714 &np);
715 if (ret != 0) {
716 return ret;
717 }
718 offset += np;
719
720 ret = ctdb_uint32_pull(buf+offset,
721 buflen-offset,
722 &value->reqid,
723 &np);
724 if (ret != 0) {
725 return ret;
726 }
727 offset += np;
728
729 *npull = offset;
730
731 return 0;
732 }
733
ctdb_event_header_extract(uint8_t * buf,size_t buflen,struct ctdb_event_header * value)734 int ctdb_event_header_extract(uint8_t *buf,
735 size_t buflen,
736 struct ctdb_event_header *value)
737 {
738 size_t np;
739
740 return ctdb_event_header_pull(buf, buflen, value, &np);
741 }
742
ctdb_event_request_data_len(struct ctdb_event_request * in)743 static size_t ctdb_event_request_data_len(struct ctdb_event_request *in)
744 {
745 size_t len;
746
747 len = ctdb_event_command_len(in->cmd);
748
749 switch (in->cmd) {
750 case CTDB_EVENT_CMD_RUN:
751 len += ctdb_event_request_run_len(in->data.run);
752 break;
753
754 case CTDB_EVENT_CMD_STATUS:
755 len += ctdb_event_request_status_len(in->data.status);
756 break;
757
758 case CTDB_EVENT_CMD_SCRIPT:
759 len += ctdb_event_request_script_len(in->data.script);
760 break;
761
762 default:
763 break;
764 }
765
766 return len;
767 }
768
ctdb_event_request_data_push(struct ctdb_event_request * in,uint8_t * buf,size_t * npush)769 static void ctdb_event_request_data_push(struct ctdb_event_request *in,
770 uint8_t *buf,
771 size_t *npush)
772 {
773 size_t offset = 0, np;
774
775 ctdb_event_command_push(in->cmd, buf+offset, &np);
776 offset += np;
777
778 switch (in->cmd) {
779 case CTDB_EVENT_CMD_RUN:
780 ctdb_event_request_run_push(in->data.run, buf+offset, &np);
781 break;
782
783 case CTDB_EVENT_CMD_STATUS:
784 ctdb_event_request_status_push(in->data.status,
785 buf+offset,
786 &np);
787 break;
788
789 case CTDB_EVENT_CMD_SCRIPT:
790 ctdb_event_request_script_push(in->data.script,
791 buf+offset,
792 &np);
793 break;
794 default:
795 np = 0;
796 break;
797 }
798 offset += np;
799
800 *npush = offset;
801 }
802
ctdb_event_request_data_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_request ** out,size_t * npull)803 static int ctdb_event_request_data_pull(uint8_t *buf,
804 size_t buflen,
805 TALLOC_CTX *mem_ctx,
806 struct ctdb_event_request **out,
807 size_t *npull)
808 {
809 struct ctdb_event_request *value;
810 size_t offset = 0, np;
811 int ret;
812
813 value = talloc(mem_ctx, struct ctdb_event_request);
814 if (value == NULL) {
815 return ENOMEM;
816 }
817
818 ret = ctdb_event_command_pull(buf+offset,
819 buflen-offset,
820 &value->cmd,
821 &np);
822 if (ret != 0) {
823 goto fail;
824 }
825 offset += np;
826
827 switch (value->cmd) {
828 case CTDB_EVENT_CMD_RUN:
829 ret = ctdb_event_request_run_pull(buf+offset,
830 buflen-offset,
831 value,
832 &value->data.run,
833 &np);
834 break;
835
836 case CTDB_EVENT_CMD_STATUS:
837 ret = ctdb_event_request_status_pull(buf+offset,
838 buflen-offset,
839 value,
840 &value->data.status,
841 &np);
842 break;
843
844 case CTDB_EVENT_CMD_SCRIPT:
845 ret = ctdb_event_request_script_pull(buf+offset,
846 buflen-offset,
847 value,
848 &value->data.script,
849 &np);
850 break;
851
852 default:
853 np = 0;
854 break;
855 }
856
857 if (ret != 0) {
858 goto fail;
859 }
860 offset += np;
861
862 *out = value;
863 *npull = offset;
864
865 return 0;
866
867 fail:
868 talloc_free(value);
869 return ret;
870 }
871
ctdb_event_reply_data_len(struct ctdb_event_reply * in)872 static size_t ctdb_event_reply_data_len(struct ctdb_event_reply *in)
873 {
874 size_t len;
875
876 len = ctdb_event_command_len(in->cmd) +
877 ctdb_int32_len(&in->result);
878
879 if (in->result != 0) {
880 goto done;
881 }
882
883 switch (in->cmd) {
884 case CTDB_EVENT_CMD_STATUS:
885 len += ctdb_event_reply_status_len(in->data.status);
886 break;
887
888 default:
889 break;
890 }
891
892 done:
893 return len;
894 }
895
ctdb_event_reply_data_push(struct ctdb_event_reply * in,uint8_t * buf,size_t * npush)896 static void ctdb_event_reply_data_push(struct ctdb_event_reply *in,
897 uint8_t *buf,
898 size_t *npush)
899 {
900 size_t offset = 0, np;
901
902 ctdb_event_command_push(in->cmd, buf+offset, &np);
903 offset += np;
904
905 ctdb_int32_push(&in->result, buf+offset, &np);
906 offset += np;
907
908 if (in->result != 0) {
909 goto done;
910 }
911
912 switch (in->cmd) {
913 case CTDB_EVENT_CMD_STATUS:
914 ctdb_event_reply_status_push(in->data.status, buf+offset, &np);
915 break;
916
917 default:
918 np = 0;
919 break;
920 }
921 offset += np;
922
923 done:
924 *npush = offset;
925 }
926
ctdb_event_reply_data_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_event_reply ** out,size_t * npull)927 static int ctdb_event_reply_data_pull(uint8_t *buf,
928 size_t buflen,
929 TALLOC_CTX *mem_ctx,
930 struct ctdb_event_reply **out,
931 size_t *npull)
932 {
933 struct ctdb_event_reply *value;
934 size_t offset = 0, np;
935 int ret;
936
937 value = talloc(mem_ctx, struct ctdb_event_reply);
938 if (value == NULL) {
939 return ENOMEM;
940 }
941
942 ret = ctdb_event_command_pull(buf+offset,
943 buflen-offset,
944 &value->cmd,
945 &np);
946 if (ret != 0) {
947 goto fail;
948 }
949 offset += np;
950
951 ret = ctdb_int32_pull(buf+offset, buflen-offset, &value->result, &np);
952 if (ret != 0) {
953 goto fail;
954 }
955 offset += np;
956
957 if (value->result != 0) {
958 goto done;
959 }
960
961 switch (value->cmd) {
962 case CTDB_EVENT_CMD_STATUS:
963 ret = ctdb_event_reply_status_pull(buf+offset,
964 buflen-offset,
965 value,
966 &value->data.status,
967 &np);
968 break;
969
970 default:
971 np = 0;
972 break;
973 }
974
975 if (ret != 0) {
976 goto fail;
977 }
978 offset += np;
979
980 done:
981 *out = value;
982 *npull = offset;
983
984 return 0;
985
986 fail:
987 talloc_free(value);
988 return ret;
989 }
990
ctdb_event_request_len(struct ctdb_event_header * h,struct ctdb_event_request * in)991 size_t ctdb_event_request_len(struct ctdb_event_header *h,
992 struct ctdb_event_request *in)
993 {
994 return ctdb_event_header_len(h) +
995 ctdb_event_request_data_len(in);
996 }
997
ctdb_event_request_push(struct ctdb_event_header * h,struct ctdb_event_request * in,uint8_t * buf,size_t * buflen)998 int ctdb_event_request_push(struct ctdb_event_header *h,
999 struct ctdb_event_request *in,
1000 uint8_t *buf,
1001 size_t *buflen)
1002 {
1003 size_t len, offset = 0, np;
1004
1005 len = ctdb_event_request_len(h, in);
1006 if (*buflen < len) {
1007 *buflen = len;
1008 return EMSGSIZE;
1009 }
1010
1011 h->length = *buflen;
1012
1013 ctdb_event_header_push(h, buf+offset, &np);
1014 offset += np;
1015
1016 ctdb_event_request_data_push(in, buf+offset, &np);
1017 offset += np;
1018
1019 if (offset > *buflen) {
1020 return EMSGSIZE;
1021 }
1022
1023 return 0;
1024 }
1025
ctdb_event_request_pull(uint8_t * buf,size_t buflen,struct ctdb_event_header * h,TALLOC_CTX * mem_ctx,struct ctdb_event_request ** out)1026 int ctdb_event_request_pull(uint8_t *buf,
1027 size_t buflen,
1028 struct ctdb_event_header *h,
1029 TALLOC_CTX *mem_ctx,
1030 struct ctdb_event_request **out)
1031 {
1032 size_t offset = 0, np;
1033 int ret;
1034
1035 ret = ctdb_event_header_pull(buf+offset, buflen-offset, h, &np);
1036 if (ret != 0) {
1037 return ret;
1038 }
1039 offset += np;
1040
1041 ret = ctdb_event_request_data_pull(buf+offset,
1042 buflen-offset,
1043 mem_ctx,
1044 out,
1045 &np);
1046 if (ret != 0) {
1047 return ret;
1048 }
1049 offset += np;
1050
1051 if (offset > buflen) {
1052 return EMSGSIZE;
1053 }
1054
1055 return 0;
1056 }
1057
ctdb_event_reply_len(struct ctdb_event_header * h,struct ctdb_event_reply * in)1058 size_t ctdb_event_reply_len(struct ctdb_event_header *h,
1059 struct ctdb_event_reply *in)
1060 {
1061 return ctdb_event_header_len(h) +
1062 ctdb_event_reply_data_len(in);
1063 }
1064
ctdb_event_reply_push(struct ctdb_event_header * h,struct ctdb_event_reply * in,uint8_t * buf,size_t * buflen)1065 int ctdb_event_reply_push(struct ctdb_event_header *h,
1066 struct ctdb_event_reply *in,
1067 uint8_t *buf,
1068 size_t *buflen)
1069 {
1070 size_t len, offset = 0, np;
1071
1072 len = ctdb_event_reply_len(h, in);
1073 if (*buflen < len) {
1074 *buflen = len;
1075 return EMSGSIZE;
1076 }
1077
1078 h->length = *buflen;
1079
1080 ctdb_event_header_push(h, buf+offset, &np);
1081 offset += np;
1082
1083 ctdb_event_reply_data_push(in, buf+offset, &np);
1084 offset += np;
1085
1086 if (offset > *buflen) {
1087 return EMSGSIZE;
1088 }
1089
1090 return 0;
1091 }
1092
ctdb_event_reply_pull(uint8_t * buf,size_t buflen,struct ctdb_event_header * h,TALLOC_CTX * mem_ctx,struct ctdb_event_reply ** out)1093 int ctdb_event_reply_pull(uint8_t *buf,
1094 size_t buflen,
1095 struct ctdb_event_header *h,
1096 TALLOC_CTX *mem_ctx,
1097 struct ctdb_event_reply **out)
1098 {
1099 size_t offset = 0, np;
1100 int ret;
1101
1102 ret = ctdb_event_header_pull(buf+offset, buflen-offset, h, &np);
1103 if (ret != 0) {
1104 return ret;
1105 }
1106 offset += np;
1107
1108 ret = ctdb_event_reply_data_pull(buf+offset,
1109 buflen-offset,
1110 mem_ctx,
1111 out,
1112 &np);
1113 if (ret != 0) {
1114 return ret;
1115 }
1116 offset += np;
1117
1118 if (offset > buflen) {
1119 return EMSGSIZE;
1120 }
1121
1122 return 0;
1123 }
1124