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