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