From 2a1738f5491ca740d5310f5ee3a4c94a0d38c485 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 2 Mar 2003 13:15:02 +0000 Subject: [PATCH] Include/Exclude with FileOptions in Director git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@363 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/dird_conf.c | 139 +++++++++++++++++++++-------------- bacula/src/dird/dird_conf.h | 12 +-- bacula/src/dird/fd_cmds.c | 141 ++++++++++++++++++++---------------- bacula/src/version.h | 4 +- 4 files changed, 173 insertions(+), 123 deletions(-) diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 1949d77a67..088b9e2307 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -462,7 +462,6 @@ char *level_to_str(int level) /* Dump contents of resource */ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...), void *sock) { - int i; URES *res = (URES *)reshdr; int recurse = 1; @@ -559,10 +558,18 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... break; case R_FILESET: sendit(sock, "FileSet: name=%s\n", res->res_fs.hdr.name); - for (i=0; ires_fs.num_includes; i++) - sendit(sock, " Inc: %s\n", res->res_fs.include_array[i]->name); - for (i=0; ires_fs.num_excludes; i++) - sendit(sock, " Exc: %s\n", res->res_fs.exclude_array[i]->name); + for (int i=0; ires_fs.num_includes; i++) { + INCEXE *incexe = res->res_fs.include_items[i]; + for (int j=0; jnum_names; j++) { + sendit(sock, " Inc: %s\n", incexe->name_list[j]); + } + } + for (int i=0; ires_fs.num_excludes; i++) { + INCEXE *incexe = res->res_fs.exclude_items[i]; + for (int j=0; jnum_names; j++) { + sendit(sock, " Exc: %s\n", incexe->name_list[j]); + } + } break; case R_SCHEDULE: if (res->res_sch.run) { @@ -772,16 +779,32 @@ void free_resource(int type) case R_FILESET: if ((num=res->res_fs.num_includes)) { while (--num >= 0) { - free(res->res_fs.include_array[num]); + INCEXE *incexe = res->res_fs.include_items[num]; + for (int i=0; inum_names; i++) { + free(incexe->name_list[i]); + } + if (incexe->name_list) { + free(incexe->name_list); + } + free(incexe); } - free(res->res_fs.include_array); + free(res->res_fs.include_items); } + res->res_fs.num_includes = 0; if ((num=res->res_fs.num_excludes)) { while (--num >= 0) { - free(res->res_fs.exclude_array[num]); + INCEXE *incexe = res->res_fs.exclude_items[num]; + for (int i=0; inum_names; i++) { + free(incexe->name_list[i]); + } + if (incexe->name_list) { + free(incexe->name_list); + } + free(incexe); } - free(res->res_fs.exclude_array); + free(res->res_fs.exclude_items); } + res->res_fs.num_excludes = 0; break; case R_POOL: if (res->res_pool.pool_type) { @@ -889,23 +912,25 @@ void save_resource(int type, struct res_items *items, int pass) /* Resources not containing a resource */ case R_CATALOG: case R_STORAGE: - case R_FILESET: + case R_FILEOPTIONS: case R_GROUP: case R_POOL: case R_MSGS: break; - /* Special case for FileOptions, all allocations are done - * only in pass 2, so here we must copy the whole structure + /* Special case for FileSet, all allocations are done + * only in pass 2, so here we must copy the whole structure. + * This is done so that we can have forward references to + * FileOptions resources within the fileset */ - case R_FILEOPTIONS: + case R_FILESET: RES res_save; - if ((res = (URES *)GetResWithName(R_FILEOPTIONS, res_all.res_dir.hdr.name)) == NULL) { - Emsg1(M_ERROR_TERM, 0, "Cannot find FileOptions resource %s\n", res_all.res_dir.hdr.name); + if ((res = (URES *)GetResWithName(R_FILESET, res_all.res_dir.hdr.name)) == NULL) { + Emsg1(M_ERROR_TERM, 0, "Cannot find FileSet resource %s\n", res_all.res_dir.hdr.name); } memcpy(&res_save, &res_all, sizeof(RES)); memcpy(&res_all, res, sizeof(RES)); - memcpy(res, &res_all, sizeof(FILEOPTIONS)); + memcpy(res, &res_all, sizeof(FILESET)); memcpy(&res_all, &res_save, sizeof(RES)); break; @@ -1402,17 +1427,43 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) } } if (!inc_opts[0]) { - strcat(inc_opts, "0 "); /* set no options */ - } else { - strcat(inc_opts, " "); /* add field separator */ + strcat(inc_opts, "0"); /* set no options */ } inc_opts_len = strlen(inc_opts); - if (pass == 1) { + if (pass == 2) { + INCEXE *incexe; if (!res_all.res_fs.have_MD5) { MD5Init(&res_all.res_fs.md5c); res_all.res_fs.have_MD5 = TRUE; } + /* Create incexe structure */ + Dmsg0(200, "Create INCEXE structure\n"); + incexe = (INCEXE *)malloc(sizeof(INCEXE)); + memset(incexe, 0, sizeof(INCEXE)); + bstrncpy(incexe->opts, inc_opts, sizeof(incexe->opts)); + incexe->fileopts = (struct s_res_fopts *)res; + Dmsg1(200, "incexe opts=%s\n", incexe->opts); + if (item->code == 0) { /* include */ + if (res_all.res_fs.num_includes == 0) { + res_all.res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *)); + } else { + res_all.res_fs.include_items = (INCEXE **)realloc(res_all.res_fs.include_items, + sizeof(INCEXE *) * res_all.res_fs.num_includes + 1); + } + res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe; + Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes); + } else { /* exclude */ + if (res_all.res_fs.num_excludes == 0) { + res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *)); + } else { + res_all.res_fs.exclude_items = (INCEXE **)realloc(res_all.res_fs.exclude_items, + sizeof(INCEXE *) * res_all.res_fs.num_excludes + 1); + } + res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe; + Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes); + } + /* Pickup include/exclude names. They are stored in INCEXE * structures which contains the options and the name. */ @@ -1425,47 +1476,27 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) case T_IDENTIFIER: case T_UNQUOTED_STRING: case T_QUOTED_STRING: - INCEXE *incexe; - incexe = (INCEXE *)malloc(lc->str_len + sizeof(INCEXE)); - memset(incexe, 0, sizeof(INCEXE)); - bstrncpy(incexe->opts, inc_opts, sizeof(incexe->opts)); - strcpy(incexe->name, lc->str); - incexe->fileopts = (struct s_res_fopts *)res; - incexe->num_fileopts = 1; - if (res_all.res_fs.have_MD5) { - MD5Update(&res_all.res_fs.md5c, (unsigned char *)incexe, - sizeof(INCEXE) + lc->str_len); + MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len); } - if (item->code == 0) { /* include */ - if (res_all.res_fs.num_includes == res_all.res_fs.include_size) { - res_all.res_fs.include_size += 10; - if (res_all.res_fs.include_array == NULL) { - res_all.res_fs.include_array = (INCEXE **)malloc(sizeof(INCEXE *) * res_all.res_fs.include_size); - } else { - res_all.res_fs.include_array = (INCEXE **)realloc(res_all.res_fs.include_array, - sizeof(INCEXE *) * res_all.res_fs.include_size); - } - } - res_all.res_fs.include_array[res_all.res_fs.num_includes++] = incexe; - } else { /* exclude */ - if (res_all.res_fs.num_excludes == res_all.res_fs.exclude_size) { - res_all.res_fs.exclude_size += 10; - if (res_all.res_fs.exclude_array == NULL) { - res_all.res_fs.exclude_array = (INCEXE **)malloc(sizeof(INCEXE *) * res_all.res_fs.exclude_size); - } else { - res_all.res_fs.exclude_array = (INCEXE **)realloc(res_all.res_fs.exclude_array, - sizeof(INCEXE *) * res_all.res_fs.exclude_size); - } + if (incexe->num_names == incexe->max_names) { + incexe->max_names += 10; + if (incexe->name_list == NULL) { + incexe->name_list = (char **)malloc(sizeof(char *) * incexe->max_names); + } else { + incexe->name_list = (char **)realloc(incexe->name_list, + sizeof(char *) * incexe->max_names); } - res_all.res_fs.exclude_array[res_all.res_fs.num_excludes++] = incexe; } + incexe->name_list[incexe->num_names++] = bstrdup(lc->str); + Dmsg1(200, "Add to name_list %s\n", incexe->name_list[incexe->num_names -1]); break; default: scan_err1(lc, "Expected a filename, got: %s", lc->str); } } - } else { /* pass 2 */ + /* Note, MD5Final is done in backup.c */ + } else { /* pass 1 */ while (lex_get_token(lc, T_ALL) != T_EOB) {} } @@ -1480,7 +1511,7 @@ static void store_match(LEX *lc, struct res_items *item, int index, int pass) int token; char *match; - if (pass == 2) { + if (pass == 1) { /* Pickup Match string */ token = lex_get_token(lc, T_ALL); @@ -1502,7 +1533,7 @@ static void store_match(LEX *lc, struct res_items *item, int index, int pass) default: scan_err1(lc, "Expected a filename, got: %s", lc->str); } - } else { /* pass 1 */ + } else { /* pass 2 */ lex_get_token(lc, T_ALL); } scan_to_eol(lc); diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index f37dd7dc87..9a188506af 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -195,11 +195,13 @@ struct s_res_fopts { }; typedef struct s_res_fopts FILEOPTIONS; +/* This is either an include item or an exclude item */ struct s_incexc_item { char opts[MAX_FO_OPTS]; /* options string */ struct s_res_fopts *fileopts; /* File Options resource */ - int num_fileopts; /* number of above */ - char name[1]; /* include/exclude name */ + char **name_list; /* filename list */ + int num_names; /* number of names in the list */ + int max_names; /* malloc'ed size of list */ }; typedef struct s_incexc_item INCEXE; @@ -210,12 +212,10 @@ typedef struct s_incexc_item INCEXE; struct s_res_fs { RES hdr; - INCEXE **include_array; /* array of incexe structures */ + INCEXE **include_items; /* array of incexe structures */ int num_includes; /* number in array */ - int include_size; /* array size */ - INCEXE **exclude_array; + INCEXE **exclude_items; int num_excludes; - int exclude_size; int have_MD5; /* set if MD5 initialized */ struct MD5Context md5c; /* MD5 of include/exclude */ char MD5[30]; /* base 64 representation of MD5 */ diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index e4e6d56cf1..3f79864aaa 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -116,14 +116,13 @@ int send_include_list(JCR *jcr) { FILESET *fileset; BSOCK *fd; - int i; fd = jcr->file_bsock; fileset = jcr->fileset; fd->msglen = sprintf(fd->msg, inc); bnet_send(fd); - for (i=0; i < fileset->num_includes; i++) { + for (int i=0; i < fileset->num_includes; i++) { BPIPE *bpipe; FILE *ffd; char buf[1000]; @@ -131,63 +130,80 @@ int send_include_list(JCR *jcr) int optlen, stat; INCEXE *ie; - Dmsg1(120, "dird>filed: include file: %s\n", fileset->include_array[i]); - ie = fileset->include_array[i]; - p = ie->name; - switch (*p++) { - case '|': - fd->msg = edit_job_codes(jcr, fd->msg, p, ""); - 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; - } - /* Copy File options */ - strcpy(buf, ie->opts); - optlen = strlen(buf); - while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) { - fd->msglen = Mmsg(&fd->msg, "%s", buf); - 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")); + ie = fileset->include_items[i]; + for (int j=0; jnum_names; j++) { + p = ie->name_list[j]; + switch (*p++) { + case '|': + fd->msg = edit_job_codes(jcr, fd->msg, p, ""); + 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; } - } - 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) { - Jmsg(jcr, M_FATAL, 0, _("Cannot open included file: %s. ERR=%s\n"), - p, strerror(errno)); - goto bail_out; - } - /* Copy File options */ - strcpy(buf, ie->opts); - optlen = strlen(buf); - while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) { - fd->msglen = Mmsg(&fd->msg, "%s", buf); + /* Copy File options */ + if (ie->fileopts) { + strcpy(buf, ie->fileopts->opts); + } else { + strcpy(buf, ie->opts); + } + strcat(buf, " "); + optlen = strlen(buf); + while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) { + fd->msglen = Mmsg(&fd->msg, "%s", buf); + 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; + } + } + 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) { + Jmsg(jcr, M_FATAL, 0, _("Cannot open included file: %s. ERR=%s\n"), + p, strerror(errno)); + goto bail_out; + } + /* Copy File options */ + if (ie->fileopts) { + strcpy(buf, ie->fileopts->opts); + } else { + strcpy(buf, ie->opts); + } + strcat(buf, " "); + optlen = strlen(buf); + 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")); + goto bail_out; + } + } + fclose(ffd); + break; + default: + if (ie->fileopts) { + pm_strcpy(&fd->msg, ie->fileopts->opts); + Dmsg1(200, "Fileopts=%s\n", fd->msg); + } else { + pm_strcpy(&fd->msg, ie->opts); + } + pm_strcat(&fd->msg, " "); + pm_strcat(&fd->msg, ie->name_list[j]); + Dmsg1(200, "Include name=%s\n", fd->msg); + fd->msglen = strlen(fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); goto bail_out; } + break; } - fclose(ffd); - break; - default: - strcpy(fd->msg, ie->opts); - pm_strcat(&fd->msg, ie->name); - Dmsg1(000, "Include name=%s\n", ie->name); - fd->msglen = strlen(fd->msg); - if (!bnet_send(fd)) { - Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); - goto bail_out; - } - break; } } bnet_sig(fd, BNET_EOD); /* end of data */ @@ -209,21 +225,24 @@ int send_exclude_list(JCR *jcr) { FILESET *fileset; BSOCK *fd; - int i; fd = jcr->file_bsock; fileset = jcr->fileset; fd->msglen = sprintf(fd->msg, exc); bnet_send(fd); - for (i=0; i < fileset->num_excludes; i++) { - pm_strcpy(&fd->msg, fileset->exclude_array[i]->name); - fd->msglen = strlen(fd->msg); - Dmsg1(200, "dird>filed: exclude file: %s\n", fileset->exclude_array[i]->name); - if (!bnet_send(fd)) { - Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); - set_jcr_job_status(jcr, JS_ErrorTerminated); - return 0; + for (int i=0; i < fileset->num_excludes; i++) { + INCEXE *ie; + ie = fileset->exclude_items[i]; + for (int j=0; jnum_names; j++) { + pm_strcpy(&fd->msg, ie->name_list[j]); + fd->msglen = strlen(fd->msg); + Dmsg1(200, "Exclude name: %s\n", fd->msg); + if (!bnet_send(fd)) { + Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); + set_jcr_job_status(jcr, JS_ErrorTerminated); + return 0; + } } } bnet_sig(fd, BNET_EOD); diff --git a/bacula/src/version.h b/bacula/src/version.h index 993201e999..a4e4594974 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.30" #define VSTRING "1" -#define BDATE "01 March 2003" -#define LSMDATE "01Mar03" +#define BDATE "02 March 2003" +#define LSMDATE "02Mar03" /* Debug flags */ #define DEBUG 1 -- 2.39.5