ctdb-protocol: Fix marshalling for ctdb_script_list
[vlendec/samba-autobuild/.git] / ctdb / protocol / protocol_event.c
1 /*
2    CTDB eventd protocol marshalling
3
4    Copyright (C) Amitay Isaacs  2016
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.h"
26 #include "protocol_private.h"
27 #include "protocol_api.h"
28
29 static size_t ctdb_event_len(enum ctdb_event in)
30 {
31         uint32_t u32 = in;
32
33         return ctdb_uint32_len(&u32);
34 }
35
36 static void ctdb_event_push(enum ctdb_event in, uint8_t *buf)
37 {
38         size_t np;
39         uint32_t u32 = in;
40
41         ctdb_uint32_push(&u32, buf, &np);
42 }
43
44 static int ctdb_event_pull(uint8_t *buf, size_t buflen,
45                            TALLOC_CTX *mem_ctx, enum ctdb_event *out)
46 {
47         uint32_t uint32_value;
48         enum ctdb_event value;
49         size_t np;
50         int ret;
51
52         ret = ctdb_uint32_pull(buf, buflen, &uint32_value, &np);
53         if (ret != 0) {
54                 return ret;
55         }
56
57         switch (uint32_value) {
58         case 0:
59                 value = CTDB_EVENT_INIT;
60                 break;
61
62         case 1:
63                 value = CTDB_EVENT_SETUP;
64                 break;
65
66         case 2:
67                 value = CTDB_EVENT_STARTUP;
68                 break;
69
70         case 3:
71                 value = CTDB_EVENT_START_RECOVERY;
72                 break;
73
74         case 4:
75                 value = CTDB_EVENT_RECOVERED;
76                 break;
77
78         case 5:
79                 value = CTDB_EVENT_TAKE_IP;
80                 break;
81
82         case 6:
83                 value = CTDB_EVENT_RELEASE_IP;
84                 break;
85
86         case 7:
87                 value = CTDB_EVENT_STOPPED;
88                 break;
89
90         case 8:
91                 value = CTDB_EVENT_MONITOR;
92                 break;
93
94         case 9:
95                 value = CTDB_EVENT_STATUS;
96                 break;
97
98         case 10:
99                 value = CTDB_EVENT_SHUTDOWN;
100                 break;
101
102         case 11:
103                 value = CTDB_EVENT_RELOAD;
104                 break;
105
106         case 12:
107                 value = CTDB_EVENT_UPDATE_IP;
108                 break;
109
110         case 13:
111                 value = CTDB_EVENT_IPREALLOCATED;
112                 break;
113
114         default:
115                 return EINVAL;
116         }
117
118         *out = value;
119         return 0;
120 }
121
122 static size_t ctdb_event_command_len(enum ctdb_event_command in)
123 {
124         uint32_t u32 = in;
125
126         return ctdb_uint32_len(&u32);
127 }
128
129 static void ctdb_event_command_push(enum ctdb_event_command in, uint8_t *buf)
130 {
131         size_t np;
132         uint32_t u32 = in;
133
134         ctdb_uint32_push(&u32, buf, &np);
135 }
136
137 static int ctdb_event_command_pull(uint8_t *buf, size_t buflen,
138                                    TALLOC_CTX *mem_ctx,
139                                    enum ctdb_event_command *out)
140 {
141         uint32_t uint32_value;
142         enum ctdb_event_command value;
143         size_t np;
144         int ret;
145
146         ret = ctdb_uint32_pull(buf, buflen, &uint32_value, &np);
147         if (ret != 0) {
148                 return ret;
149         }
150
151         switch (uint32_value) {
152         case 1:
153                 value = CTDB_EVENT_COMMAND_RUN;
154                 break;
155
156         case 2:
157                 value = CTDB_EVENT_COMMAND_STATUS;
158                 break;
159
160         case 3:
161                 value = CTDB_EVENT_COMMAND_SCRIPT_LIST;
162                 break;
163
164         case 4:
165                 value = CTDB_EVENT_COMMAND_SCRIPT_ENABLE;
166                 break;
167
168         case 5:
169                 value = CTDB_EVENT_COMMAND_SCRIPT_DISABLE;
170                 break;
171
172         default:
173                 return EINVAL;
174         }
175
176         *out = value;
177         return 0;
178 }
179
180 static size_t ctdb_event_status_state_len(enum ctdb_event_status_state in)
181 {
182         uint32_t u32 = in;
183
184         return ctdb_uint32_len(&u32);
185 }
186
187 static void ctdb_event_status_state_push(enum ctdb_event_status_state in,
188                                          uint8_t *buf)
189 {
190         size_t np;
191         uint32_t u32 = in;
192
193         ctdb_uint32_push(&u32, buf, &np);
194 }
195
196 static int ctdb_event_status_state_pull(uint8_t *buf, size_t buflen,
197                                         TALLOC_CTX *mem_ctx,
198                                         enum ctdb_event_status_state *out)
199 {
200         uint32_t uint32_value;
201         enum ctdb_event_status_state value;
202         size_t np;
203         int ret;
204
205         ret = ctdb_uint32_pull(buf, buflen, &uint32_value, &np);
206         if (ret != 0) {
207                 return ret;
208         }
209
210         switch (uint32_value) {
211         case 1:
212                 value = CTDB_EVENT_LAST_RUN;
213                 break;
214
215         case 2:
216                 value = CTDB_EVENT_LAST_PASS;
217                 break;
218
219         case 3:
220                 value = CTDB_EVENT_LAST_FAIL;
221                 break;
222
223         default:
224                 return EINVAL;
225         }
226
227         *out = value;
228         return 0;
229 }
230
231 static size_t ctdb_event_request_run_len(struct ctdb_event_request_run *in)
232 {
233         return ctdb_event_len(in->event) +
234                ctdb_uint32_len(&in->timeout) +
235                ctdb_stringn_len(&in->arg_str);
236 }
237
238 static void ctdb_event_request_run_push(struct ctdb_event_request_run *in,
239                                         uint8_t *buf)
240 {
241         size_t offset = 0, np;
242
243         ctdb_event_push(in->event, buf);
244         offset += ctdb_event_len(in->event);
245
246         ctdb_uint32_push(&in->timeout, buf+offset, &np);
247         offset += np;
248
249         ctdb_stringn_push(&in->arg_str, buf+offset, &np);
250 }
251
252 static int ctdb_event_request_run_pull(uint8_t *buf, size_t buflen,
253                                        TALLOC_CTX *mem_ctx,
254                                        struct ctdb_event_request_run **out)
255 {
256         struct ctdb_event_request_run *rdata;
257         size_t offset = 0, np;
258         int ret;
259
260         rdata = talloc(mem_ctx, struct ctdb_event_request_run);
261         if (rdata == NULL) {
262                 return ENOMEM;
263         }
264
265         ret = ctdb_event_pull(buf, buflen, rdata, &rdata->event);
266         if (ret != 0) {
267                 goto fail;
268         }
269         offset += ctdb_event_len(rdata->event);
270
271         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &rdata->timeout,
272                                &np);
273         if (ret != 0) {
274                 goto fail;
275         }
276         offset += np;
277
278         ret = ctdb_stringn_pull(buf+offset, buflen-offset,
279                                 rdata, &rdata->arg_str, &np);
280         if (ret != 0) {
281                 goto fail;
282         }
283
284         *out = rdata;
285         return 0;
286
287 fail:
288         talloc_free(rdata);
289         return ret;
290 }
291
292 static size_t ctdb_event_request_status_len(
293                                 struct ctdb_event_request_status *in)
294 {
295         return ctdb_event_len(in->event) +
296                ctdb_event_status_state_len(in->state);
297 }
298
299 static void ctdb_event_request_status_push(
300                                 struct ctdb_event_request_status *in,
301                                 uint8_t *buf)
302 {
303         size_t offset = 0;
304
305         ctdb_event_push(in->event, buf);
306         offset += ctdb_event_len(in->event);
307
308         ctdb_event_status_state_push(in->state, buf+offset);
309 }
310
311 static int ctdb_event_request_status_pull(
312                                 uint8_t *buf, size_t buflen,
313                                 TALLOC_CTX *mem_ctx,
314                                 struct ctdb_event_request_status **out)
315 {
316         struct ctdb_event_request_status *rdata;
317         size_t offset = 0;
318         int ret;
319
320         rdata = talloc(mem_ctx, struct ctdb_event_request_status);
321         if (rdata == NULL) {
322                 return ENOMEM;
323         }
324
325         ret = ctdb_event_pull(buf, buflen, rdata, &rdata->event);
326         if (ret != 0) {
327                 talloc_free(rdata);
328                 return ret;
329         }
330         offset += ctdb_event_len(rdata->event);
331
332         ret = ctdb_event_status_state_pull(buf+offset, buflen-offset,
333                                            rdata, &rdata->state);
334         if (ret != 0) {
335                 talloc_free(rdata);
336                 return ret;
337         }
338
339         *out = rdata;
340         return 0;
341 }
342
343 static size_t ctdb_event_request_script_enable_len(
344                                 struct ctdb_event_request_script_enable *in)
345 {
346         return ctdb_stringn_len(&in->script_name);
347 }
348
349 static void ctdb_event_request_script_enable_push(
350                                 struct ctdb_event_request_script_enable *in,
351                                 uint8_t *buf)
352 {
353         size_t np;
354
355         ctdb_stringn_push(&in->script_name, buf, &np);
356 }
357
358 static int ctdb_event_request_script_enable_pull(
359                                 uint8_t *buf, size_t buflen,
360                                 TALLOC_CTX *mem_ctx,
361                                 struct ctdb_event_request_script_enable **out)
362 {
363         struct ctdb_event_request_script_enable *rdata;
364         size_t np;
365         int ret;
366
367         rdata = talloc(mem_ctx, struct ctdb_event_request_script_enable);
368         if (rdata == NULL) {
369                 return ENOMEM;
370         }
371
372         ret = ctdb_stringn_pull(buf, buflen, rdata, &rdata->script_name, &np);
373         if (ret != 0) {
374                 talloc_free(rdata);
375                 return ret;
376         }
377
378         *out = rdata;
379         return 0;
380 }
381
382 static size_t ctdb_event_request_script_disable_len(
383                                 struct ctdb_event_request_script_disable *in)
384 {
385         return ctdb_stringn_len(&in->script_name);
386 }
387
388 static void ctdb_event_request_script_disable_push(
389                                 struct ctdb_event_request_script_disable *in,
390                                 uint8_t *buf)
391 {
392         size_t np;
393
394         ctdb_stringn_push(&in->script_name, buf, &np);
395 }
396
397 static int ctdb_event_request_script_disable_pull(
398                                 uint8_t *buf, size_t buflen,
399                                 TALLOC_CTX *mem_ctx,
400                                 struct ctdb_event_request_script_disable **out)
401 {
402         struct ctdb_event_request_script_disable *rdata;
403         size_t np;
404         int ret;
405
406         rdata = talloc(mem_ctx, struct ctdb_event_request_script_disable);
407         if (rdata == NULL) {
408                 return ENOMEM;
409         }
410
411         ret = ctdb_stringn_pull(buf, buflen, rdata, &rdata->script_name, &np);
412         if (ret != 0) {
413                 talloc_free(rdata);
414                 return ret;
415         }
416
417         *out = rdata;
418         return 0;
419 }
420
421 static size_t ctdb_event_request_data_len(struct ctdb_event_request_data *in)
422 {
423         size_t len = 0;
424
425         len += ctdb_event_command_len(in->command);
426
427         switch(in->command) {
428         case CTDB_EVENT_COMMAND_RUN:
429                 len += ctdb_event_request_run_len(in->data.run);
430                 break;
431
432         case CTDB_EVENT_COMMAND_STATUS:
433                 len += ctdb_event_request_status_len(in->data.status);
434                 break;
435
436         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
437                 break;
438
439         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
440                 len += ctdb_event_request_script_enable_len(
441                                                 in->data.script_enable);
442                 break;
443
444         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
445                 len += ctdb_event_request_script_disable_len(
446                                                 in->data.script_disable);
447                 break;
448         }
449
450         return len;
451 }
452
453 static void ctdb_event_request_data_push(struct ctdb_event_request_data *in,
454                                          uint8_t *buf)
455 {
456         size_t offset = 0;
457
458         ctdb_event_command_push(in->command, buf);
459         offset += ctdb_event_command_len(in->command);
460
461         switch (in->command) {
462         case CTDB_EVENT_COMMAND_RUN:
463                 ctdb_event_request_run_push(in->data.run, buf+offset);
464                 break;
465
466         case CTDB_EVENT_COMMAND_STATUS:
467                 ctdb_event_request_status_push(in->data.status, buf+offset);
468                 break;
469
470         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
471                 break;
472
473         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
474                 ctdb_event_request_script_enable_push(
475                                                 in->data.script_enable,
476                                                 buf+offset);
477                 break;
478
479         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
480                 ctdb_event_request_script_disable_push(
481                                                 in->data.script_disable,
482                                                 buf+offset);
483                 break;
484         }
485 }
486
487 static int ctdb_event_request_data_pull(uint8_t *buf, size_t buflen,
488                                         TALLOC_CTX *mem_ctx,
489                                         struct ctdb_event_request_data *out)
490 {
491         size_t offset = 0;
492         int ret;
493
494         ret = ctdb_event_command_pull(buf, buflen, mem_ctx, &out->command);
495         if (ret != 0) {
496                 return ret;
497         }
498         offset += ctdb_event_command_len(out->command);
499
500         switch (out->command) {
501         case CTDB_EVENT_COMMAND_RUN:
502                 ret = ctdb_event_request_run_pull(buf+offset, buflen-offset,
503                                                   mem_ctx, &out->data.run);
504                 break;
505
506         case CTDB_EVENT_COMMAND_STATUS:
507                 ret = ctdb_event_request_status_pull(
508                                                 buf+offset, buflen-offset,
509                                                 mem_ctx, &out->data.status);
510                 break;
511
512         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
513                 ret = 0;
514                 break;
515
516         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
517                 ret = ctdb_event_request_script_enable_pull(
518                                                 buf+offset, buflen-offset,
519                                                 mem_ctx,
520                                                 &out->data.script_enable);
521                 break;
522
523         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
524                 ret = ctdb_event_request_script_disable_pull(
525                                                 buf+offset, buflen-offset,
526                                                 mem_ctx,
527                                                 &out->data.script_disable);
528                 break;
529         }
530
531         if (ret != 0) {
532                 return ret;
533         }
534
535         return 0;
536 }
537
538 static size_t ctdb_event_reply_status_len(struct ctdb_event_reply_status *in)
539 {
540         return ctdb_int32_len(&in->status) +
541                ctdb_script_list_len(in->script_list);
542 }
543
544 static void ctdb_event_reply_status_push(struct ctdb_event_reply_status *in,
545                                          uint8_t *buf)
546 {
547         size_t offset = 0, np;
548
549         ctdb_int32_push(&in->status, buf, &np);
550         offset += np;
551
552         ctdb_script_list_push(in->script_list, buf+offset, &np);
553 }
554
555 static int ctdb_event_reply_status_pull(uint8_t *buf, size_t buflen,
556                                         TALLOC_CTX *mem_ctx,
557                                         struct ctdb_event_reply_status **out)
558 {
559         struct ctdb_event_reply_status *rdata;
560         size_t offset = 0, np;
561         int ret;
562
563         rdata = talloc(mem_ctx, struct ctdb_event_reply_status);
564         if (rdata == NULL) {
565                 return ENOMEM;
566         }
567
568         ret = ctdb_int32_pull(buf, buflen, &rdata->status, &np);
569         if (ret != 0) {
570                 talloc_free(rdata);
571                 return ret;
572         }
573         offset += np;
574
575         ret = ctdb_script_list_pull(buf+offset, buflen-offset,
576                                     rdata, &rdata->script_list, &np);
577         if (ret != 0) {
578                 talloc_free(rdata);
579                 return ret;
580         }
581
582         *out = rdata;
583         return 0;
584 }
585
586 static size_t ctdb_event_reply_script_list_len(
587                                 struct ctdb_event_reply_script_list *in)
588 {
589         return ctdb_script_list_len(in->script_list);
590 }
591
592 static void ctdb_event_reply_script_list_push(
593                                 struct ctdb_event_reply_script_list *in,
594                                 uint8_t *buf)
595 {
596         size_t np;
597
598         ctdb_script_list_push(in->script_list, buf, &np);
599 }
600
601 static int ctdb_event_reply_script_list_pull(
602                                 uint8_t *buf, size_t buflen,
603                                 TALLOC_CTX *mem_ctx,
604                                 struct ctdb_event_reply_script_list **out)
605 {
606         struct ctdb_event_reply_script_list *rdata;
607         size_t np;
608         int ret;
609
610         rdata = talloc(mem_ctx, struct ctdb_event_reply_script_list);
611         if (rdata == NULL) {
612                 return ENOMEM;
613         }
614
615         ret = ctdb_script_list_pull(buf, buflen, rdata, &rdata->script_list,
616                                     &np);
617         if (ret != 0) {
618                 talloc_free(rdata);
619                 return ret;
620         }
621
622         *out = rdata;
623         return 0;
624 }
625
626 static size_t ctdb_event_reply_data_len(struct ctdb_event_reply_data *in)
627 {
628         size_t len = 0;
629
630         len += ctdb_event_command_len(in->command);
631         len += ctdb_int32_len(&in->result);
632
633         switch (in->command) {
634         case CTDB_EVENT_COMMAND_RUN:
635                 break;
636
637         case CTDB_EVENT_COMMAND_STATUS:
638                 len += ctdb_event_reply_status_len(in->data.status);
639                 break;
640
641         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
642                 len += ctdb_event_reply_script_list_len(in->data.script_list);
643                 break;
644
645         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
646                 break;
647
648         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
649                 break;
650         }
651
652         return len;
653 }
654
655 static void ctdb_event_reply_data_push(struct ctdb_event_reply_data *in,
656                                        uint8_t *buf)
657 {
658         size_t offset = 0, np;
659
660         ctdb_event_command_push(in->command, buf);
661         offset += ctdb_event_command_len(in->command);
662
663         ctdb_int32_push(&in->result, buf+offset, &np);
664         offset += np;
665
666         switch (in->command) {
667         case CTDB_EVENT_COMMAND_RUN:
668                 break;
669
670         case CTDB_EVENT_COMMAND_STATUS:
671                 ctdb_event_reply_status_push(in->data.status, buf+offset);
672                 break;
673
674         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
675                 ctdb_event_reply_script_list_push(in->data.script_list,
676                                                   buf+offset);
677                 break;
678
679         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
680                 break;
681
682         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
683                 break;
684         }
685 }
686
687 static int ctdb_event_reply_data_pull(uint8_t *buf, size_t buflen,
688                                       TALLOC_CTX *mem_ctx,
689                                       struct ctdb_event_reply_data *out)
690 {
691         size_t offset = 0, np;
692         int ret;
693
694         ret = ctdb_event_command_pull(buf, buflen, mem_ctx, &out->command);
695         if (ret != 0) {
696                 return ret;
697         }
698         offset += ctdb_event_command_len(out->command);
699
700         ret = ctdb_int32_pull(buf+offset, buflen-offset, &out->result, &np);
701         if (ret != 0) {
702                 return ret;
703         }
704         offset += np;
705
706         switch (out->command) {
707         case CTDB_EVENT_COMMAND_RUN:
708                 break;
709
710         case CTDB_EVENT_COMMAND_STATUS:
711                 ret = ctdb_event_reply_status_pull(
712                                         buf+offset, buflen-offset,
713                                         mem_ctx, &out->data.status);
714                 break;
715
716         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
717                 ret = ctdb_event_reply_script_list_pull(
718                                         buf+offset, buflen-offset,
719                                         mem_ctx, &out->data.script_list);
720                 break;
721
722         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
723                 break;
724
725         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
726                 break;
727         }
728
729         if (ret != 0) {
730                 return ret;
731         }
732
733         return 0;
734 }
735
736 static size_t ctdb_event_header_len(struct ctdb_event_header *in)
737 {
738         return ctdb_uint32_len(&in->length) + ctdb_uint32_len(&in->reqid);
739 }
740
741 static void ctdb_event_header_push(struct ctdb_event_header *in, uint8_t *buf)
742 {
743         size_t offset = 0, np;
744
745         ctdb_uint32_push(&in->length, buf, &np);
746         offset += np;
747
748         ctdb_uint32_push(&in->reqid, buf+offset, &np);
749 }
750
751 static int ctdb_event_header_pull(uint8_t *buf, size_t buflen,
752                                   TALLOC_CTX *mem_ctx,
753                                   struct ctdb_event_header *out)
754 {
755         size_t offset = 0, np;
756         int ret;
757
758         ret = ctdb_uint32_pull(buf, buflen, &out->length, &np);
759         if (ret != 0) {
760                 return ret;
761         }
762         offset += np;
763
764         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->reqid, &np);
765         if (ret != 0) {
766                 return ret;
767         }
768
769         return 0;
770 }
771
772 void ctdb_event_header_fill(struct ctdb_event_header *h, uint32_t reqid)
773 {
774         h->length = ctdb_event_header_len(h);
775         h->reqid = reqid;
776 }
777
778 size_t ctdb_event_request_len(struct ctdb_event_request *in)
779 {
780         return ctdb_event_header_len(&in->header) +
781                ctdb_event_request_data_len(&in->rdata);
782 }
783
784 int ctdb_event_request_push(struct ctdb_event_request *in,
785                             uint8_t *buf, size_t *buflen)
786 {
787         size_t len, offset = 0;
788
789         len = ctdb_event_request_len(in);
790         if (*buflen < len) {
791                 *buflen = len;
792                 return EMSGSIZE;
793         }
794
795         in->header.length = *buflen;
796
797         ctdb_event_header_push(&in->header, buf);
798         offset += ctdb_event_header_len(&in->header);
799
800         ctdb_event_request_data_push(&in->rdata, buf+offset);
801
802         return 0;
803 }
804
805 int ctdb_event_request_pull(uint8_t *buf, size_t buflen,
806                             TALLOC_CTX *mem_ctx,
807                             struct ctdb_event_request *out)
808 {
809         size_t offset = 0;
810         int ret;
811
812         ret = ctdb_event_header_pull(buf, buflen, mem_ctx, &out->header);
813         if (ret != 0) {
814                 return ret;
815         }
816         offset += ctdb_event_header_len(&out->header);
817
818         ret = ctdb_event_request_data_pull(buf+offset, buflen-offset,
819                                            mem_ctx, &out->rdata);
820         if (ret != 0) {
821                 return ret;
822         }
823
824         return 0;
825 }
826
827 size_t ctdb_event_reply_len(struct ctdb_event_reply *in)
828 {
829         return ctdb_event_header_len(&in->header) +
830                ctdb_event_reply_data_len(&in->rdata);
831 }
832
833 int ctdb_event_reply_push(struct ctdb_event_reply *in,
834                           uint8_t *buf, size_t *buflen)
835 {
836         size_t len, offset = 0;
837
838         len = ctdb_event_reply_len(in);
839         if (*buflen < len) {
840                 *buflen = len;
841                 return EMSGSIZE;
842         }
843
844         in->header.length = *buflen;
845
846         ctdb_event_header_push(&in->header, buf);
847         offset += ctdb_event_header_len(&in->header);
848
849         ctdb_event_reply_data_push(&in->rdata, buf+offset);
850
851         return 0;
852 }
853
854 int ctdb_event_reply_pull(uint8_t *buf, size_t buflen,
855                           TALLOC_CTX *mem_ctx,
856                           struct ctdb_event_reply *out)
857 {
858         size_t offset = 0;
859         int ret;
860
861         ret = ctdb_event_header_pull(buf, buflen, mem_ctx, &out->header);
862         if (ret != 0) {
863                 return ret;
864         }
865         offset += ctdb_event_header_len(&out->header);
866
867         ret = ctdb_event_reply_data_pull(buf+offset, buflen-offset,
868                                          mem_ctx, &out->rdata);
869         if (ret != 0) {
870                 return ret;
871         }
872
873         return 0;
874 }