]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bpipe.c
03640a5fb17a375fcd93371f46189859c296fdac
[bacula/bacula] / bacula / src / lib / bpipe.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2002-2007 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *   bpipe.c bi-directional pipe
30  *
31  *    Kern Sibbald, November MMII
32  *
33  *   Version $Id$
34  */
35
36
37 #include "bacula.h"
38 #include "jcr.h"
39
40 int execvp_errors[] = {
41         EACCES,
42         ENOEXEC,
43         EFAULT,
44         EINTR,
45         E2BIG,
46         ENAMETOOLONG,
47         ENOMEM,
48 #ifndef HAVE_WIN32
49         ETXTBSY,
50 #endif
51         ENOENT
52 };
53 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
54
55
56 #define MAX_ARGV 100
57
58 #if !defined(HAVE_WIN32)
59 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
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)
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;
74    BPIPE *bpipe;
75    int save_errno;
76
77    bpipe = (BPIPE *)malloc(sizeof(BPIPE));
78    memset(bpipe, 0, sizeof(BPIPE));
79    mode_read = (mode[0] == 'r');
80    mode_write = (mode[0] == 'w' || mode[1] == 'w');
81    /* Build arguments for running program. */
82    tprog = get_pool_memory(PM_FNAME);
83    pm_strcpy(tprog, prog);
84    build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
85 #ifdef  xxxxxx
86    printf("argc=%d\n", bargc);
87    for (i=0; i<bargc; i++) {
88       printf("argc=%d argv=%s:\n", i, bargv[i]);
89    }
90 #endif
91
92    /* Each pipe is one way, write one end, read the other, so we need two */
93    if (mode_write && pipe(writep) == -1) {
94       save_errno = errno;
95       free(bpipe);
96       free_pool_memory(tprog);
97       errno = save_errno;
98       return NULL;
99    }
100    if (mode_read && pipe(readp) == -1) {
101       save_errno = errno;
102       if (mode_write) {
103          close(writep[0]);
104          close(writep[1]);
105       }
106       free(bpipe);
107       free_pool_memory(tprog);
108       errno = save_errno;
109       return NULL;
110    }
111    /* Start worker process */
112    switch (bpipe->worker_pid = fork()) {
113    case -1:                           /* error */
114       save_errno = errno;
115       if (mode_write) {
116          close(writep[0]);
117          close(writep[1]);
118       }
119       if (mode_read) {
120          close(readp[0]);
121          close(readp[1]);
122       }
123       free(bpipe);
124       free_pool_memory(tprog);
125       errno = save_errno;
126       return NULL;
127
128    case 0:                            /* child */
129       if (mode_write) {
130          close(writep[1]);
131          dup2(writep[0], 0);          /* Dup our write to his stdin */
132       }
133       if (mode_read) {
134          close(readp[0]);             /* Close unused child fds */
135          dup2(readp[1], 1);           /* dup our read to his stdout */
136          dup2(readp[1], 2);           /*   and his stderr */
137       }
138       closelog();                     /* close syslog if open */
139       for (i=3; i<=32; i++) {         /* close any open file descriptors */
140          close(i);
141       }
142       execvp(bargv[0], bargv);        /* call the program */
143       /* Convert errno into an exit code for later analysis */
144       for (i=0; i< num_execvp_errors; i++) {
145          if (execvp_errors[i] == errno) {
146             exit(200 + i);            /* exit code => errno */
147          }
148       }
149       exit(255);                      /* unknown errno */
150
151    default:                           /* parent */
152       break;
153    }
154    free_pool_memory(tprog);
155    if (mode_read) {
156       close(readp[1]);                /* close unused parent fds */
157       bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
158    }
159    if (mode_write) {
160       close(writep[0]);
161       bpipe->wfd = fdopen(writep[1], "w");
162    }
163    bpipe->worker_stime = time(NULL);
164    bpipe->wait = wait;
165    if (wait > 0) {
166       bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
167    }
168    return bpipe;
169 }
170
171 /* Close the write pipe only */
172 int close_wpipe(BPIPE *bpipe)
173 {
174    int stat = 1;
175
176    if (bpipe->wfd) {
177       fflush(bpipe->wfd);
178       if (fclose(bpipe->wfd) != 0) {
179          stat = 0;
180       }
181       bpipe->wfd = NULL;
182    }
183    return stat;
184 }
185
186 /*
187  * Close both pipes and free resources
188  *
189  *  Returns: 0 on success
190  *           berrno on failure
191  */
192 int close_bpipe(BPIPE *bpipe)
193 {
194    int chldstatus = 0;
195    int stat = 0;
196    int wait_option;
197    int remaining_wait;
198    pid_t wpid = 0;
199
200
201    /* Close pipes */
202    if (bpipe->rfd) {
203       fclose(bpipe->rfd);
204       bpipe->rfd = NULL;
205    }
206    if (bpipe->wfd) {
207       fclose(bpipe->wfd);
208       bpipe->wfd = NULL;
209    }
210
211    if (bpipe->wait == 0) {
212       wait_option = 0;                /* wait indefinitely */
213    } else {
214       wait_option = WNOHANG;          /* don't hang */
215    }
216    remaining_wait = bpipe->wait;
217
218    /* wait for worker child to exit */
219    for ( ;; ) {
220       Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
221       do {
222          wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
223       } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
224       if (wpid == bpipe->worker_pid || wpid == -1) {
225          berrno be;
226          stat = errno;
227          Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
228             wpid==-1?be.bstrerror():"none");
229          break;
230       }
231       Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
232             wpid==-1?strerror(errno):"none");
233       if (remaining_wait > 0) {
234          bmicrosleep(1, 0);           /* wait one second */
235          remaining_wait--;
236       } else {
237          stat = ETIME;                /* set error status */
238          wpid = -1;
239          break;                       /* don't wait any longer */
240       }
241    }
242    if (wpid > 0) {
243       if (WIFEXITED(chldstatus)) {    /* process exit()ed */
244          stat = WEXITSTATUS(chldstatus);
245          if (stat != 0) {
246             Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
247             stat |= b_errno_exit;        /* exit status returned */
248          }
249          Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
250       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
251 #ifndef HAVE_WIN32
252          stat = WTERMSIG(chldstatus);
253 #else
254          stat = 1;                    /* fake child status */
255 #endif
256          Dmsg1(800, "Child died from signal %d\n", stat);
257          stat |= b_errno_signal;      /* exit signal returned */
258       }
259    }
260    if (bpipe->timer_id) {
261       stop_child_timer(bpipe->timer_id);
262    }
263    free(bpipe);
264    Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
265    return stat;
266 }
267
268 /*
269  * Build argc and argv from a string
270  */
271 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
272 {
273    int i;
274    char *p, *q, quote;
275    int argc = 0;
276
277    argc = 0;
278    for (i=0; i<max_argv; i++)
279       bargv[i] = NULL;
280
281    p = cmd;
282    quote = 0;
283    while  (*p && (*p == ' ' || *p == '\t'))
284       p++;
285    if (*p == '\"' || *p == '\'') {
286       quote = *p;
287       p++;
288    }
289    if (*p) {
290       while (*p && argc < MAX_ARGV) {
291          q = p;
292          if (quote) {
293             while (*q && *q != quote)
294             q++;
295             quote = 0;
296          } else {
297             while (*q && *q != ' ')
298             q++;
299          }
300          if (*q)
301             *(q++) = '\0';
302          bargv[argc++] = p;
303          p = q;
304          while (*p && (*p == ' ' || *p == '\t'))
305             p++;
306          if (*p == '\"' || *p == '\'') {
307             quote = *p;
308             p++;
309          }
310       }
311    }
312    *bargc = argc;
313 }
314 #endif /* HAVE_WIN32 */
315
316 /*
317  * Run an external program. Optionally wait a specified number
318  *   of seconds. Program killed if wait exceeded. Optionally
319  *   return the output from the program (normally a single line).
320  *
321  *   If the watchdog kills the program, fgets returns, and ferror is set
322  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
323  *
324  * Contrary to my normal calling conventions, this program
325  *
326  *  Returns: 0 on success
327  *           non-zero on error == berrno status
328  */
329 int run_program(char *prog, int wait, POOLMEM *results)
330 {
331    BPIPE *bpipe;
332    int stat1, stat2;
333    char *mode;
334
335    mode = (char *)(results != NULL ? "r" : "");
336    bpipe = open_bpipe(prog, wait, mode);
337    if (!bpipe) {
338       return ENOENT;
339    }
340    if (results) {
341       results[0] = 0;
342       int len = sizeof_pool_memory(results) - 1;
343       fgets(results, len, bpipe->rfd);
344       results[len] = 0;
345       if (feof(bpipe->rfd)) {
346          stat1 = 0;
347       } else {
348          stat1 = ferror(bpipe->rfd);
349       }
350       if (stat1 < 0) {
351          berrno be;
352          Dmsg2(150, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
353       } else if (stat1 != 0) {
354          Dmsg1(150, "Run program fgets stat=%d\n", stat1);
355          if (bpipe->timer_id) {
356             Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
357             /* NB: I'm not sure it is really useful for run_program. Without the
358              * following lines run_program would not detect if the program was killed
359              * by the watchdog. */
360             if (bpipe->timer_id->killed) {
361                stat1 = ETIME;
362                pm_strcat(results, _("Program killed by Bacula watchdog (timeout)\n"));
363             }
364          }
365       }
366    } else {
367       stat1 = 0;
368    }
369    stat2 = close_bpipe(bpipe);
370    stat1 = stat2 != 0 ? stat2 : stat1;
371    Dmsg1(150, "Run program returning %d\n", stat1);
372    return stat1;
373 }
374
375 /*
376  * Run an external program. Optionally wait a specified number
377  *   of seconds. Program killed if wait exceeded (it is done by the 
378  *   watchdog, as fgets is a blocking function).
379  *
380  *   If the watchdog kills the program, fgets returns, and ferror is set
381  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
382  *
383  *   Return the full output from the program (not only the first line).
384  *
385  * Contrary to my normal calling conventions, this program
386  *
387  *  Returns: 0 on success
388  *           non-zero on error == berrno status
389  *
390  */
391 int run_program_full_output(char *prog, int wait, POOLMEM *results)
392 {
393    BPIPE *bpipe;
394    int stat1, stat2;
395    char *mode;
396    POOLMEM* tmp;
397    char *buf;
398    const int bufsize = 32000;
399
400    if (results == NULL) {
401       return run_program(prog, wait, NULL);
402    }
403    
404    sm_check(__FILE__, __LINE__, false);
405
406    tmp = get_pool_memory(PM_MESSAGE);
407    buf = (char *)malloc(bufsize+1);
408    
409    mode = (char *)"r";
410    bpipe = open_bpipe(prog, wait, mode);
411    if (!bpipe) {
412       if (results) {
413          results[0] = 0;
414       }
415       return ENOENT;
416    }
417    
418    sm_check(__FILE__, __LINE__, false);
419    tmp[0] = 0;
420    while (1) {
421       buf[0] = 0;
422       fgets(buf, bufsize, bpipe->rfd);
423       buf[bufsize] = 0;
424       pm_strcat(tmp, buf);
425       if (feof(bpipe->rfd)) {
426          stat1 = 0;
427          Dmsg1(900, "Run program fgets stat=%d\n", stat1);
428          break;
429       } else {
430          stat1 = ferror(bpipe->rfd);
431       }
432       if (stat1 < 0) {
433          berrno be;
434          Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
435          break;
436       } else if (stat1 != 0) {
437          Dmsg1(900, "Run program fgets stat=%d\n", stat1);
438          if (bpipe->timer_id && bpipe->timer_id->killed) {
439             Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
440             break;
441          }
442       }
443    }
444    /*
445     * We always check whether the timer killed the program. We would see
446     * an eof even when it does so we just have to trust the killed flag
447     * and set the timer values to avoid edge cases where the program ends
448     * just as the timer kills it.
449     */
450    if (bpipe->timer_id && bpipe->timer_id->killed) {
451       Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
452       pm_strcat(tmp, _("Program killed by Bacula watchdog (timeout)\n"));
453       stat1 = ETIME;
454    }
455    int len = sizeof_pool_memory(results) - 1;
456    bstrncpy(results, tmp, len);
457    Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
458    stat2 = close_bpipe(bpipe);
459    stat1 = stat2 != 0 ? stat2 : stat1;
460    
461    Dmsg1(900, "Run program returning %d\n", stat1);
462    free_pool_memory(tmp);
463    free(buf);
464    return stat1;
465 }