ctdb-common: Fix compilation issue with strncpy()
[vlendec/samba-autobuild/.git] / ctdb / common / run_event.c
1 /*
2    Run scripts in a directory with specific event arguments
3
4    Copyright (C) Amitay Isaacs  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/filesys.h"
22 #include "system/dir.h"
23 #include "system/glob.h"
24 #include "system/wait.h"
25
26 #include <talloc.h>
27 #include <tevent.h>
28
29 #include "lib/util/tevent_unix.h"
30 #include "lib/util/debug.h"
31
32 #include "common/logging.h"
33 #include "common/run_proc.h"
34 #include "common/run_event.h"
35
36 /*
37  * Utility functions
38  */
39
40 static int script_filter(const struct dirent *de)
41 {
42         int ret;
43
44         /* Match a script pattern */
45         ret = fnmatch("[0-9][0-9].*.script", de->d_name, 0);
46         if (ret == 0) {
47                 return 1;
48         }
49
50         return 0;
51 }
52
53 static int get_script_list(TALLOC_CTX *mem_ctx,
54                            const char *script_dir,
55                            struct run_event_script_list **out)
56 {
57         struct dirent **namelist = NULL;
58         struct run_event_script_list *script_list;
59         size_t ls;
60         int count, ret;
61         int i;
62
63         count = scandir(script_dir, &namelist, script_filter, alphasort);
64         if (count == -1) {
65                 ret = errno;
66                 if (ret == ENOENT) {
67                         D_WARNING("event script dir %s removed\n", script_dir);
68                 } else {
69                         D_WARNING("scandir() failed on %s, ret=%d\n",
70                                   script_dir, ret);
71                 }
72                 *out = NULL;
73                 goto done;
74         }
75
76         if (count == 0) {
77                 *out = NULL;
78                 ret = 0;
79                 goto done;
80         }
81
82         script_list = talloc_zero(mem_ctx, struct run_event_script_list);
83         if (script_list == NULL) {
84                 return ENOMEM;
85         }
86
87         script_list->num_scripts = count;
88         script_list->script = talloc_zero_array(script_list,
89                                                 struct run_event_script,
90                                                 count);
91         if (script_list->script == NULL) {
92                 ret = ENOMEM;
93                 talloc_free(script_list);
94                 goto done;
95         }
96
97         ls = strlen(".script");
98         for (i=0; i<count; i++) {
99                 struct run_event_script *s = &script_list->script[i];
100
101                 s->name = talloc_strndup(script_list,
102                                          namelist[i]->d_name,
103                                          strlen(namelist[i]->d_name) - ls);
104                 if (s->name == NULL) {
105                         ret = ENOMEM;
106                         talloc_free(script_list);
107                         goto done;
108                 }
109         }
110
111         *out = script_list;
112         ret = 0;
113
114 done:
115         if (namelist != NULL && count != -1) {
116                 for (i=0; i<count; i++) {
117                         free(namelist[i]);
118                 }
119                 free(namelist);
120         }
121         return ret;
122 }
123
124 static int script_chmod(TALLOC_CTX *mem_ctx, const char *script_dir,
125                         const char *script_name, bool enable)
126 {
127         DIR *dirp;
128         struct dirent *de;
129         char script_file[PATH_MAX];
130         int ret, new_mode;
131         char *filename;
132         struct stat st;
133         bool found;
134         int fd = -1;
135
136         ret = snprintf(script_file,
137                        sizeof(script_file),
138                        "%s.script",
139                        script_name);
140         if (ret >= sizeof(script_file)) {
141                 return ENAMETOOLONG;
142         }
143
144         dirp = opendir(script_dir);
145         if (dirp == NULL) {
146                 return errno;
147         }
148
149         found = false;
150         while ((de = readdir(dirp)) != NULL) {
151                 if (strcmp(de->d_name, script_file) == 0) {
152
153                         /* check for valid script names */
154                         ret = script_filter(de);
155                         if (ret == 0) {
156                                 closedir(dirp);
157                                 return EINVAL;
158                         }
159
160                         found = true;
161                         break;
162                 }
163         }
164         closedir(dirp);
165
166         if (! found) {
167                 return ENOENT;
168         }
169
170         filename = talloc_asprintf(mem_ctx, "%s/%s", script_dir, script_file);
171         if (filename == NULL) {
172                 return ENOMEM;
173         }
174
175         fd = open(filename, O_RDWR);
176         if (fd == -1) {
177                 ret = errno;
178                 goto done;
179         }
180
181         ret = fstat(fd, &st);
182         if (ret != 0) {
183                 ret = errno;
184                 goto done;
185         }
186
187         if (enable) {
188                 new_mode = st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH);
189         } else {
190                 new_mode = st.st_mode & ~(S_IXUSR | S_IXGRP | S_IXOTH);
191         }
192
193         ret = fchmod(fd, new_mode);
194         if (ret != 0) {
195                 ret = errno;
196                 goto done;
197         }
198
199 done:
200         if (fd != -1) {
201                 close(fd);
202         }
203         talloc_free(filename);
204         return ret;
205 }
206
207 static int script_args(TALLOC_CTX *mem_ctx, const char *event_str,
208                        const char *arg_str, const char ***out)
209 {
210         const char **argv;
211         int argc;
212         size_t len;
213
214         /* Preallocate argv array to avoid reallocation. */
215         len = 8;
216         argv = talloc_array(mem_ctx, const char *, len);
217         if (argv == NULL) {
218                 return ENOMEM;
219         }
220
221         argv[0] = NULL; /* script name */
222         argv[1] = event_str;
223         argc = 2;
224
225         if (arg_str != NULL) {
226                 char *str, *t, *tok;
227
228                 str = talloc_strdup(argv, arg_str);
229                 if (str == NULL) {
230                         return ENOMEM;
231                 }
232
233                 t = str;
234                 while ((tok = strtok(t, " ")) != NULL) {
235                         argv[argc] = talloc_strdup(argv, tok);
236                         if (argv[argc] == NULL) {
237                                 talloc_free(argv);
238                                 return ENOMEM;
239                         }
240                         argc += 1;
241                         if (argc >= len) {
242                                 argv = talloc_realloc(mem_ctx, argv,
243                                                       const char *, len + 8);
244                                 if (argv == NULL) {
245                                         return ENOMEM;
246                                 }
247                                 len += 8;
248                         }
249                         t = NULL;
250                 }
251
252                 talloc_free(str);
253         }
254
255         argv[argc] = NULL;
256         argc += 1;
257
258         *out = argv;
259         return 0;
260 }
261
262 struct run_event_context {
263         struct run_proc_context *run_proc_ctx;
264         const char *script_dir;
265         const char *debug_prog;
266         bool debug_running;
267
268         struct tevent_queue *queue;
269         struct tevent_req *current_req;
270         bool monitor_running;
271 };
272
273
274 int run_event_init(TALLOC_CTX *mem_ctx, struct run_proc_context *run_proc_ctx,
275                    const char *script_dir, const char *debug_prog,
276                    struct run_event_context **out)
277 {
278         struct run_event_context *run_ctx;
279         struct stat st;
280         int ret;
281
282         run_ctx = talloc_zero(mem_ctx, struct run_event_context);
283         if (run_ctx == NULL) {
284                 return ENOMEM;
285         }
286
287         run_ctx->run_proc_ctx = run_proc_ctx;
288
289         ret = stat(script_dir, &st);
290         if (ret != 0) {
291                 ret = errno;
292                 talloc_free(run_ctx);
293                 return ret;
294         }
295
296         if (! S_ISDIR(st.st_mode)) {
297                 talloc_free(run_ctx);
298                 return ENOTDIR;
299         }
300
301         run_ctx->script_dir = talloc_strdup(run_ctx, script_dir);
302         if (run_ctx->script_dir == NULL) {
303                 talloc_free(run_ctx);
304                 return ENOMEM;
305         }
306
307         if (debug_prog != NULL) {
308                 run_ctx->debug_prog = talloc_strdup(run_ctx, debug_prog);
309                 if (run_ctx->debug_prog == NULL) {
310                         talloc_free(run_ctx);
311                         return ENOMEM;
312                 }
313         }
314
315         run_ctx->debug_running = false;
316
317         run_ctx->queue = tevent_queue_create(run_ctx, "run event queue");
318         if (run_ctx->queue == NULL) {
319                 talloc_free(run_ctx);
320                 return ENOMEM;
321         }
322
323         run_ctx->monitor_running = false;
324
325         *out = run_ctx;
326         return 0;
327 }
328
329 static struct run_proc_context *
330 run_event_run_proc_context(struct run_event_context *run_ctx)
331 {
332         return run_ctx->run_proc_ctx;
333 }
334
335 static const char *run_event_script_dir(struct run_event_context *run_ctx)
336 {
337         return run_ctx->script_dir;
338 }
339
340 static const char *run_event_debug_prog(struct run_event_context *run_ctx)
341 {
342         return run_ctx->debug_prog;
343 }
344
345 static struct tevent_queue *run_event_queue(struct run_event_context *run_ctx)
346 {
347         return run_ctx->queue;
348 }
349
350 static void run_event_start_running(struct run_event_context *run_ctx,
351                                     struct tevent_req *req, bool is_monitor)
352 {
353         run_ctx->current_req = req;
354         run_ctx->monitor_running = is_monitor;
355 }
356
357 static void run_event_stop_running(struct run_event_context *run_ctx)
358 {
359         run_ctx->current_req = NULL;
360         run_ctx->monitor_running = false;
361 }
362
363 static struct tevent_req *run_event_get_running(
364                                 struct run_event_context *run_ctx,
365                                 bool *is_monitor)
366 {
367         *is_monitor = run_ctx->monitor_running;
368         return run_ctx->current_req;
369 }
370
371 static int run_event_script_status(struct run_event_script *script)
372 {
373         int ret;
374
375         if (script->result.sig > 0) {
376                 ret = -EINTR;
377         } else if (script->result.err > 0) {
378                 if (script->result.err == EACCES) {
379                         /* Map EACCESS to ENOEXEC */
380                         ret = -ENOEXEC;
381                 } else {
382                         ret = -script->result.err;
383                 }
384         } else {
385                 ret = script->result.status;
386         }
387
388         return ret;
389 }
390
391 int run_event_list(struct run_event_context *run_ctx,
392                    TALLOC_CTX *mem_ctx,
393                    struct run_event_script_list **output)
394 {
395         struct run_event_script_list *script_list;
396         int ret, i;
397
398         ret = get_script_list(mem_ctx, run_event_script_dir(run_ctx),
399                               &script_list);
400         if (ret != 0) {
401                 return ret;
402         }
403
404         if (script_list == NULL) {
405                 *output = NULL;
406                 return 0;
407         }
408
409         for (i=0; i<script_list->num_scripts; i++) {
410                 struct run_event_script *script = &script_list->script[i];
411                 struct stat st;
412                 char *path = NULL;
413
414                 path = talloc_asprintf(mem_ctx, "%s/%s.script",
415                                        run_event_script_dir(run_ctx),
416                                        script->name);
417                 if (path == NULL) {
418                         continue;
419                 }
420
421                 ret = stat(path, &st);
422                 if (ret != 0) {
423                         TALLOC_FREE(path);
424                         continue;
425                 }
426
427                 if (! (st.st_mode & S_IXUSR)) {
428                         script->summary = -ENOEXEC;
429                 }
430
431                 TALLOC_FREE(path);
432         }
433
434         *output = script_list;
435         return 0;
436 }
437
438 int run_event_script_enable(struct run_event_context *run_ctx,
439                             const char *script_name)
440 {
441         return script_chmod(run_ctx, run_event_script_dir(run_ctx),
442                             script_name, true);
443 }
444
445 int run_event_script_disable(struct run_event_context *run_ctx,
446                              const char *script_name)
447 {
448         return script_chmod(run_ctx, run_event_script_dir(run_ctx),
449                             script_name, false);
450 }
451
452 /*
453  * Run debug program to diagnose hung scripts
454  */
455
456 static int debug_args(TALLOC_CTX *mem_ctx, const char *path,
457                       const char *event_str, pid_t pid, const char ***out)
458 {
459         const char **argv;
460
461         argv = talloc_array(mem_ctx, const char *, 4);
462         if (argv == NULL) {
463                 return ENOMEM;
464         }
465
466         argv[0] = path;
467         argv[1] = talloc_asprintf(argv, "%d", pid);
468         argv[2] = event_str;
469         if (argv[1] == NULL) {
470                 talloc_free(argv);
471                 return ENOMEM;
472         }
473         argv[3] = NULL;
474
475         *out = argv;
476         return 0;
477 }
478
479 static void debug_log(int loglevel, const char *output, const char *log_prefix)
480 {
481         char *line, *s;
482
483         s = strdup(output);
484         if (s == NULL) {
485                 DEBUG(loglevel, ("%s: %s\n", log_prefix, output));
486                 return;
487         }
488
489         line = strtok(s, "\n");
490         while (line != NULL) {
491                 DEBUG(loglevel, ("%s: %s\n", log_prefix, line));
492                 line = strtok(NULL, "\n");
493         }
494         free(s);
495 }
496
497 struct run_debug_state {
498         struct run_event_context *run_ctx;
499         pid_t pid;
500 };
501
502 static void run_debug_done(struct tevent_req *subreq);
503
504 static struct tevent_req *run_debug_send(TALLOC_CTX *mem_ctx,
505                                          struct tevent_context *ev,
506                                          struct run_event_context *run_ctx,
507                                          const char *event_str, pid_t pid)
508 {
509         struct tevent_req *req, *subreq;
510         struct run_debug_state *state;
511         const char **argv;
512         const char *debug_prog;
513         int ret;
514
515         req = tevent_req_create(mem_ctx, &state, struct run_debug_state);
516         if (req == NULL) {
517                 return NULL;
518         }
519
520         state->run_ctx = run_ctx;
521         state->pid = pid;
522
523         debug_prog = run_event_debug_prog(run_ctx);
524         if (debug_prog == NULL) {
525                 tevent_req_done(req);
526                 return tevent_req_post(req, ev);
527         }
528
529         if (run_ctx->debug_running) {
530                 tevent_req_done(req);
531                 return tevent_req_post(req, ev);
532         }
533
534         if (pid == -1) {
535                 D_DEBUG("Event script terminated, nothing to debug\n");
536                 tevent_req_done(req);
537                 return tevent_req_post(req, ev);
538         }
539
540         ret = debug_args(state, debug_prog, event_str, pid, &argv);
541         if (ret != 0) {
542                 D_ERR("debug_args() failed\n");
543                 tevent_req_error(req, ret);
544                 return tevent_req_post(req, ev);
545         }
546
547         D_DEBUG("Running debug %s with args \"%s %s\"\n",
548                 debug_prog, argv[1], argv[2]);
549
550         subreq = run_proc_send(state, ev, run_event_run_proc_context(run_ctx),
551                                debug_prog, argv, -1, tevent_timeval_zero());
552         if (tevent_req_nomem(subreq, req)) {
553                 return tevent_req_post(req, ev);
554         }
555         tevent_req_set_callback(subreq, run_debug_done, req);
556
557         run_ctx->debug_running = true;
558
559         talloc_free(argv);
560         return req;
561 }
562
563 static void run_debug_done(struct tevent_req *subreq)
564 {
565         struct tevent_req *req = tevent_req_callback_data(
566                 subreq, struct tevent_req);
567         struct run_debug_state *state = tevent_req_data(
568                 req, struct run_debug_state);
569         char *output;
570         int ret;
571         bool status;
572
573         state->run_ctx->debug_running = false;
574
575         status = run_proc_recv(subreq, &ret, NULL, NULL, state, &output);
576         TALLOC_FREE(subreq);
577         if (! status) {
578                 D_ERR("Running debug failed, ret=%d\n", ret);
579         }
580
581         /* Log output */
582         if (output != NULL) {
583                 debug_log(DEBUG_ERR, output, "event_debug");
584                 talloc_free(output);
585         }
586
587         kill(-state->pid, SIGTERM);
588         tevent_req_done(req);
589 }
590
591 static bool run_debug_recv(struct tevent_req *req, int *perr)
592 {
593         int ret;
594
595         if (tevent_req_is_unix_error(req, &ret)) {
596                 if (perr != NULL) {
597                         *perr = ret;
598                 }
599                 return false;
600         }
601
602         return true;
603 }
604
605 /*
606  * Run a single event
607  */
608
609 struct run_event_state {
610         struct tevent_context *ev;
611         struct run_event_context *run_ctx;
612         const char *event_str;
613         const char *arg_str;
614         struct timeval timeout;
615         bool continue_on_failure;
616
617         struct run_event_script_list *script_list;
618         const char **argv;
619         struct tevent_req *script_subreq;
620         int index;
621         bool cancelled;
622 };
623
624 static void run_event_cancel(struct tevent_req *req);
625 static void run_event_trigger(struct tevent_req *req, void *private_data);
626 static struct tevent_req *run_event_run_script(struct tevent_req *req);
627 static void run_event_next_script(struct tevent_req *subreq);
628 static void run_event_debug(struct tevent_req *req, pid_t pid);
629 static void run_event_debug_done(struct tevent_req *subreq);
630
631 struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
632                                   struct tevent_context *ev,
633                                   struct run_event_context *run_ctx,
634                                   const char *event_str,
635                                   const char *arg_str,
636                                   struct timeval timeout,
637                                   bool continue_on_failure)
638 {
639         struct tevent_req *req, *current_req;
640         struct run_event_state *state;
641         bool monitor_running, status;
642
643         req = tevent_req_create(mem_ctx, &state, struct run_event_state);
644         if (req == NULL) {
645                 return NULL;
646         }
647
648         state->ev = ev;
649         state->run_ctx = run_ctx;
650         state->event_str = talloc_strdup(state, event_str);
651         if (tevent_req_nomem(state->event_str, req)) {
652                 return tevent_req_post(req, ev);
653         }
654         if (arg_str != NULL) {
655                 state->arg_str = talloc_strdup(state, arg_str);
656                 if (tevent_req_nomem(state->arg_str, req)) {
657                         return tevent_req_post(req, ev);
658                 }
659         }
660         state->timeout = timeout;
661         state->continue_on_failure = continue_on_failure;
662         state->cancelled = false;
663
664         state->script_list = talloc_zero(state, struct run_event_script_list);
665         if (tevent_req_nomem(state->script_list, req)) {
666                 return tevent_req_post(req, ev);
667         }
668
669         /*
670          * If monitor event is running,
671          *   cancel the running monitor event and run new event
672          *
673          * If any other event is running,
674          *   if new event is monitor, cancel that event
675          *   else add new event to the queue
676          */
677
678         current_req = run_event_get_running(run_ctx, &monitor_running);
679         if (current_req != NULL) {
680                 if (monitor_running) {
681                         run_event_cancel(current_req);
682                 } else if (strcmp(event_str, "monitor") == 0) {
683                         state->script_list->summary = -ECANCELED;
684                         tevent_req_done(req);
685                         return tevent_req_post(req, ev);
686                 }
687         }
688
689         status = tevent_queue_add(run_event_queue(run_ctx), ev, req,
690                                   run_event_trigger, NULL);
691         if (! status) {
692                 tevent_req_error(req, ENOMEM);
693                 return tevent_req_post(req, ev);
694         }
695
696         return req;
697 }
698
699 static void run_event_cancel(struct tevent_req *req)
700 {
701         struct run_event_state *state = tevent_req_data(
702                 req, struct run_event_state);
703
704         run_event_stop_running(state->run_ctx);
705
706         state->script_list->summary = -ECANCELED;
707         state->cancelled = true;
708
709         TALLOC_FREE(state->script_subreq);
710
711         tevent_req_done(req);
712 }
713
714 static void run_event_trigger(struct tevent_req *req, void *private_data)
715 {
716         struct tevent_req *subreq;
717         struct run_event_state *state = tevent_req_data(
718                 req, struct run_event_state);
719         struct run_event_script_list *script_list;
720         int ret;
721         bool is_monitor = false;
722
723         D_DEBUG("Running event %s with args \"%s\"\n", state->event_str,
724                 state->arg_str == NULL ? "(null)" : state->arg_str);
725
726         ret = get_script_list(state,
727                               run_event_script_dir(state->run_ctx),
728                               &script_list);
729         if (ret != 0) {
730                 D_ERR("get_script_list() failed, ret=%d\n", ret);
731                 tevent_req_error(req, ret);
732                 return;
733         }
734
735         /* No scripts */
736         if (script_list == NULL || script_list->num_scripts == 0) {
737                 tevent_req_done(req);
738                 return;
739         }
740
741         talloc_free(state->script_list);
742         state->script_list = script_list;
743
744         ret = script_args(state, state->event_str, state->arg_str,
745                           &state->argv);
746         if (ret != 0) {
747                 D_ERR("script_args() failed, ret=%d\n", ret);
748                 tevent_req_error(req, ret);
749                 return;
750         }
751
752         state->index = 0;
753
754         subreq = run_event_run_script(req);
755         if (tevent_req_nomem(subreq, req)) {
756                 return;
757         }
758         tevent_req_set_callback(subreq, run_event_next_script, req);
759
760         state->script_subreq = subreq;
761
762         if (strcmp(state->event_str, "monitor") == 0) {
763                 is_monitor = true;
764         }
765         run_event_start_running(state->run_ctx, req, is_monitor);
766 }
767
768 static struct tevent_req *run_event_run_script(struct tevent_req *req)
769 {
770         struct run_event_state *state = tevent_req_data(
771                 req, struct run_event_state);
772         struct run_event_script *script;
773         struct tevent_req *subreq;
774         char *path;
775
776         script = &state->script_list->script[state->index];
777
778         path = talloc_asprintf(state, "%s/%s.script",
779                                run_event_script_dir(state->run_ctx),
780                                script->name);
781         if (path == NULL) {
782                 return NULL;
783         }
784
785         state->argv[0] = script->name;
786         script->begin = tevent_timeval_current();
787
788         D_DEBUG("Running %s with args \"%s %s\"\n",
789                 path, state->argv[0], state->argv[1]);
790
791         subreq = run_proc_send(state, state->ev,
792                                run_event_run_proc_context(state->run_ctx),
793                                path, state->argv, -1, state->timeout);
794
795         talloc_free(path);
796
797         return subreq;
798 }
799
800 static void run_event_next_script(struct tevent_req *subreq)
801 {
802         struct tevent_req *req = tevent_req_callback_data(
803                 subreq, struct tevent_req);
804         struct run_event_state *state = tevent_req_data(
805                 req, struct run_event_state);
806         struct run_event_script *script;
807         pid_t pid;
808         int ret;
809         bool status;
810
811         script = &state->script_list->script[state->index];
812         script->end = tevent_timeval_current();
813
814         status = run_proc_recv(subreq, &ret, &script->result, &pid,
815                                state->script_list, &script->output);
816         TALLOC_FREE(subreq);
817         state->script_subreq = NULL;
818         if (! status) {
819                 D_ERR("run_proc failed for %s, ret=%d\n", script->name, ret);
820                 run_event_stop_running(state->run_ctx);
821                 tevent_req_error(req, ret);
822                 return;
823         }
824
825         if (state->cancelled) {
826                 return;
827         }
828
829         /* Log output */
830         if (script->output != NULL) {
831                 debug_log(DEBUG_ERR, script->output, script->name);
832         }
833
834         D_DEBUG("Script %s finished sig=%d, err=%d, status=%d\n",
835                 script->name, script->result.sig, script->result.err,
836                 script->result.status);
837
838
839         /* If a script fails, stop running */
840         script->summary = run_event_script_status(script);
841         if (script->summary != 0 && script->summary != -ENOEXEC) {
842                 state->script_list->summary = script->summary;
843
844                 if (! state->continue_on_failure) {
845                         state->script_list->num_scripts = state->index + 1;
846
847                         if (script->summary == -ETIME && pid != -1) {
848                                 run_event_debug(req, pid);
849                         }
850                         D_NOTICE("%s event %s\n", state->event_str,
851                                  (script->summary == -ETIME) ?
852                                   "timed out" :
853                                   "failed");
854                         run_event_stop_running(state->run_ctx);
855                         tevent_req_done(req);
856                         return;
857                 }
858         }
859
860         state->index += 1;
861
862         /* All scripts executed */
863         if (state->index >= state->script_list->num_scripts) {
864                 run_event_stop_running(state->run_ctx);
865                 tevent_req_done(req);
866                 return;
867         }
868
869         subreq = run_event_run_script(req);
870         if (tevent_req_nomem(subreq, req)) {
871                 return;
872         }
873         tevent_req_set_callback(subreq, run_event_next_script, req);
874
875         state->script_subreq = subreq;
876 }
877
878 static void run_event_debug(struct tevent_req *req, pid_t pid)
879 {
880         struct run_event_state *state = tevent_req_data(
881                 req, struct run_event_state);
882         struct tevent_req *subreq;
883
884         /* Debug script is run with ectx as the memory context */
885         subreq = run_debug_send(state->run_ctx, state->ev, state->run_ctx,
886                                 state->event_str, pid);
887         if (subreq == NULL) {
888                 /* If run debug fails, it's not an error */
889                 D_NOTICE("Failed to run event debug\n");
890                 return;
891         }
892         tevent_req_set_callback(subreq, run_event_debug_done, NULL);
893 }
894
895 static void run_event_debug_done(struct tevent_req *subreq)
896 {
897         int ret = 0;
898         bool status;
899
900         status = run_debug_recv(subreq, &ret);
901         TALLOC_FREE(subreq);
902         if (! status) {
903                 D_NOTICE("run_debug() failed, ret=%d\n", ret);
904         }
905 }
906
907 bool run_event_recv(struct tevent_req *req, int *perr,
908                     TALLOC_CTX *mem_ctx,
909                     struct run_event_script_list **script_list)
910 {
911         struct run_event_state *state = tevent_req_data(
912                 req, struct run_event_state);
913         int ret;
914
915         if (tevent_req_is_unix_error(req, &ret)) {
916                 if (perr != NULL) {
917                         *perr = ret;
918                 }
919                 return false;
920         }
921
922         if (script_list != NULL) {
923                 *script_list = talloc_steal(mem_ctx, state->script_list);
924         }
925         return true;
926 }
927