+
+static bool copy_fileset(FF_PKT *ff, JCR *jcr)
+{
+ FILESET *jcr_fileset = jcr->fileset;
+ int num;
+ bool include = true;
+
+ findFILESET *fileset;
+ findFOPTS *current_opts;
+
+ fileset = (findFILESET *)malloc(sizeof(findFILESET));
+ memset(fileset, 0, sizeof(findFILESET));
+ ff->fileset = fileset;
+
+ fileset->state = state_none;
+ fileset->include_list.init(1, true);
+ fileset->exclude_list.init(1, true);
+
+ for ( ;; ) {
+ if (include) {
+ num = jcr_fileset->num_includes;
+ } else {
+ num = jcr_fileset->num_excludes;
+ }
+ for (int i=0; i<num; i++) {
+ INCEXE *ie;
+ int j, k;
+
+ if (include) {
+ ie = jcr_fileset->include_items[i];
+
+ /* New include */
+ fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
+ memset(fileset->incexe, 0, sizeof(findINCEXE));
+ fileset->incexe->opts_list.init(1, true);
+ fileset->incexe->name_list.init(0, 0);
+ fileset->include_list.append(fileset->incexe);
+ } else {
+ ie = jcr_fileset->exclude_items[i];
+
+ /* New exclude */
+ fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
+ memset(fileset->incexe, 0, sizeof(findINCEXE));
+ fileset->incexe->opts_list.init(1, true);
+ fileset->incexe->name_list.init(0, 0);
+ fileset->exclude_list.append(fileset->incexe);
+ }
+
+ for (j=0; j<ie->num_opts; j++) {
+ FOPTS *fo = ie->opts_list[j];
+
+ current_opts = (findFOPTS *)malloc(sizeof(findFOPTS));
+ memset(current_opts, 0, sizeof(findFOPTS));
+ fileset->incexe->current_opts = current_opts;
+ fileset->incexe->opts_list.append(current_opts);
+
+ current_opts->regex.init(1, true);
+ current_opts->regexdir.init(1, true);
+ current_opts->regexfile.init(1, true);
+ current_opts->wild.init(1, true);
+ current_opts->wilddir.init(1, true);
+ current_opts->wildfile.init(1, true);
+ current_opts->wildbase.init(1, true);
+ current_opts->fstype.init(1, true);
+ current_opts->drivetype.init(1, true);
+
+ set_options(current_opts, fo->opts);
+
+ for (k=0; k<fo->regex.size(); k++) {
+ // fd->fsend("R %s\n", fo->regex.get(k));
+ current_opts->regex.append(bstrdup((const char *)fo->regex.get(k)));
+ }
+ for (k=0; k<fo->regexdir.size(); k++) {
+ // fd->fsend("RD %s\n", fo->regexdir.get(k));
+ current_opts->regexdir.append(bstrdup((const char *)fo->regexdir.get(k)));
+ }
+ for (k=0; k<fo->regexfile.size(); k++) {
+ // fd->fsend("RF %s\n", fo->regexfile.get(k));
+ current_opts->regexfile.append(bstrdup((const char *)fo->regexfile.get(k)));
+ }
+ for (k=0; k<fo->wild.size(); k++) {
+ current_opts->wild.append(bstrdup((const char *)fo->wild.get(k)));
+ }
+ for (k=0; k<fo->wilddir.size(); k++) {
+ current_opts->wilddir.append(bstrdup((const char *)fo->wilddir.get(k)));
+ }
+ for (k=0; k<fo->wildfile.size(); k++) {
+ current_opts->wildfile.append(bstrdup((const char *)fo->wildfile.get(k)));
+ }
+ for (k=0; k<fo->wildbase.size(); k++) {
+ current_opts->wildbase.append(bstrdup((const char *)fo->wildbase.get(k)));
+ }
+ for (k=0; k<fo->fstype.size(); k++) {
+ current_opts->fstype.append(bstrdup((const char *)fo->fstype.get(k)));
+ }
+ for (k=0; k<fo->drivetype.size(); k++) {
+ current_opts->drivetype.append(bstrdup((const char *)fo->drivetype.get(k)));
+ }
+ }
+
+ for (j=0; j<ie->name_list.size(); j++) {
+ fileset->incexe->name_list.append(bstrdup((const char *)ie->name_list.get(j)));
+ }
+ }
+
+ if (!include) { /* If we just did excludes */
+ break; /* all done */
+ }
+
+ include = false; /* Now do excludes */
+ }
+
+ return true;
+}
+
+static void set_options(findFOPTS *fo, const char *opts)
+{
+ int j;
+ const char *p;
+
+ for (p=opts; *p; p++) {
+ switch (*p) {
+ case 'a': /* alway replace */
+ case '0': /* no option */
+ break;
+ case 'e':
+ fo->flags |= FO_EXCLUDE;
+ break;
+ case 'f':
+ fo->flags |= FO_MULTIFS;
+ break;
+ case 'h': /* no recursion */
+ fo->flags |= FO_NO_RECURSION;
+ break;
+ case 'H': /* no hard link handling */
+ fo->flags |= FO_NO_HARDLINK;
+ break;
+ case 'i':
+ fo->flags |= FO_IGNORECASE;
+ break;
+ case 'M': /* MD5 */
+ fo->flags |= FO_MD5;
+ break;
+ case 'n':
+ fo->flags |= FO_NOREPLACE;
+ break;
+ case 'p': /* use portable data format */
+ fo->flags |= FO_PORTABLE;
+ break;
+ case 'R': /* Resource forks and Finder Info */
+ fo->flags |= FO_HFSPLUS;
+ case 'r': /* read fifo */
+ fo->flags |= FO_READFIFO;
+ break;
+ case 'S':
+ switch(*(p + 1)) {
+ case ' ':
+ /* Old director did not specify SHA variant */
+ fo->flags |= FO_SHA1;
+ break;
+ case '1':
+ fo->flags |= FO_SHA1;
+ p++;
+ break;
+#ifdef HAVE_SHA2
+ case '2':
+ fo->flags |= FO_SHA256;
+ p++;
+ break;
+ case '3':
+ fo->flags |= FO_SHA512;
+ p++;
+ break;
+#endif
+ default:
+ /* Automatically downgrade to SHA-1 if an unsupported
+ * SHA variant is specified */
+ fo->flags |= FO_SHA1;
+ p++;
+ break;
+ }
+ break;
+ case 's':
+ fo->flags |= FO_SPARSE;
+ break;
+ case 'm':
+ fo->flags |= FO_MTIMEONLY;
+ break;
+ case 'k':
+ fo->flags |= FO_KEEPATIME;
+ break;
+ case 'A':
+ fo->flags |= FO_ACL;
+ break;
+ case 'V': /* verify options */
+ /* Copy Verify Options */
+ for (j=0; *p && *p != ':'; p++) {
+ fo->VerifyOpts[j] = *p;
+ if (j < (int)sizeof(fo->VerifyOpts) - 1) {
+ j++;
+ }
+ }
+ fo->VerifyOpts[j] = 0;
+ break;
+ case 'w':
+ fo->flags |= FO_IF_NEWER;
+ break;
+ case 'W':
+ fo->flags |= FO_ENHANCEDWILD;
+ break;
+ case 'Z': /* compression */
+ p++; /* skip Z */
+ if (*p >= '0' && *p <= '9') {
+ fo->flags |= FO_COMPRESS;
+ fo->Compress_algo = COMPRESS_GZIP;
+ fo->Compress_level = *p - '0';
+ }
+ else if (*p == 'o') {
+ fo->flags |= FO_COMPRESS;
+ fo->Compress_algo = COMPRESS_LZO1X;
+ fo->Compress_level = 1; /* not used with LZO */
+ }
+ Dmsg2(200, "Compression alg=%d level=%d\n", fo->Compress_algo, fo->Compress_level);
+ break;
+ case 'X':
+ fo->flags |= FO_XATTR;
+ break;
+ default:
+ Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p);
+ break;
+ }
+ }
+}