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