]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bpipe.c
b28068522f33112964cb6bf5bc2ef8cb2b3d8d1b
[bacula/bacula] / bacula / src / lib / bpipe.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *   bpipe.c bi-directional pipe
21  *
22  *    Kern Sibbald, November MMII
23  *
24  */
25
26
27 #include "bacula.h"
28 #include "jcr.h"
29 #include <sys/resource.h>
30
31 int execvp_errors[] = {
32         EACCES,
33         ENOEXEC,
34         EFAULT,
35         EINTR,
36         E2BIG,
37         ENAMETOOLONG,
38         ENOMEM,
39 #ifndef HAVE_WIN32
40         ETXTBSY,
41 #endif
42         ENOENT
43 };
44 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
45
46
47 #define MAX_ARGV 100
48
49 #if !defined(HAVE_WIN32)
50 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
51
52 void build_sh_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg)
53 {
54    bargv[0] = (char *)"/bin/sh";
55    bargv[1] = (char *)"-c";
56    bargv[2] = cmd;
57    bargv[3] = NULL;
58    *bargc = 3;
59 }
60
61 /*
62  * Run an external program. Optionally wait a specified number
63  *   of seconds. Program killed if wait exceeded. We open
64  *   a bi-directional pipe so that the user can read from and
65  *   write to the program.
66  */
67 BPIPE *open_bpipe(char *prog, int wait, const char *mode, char *envp[])
68 {
69    char *bargv[MAX_ARGV];
70    int bargc, i;
71    int readp[2], writep[2];
72    POOLMEM *tprog;
73    int mode_read, mode_write, mode_shell;
74    BPIPE *bpipe;
75    int save_errno;
76 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
77    struct rlimit rl;
78    int64_t rlimitResult=0;
79 #endif
80
81    if (!prog || !*prog) {
82       /* execve(3) A component of the file does not name an existing file or file is an empty string. */
83       errno = ENOENT; 
84       return NULL;
85    }
86    
87    bpipe = (BPIPE *)malloc(sizeof(BPIPE));
88    memset(bpipe, 0, sizeof(BPIPE));
89    mode_read = (mode[0] == 'r');
90    mode_write = (mode[0] == 'w' || mode[1] == 'w');
91    /* mode is at least 2 bytes long, can be 3, rs, rws, ws */
92    mode_shell = (mode[1] == 's' || (mode[1] && mode[2] == 's'));
93    /* Build arguments for running program. */
94    tprog = get_pool_memory(PM_FNAME);
95    pm_strcpy(tprog, prog);
96    if (mode_shell) {
97       build_sh_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
98
99    } else {
100       build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
101    }
102
103    /* Unable to parse the command, avoid segfault after the fork() */
104    if (bargc == 0 || bargv[0] == NULL) {
105       free_pool_memory(tprog);
106       free(bpipe);
107       /* execve(3) A component of the file does not name an existing file or file is an empty string. */
108       errno = ENOENT;
109       return NULL;
110    }
111
112 #ifdef  xxxxxx
113    printf("argc=%d\n", bargc);
114    for (i=0; i<bargc; i++) {
115       printf("argc=%d argv=%s:\n", i, bargv[i]);
116    }
117 #endif
118
119    /* Each pipe is one way, write one end, read the other, so we need two */
120    if (mode_write && pipe(writep) == -1) {
121       save_errno = errno;
122       free(bpipe);
123       free_pool_memory(tprog);
124       errno = save_errno;
125       return NULL;
126    }
127    if (mode_read && pipe(readp) == -1) {
128       save_errno = errno;
129       if (mode_write) {
130          close(writep[0]);
131          close(writep[1]);
132       }
133       free(bpipe);
134       free_pool_memory(tprog);
135       errno = save_errno;
136       return NULL;
137    }
138
139    /* Many systems doesn't have the correct system call
140     * to determine the FD list to close.
141     */
142 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
143    if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
144       rlimitResult = sysconf(_SC_OPEN_MAX);
145    } else {
146       rlimitResult = rl.rlim_max;
147    }
148 #endif
149
150    /* Start worker process */
151    switch (bpipe->worker_pid = fork()) {
152    case -1:                           /* error */
153       save_errno = errno;
154       if (mode_write) {
155          close(writep[0]);
156          close(writep[1]);
157       }
158       if (mode_read) {
159          close(readp[0]);
160          close(readp[1]);
161       }
162       free(bpipe);
163       free_pool_memory(tprog);
164       errno = save_errno;
165       return NULL;
166
167    case 0:                            /* child */
168       if (mode_write) {
169          close(writep[1]);
170          dup2(writep[0], 0);          /* Dup our write to his stdin */
171       }
172       if (mode_read) {
173          close(readp[0]);             /* Close unused child fds */
174          dup2(readp[1], 1);           /* dup our read to his stdout */
175          dup2(readp[1], 2);           /*   and his stderr */
176       }
177
178 #if HAVE_FCNTL_F_CLOSEM
179       fcntl(3, F_CLOSEM);
180 #elif HAVE_CLOSEFROM
181       closefrom(3);
182 #else
183       for (i=rlimitResult; i >= 3; i--) {
184          close(i);
185       }
186 #endif
187
188       /* Setup the environment if requested, we do not use execvpe()
189        * because it's not wildly available
190        * TODO: Implement envp to windows version of bpipe
191        */
192       setup_env(envp);
193
194       execvp(bargv[0], bargv);        /* call the program */
195       /* Convert errno into an exit code for later analysis */
196       for (i=0; i< num_execvp_errors; i++) {
197          if (execvp_errors[i] == errno) {
198             _exit(200 + i);            /* exit code => errno */
199          }
200       }
201       /* Do not flush stdio */
202       _exit(255);                      /* unknown errno */
203
204    default:                           /* parent */
205       break;
206    }
207    free_pool_memory(tprog);
208    if (mode_read) {
209       close(readp[1]);                /* close unused parent fds */
210       bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
211    }
212    if (mode_write) {
213       close(writep[0]);
214       bpipe->wfd = fdopen(writep[1], "w");
215    }
216    bpipe->worker_stime = time(NULL);
217    bpipe->wait = wait;
218    if (wait > 0) {
219       bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
220    }
221    return bpipe;
222 }
223
224 /* Close the write pipe only */
225 int close_wpipe(BPIPE *bpipe)
226 {
227    int stat = 1;
228
229    if (bpipe->wfd) {
230       fflush(bpipe->wfd);
231       if (fclose(bpipe->wfd) != 0) {
232          stat = 0;
233       }
234       bpipe->wfd = NULL;
235    }
236    return stat;
237 }
238
239 /*
240  * Close both pipes and free resources
241  *
242  *  Returns: 0 on success
243  *           berrno on failure
244  */
245 int close_bpipe(BPIPE *bpipe)
246 {
247    int chldstatus = 0;
248    int stat = 0;
249    int wait_option;
250    int remaining_wait;
251    pid_t wpid = 0;
252
253
254    /* Close pipes */
255    if (bpipe->rfd) {
256       fclose(bpipe->rfd);
257       bpipe->rfd = NULL;
258    }
259    if (bpipe->wfd) {
260       fclose(bpipe->wfd);
261       bpipe->wfd = NULL;
262    }
263
264    if (bpipe->wait == 0) {
265       wait_option = 0;                /* wait indefinitely */
266    } else {
267       wait_option = WNOHANG;          /* don't hang */
268    }
269    remaining_wait = bpipe->wait;
270
271    /* wait for worker child to exit */
272    for ( ;; ) {
273       Dmsg2(100, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
274       do {
275          wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
276       } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
277       if (wpid == bpipe->worker_pid || wpid == -1) {
278          berrno be;
279          stat = errno;
280          Dmsg3(100, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
281             wpid==-1?be.bstrerror():"none");
282          break;
283       }
284       Dmsg3(100, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
285             wpid==-1?strerror(errno):"none");
286       if (remaining_wait > 0) {
287          bmicrosleep(1, 0);           /* wait one second */
288          remaining_wait--;
289       } else {
290          stat = ETIME;                /* set error status */
291          wpid = -1;
292          break;                       /* don't wait any longer */
293       }
294    }
295    if (wpid > 0) {
296       if (WIFEXITED(chldstatus)) {    /* process exit()ed */
297          stat = WEXITSTATUS(chldstatus);
298          if (stat != 0) {
299             Dmsg1(100, "Non-zero status %d returned from child.\n", stat);
300             stat |= b_errno_exit;        /* exit status returned */
301          }
302          Dmsg1(100, "child status=%d\n", stat & ~b_errno_exit);
303       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
304 #ifndef HAVE_WIN32
305          stat = WTERMSIG(chldstatus);
306 #else
307          stat = 1;                    /* fake child status */
308 #endif
309          Dmsg1(100, "Child died from signal %d\n", stat);
310          stat |= b_errno_signal;      /* exit signal returned */
311       }
312    }
313    if (bpipe->timer_id) {
314       stop_child_timer(bpipe->timer_id);
315    }
316    free(bpipe);
317    Dmsg2(100, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
318    return stat;
319 }
320
321 /*
322  * Build argc and argv from a string
323  */
324 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
325 {
326    int i;
327    char *p, *q, quote;
328    int argc = 0;
329
330    argc = 0;
331    for (i=0; i<max_argv; i++)
332       bargv[i] = NULL;
333
334    p = cmd;
335    quote = 0;
336    while  (*p && (*p == ' ' || *p == '\t'))
337       p++;
338    if (*p == '\"' || *p == '\'') {
339       quote = *p;
340       p++;
341    }
342    if (*p) {
343       while (*p && argc < MAX_ARGV) {
344          q = p;
345          if (quote) {
346             while (*q && *q != quote)
347             q++;
348             quote = 0;
349          } else {
350             while (*q && *q != ' ')
351             q++;
352          }
353          if (*q)
354             *(q++) = '\0';
355          bargv[argc++] = p;
356          p = q;
357          while (*p && (*p == ' ' || *p == '\t'))
358             p++;
359          if (*p == '\"' || *p == '\'') {
360             quote = *p;
361             p++;
362          }
363       }
364    }
365    *bargc = argc;
366 }
367 #endif /* HAVE_WIN32 */
368
369 /*
370  * Run an external program. Optionally wait a specified number
371  *   of seconds. Program killed if wait exceeded. Optionally
372  *   return the output from the program (normally a single line).
373  *
374  *   If the watchdog kills the program, fgets returns, and ferror is set
375  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
376  *
377  * Contrary to my normal calling conventions, this program
378  *
379  *  Returns: 0 on success
380  *           non-zero on error == berrno status
381  */
382 int run_program(char *prog, int wait, POOLMEM *&results)
383 {
384    BPIPE *bpipe;
385    int stat1, stat2;
386    char *mode;
387
388    mode = (char *)"r";
389    bpipe = open_bpipe(prog, wait, mode);
390    if (!bpipe) {
391       return ENOENT;
392    }
393    results[0] = 0;
394    int len = sizeof_pool_memory(results) - 1;
395    fgets(results, len, bpipe->rfd);
396    results[len] = 0;
397    if (feof(bpipe->rfd)) {
398       stat1 = 0;
399    } else {
400       stat1 = ferror(bpipe->rfd);
401    }
402    if (stat1 < 0) {
403       berrno be;
404       Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
405    } else if (stat1 != 0) {
406       Dmsg1(100, "Run program fgets stat=%d\n", stat1);
407       if (bpipe->timer_id) {
408          Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
409          /* NB: I'm not sure it is really useful for run_program. Without the
410           * following lines run_program would not detect if the program was killed
411           * by the watchdog. */
412          if (bpipe->timer_id->killed) {
413             stat1 = ETIME;
414             pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
415          }
416       }
417    }
418    stat2 = close_bpipe(bpipe);
419    stat1 = stat2 != 0 ? stat2 : stat1;
420    Dmsg1(100, "Run program returning %d\n", stat1);
421    return stat1;
422 }
423
424 /*
425  * Run an external program. Optionally wait a specified number
426  *   of seconds. Program killed if wait exceeded (it is done by the
427  *   watchdog, as fgets is a blocking function).
428  *
429  *   If the watchdog kills the program, fgets returns, and ferror is set
430  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
431  *
432  *   Return the full output from the program (not only the first line).
433  *
434  * Contrary to my normal calling conventions, this program
435  *
436  *  Returns: 0 on success
437  *           non-zero on error == berrno status
438  *
439  */
440 int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
441 {
442    BPIPE *bpipe;
443    int stat1, stat2;
444    char *mode;
445    POOLMEM* tmp;
446    char *buf;
447    const int bufsize = 32000;
448
449
450    Dsm_check(200);
451
452    tmp = get_pool_memory(PM_MESSAGE);
453    buf = (char *)malloc(bufsize+1);
454
455    results[0] = 0;
456    mode = (char *)"r";
457    bpipe = open_bpipe(prog, wait, mode, env);
458    if (!bpipe) {
459       stat1 = ENOENT;
460       goto bail_out;
461    }
462
463    Dsm_check(200);
464    tmp[0] = 0;
465    while (1) {
466       buf[0] = 0;
467       fgets(buf, bufsize, bpipe->rfd);
468       buf[bufsize] = 0;
469       pm_strcat(tmp, buf);
470       if (feof(bpipe->rfd)) {
471          stat1 = 0;
472          Dmsg1(100, "Run program fgets stat=%d\n", stat1);
473          break;
474       } else {
475          stat1 = ferror(bpipe->rfd);
476       }
477       if (stat1 < 0) {
478          berrno be;
479          Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
480          break;
481       } else if (stat1 != 0) {
482          Dmsg1(200, "Run program fgets stat=%d\n", stat1);
483          if (bpipe->timer_id && bpipe->timer_id->killed) {
484             Dmsg1(100, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
485             break;
486          }
487       }
488    }
489    /*
490     * We always check whether the timer killed the program. We would see
491     * an eof even when it does so we just have to trust the killed flag
492     * and set the timer values to avoid edge cases where the program ends
493     * just as the timer kills it.
494     */
495    if (bpipe->timer_id && bpipe->timer_id->killed) {
496       Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
497       pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
498       stat1 = ETIME;
499    }
500    pm_strcpy(results, tmp);
501    Dmsg3(200, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
502    stat2 = close_bpipe(bpipe);
503    stat1 = stat2 != 0 ? stat2 : stat1;
504
505    Dmsg1(100, "Run program returning %d\n", stat1);
506 bail_out:
507    free_pool_memory(tmp);
508    free(buf);
509    return stat1;
510 }