]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bpipe.c
kes Add dynamic dll entry point for SHGetFolderPath to Win32 code.
[bacula/bacula] / bacula / src / lib / bpipe.c
1 /*
2  *   bpipe.c bi-directional pipe
3  *
4  *    Kern Sibbald, November MMII
5  *
6  *   Version $Id$
7  */
8 /*
9    Bacula® - The Network Backup Solution
10
11    Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
12
13    The main author of Bacula is Kern Sibbald, with contributions from
14    many others, a complete list can be found in the file AUTHORS.
15    This program is Free Software; you can redistribute it and/or
16    modify it under the terms of version two of the GNU General Public
17    License as published by the Free Software Foundation plus additions
18    that are listed in the file LICENSE.
19
20    This program is distributed in the hope that it will be useful, but
21    WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23    General Public License for more details.
24
25    You should have received a copy of the GNU General Public License
26    along with this program; if not, write to the Free Software
27    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28    02110-1301, USA.
29
30    Bacula® is a registered trademark of John Walker.
31    The licensor of Bacula is the Free Software Foundation Europe
32    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
33    Switzerland, email:ftf@fsfeurope.org.
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(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          stat = errno;
226          Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
227             wpid==-1?strerror(errno):"none");
228          break;
229       }
230       Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
231             wpid==-1?strerror(errno):"none");
232       if (remaining_wait > 0) {
233          bmicrosleep(1, 0);           /* wait one second */
234          remaining_wait--;
235       } else {
236          stat = ETIME;                /* set error status */
237          wpid = -1;
238          break;                       /* don't wait any longer */
239       }
240    }
241    if (wpid > 0) {
242       if (WIFEXITED(chldstatus)) {    /* process exit()ed */
243          stat = WEXITSTATUS(chldstatus);
244          if (stat != 0) {
245             Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
246             stat |= b_errno_exit;        /* exit status returned */
247          }
248          Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
249       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
250 #ifndef HAVE_WIN32
251          stat = WTERMSIG(chldstatus);
252 #else
253          stat = 1;                    /* fake child status */
254 #endif
255          Dmsg1(800, "Child died from signal %d\n", stat);
256          stat |= b_errno_signal;      /* exit signal returned */
257       }
258    }
259    if (bpipe->timer_id) {
260       stop_child_timer(bpipe->timer_id);
261    }
262    free(bpipe);
263    Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
264    return stat;
265 }
266
267 /*
268  * Build argc and argv from a string
269  */
270 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
271 {
272    int i;
273    char *p, *q, quote;
274    int argc = 0;
275
276    argc = 0;
277    for (i=0; i<max_argv; i++)
278       bargv[i] = NULL;
279
280    p = cmd;
281    quote = 0;
282    while  (*p && (*p == ' ' || *p == '\t'))
283       p++;
284    if (*p == '\"' || *p == '\'') {
285       quote = *p;
286       p++;
287    }
288    if (*p) {
289       while (*p && argc < MAX_ARGV) {
290          q = p;
291          if (quote) {
292             while (*q && *q != quote)
293             q++;
294             quote = 0;
295          } else {
296             while (*q && *q != ' ')
297             q++;
298          }
299          if (*q)
300             *(q++) = '\0';
301          bargv[argc++] = p;
302          p = q;
303          while (*p && (*p == ' ' || *p == '\t'))
304             p++;
305          if (*p == '\"' || *p == '\'') {
306             quote = *p;
307             p++;
308          }
309       }
310    }
311    *bargc = argc;
312 }
313 #endif /* HAVE_WIN32 */
314
315 /*
316  * Run an external program. Optionally wait a specified number
317  *   of seconds. Program killed if wait exceeded. Optionally
318  *   return the output from the program (normally a single line).
319  *
320  *   If the watchdog kills the program, fgets returns, and ferror is set
321  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
322  *
323  * Contrary to my normal calling conventions, this program
324  *
325  *  Returns: 0 on success
326  *           non-zero on error == berrno status
327  */
328 int run_program(char *prog, int wait, POOLMEM *results)
329 {
330    BPIPE *bpipe;
331    int stat1, stat2;
332    char *mode;
333
334    mode = (char *)(results != NULL ? "r" : "");
335    bpipe = open_bpipe(prog, wait, mode);
336    if (!bpipe) {
337       return ENOENT;
338    }
339    if (results) {
340       results[0] = 0;
341       int len = sizeof_pool_memory(results) - 1;
342       fgets(results, len, bpipe->rfd);
343       results[len] = 0;
344       if (feof(bpipe->rfd)) {
345          stat1 = 0;
346       } else {
347          stat1 = ferror(bpipe->rfd);
348       }
349       if (stat1 < 0) {
350          Dmsg2(150, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
351       } else if (stat1 != 0) {
352          Dmsg1(150, "Run program fgets stat=%d\n", stat1);
353          if (bpipe->timer_id) {
354             Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
355             /* NB: I'm not sure it is really useful for run_program. Without the
356              * following lines run_program would not detect if the program was killed
357              * by the watchdog. */
358             if (bpipe->timer_id->killed) {
359                stat1 = ETIME;
360                pm_strcat(results, _("Program killed by Bacula watchdog (timeout)\n"));
361             }
362          }
363       }
364    } else {
365       stat1 = 0;
366    }
367    stat2 = close_bpipe(bpipe);
368    stat1 = stat2 != 0 ? stat2 : stat1;
369    Dmsg1(150, "Run program returning %d\n", stat1);
370    return stat1;
371 }
372
373 /*
374  * Run an external program. Optionally wait a specified number
375  *   of seconds. Program killed if wait exceeded (it is done by the 
376  *   watchdog, as fgets is a blocking function).
377  *
378  *   If the watchdog kills the program, fgets returns, and ferror is set
379  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
380  *
381  *   Return the full output from the program (not only the first line).
382  *
383  * Contrary to my normal calling conventions, this program
384  *
385  *  Returns: 0 on success
386  *           non-zero on error == berrno status
387  *
388  */
389 int run_program_full_output(char *prog, int wait, POOLMEM *results)
390 {
391    BPIPE *bpipe;
392    int stat1, stat2;
393    char *mode;
394    POOLMEM* tmp;
395    char *buf;
396    const int bufsize = 32000;
397
398    if (results == NULL) {
399       return run_program(prog, wait, NULL);
400    }
401    
402    sm_check(__FILE__, __LINE__, false);
403
404    tmp = get_pool_memory(PM_MESSAGE);
405    buf = (char *)malloc(bufsize+1);
406    
407    mode = (char *)"r";
408    bpipe = open_bpipe(prog, wait, mode);
409    if (!bpipe) {
410       if (results) {
411          results[0] = 0;
412       }
413       return ENOENT;
414    }
415    
416    sm_check(__FILE__, __LINE__, false);
417    tmp[0] = 0;
418    while (1) {
419       buf[0] = 0;
420       fgets(buf, bufsize, bpipe->rfd);
421       buf[bufsize] = 0;
422       pm_strcat(tmp, buf);
423       if (feof(bpipe->rfd)) {
424          stat1 = 0;
425          Dmsg1(900, "Run program fgets stat=%d\n", stat1);
426          break;
427       } else {
428          stat1 = ferror(bpipe->rfd);
429       }
430       if (stat1 < 0) {
431          berrno be;
432          Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.strerror());
433          break;
434       } else if (stat1 != 0) {
435          Dmsg1(900, "Run program fgets stat=%d\n", stat1);
436          if (bpipe->timer_id && bpipe->timer_id->killed) {
437             Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
438             break;
439          }
440       }
441    }
442    /*
443     * We always check whether the timer killed the program. We would see
444     * an eof even when it does so we just have to trust the killed flag
445     * and set the timer values to avoid edge cases where the program ends
446     * just as the timer kills it.
447     */
448    if (bpipe->timer_id && bpipe->timer_id->killed) {
449       Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
450       pm_strcat(tmp, _("Program killed by Bacula watchdog (timeout)\n"));
451       stat1 = ETIME;
452    }
453    int len = sizeof_pool_memory(results) - 1;
454    bstrncpy(results, tmp, len);
455    Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
456    stat2 = close_bpipe(bpipe);
457    stat1 = stat2 != 0 ? stat2 : stat1;
458    
459    Dmsg1(900, "Run program returning %d\n", stat1);
460    free_pool_memory(tmp);
461    free(buf);
462    return stat1;
463 }