From 5879d587a7fce0bf299d2dbee461eeeae7a360f8 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 9 Jan 2003 10:10:17 +0000 Subject: [PATCH] Fix dynamic file options git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@277 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 1 + bacula/src/cats/sql_get.c | 2 +- bacula/src/dird/dird_conf.c | 4 +++ bacula/src/dird/fd_cmds.c | 35 +++++++++++++++------- bacula/src/dird/job.c | 2 +- bacula/src/dird/ua_output.c | 2 +- bacula/src/findlib/attribs.c | 2 +- bacula/src/findlib/find.c | 1 - bacula/src/findlib/find.h | 16 ++++++---- bacula/src/findlib/find_one.c | 17 ++++------- bacula/src/findlib/match.c | 56 +++++++++++++---------------------- bacula/src/findlib/protos.h | 22 +++++++------- bacula/src/lib/bpipe.c | 3 ++ bacula/src/version.h | 4 +-- 14 files changed, 86 insertions(+), 81 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 352da3bfba..d14bc6dc39 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -16,6 +16,7 @@ Testing to do: (painful) - test and fix < code and | code. For 1.29 release: +- Get correct error status from run_program or open_bpipe(). - Figure out how to allow multiple simultaneous file Volumes on a single device. - Why are save/restore of device different sizes (sparse?) diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index f3f0539987..197adfc372 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -10,7 +10,7 @@ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 91f3d11475..bebf9c27ad 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -356,6 +356,7 @@ struct s_kw ReplaceOptions[] = { #define INC_KW_RECURSE 6 #define INC_KW_SPARSE 7 #define INC_KW_REPLACE 8 /* restore options */ +#define INC_KW_READFIFO 9 /* Causes fifo data to be read */ /* Include keywords */ static struct s_kw FS_option_kw[] = { @@ -367,6 +368,7 @@ static struct s_kw FS_option_kw[] = { {"recurse", INC_KW_RECURSE}, {"sparse", INC_KW_SPARSE}, {"replace", INC_KW_REPLACE}, + {"readfifo", INC_KW_READFIFO}, {NULL, 0} }; @@ -402,6 +404,8 @@ static struct s_fs_opt FS_options[] = { {"always", INC_KW_REPLACE, "a"}, {"ifnewer", INC_KW_REPLACE, "w"}, {"never", INC_KW_REPLACE, "n"}, + {"yes", INC_KW_READFIFO, "r"}, + {"no", INC_KW_READFIFO, "0"}, {NULL, 0, 0} }; diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index cb16e691b3..a668d3c793 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -112,7 +112,7 @@ int send_include_list(JCR *jcr) { FILESET *fileset; BSOCK *fd; - int i; + int i, j; char *msgsave; fd = jcr->file_bsock; @@ -124,33 +124,41 @@ int send_include_list(JCR *jcr) BPIPE *bpipe; FILE *ffd; char buf[1000]; - char *p; + char *o, *p, *q; + int optlen, stat; Dmsg1(120, "dird>filed: include file: %s\n", fileset->include_array[i]); - p = fileset->include_array[i]; - skip_nonspaces(&p); + o = p = fileset->include_array[i]; + skip_nonspaces(&p); /* skip options */ skip_spaces(&p); + q = p; /* save end of options */ switch (*p++) { case '|': fd->msg = edit_job_codes(jcr, fd->msg, p, ""); - Dmsg1(000, "Doing bopen: %s\n", fd->msg); bpipe = open_bpipe(fd->msg, 0, "r"); if (!bpipe) { Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"), p, strerror(errno)); goto bail_out; } - Dmsg0(000, "Call fgets\n"); - while (fgets(buf, sizeof(buf), bpipe->rfd)) { + /* Copy File options */ + optlen = q - o; + for (j=0; j < optlen; j++) { + buf[j] = *o++; + } + while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) { fd->msglen = Mmsg(&fd->msg, "%s", buf); - Dmsg2(000, "Including len=%d: %s", fd->msglen, fd->msg); + Dmsg2(200, "Including len=%d: %s", fd->msglen, fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); goto bail_out; } } - Dmsg0(000, "Close bpipe\n"); - close_bpipe(bpipe); + if ((stat=close_bpipe(bpipe)) != 0) { + Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. RtnStat=%d ERR=%s\n"), + p, stat, strerror(errno)); + goto bail_out; + } break; case '<': if ((ffd = fopen(p, "r")) == NULL) { @@ -158,7 +166,12 @@ int send_include_list(JCR *jcr) p, strerror(errno)); goto bail_out; } - while (fgets(buf, sizeof(buf), ffd)) { + /* Copy File options */ + optlen = q - o; + for (j=0; j < optlen; j++) { + buf[j] = *o++; + } + while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) { fd->msglen = Mmsg(&fd->msg, "%s", buf); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index 2c1055a254..68ed80a35a 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -7,7 +7,7 @@ * Version $Id$ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index a61feeb4de..fb6b3689e6 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -9,7 +9,7 @@ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index 5471759308..57e4cd3fee 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -9,7 +9,7 @@ * */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index afc1097d25..d7fc75fb89 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -56,7 +56,6 @@ FF_PKT *init_find_files() init_include_exclude_files(ff); /* init lists */ ff->mtime_only = 1; - ff->one_file_system = 1; /* Get system path and filename maximum lengths */ path_max = pathconf(".", _PC_PATH_MAX); diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 2d1f8da958..a16a3f2a2c 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -83,9 +83,15 @@ #define FO_SPARSE 0x10 /* do sparse file checking */ #define FO_IF_NEWER 0x20 /* replace if newer */ #define FO_NOREPLACE 0x40 /* never replace */ +#define FO_READFIFO 0x80 /* read data from fifo */ -/* Options saved in "options" of include list */ -/* ****FIXME**** replace OPT_ flags with FO_ */ +/* + * Options saved in "options" of include list + * These are now directly jammed into ff->flags, so the above + * FO_xxx options may be used + * + * ***FIXME*** replace all OPT_xxx with FO_xxx or vise-versa + */ #define OPT_compute_MD5 0x01 /* compute MD5 of file's data */ #define OPT_GZIP_compression 0x02 /* use GZIP compression */ #define OPT_no_recursion 0x04 /* no recursion in directories */ @@ -93,6 +99,8 @@ #define OPT_sparse 0x10 /* do sparse file checking */ #define OPT_replace_if_newer 0x20 /* replace file if newer */ #define OPT_never_replace 0x40 /* never replace */ +#define OPT_read_fifo 0x80 /* read data from fifo (named pipe) */ + struct s_included_file { @@ -127,13 +135,9 @@ typedef struct ff { int ff_errno; /* errno */ int incremental; /* do incremental save */ time_t save_time; /* start of incremental time */ - int no_recursion; /* do not recurse into sub directories */ int mtime_only; /* incremental on mtime_only */ int dereference; /* follow links */ - int compute_MD5; /* compute MD5 checksum */ - int GZIP_compression; /* compress the file */ int GZIP_level; /* compression level */ - int one_file_system; /* do not traverse file systems */ int atime_preserve; /* preserve access times */ int null_output_device; /* using null output device */ char VerifyOpts[20]; diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index d6fa4f3955..0b783f0cc2 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -77,12 +77,6 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt int rtn_stat; ff_pkt->fname = ff_pkt->link = fname; - if (ff_pkt->compute_MD5) { - ff_pkt->flags |= FO_MD5; - } - if (ff_pkt->GZIP_compression) { - ff_pkt->flags |= FO_GZIP; - } if (lstat(fname, &ff_pkt->statp) != 0) { /* Cannot stat file */ @@ -241,7 +235,7 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt * Do not decend into subdirectories (recurse) if the * user has turned it off for this directory. */ - if (ff_pkt->no_recursion) { + if (ff_pkt->flags & FO_NO_RECURSION) { free(namebuf); /* No recursion into this directory */ ff_pkt->type = FT_NORECURSE; @@ -252,13 +246,13 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt * See if we are crossing file systems, and * avoid doing so if the user only wants to dump one file system. */ - if (ff_pkt->one_file_system && !top_level - && parent_device != ff_pkt->statp.st_dev) { + if (!top_level && !(ff_pkt->flags & FO_MULTIFS) && + parent_device != ff_pkt->statp.st_dev) { free(namebuf); + /* returning here means we do not handle this directory */ ff_pkt->type = FT_NOFSCHG; return handle_file(ff_pkt, pkt); } - /* * Now process the files in this directory. */ @@ -317,7 +311,8 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt */ if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) { ff_pkt->type = FT_RAW; /* raw partition */ - } else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode)) { + } else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) && + ff_pkt->flags & FO_READFIFO) { ff_pkt->type = FT_FIFO; } else { /* The only remaining types are special (character, ...) files */ diff --git a/bacula/src/findlib/match.c b/bacula/src/findlib/match.c index 9d3aee96a1..3701860623 100644 --- a/bacula/src/findlib/match.c +++ b/bacula/src/findlib/match.c @@ -6,7 +6,7 @@ * */ /* - Copyright (C) 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2001-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -107,25 +107,20 @@ void add_fname_to_include_list(FF_PKT *ff, int prefixed, char *fname) case 'a': /* alway replace */ case '0': /* no option */ break; - case 'w': - inc->options |= OPT_replace_if_newer; + case 'f': + inc->options |= OPT_multifs; break; - case 'n': - inc->options |= OPT_never_replace; + case 'h': /* no recursion */ + inc->options |= OPT_no_recursion; break; case 'M': /* MD5 */ inc->options |= OPT_compute_MD5; break; - case 'Z': /* gzip compression */ - inc->options |= OPT_GZIP_compression; - inc->level = *++p - '0'; - Dmsg1(200, "Compression level=%d\n", inc->level); - break; - case 'h': /* no recursion */ - inc->options |= OPT_no_recursion; + case 'n': + inc->options |= OPT_never_replace; break; - case 'f': - inc->options |= OPT_multifs; + case 'r': /* read fifo */ + inc->options |= OPT_read_fifo; break; case 's': inc->options |= OPT_sparse; @@ -140,6 +135,14 @@ void add_fname_to_include_list(FF_PKT *ff, int prefixed, char *fname) } inc->VerifyOpts[j] = 0; break; + case 'w': + inc->options |= OPT_replace_if_newer; + break; + case 'Z': /* gzip compression */ + inc->options |= OPT_GZIP_compression; + inc->level = *++p - '0'; + Dmsg1(200, "Compression level=%d\n", inc->level); + break; default: Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p); break; @@ -212,29 +215,12 @@ struct s_included_file *get_next_included_file(FF_PKT *ff, struct s_included_fil } else { inc = ainc->next; } + /* + * copy inc_options for this file into the ff packet + */ if (inc) { ff->flags = inc->options; - if (inc->options & OPT_compute_MD5) { - ff->compute_MD5 = 1; - } else { - ff->compute_MD5 = 0; - } - if (inc->options & OPT_GZIP_compression) { - ff->GZIP_compression = 1; - ff->GZIP_level = inc->level; - } else { - ff->GZIP_compression = 0; - } - if (inc->options & OPT_no_recursion) { - ff->no_recursion = 1; - } else { - ff->no_recursion = 0; - } - if (inc->options & OPT_multifs) { - ff->one_file_system = 0; - } else { - ff->one_file_system = 1; - } + ff->GZIP_level = inc->level; } return inc; } diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h index 5e2a61801e..e2f4960e90 100644 --- a/bacula/src/findlib/protos.h +++ b/bacula/src/findlib/protos.h @@ -4,7 +4,7 @@ * Version $Id$ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -24,17 +24,17 @@ */ /* from attribs.c */ -void encode_stat (char *buf, struct stat *statp); -void decode_stat (char *buf, struct stat *statp); -int encode_attribsEx (void *jcr, char *attribsEx, FF_PKT *ff_pkt); +void encode_stat (char *buf, struct stat *statp); +void decode_stat (char *buf, struct stat *statp); +int encode_attribsEx (void *jcr, char *attribsEx, FF_PKT *ff_pkt); int set_attributes(void *jcr, char *fname, char *ofile, char *lname, - int type, int stream, struct stat *statp, - char *attribsEx, int *ofd); + int type, int stream, struct stat *statp, + char *attribsEx, int *ofd); /* from create_file.c */ int create_file(void *jcr, char *fname, char *ofile, char *lname, - int type, int stream, struct stat *statp, - char *attribsEx, int *ofd, int replace); + int type, int stream, struct stat *statp, + char *attribsEx, int *ofd, int replace); /* From find.c */ FF_PKT *init_find_files(); @@ -50,10 +50,10 @@ void add_fname_to_exclude_list(FF_PKT *ff, char *fname); int file_is_excluded(FF_PKT *ff, char *file); int file_is_included(FF_PKT *ff, char *file); struct s_included_file *get_next_included_file(FF_PKT *ff, - struct s_included_file *inc); + struct s_included_file *inc); /* from makepath.c */ int make_path(void *jcr, const char *argpath, int mode, - int parent_mode, uid_t owner, gid_t group, - int preserve_existing, char *verbose_fmt_string); + int parent_mode, uid_t owner, gid_t group, + int preserve_existing, char *verbose_fmt_string); diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index fdb3f634fa..dae80dd98f 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -173,6 +173,9 @@ int close_bpipe(BPIPE *bpipe) } if (wpid != -1 && WIFEXITED(chldstatus)) { stat = WEXITSTATUS(chldstatus); + if (stat != 0) { + errno = ECHILD; + } } if (bpipe->timer_id) { stop_child_timer(bpipe->timer_id); diff --git a/bacula/src/version.h b/bacula/src/version.h index 6e27719cb1..a70ac7728c 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.29" #define VSTRING "1" -#define DATE "8 January 2003" -#define LSMDATE "08Jan03" +#define DATE "9 January 2003" +#define LSMDATE "09Jan03" /* Debug flags */ #define DEBUG 1 -- 2.39.5