]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bpipe.c
Reorganize regex code
[bacula/bacula] / bacula / src / lib / bpipe.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2002-2008 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 Kern Sibbald.
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 /* Note, the close log cause problems, see bug #1536 */
139 /*    closelog();                        close syslog if open */
140       for (i=3; i<=32; i++) {         /* close any open file descriptors */
141          close(i);
142       }
143       execvp(bargv[0], bargv);        /* call the program */
144       /* Convert errno into an exit code for later analysis */
145       for (i=0; i< num_execvp_errors; i++) {
146          if (execvp_errors[i] == errno) {
147             exit(200 + i);            /* exit code => errno */
148          }
149       }
150       exit(255);                      /* unknown errno */
151
152    default:                           /* parent */
153       break;
154    }
155    free_pool_memory(tprog);
156    if (mode_read) {
157       close(readp[1]);                /* close unused parent fds */
158       bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
159    }
160    if (mode_write) {
161       close(writep[0]);
162       bpipe->wfd = fdopen(writep[1], "w");
163    }
164    bpipe->worker_stime = time(NULL);
165    bpipe->wait = wait;
166    if (wait > 0) {
167       bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
168    }
169    return bpipe;
170 }
171
172 /* Close the write pipe only */
173 int close_wpipe(BPIPE *bpipe)
174 {
175    int stat = 1;
176
177    if (bpipe->wfd) {
178       fflush(bpipe->wfd);
179       if (fclose(bpipe->wfd) != 0) {
180          stat = 0;
181       }
182       bpipe->wfd = NULL;
183    }
184    return stat;
185 }
186
187 /*
188  * Close both pipes and free resources
189  *
190  *  Returns: 0 on success
191  *           berrno on failure
192  */
193 int close_bpipe(BPIPE *bpipe)
194 {
195    int chldstatus = 0;
196    int stat = 0;
197    int wait_option;
198    int remaining_wait;
199    pid_t wpid = 0;
200
201
202    /* Close pipes */
203    if (bpipe->rfd) {
204       fclose(bpipe->rfd);
205       bpipe->rfd = NULL;
206    }
207    if (bpipe->wfd) {
208       fclose(bpipe->wfd);
209       bpipe->wfd = NULL;
210    }
211
212    if (bpipe->wait == 0) {
213       wait_option = 0;                /* wait indefinitely */
214    } else {
215       wait_option = WNOHANG;          /* don't hang */
216    }
217    remaining_wait = bpipe->wait;
218
219    /* wait for worker child to exit */
220    for ( ;; ) {
221       Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
222       do {
223          wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
224       } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
225       if (wpid == bpipe->worker_pid || wpid == -1) {
226          berrno be;
227          stat = errno;
228          Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
229             wpid==-1?be.bstrerror():"none");
230          break;
231       }
232       Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
233             wpid==-1?strerror(errno):"none");
234       if (remaining_wait > 0) {
235          bmicrosleep(1, 0);           /* wait one second */
236          remaining_wait--;
237       } else {
238          stat = ETIME;                /* set error status */
239          wpid = -1;
240          break;                       /* don't wait any longer */
241       }
242    }
243    if (wpid > 0) {
244       if (WIFEXITED(chldstatus)) {    /* process exit()ed */
245          stat = WEXITSTATUS(chldstatus);
246          if (stat != 0) {
247             Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
248             stat |= b_errno_exit;        /* exit status returned */
249          }
250          Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
251       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
252 #ifndef HAVE_WIN32
253          stat = WTERMSIG(chldstatus);
254 #else
255          stat = 1;                    /* fake child status */
256 #endif
257          Dmsg1(800, "Child died from signal %d\n", stat);
258          stat |= b_errno_signal;      /* exit signal returned */
259       }
260    }
261    if (bpipe->timer_id) {
262       stop_child_timer(bpipe->timer_id);
263    }
264    free(bpipe);
265    Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
266    return stat;
267 }
268
269 /*
270  * Build argc and argv from a string
271  */
272 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
273 {
274    int i;
275    char *p, *q, quote;
276    int argc = 0;
277
278    argc = 0;
279    for (i=0; i<max_argv; i++)
280       bargv[i] = NULL;
281
282    p = cmd;
283    quote = 0;
284    while  (*p && (*p == ' ' || *p == '\t'))
285       p++;
286    if (*p == '\"' || *p == '\'') {
287       quote = *p;
288       p++;
289    }
290    if (*p) {
291       while (*p && argc < MAX_ARGV) {
292          q = p;
293          if (quote) {
294             while (*q && *q != quote)
295             q++;
296             quote = 0;
297          } else {
298             while (*q && *q != ' ')
299             q++;
300          }
301          if (*q)
302             *(q++) = '\0';
303          bargv[argc++] = p;
304          p = q;
305          while (*p && (*p == ' ' || *p == '\t'))
306             p++;
307          if (*p == '\"' || *p == '\'') {
308             quote = *p;
309             p++;
310          }
311       }
312    }
313    *bargc = argc;
314 }
315 #endif /* HAVE_WIN32 */
316
317 /*
318  * Run an external program. Optionally wait a specified number
319  *   of seconds. Program killed if wait exceeded. Optionally
320  *   return the output from the program (normally a single line).
321  *
322  *   If the watchdog kills the program, fgets returns, and ferror is set
323  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
324  *
325  * Contrary to my normal calling conventions, this program
326  *
327  *  Returns: 0 on success
328  *           non-zero on error == berrno status
329  */
330 int run_program(char *prog, int wait, POOLMEM *&results)
331 {
332    BPIPE *bpipe;
333    int stat1, stat2;
334    char *mode;
335
336    mode = (char *)"r";
337    bpipe = open_bpipe(prog, wait, mode);
338    if (!bpipe) {
339       return ENOENT;
340    }
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_strcpy(results, _("Program killed by Bacula (timeout)\n"));
363          }
364       }
365    }
366    stat2 = close_bpipe(bpipe);
367    stat1 = stat2 != 0 ? stat2 : stat1;
368    Dmsg1(150, "Run program returning %d\n", stat1);
369    return stat1;
370 }
371
372 /*
373  * Run an external program. Optionally wait a specified number
374  *   of seconds. Program killed if wait exceeded (it is done by the 
375  *   watchdog, as fgets is a blocking function).
376  *
377  *   If the watchdog kills the program, fgets returns, and ferror is set
378  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
379  *
380  *   Return the full output from the program (not only the first line).
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  */
388 int run_program_full_output(char *prog, int wait, POOLMEM *&results)
389 {
390    BPIPE *bpipe;
391    int stat1, stat2;
392    char *mode;
393    POOLMEM* tmp;
394    char *buf;
395    const int bufsize = 32000;
396
397    
398    sm_check(__FILE__, __LINE__, false);
399
400    tmp = get_pool_memory(PM_MESSAGE);
401    buf = (char *)malloc(bufsize+1);
402    
403    results[0] = 0;
404    mode = (char *)"r";
405    bpipe = open_bpipe(prog, wait, mode);
406    if (!bpipe) {
407       stat1 = ENOENT;
408       goto bail_out;
409    }
410    
411    sm_check(__FILE__, __LINE__, false);
412    tmp[0] = 0;
413    while (1) {
414       buf[0] = 0;
415       fgets(buf, bufsize, bpipe->rfd);
416       buf[bufsize] = 0;
417       pm_strcat(tmp, buf);
418       if (feof(bpipe->rfd)) {
419          stat1 = 0;
420          Dmsg1(900, "Run program fgets stat=%d\n", stat1);
421          break;
422       } else {
423          stat1 = ferror(bpipe->rfd);
424       }
425       if (stat1 < 0) {
426          berrno be;
427          Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
428          break;
429       } else if (stat1 != 0) {
430          Dmsg1(900, "Run program fgets stat=%d\n", stat1);
431          if (bpipe->timer_id && bpipe->timer_id->killed) {
432             Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
433             break;
434          }
435       }
436    }
437    /*
438     * We always check whether the timer killed the program. We would see
439     * an eof even when it does so we just have to trust the killed flag
440     * and set the timer values to avoid edge cases where the program ends
441     * just as the timer kills it.
442     */
443    if (bpipe->timer_id && bpipe->timer_id->killed) {
444       Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
445       pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
446       stat1 = ETIME;
447    }
448    pm_strcpy(results, tmp);
449    Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
450    stat2 = close_bpipe(bpipe);
451    stat1 = stat2 != 0 ? stat2 : stat1;
452    
453    Dmsg1(900, "Run program returning %d\n", stat1);
454 bail_out:
455    free_pool_memory(tmp);
456    free(buf);
457    return stat1;
458 }