]> git.sur5r.net Git - bacula/bacula/commitdiff
More FileSet changes
authorKern Sibbald <kern@sibbald.com>
Fri, 30 Apr 2004 13:34:38 +0000 (13:34 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 30 Apr 2004 13:34:38 +0000 (13:34 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1328 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kernstodo
bacula/src/dird/fd_cmds.c
bacula/src/dird/inc_conf.c
bacula/src/filed/job.c
bacula/src/findlib/create_file.c
bacula/src/findlib/find.c
bacula/src/findlib/find.h
bacula/src/findlib/find_one.c
bacula/src/findlib/match.c

index fa365949982310c26944533ada83a750762fa308..809bba0f0540236f312565989978ef1cea01928e 100644 (file)
@@ -170,30 +170,6 @@ For version 1.35:
   in Job, Client, and Pool, with precedence such that Job overrides Client
   which in turn overrides Pool.
 - Print a message when a job starts if the conf file is not current.
-- To pass Include 1 or two letter commands
-  I Name           Include name - first record
-  B Name           Base name - repeat
-  R "xxx"          Regexp
-  W "xxx"          Wild Card
-  E zzz            Exclude expression (wild card)
-  P "plugin"       Plugin
-  D "reader"       Reader program
-  T "writer"       Writer program
-  O Options        In current commpressed format
-    (compression, signature, onefs, recurse, sparse,
-     replace, verify options, ...)
-  N                End option set
-  B BaseName       Start second option set any letter
-  ...
-  E
-  F Number         Number of filenames to follow
-  <file-name>
-  B Name
-  ...
-  N                End option set
-  F Number         Number of filenames to follow
-  <file-name>
-  ...
 
 - Spooling ideas taken from Volker Sauer's and other's emails:
    > IMHO job spooling should be turned on
@@ -849,167 +825,6 @@ Need:
   VolSessionId and VolSessionTime.
 =========================================================  
 
-=============================================================
-
-              File Backup Options Project
-                  28 April 2004
-
-
-Subject: File Backup Options
-
-Problem: 
-  Bacula users who are using compression would like to suppress
-  compressing all .gz files since it was a waste of CPU time.
-  Although Bacula currently permits using different options
-  (compression, ...) on a directory by directory basis, it cannot
-  do it on a file by file basis, which is clearly what was
-  desired.
-
-Proposed Implementation:
-  To solve this problem, I propose the following:
-
-  - Add a new Director resource type called Options.  
-
-  - The Options resource will have records for all options that
-    can currently be specified on the Include record (in a
-    FileSet).  Examples below.
-
-  - The Options resource will permit an exclude option as well
-    as a number of additional options.
-
-  - The heart of the Options resource is the ability to supply
-    any number of Regex records which specify POSIX regular
-    expressions.  These regular expressions are applied to the
-    fully qualified filename (path and all).  If one matches,
-    then the Options will be used.
-
-  - When a Regex specification matches an included file, the
-    options specified in the Options resource will override the
-    default options specified on the Include record.
-
-  - Include records will be modified to permit referencing one or
-    more Options resources.  The Options will be used in the
-    order listed on the Include record and the first one that
-    matches will be applied.
-
-  - Options (or specifications) currently supplied on the Include
-    record will be deprecated (i.e.  removed in a later version a
-    year or so from now).
-
-  - The Exclude record will be deprecated as the same functionality
-    can be obtained by using an Exclude = yes in the Options or
-    an Exclude = xxxx directive.
-
-Options records:
-  The following records can appear in the Options resource. An
-  asterisk preceding the name indicates a feature not currently
-  implemented.
-
-    - Regexp "xxx"            - Match regular expression
-    - Wild "xxx"              - Do a wild card match
-
-  For Backup Jobs:
-    - Compression= (GZIP, ...)
-    - Signature=   (MD5, SHA1, ...)
-    - *Encryption=
-    - OneFs=      (yes/no)    - remain on one filesystem
-    - Recurse=    (yes/no)    - recurse into subdirectories
-    - Sparse=     (yes/no)    - do sparse file backup
-    - *Exclude=   (yes/no)    - exclude file from being saved
-    - *INclude=   (yes/no)    - include the file (needed??)
-    - *Reader=    (filename)  - external read (backup) program
-    - *Plugin=    (filename)  - read/write plugin module
-
-  For Verify Jobs:
-    - verify=     (ipnougsamc5) - verify options
-
-  For Restore Jobs:
-    - replace= (always/ifnewer/ifolder/never) - replace options currently
-                                                implemented in 1.31
-    - *Writer= (filename)   - external write (restore) program
-
-
-Implementation:
-  Currently options specifying compression, MD5 signatures,
-  recursion, ...  of a FileSet are supplied on the Include
-  record.  These will now all be collected into a Options
-  resource, which will be specified in the Include in place of
-  the options.  Multiple Options may be specified.  Since the
-  Options may contain regular expressions that are applied to the
-  full filename, this will give the ability to specify backup
-  options on a file by file basis to whatever level of detail you
-  wish.
-
-Example:
-
-  Today:
-
-    FileSet {
-      Name = "FullSet"
-      Include = compression=GZIP signature=MD5 {
-        /
-      }
-    }
-
-  Proposal:
-
-    FileSet {
-      Name = "FullSet"
-      Include {
-        Options {
-          Compression = GZIP;
-          Signature = MD5
-          Wild  = /*.?*/                # matches all files.
-        }
-        Include = /
-      }
-    }
-
-  That's a lot more to do the same thing, but it gives the ability to
-  apply options on a file by file basis.  For example, suppose you
-  want to compress all files but not any file with extensions .gz or .Z.
-  In that case, you will need to group two sets of options using
-  the Options resource. Files may be anywhere except in an
-  option set ???  All Options apply to all files in the order
-  the Options were specified.  To have files included with
-  different option sets without using wild-cards, use two or more
-  Includes -- each one is handled in turn using only the files and
-  optionsets specified in the include.
-
-    FileSet {
-      Name = "FullSet"
-      Include {
-        Options {
-          Signature = MD5
-          # Note multiple Matches are ORed
-          Wild  = "*.gz"   # matches .gz files
-          Wild  = "*.Z"    # matches .Z files
-        }
-        Options {
-          Compression = GZIP
-          Signature = MD5
-          Wild  = "*.?*"   # matches all files
-        }
-        Include = /
-      }
-    }
-
-  Now, since the no Compression option is specified in the
-  first group of Options, *.gz or *.Z file will have an MD5 signature computed,
-  but will not be compressed. For all other files, the *.gz *.Z will not
-  match, so the second group of options will be used which will include GZIP
-  compression.
-
-Questions:
-  
-Results:
-  After implementing the above, the user will be able to specify
-  on a file by file basis (using regular expressions) what options are
-  applied for the backup.
-
-
-=============================================
-
 
 ========================================================== 
     Unsaved File design
@@ -1177,203 +992,29 @@ Block Position: 0
 ====
 
 
-=== Done in 1.33
-- Change console to bconsole.
-- Change smtp to bsmtp.
-- Fix time difference problem between Bacula and Client
-  so that everything is in GMT.
-- Fix TimeZone problem!
-- Mount a tape that is not right for the job (wrong # files on tape)
-  Bacula asks for another tape, fix problems with first tape and
-  say "mount". All works OK, but status shows:
-   Device /dev/nst0 open but no Bacula volume is mounted.
-       Total Bytes=1,153,820,213 Blocks=17,888 Bytes/block=64,502
-       Positioned at File=9 Block=3,951
-   Full Backup job Rufus.2003-10-26_16.45.31 using Volume "DLT-24Oct03" on device /dev/nst0
-       Files=21,003 Bytes=253,954,408 Bytes/sec=2,919,016
-       FDReadSeqNo=192,134 in_msg=129830 out_msg=5 fd=7
-- Upgrade to cygwin 1.5
-- Optimize fsf not to read.
-- Use ioctl() fsf if it exists. Figure out where we are from
-  the mt_status command. Use slow fsf only if other does not work.
-- Enhance "update slots" to include a "scan" feature
-  scan 1; scan 1-5; scan 1,2,4 ...  to update the catalog 
-- Allow a slot or range of slots on the label barcodes command.
-- Finish implementation of Verify=DiskToCatalog
-- Make sure that Volumes are recycled based on "Least recently used"
-  rather than lowest MediaId.
-- Add flag to write only one EOF mark on the tape.
-- Implement autochanger testing in btape "test" command.
-- Implement lmark to list everyfile marked.
-- Make mark/unmark report how many files marked/unmarked.
-- Keep last 5 or 10 completed jobs and show them in a similar list.
-- Make a Running Jobs: output similar to current Scheduled Jobs:
-- Change "create_media_record in bscan to use Archive instead of Full.
-- Have some way to estimate the restore size or have it printed.
-- Volume problems occurs if you have valid volume, written, then it is
-  truncated. You get 12-Nov-2003 11:48 rufus-sd: kernsave.2003-11-12_11.48.09 Warning: mount.c:228 Volume on /tmp is not a Bacula labeled Volume, because:
-     block.c:640 Read zero bytes on device /tmp.
-- Make sure that 64 bit I/O packets are used on Cygwin.
-- Add to supported autochangers 
-  OS              : FreeBSD-4.9
-  Auto-Changer    : QUALSTAR TLS-4210
-    Manufufactur  : Qualstar
-    Tapes         : 12 (AIT1: 36GB, AIT2: 50GB all uncompressed)
-    Drives        : 2xAIT2 (installed in the Qualstar: SONY SDX-500C AIT2)
-- Document estimate command in tree.
-- Document lsmark command in tree.
-- Setup a standard job that builds a bootstrap file and saves
-  it with the catalog database.
-- See if a restore job can add a file to the tape (prohibit this).
-- Restrict characters permitted in a name.
-- In restore, provide option for limiting to a particular Pool.
-- In restore, list FileSets that only have different base names --
-  i.e. any FileSet with the same name should be treated as the same.
-- Make Scheduler sort jobs by StartTime, Priority.
-- Make sure smtp and any other useful program is executable by the world
-  in case Bacula is not running as root.
-- Look at Dan's field width problems in PostgreSQL.
-- Look at effect of removing GROUP BYs.
-- In restore take all filesets with same base name.
-- From Alan Brown <ajb2@mssl.ucl.ac.uk>
-    BTW, there's a make install bug in 1.33 - with --enable-gnome,
-    gnome-console is built, but the binary and .conf are not being installed.
-- Permit Bacula and apcupsd donations (not done for apcupsd).
-- Fix Ctl-C crashing the Console (readline?).
-- Look at code in recycle_oldes_purged_volume() recycle.c. Why not
-  let SQL do ORDER BY LastWritten ASC?
-- Look at find_next_volume() algorithm. Currently, it selects:
-    +---------+------------+---------------------+-----------+
-    | MediaId | VolumeName | LastWritten         | VolBytes  |
-    +---------+------------+---------------------+-----------+
-    |       3 | Test13     | 0000-00-00 00:00:00 |         1 |
-    |       4 | Test14     | 0000-00-00 00:00:00 |         1 |
-    |       1 | test11     | 2003-12-03 18:39:55 | 4,004,926 |
-    |       2 | test12     | 2004-01-04 15:25:56 | 2,078,691 |
-    +---------+------------+---------------------+-----------+
-  but perhaps it should fill already used Volumes first, and use
-  Append volumes before Purged, or Recycled, ...
-- Possibly remove the "|| ap == NULL" on lines 123 and 207 of lib/var.c,
-  which creates compile problems on alpha systems.
-  var.c:123: no match for `va_list & == long int'
-- Check "restore" 3 (JobId), then it asks for Storage resource. Does
-  it verify that the correct volume is chosen?
-- Make Bacula "poll a drive".
-- Notes for final checking of Nic's code:
-  Could I get you to double check the switch () statements in the
-  job_check_maxwaittime and job_check_maxruntime functions in
-  src/dird/job.c?
-- Define week of year for scheduler.  W01, W02, ...
-  Week 01 of a year is per definition the first week that has the
-  Thursday in this year, which is equivalent to the week that contains the
-  fourth day of January.  In other words, the first week of a new year is
-  the week that has the majority of its days in the new year.  Week 01
-  might also contain days from the previous year and the week before week
-  01 of a year is the last week (52 or 53) of the previous year even if it
-  contains days from the new year.  A week starts with Monday (day 1) and
-  ends with Sunday (day 7).  For example, the first week of the year 1997
-  lasts from 1996-12-30 to 1997-01-05 and can be written in standard
-  notation as
-    1997-W01 or 1997W01
-  The week notation can also be extended by a number indicating the day
-  of the week.  For example, the day 1996-12-31, which is the Tuesday (day
-  2) of the first week of 1997, can also be written as
-    1997-W01-2 or 1997W012
-- Either restrict the characters in a name, or fix the problem 
-  emailing with names containing / (smtp command line breaks).
-- Implement .consolerc for Console
-- Implement scan: for every slot it finds, zero the slot of
-  Volume other volume having that slot.
-- Make restore job check if all the files are actually restored.
-- Look at 2Gb limit for SQLite.
-- Fix get_storage_from_media_type (ua_restore) to use command line     
-  storage=
-- Don't print "Warning: Wrong Volume mounted ..." if mounting second volume.
-- Write a mini-readline with history and editing.
-- Take a careful look a the Basic recycling algorithm.  When Bacula
-  chooses, the order should be:
-   - Look for Append
-   - Look for Recycle or Purged
-   - Prune volumes
-   - Look for purged
-  Instead of using lowest media Id, find the least recently used
-  volume.
-
-  When the tape is mounted and Bacula requests the status
-  - Do everything possible to use it.
-
-  Define a "available" status, which is the currently mounted 
-  Volume and all volumes that are currently in the autochanger.
-- Is a pool specification really needed for a restore?  Yes, and
-  you may want to exclude archive Pools.
-- Implement a PostgreSQL driver.
-- Fix restore to list errors if Invalid block found, and if # files
-  restored does not match # expected.
-- Something is not right in last block of fill command.
-- Add FileSet to command line arguments for restore.
-- Enhance time and size scanning routines.
-- Add Console usr permissions -- do by adding filters for
-  jobs, clients, storage, ...
-- Put max network buffer size on a directive.
-- Why does "mark cygwin" take so long!!!!!!!!
-- Implement alist processing for ACLs from Console.
-- When a file is set for restore, walk back up the chain of 
-  directories, setting them to be restored.
-- Figure out a way to set restore on a directory without recursively
-  decending.  (recurse off?).
-- Fix restore to only pull in last Differential and later Incrementals.
-- Implement 3 Pools for a Job:
-   Job {
-     Name = ...
-     Full Backup Pool = xxx
-     Incremental Backup Pool = yyy
-     Differential Backup Pool = zzz
-   }
-- Look at ASSERT() at 384 src/lib/bnet.c
-- Dates are wrong in restore list from Win32 FD.
-- Dates are wrong in catalog from Win32 FD.
-- Remove h_errno from bnet.c by including proper header.
-- For "list jobs" order by EndTime.
-- Make two tape fill test work.
-- Add atime preservation.
-- Do not err job if could not write bootstrap file.
-- Save and restore last_job across executions.
-- Have each daemon save the last_jobs structure when exiting and
-  read it back in when starting up.
-- "restore jobid=1 select" calls get_storage_xxx, which prints "JobId 1 is
-  not running."
-- Make column listing for running jobs JobId Level Type Started Name  Status
-- Why does Bacula need the drive open to do "autochanger list" ?
-- Add data compare on write/read in btape "test". 
-- Rescue builds incorrect script files on Rufus.  
-- Release SQLite 2.8.9
-- During install, copy any console.conf to bconsole.conf.
-- Check: Run = Level=Differential feb-dec 1 at 1:05 to see if wday is empty.
-- Look at installation file permissions with Scott so that make install
-  and the rpms agree.
-- Finish code passing files=nnn to restore start.
-- Add ctl-c to console to stop current command and discard buffered
-  output.
-- Estimate to Tibs never returns.
-- Symbolic link a directory to another one, then backup the symbolic link.
-- Check and possibly fix problems with hard links.
-- Fix query buffer clobber ua_query.c
-- Allow "delete job jobid=xx jobid=xxx".   
-- Update volume FromPool (or FromPool=xxx) refreshes the Volume defaults from Pool.
-- Implement multiple Volume in "purge jobs volume=".
-- Test Qmsg() code to be used in bnet.c to prevent recursion.  Queue the
-  message. If dequeueing toss the messages. Lock while dequeuing so that
-  it cannot be called recursively and set dequeuing flag.
-- On unknown client in restore "client=xxx"
-  Could not find Client "Matou": ERR=Query failed: DROP TABLE temp1: 
-     ERR=no such table: temp1
-- Null dlist head and tail pointers if all items are removed.
-- Build console in client-only build.
-- Phil says that Windows file sizes mismatch in Verify when they should,
-  and that either the file size or the catalog size was zero.
-- Check time/dates printed during restore when using Win32 API.
-- Once a job is canceled, make sure the status reflects that even if the
-  job is "stuck" in the run queue.
-- Test work on conio.c -- particularly linking.
-- Complete Win32 installer
-- Add ms disk example
+=== Done in 1.35
+- To pass Include 1 or two letter commands
+  I Name           Include name - first record
+  B Name           Base name - repeat
+  R "xxx"          Regexp
+  W "xxx"          Wild Card
+  E zzz            Exclude expression (wild card)
+  P "plugin"       Plugin
+  D "reader"       Reader program
+  T "writer"       Writer program
+  O Options        In current commpressed format
+    (compression, signature, onefs, recurse, sparse,
+     replace, verify options, ...)
+  N                End option set
+  B BaseName       Start second option set any letter
+  ...
+  E
+  F Number         Number of filenames to follow
+  <file-name>
+  B Name
+  ...
+  N                End option set
+  F Number         Number of filenames to follow
+  <file-name>
+  ...
+
index 27c41b68b21915822ed210edf46af14d57620bb4..49289929a2f229fe7daec27fa5ffc0efc755d843 100644 (file)
@@ -495,6 +495,9 @@ int send_include_list(JCR *jcr)
 int send_exclude_list(JCR *jcr)
 {
    BSOCK *fd = jcr->file_bsock;
+   if (jcr->fileset->new_include) {
+      return 1;
+   }
    bnet_fsend(fd, exc);
    return send_list(jcr, EXC_LIST);
 }
index e99e70771b9eca454c62f1776f032f75bd92ccdb..ff76230b9c67792dbf925331eb8d8bcccf32ea8a 100644 (file)
@@ -60,7 +60,6 @@ static INCEXE res_incexe;
  */
 static RES_ITEM newinc_items[] = {
    {"file",            store_fname,   NULL,     0, 0, 0},
-   {"include",         store_fname,   NULL,     0, 0, 0},
    {"options",         options_res,   NULL,     0, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
@@ -241,7 +240,7 @@ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass)
 
    /*
     * Decide if we are doing a new Include or an old include. The
-    *  new Include is followed immediately by {, whereas the
+    *  new Include is followed immediately by open brace, whereas the
     *  old include has options following the Include.
     */
    token = lex_get_token(lc, T_ALL);           
@@ -360,7 +359,7 @@ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass)
 /*
  * Store FileSet FInclude/FExclude info   
  *  Note, when this routine is called, we are inside a FileSet
- *  resource.  We treat the Finclude/Fexeclude like a sort of
+ *  resource.  We treat the Include/Execlude like a sort of
  *  mini-resource within the FileSet resource.
  */
 static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass)
index dbc02531d4d82515fbe2f0b7d27a93518617b56f..071d150e736329b75a9f804eb1952cd4631dbdc6 100644 (file)
@@ -58,6 +58,7 @@ static int send_bootstrap_file(JCR *jcr);
 static int runbefore_cmd(JCR *jcr);
 static int runafter_cmd(JCR *jcr);
 static int run_cmd(JCR *jcr, char *cmd, const char *name);
+static void set_options(findFOPTS *fo, const char *opts);
 
 
 /* Exported functions */
@@ -585,7 +586,7 @@ static bool init_fileset(JCR *jcr)
    return true;
 }
 
-static findFOPTS *set_options(FF_PKT *ff)
+static findFOPTS *start_options(FF_PKT *ff)
 {
    int state = ff->fileset->state;
    findINCEXE *incexe = ff->fileset->incexe;
@@ -646,23 +647,23 @@ static void add_fileset(JCR *jcr, const char *item)
       fileset->incexe->name_list.append(bstrdup(item));
       break;
    case 'R':
-      current_opts = set_options(ff);
+      current_opts = start_options(ff);
       current_opts->regex.append(bstrdup(item));
       state = state_options;
       break;
    case 'B':
-      current_opts = set_options(ff);
+      current_opts = start_options(ff);
       current_opts->base.append(bstrdup(item));
       state = state_options;
       break;
    case 'W':
-      current_opts = set_options(ff);
+      current_opts = start_options(ff);
       current_opts->wild.append(bstrdup(item));
       state = state_options;
       break;
    case 'O':   
-      current_opts = set_options(ff);
-      bstrncpy(current_opts->opts, item, MAX_FOPTS);
+      current_opts = start_options(ff);
+      set_options(current_opts, item);
       state = state_options;
       break;
    default:
@@ -684,7 +685,6 @@ static bool term_fileset(JCR *jcr)
       Dmsg0(400, "I\n");
       for (j=0; j<incexe->opts_list.size(); j++) {
         findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
-         Dmsg1(400, "O %s\n", fo->opts);
         for (k=0; k<fo->regex.size(); k++) {
             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
         }
@@ -704,7 +704,6 @@ static bool term_fileset(JCR *jcr)
       Dmsg0(400, "E\n");
       for (j=0; j<incexe->opts_list.size(); j++) {
         findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
-         Dmsg1(400, "O %s\n", fo->opts);
         for (k=0; k<fo->regex.size(); k++) {
             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
         }
@@ -719,12 +718,83 @@ static bool term_fileset(JCR *jcr)
          Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j));
       }
    }
-
-
    return ff->fileset->state != state_error;
 }
 
 
+/*
+ * As an optimization, we should do this during
+ *  "compile" time in filed/job.c, and keep only a bit mask
+ *  and the Verify options.
+ */
+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 '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':                 /* read fifo */
+        fo->flags |= FO_READFIFO;
+        break;
+      case 'S':
+        fo->flags |= FO_SHA1;
+        break;
+      case 's':
+        fo->flags |= FO_SPARSE;
+        break;
+      case 'm':
+        fo->flags |= FO_MTIMEONLY;
+        break;
+      case 'k':
+        fo->flags |= FO_KEEPATIME;
+        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 'Z':                 /* gzip compression */
+        fo->flags |= FO_GZIP;
+         fo->GZIP_level = *++p - '0';
+         Dmsg1(200, "Compression level=%d\n", fo->GZIP_level);
+        break;
+      default:
+         Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p);
+        break;
+      }
+   }
+} 
+
 
 /*
  * Director is passing his Fileset   
index 500061d25a1eb343516d9ed41e8f5213d93467b3..1455ce11bd5c9ff83377abb3b91d96b4c81884ad 100644 (file)
@@ -243,7 +243,8 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
 #endif
       } /* End inner switch */
 
-   case FT_DIR:
+   case FT_DIRBEGIN:
+   case FT_DIREND:
       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
       if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
         return CF_ERROR;
index bbf9a14984128e4fc62711a764c74d8110b173c1..d9ec87cd3950f82faf8be6c419e461b7154e79c3 100644 (file)
 #include "find.h"
 
 
-int32_t name_max;              /* filename max length */
-int32_t path_max;              /* path name max length */
+int32_t name_max;             /* filename max length */
+int32_t path_max;             /* path name max length */
 
 
 /* ****FIXME**** debug until stable */
 #undef bmalloc
 #define bmalloc(x) sm_malloc(__FILE__, __LINE__, x)
-static void set_options(FF_PKT *ff, const char *opts);
 static int our_callback(FF_PKT *ff, void *hpkt);
 static bool accept_file(FF_PKT *ff);
 
@@ -46,14 +45,14 @@ static bool accept_file(FF_PKT *ff);
  */
 FF_PKT *init_find_files()
 {
-  FF_PKT *ff;    
+  FF_PKT *ff;   
 
   ff = (FF_PKT *)bmalloc(sizeof(FF_PKT));
   memset(ff, 0, sizeof(FF_PKT));
 
   ff->sys_fname = get_pool_memory(PM_FNAME);
 
-  init_include_exclude_files(ff);           /* init lists */
+  init_include_exclude_files(ff);          /* init lists */
 
    /* Get system path and filename maximum lengths */
    path_max = pathconf(".", _PC_PATH_MAX);
@@ -65,8 +64,8 @@ FF_PKT *init_find_files()
    if (name_max < 1024) {
       name_max = 1024;
    }
-   path_max++;                        /* add for EOS */
-   name_max++;                        /* add for EOS */
+   path_max++;                       /* add for EOS */
+   name_max++;                       /* add for EOS */
 
   Dmsg1(100, "init_find_files ff=%p\n", ff);
   return ff;
@@ -112,39 +111,42 @@ find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt), void
    findFILESET *fileset = ff->fileset;
    if (fileset) {
       int i, j;
+      ff->flags = 0;
+      ff->VerifyOpts[0] = 0;
       for (i=0; i<fileset->include_list.size(); i++) {
-         findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
-         fileset->incexe = incexe;
-         /*
-          * By setting all options, we in effect or the global options
-          *   which is what we want.
-          */
-         for (j=0; j<incexe->opts_list.size(); j++) {
-            findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
-            Dmsg1(400, "Find global options O %s\n", fo->opts);
-            set_options(ff, fo->opts);
-         }
-         for (j=0; j<incexe->name_list.size(); j++) {
+        findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
+        fileset->incexe = incexe;
+        /*
+         * By setting all options, we in effect or the global options
+         *   which is what we want.
+         */
+        for (j=0; j<incexe->opts_list.size(); j++) {
+           findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+           ff->flags |= fo->flags;
+           ff->GZIP_level = fo->GZIP_level;
+           bstrncpy(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts)); 
+        }
+        for (j=0; j<incexe->name_list.size(); j++) {
             Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j));
-            char *fname = (char *)incexe->name_list.get(j);
-            if (!find_one_file(jcr, ff, our_callback, his_pkt, fname, (dev_t)-1, 1)) {
-               return 0;                  /* error return */
-            }
-         }
+           char *fname = (char *)incexe->name_list.get(j);
+           if (!find_one_file(jcr, ff, our_callback, his_pkt, fname, (dev_t)-1, 1)) {
+              return 0;                  /* error return */
+           }
+        }
       }
    } else {
       struct s_included_file *inc = NULL;
 
       /* This is the old deprecated way */
       while (!job_canceled(jcr) && (inc = get_next_included_file(ff, inc))) {
-         /* Copy options for this file */
-         bstrncpy(ff->VerifyOpts, inc->VerifyOpts, sizeof(ff->VerifyOpts)); 
+        /* Copy options for this file */
+        bstrncpy(ff->VerifyOpts, inc->VerifyOpts, sizeof(ff->VerifyOpts)); 
          Dmsg1(50, "find_files: file=%s\n", inc->fname);
-         if (!file_is_excluded(ff, inc->fname)) {
-            if (!find_one_file(jcr, ff, callback, his_pkt, inc->fname, (dev_t)-1, 1)) {
-               return 0;                  /* error return */
-            }
-         }
+        if (!file_is_excluded(ff, inc->fname)) {
+           if (!find_one_file(jcr, ff, callback, his_pkt, inc->fname, (dev_t)-1, 1)) {
+              return 0;                  /* error return */
+           }
+        }
       }
    }
    return 1;
@@ -159,31 +161,35 @@ static bool accept_file(FF_PKT *ff)
    for (j=0; j<incexe->opts_list.size(); j++) {
       findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
       for (k=0; k<fo->wild.size(); k++) {
-         
+        if (fnmatch((char *)fo->wild.get(k), ff->fname, 0) == 0) {
+           ff->flags = fo->flags;
+           ff->GZIP_level = fo->GZIP_level;
+           if (ff->flags & FO_EXCLUDE) {
+              return false;          /* reject file */
+           }
+           return true;              /* accept file */
+        }
       }
    }
 
    for (i=0; i<fileset->exclude_list.size(); i++) {
       findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
       for (j=0; j<incexe->opts_list.size(); j++) {
-         findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
-         for (k=0; k<fo->wild.size(); k++) {
-            Dmsg1(400, "W %s\n", (char *)fo->wild.get(k));
-            if (fnmatch((char *)fo->wild.get(k), ff->fname, FNM_PATHNAME) == 0) {
-               Dmsg1(000, "Reject wild: %s\n", ff->fname);
-               return false;          /* reject file */
-            }
-         }
+        findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+        for (k=0; k<fo->wild.size(); k++) {
+           if (fnmatch((char *)fo->wild.get(k), ff->fname, 0) == 0) {
+               Dmsg1(400, "Reject wild1: %s\n", ff->fname);
+              return false;          /* reject file */
+           }
+        }
       }
       for (j=0; j<incexe->name_list.size(); j++) {
-         Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j));
-         if (fnmatch((char *)incexe->name_list.get(j), ff->fname, FNM_PATHNAME) == 0) {
-            Dmsg1(000, "Reject: %s\n", ff->fname);
-            return false;          /* reject file */
-         }
+        if (fnmatch((char *)incexe->name_list.get(j), ff->fname, 0) == 0) {
+            Dmsg1(400, "Reject wild2: %s\n", ff->fname);
+           return false;          /* reject file */
+        }
       }
    }
-   Dmsg1(000, "Accept: %s\n", ff->fname);
    return true;
 }
 
@@ -203,7 +209,6 @@ static int our_callback(FF_PKT *ff, void *hpkt)
    case FT_NORECURSE:
    case FT_NOFSCHG:
    case FT_NOOPEN:
-      Dmsg1(000, "File=%s\n", ff->fname);
       return ff->callback(ff, hpkt);
 
    /* These items can be filtered */
@@ -215,89 +220,15 @@ static int our_callback(FF_PKT *ff, void *hpkt)
    case FT_DIREND:
    case FT_SPEC:
       if (accept_file(ff)) {
-         return ff->callback(ff, hpkt);
+        return ff->callback(ff, hpkt);
       } else {
-         return 0;
+        return 0;
       }
-   }    
+   }   
    return 0;
 }
 
 
-/*
- * As an optimization, we should do this during
- *  "compile" time in filed/job.c, and keep only a bit mask
- *  and the Verify options.
- */
-static void set_options(FF_PKT *ff, 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':
-         ff->flags |= FO_EXCLUDE;
-         break;
-      case 'f':
-         ff->flags |= FO_MULTIFS;
-         break;
-      case 'h':                 /* no recursion */
-         ff->flags |= FO_NO_RECURSION;
-         break;
-      case 'M':                 /* MD5 */
-         ff->flags |= FO_MD5;
-         break;
-      case 'n':
-         ff->flags |= FO_NOREPLACE;
-         break;
-      case 'p':                 /* use portable data format */
-         ff->flags |= FO_PORTABLE;
-         break;
-      case 'r':                 /* read fifo */
-         ff->flags |= FO_READFIFO;
-         break;
-      case 'S':
-         ff->flags |= FO_SHA1;
-         break;
-      case 's':
-         ff->flags |= FO_SPARSE;
-         break;
-      case 'm':
-         ff->flags |= FO_MTIMEONLY;
-         break;
-      case 'k':
-         ff->flags |= FO_KEEPATIME;
-         break;
-      case 'V':                  /* verify options */
-         /* Copy Verify Options */
-         for (j=0; *p && *p != ':'; p++) {
-            ff->VerifyOpts[j] = *p;
-            if (j < (int)sizeof(ff->VerifyOpts) - 1) {
-               j++;
-            }
-         }
-         ff->VerifyOpts[j] = 0;
-         break;
-      case 'w':
-         ff->flags |= FO_IF_NEWER;
-         break;
-      case 'Z':                 /* gzip compression */
-         ff->flags |= FO_GZIP;
-         ff->GZIP_level = *++p - '0';
-         Dmsg1(200, "Compression level=%d\n", ff->GZIP_level);
-         break;
-      default:
-         Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p);
-         break;
-      }
-   }
-}
-
-
 /*
  * Terminate find_files() and release
  * all allocated memory   
index 15c4f8a2e72b52fd24c94ebf7f17906aeb2fee2e..32dda2c8a02bc5818b231ba1b85c1e1b2f8dab87 100755 (executable)
@@ -120,7 +120,6 @@ enum {
 
 /* File options structure */
 struct findFOPTS {
-   char opts[MAX_FOPTS];              /* options string */
    uint32_t flags;                    /* options in bits */
    int GZIP_level;                    /* GZIP level */
    char VerifyOpts[MAX_FOPTS];        /* verify options */
index bb0a2635e97400cacb979cae87dffbf0e05f117d..36a7d2afac6fcf007bbfb898df0897bde02a0b6b 100755 (executable)
@@ -28,8 +28,8 @@
 #include "bacula.h"
 #include "find.h"
 
-extern int32_t name_max;              /* filename max length */
-extern int32_t path_max;              /* path name max length */
+extern int32_t name_max;             /* filename max length */
+extern int32_t path_max;             /* path name max length */
 
 /*
  * Structure for keeping track of hard linked files, we   
@@ -40,11 +40,11 @@ extern int32_t path_max;              /* path name max length */
  */
 struct f_link {
     struct f_link *next;
-    dev_t dev;                        /* device */
-    ino_t ino;                        /* inode with device is unique */
+    dev_t dev;                       /* device */
+    ino_t ino;                       /* inode with device is unique */
     short linkcount;
-    uint32_t FileIndex;               /* Bacula FileIndex of this file */
-    char name[1];                     /* The name */
+    uint32_t FileIndex;              /* Bacula FileIndex of this file */
+    char name[1];                    /* The name */
 };
 
 static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt)
@@ -56,7 +56,7 @@ static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt)
 }
 
 /*
- * Find a single file.                        
+ * Find a single file.                       
  * handle_file is the callback for handling the file.
  * p is the filename
  * parent_device is the device we are currently on 
@@ -65,7 +65,7 @@ static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt)
  */
 int
 find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), 
-               void *pkt, char *fname, dev_t parent_device, int top_level)
+              void *pkt, char *fname, dev_t parent_device, int top_level)
 {
    struct utimbuf restore_times;
    int rtn_stat;
@@ -97,11 +97,11 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       Dmsg1(300, "Non-directory incremental: %s\n", ff_pkt->fname);
       /* Not a directory */
       if (ff_pkt->statp.st_mtime < ff_pkt->save_time
-          && ((ff_pkt->flags & FO_MTIMEONLY) || 
-              ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
-         /* Incremental option, file not changed */
-         ff_pkt->type = FT_NOCHG;
-         return handle_file(ff_pkt, pkt);
+         && ((ff_pkt->flags & FO_MTIMEONLY) || 
+             ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
+        /* Incremental option, file not changed */
+        ff_pkt->type = FT_NOCHG;
+        return handle_file(ff_pkt, pkt);
       }
    }
 
@@ -123,27 +123,27 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
     */
    if (ff_pkt->statp.st_nlink > 1
        && (S_ISREG(ff_pkt->statp.st_mode)
-           || S_ISCHR(ff_pkt->statp.st_mode)
-           || S_ISBLK(ff_pkt->statp.st_mode)
-           || S_ISFIFO(ff_pkt->statp.st_mode)
-           || S_ISSOCK(ff_pkt->statp.st_mode))) {
+          || S_ISCHR(ff_pkt->statp.st_mode)
+          || S_ISBLK(ff_pkt->statp.st_mode)
+          || S_ISFIFO(ff_pkt->statp.st_mode)
+          || S_ISSOCK(ff_pkt->statp.st_mode))) {
 
        struct f_link *lp;
 
       /* Search link list of hard linked files */
       for (lp = ff_pkt->linklist; lp; lp = lp->next)
-         if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) {
+        if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) {
              /* If we have already backed up the hard linked file don't do it again */
-             if (strcmp(lp->name, fname) == 0) {
+            if (strcmp(lp->name, fname) == 0) {
                 Jmsg1(jcr, M_WARNING, 0, _("Attempt to backup hard linked file %s twice ignored.\n"),
-                   fname);
-                return 1;             /* ignore */
-             }
-             ff_pkt->link = lp->name;
-             ff_pkt->type = FT_LNKSAVED;       /* Handle link, file already saved */
-             ff_pkt->LinkFI = lp->FileIndex;
-             return handle_file(ff_pkt, pkt);
-         }
+                  fname);
+               return 1;             /* ignore */
+            }
+            ff_pkt->link = lp->name;
+            ff_pkt->type = FT_LNKSAVED;       /* Handle link, file already saved */
+            ff_pkt->LinkFI = lp->FileIndex;
+            return handle_file(ff_pkt, pkt);
+        }
 
       /* File not previously dumped. Chain it into our list. */
       lp = (struct f_link *)bmalloc(sizeof(struct f_link) + strlen(fname) +1);
@@ -152,7 +152,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       strcpy(lp->name, fname);
       lp->next = ff_pkt->linklist;
       ff_pkt->linklist = lp;
-      ff_pkt->linked = lp;            /* mark saved link */
+      ff_pkt->linked = lp;           /* mark saved link */
    } else {
       ff_pkt->linked = NULL;
    }
@@ -164,16 +164,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       sizeleft = ff_pkt->statp.st_size;
 
       /* Don't bother opening empty, world readable files.  Also do not open
-         files when archive is meant for /dev/null.  */
+        files when archive is meant for /dev/null.  */
       if (ff_pkt->null_output_device || (sizeleft == 0
-              && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) {
-         ff_pkt->type = FT_REGE;
+             && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) {
+        ff_pkt->type = FT_REGE;
       } else {
-         ff_pkt->type = FT_REG;
+        ff_pkt->type = FT_REG;
       }
       rtn_stat = handle_file(ff_pkt, pkt);
       if (ff_pkt->linked) {
-         ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+        ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
       }
       return rtn_stat;
 
@@ -184,21 +184,21 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
 
       size = readlink(fname, buffer, path_max + name_max + 101);
       if (size < 0) {
-         /* Could not follow link */                             
-         ff_pkt->type = FT_NOFOLLOW;
-         ff_pkt->ff_errno = errno;
-         rtn_stat = handle_file(ff_pkt, pkt);
-         if (ff_pkt->linked) {
-            ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-         }
-         return rtn_stat;
+        /* Could not follow link */                             
+        ff_pkt->type = FT_NOFOLLOW;
+        ff_pkt->ff_errno = errno;
+        rtn_stat = handle_file(ff_pkt, pkt);
+        if (ff_pkt->linked) {
+           ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+        }
+        return rtn_stat;
       }
       buffer[size] = 0;
-      ff_pkt->link = buffer;          /* point to link */
-      ff_pkt->type = FT_LNK;          /* got a real link */
+      ff_pkt->link = buffer;         /* point to link */
+      ff_pkt->type = FT_LNK;         /* got a real link */
       rtn_stat = handle_file(ff_pkt, pkt);
       if (ff_pkt->linked) {
-         ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+        ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
       }
       return rtn_stat;
 
@@ -207,7 +207,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       struct dirent *entry, *result;
       char *link;
       int link_len;
-      int len;   
+      int len;  
       int status;
       dev_t our_device = ff_pkt->statp.st_dev;
 
@@ -217,16 +217,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
        *  in principle, we should be able to access everything.
        */
       if (!have_win32_api() || (ff_pkt->flags & FO_PORTABLE)) {
-         if (access(fname, R_OK) == -1 && geteuid() != 0) {
-            /* Could not access() directory */
-            ff_pkt->type = FT_NOACCESS;
-            ff_pkt->ff_errno = errno;
-            rtn_stat = handle_file(ff_pkt, pkt);
-            if (ff_pkt->linked) {
-               ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-            }
-            return rtn_stat;
-         }
+        if (access(fname, R_OK) == -1 && geteuid() != 0) {
+           /* Could not access() directory */
+           ff_pkt->type = FT_NOACCESS;
+           ff_pkt->ff_errno = errno;
+           rtn_stat = handle_file(ff_pkt, pkt);
+           if (ff_pkt->linked) {
+              ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+           }
+           return rtn_stat;
+        }
       }
 
       /* Build a canonical directory name with a trailing slash in link var */
@@ -236,26 +236,26 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       bstrncpy(link, fname, link_len);
       /* Strip all trailing slashes */
       while (len >= 1 && link[len - 1] == '/')
-        len--;
+       len--;
       link[len++] = '/';             /* add back one */
       link[len] = 0;
 
       ff_pkt->link = link;
       if (ff_pkt->incremental &&
-          (ff_pkt->statp.st_mtime < ff_pkt->save_time &&
-           ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
-         /* Incremental option, directory entry not changed */
-         ff_pkt->type = FT_DIRNOCHG;
+         (ff_pkt->statp.st_mtime < ff_pkt->save_time &&
+          ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
+        /* Incremental option, directory entry not changed */
+        ff_pkt->type = FT_DIRNOCHG;
       } else {
-         ff_pkt->type = FT_DIRBEGIN;
+        ff_pkt->type = FT_DIRBEGIN;
       }
       /* Send off Directory packet now */
       if (!handle_file(ff_pkt, pkt)) {
-         free(link);
-         return 0;                    /* Do not save this directory */
+        free(link);
+        return 0;                    /* Do not save this directory */
       }
       if (ff_pkt->type == FT_DIRBEGIN) {
-         ff_pkt->type = FT_DIREND;
+        ff_pkt->type = FT_DIREND;
       }
 
       /*
@@ -276,7 +276,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       dir_ff_pkt->excluded_files_list = NULL;
       dir_ff_pkt->excluded_paths_list = NULL;
       dir_ff_pkt->linklist = NULL;
-        
+       
       ff_pkt->link = ff_pkt->fname;     /* reset "link" */
 
       /* 
@@ -284,15 +284,15 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
        * user has turned it off for this directory.
        */
       if (ff_pkt->flags & FO_NO_RECURSION) {
-         /* No recursion into this directory */
-         ff_pkt->type = FT_NORECURSE;
-         rtn_stat = handle_file(ff_pkt, pkt);
-         if (ff_pkt->linked) {
-            ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-         }
-         free(link);
-         free_dir_ff_pkt(dir_ff_pkt);
-         return rtn_stat;
+        /* No recursion into this directory */
+        ff_pkt->type = FT_NORECURSE;
+        rtn_stat = handle_file(ff_pkt, pkt);
+        if (ff_pkt->linked) {
+           ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+        }
+        free(link);
+        free_dir_ff_pkt(dir_ff_pkt);
+        return rtn_stat;
       }
 
       /* 
@@ -300,16 +300,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
        * avoid doing so if the user only wants to dump one file system.
        */
       if (!top_level && !(ff_pkt->flags & FO_MULTIFS) &&
-           parent_device != ff_pkt->statp.st_dev) {
-         /* returning here means we do not handle this directory */
-         ff_pkt->type = FT_NOFSCHG;
-         rtn_stat = handle_file(ff_pkt, pkt);
-         if (ff_pkt->linked) {
-            ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-         }
-         free(link);
-         free_dir_ff_pkt(dir_ff_pkt);
-         return rtn_stat;
+          parent_device != ff_pkt->statp.st_dev) {
+        /* returning here means we do not handle this directory */
+        ff_pkt->type = FT_NOFSCHG;
+        rtn_stat = handle_file(ff_pkt, pkt);
+        if (ff_pkt->linked) {
+           ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+        }
+        free(link);
+        free_dir_ff_pkt(dir_ff_pkt);
+        return rtn_stat;
       }
       /* 
        * Decend into or "recurse" into the directory to read
@@ -317,15 +317,15 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
        */
       errno = 0;
       if ((directory = opendir(fname)) == NULL) {
-         ff_pkt->type = FT_NOOPEN;
-         ff_pkt->ff_errno = errno;
-         rtn_stat = handle_file(ff_pkt, pkt);
-         if (ff_pkt->linked) {
-            ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-         }
-         free(link);
-         free_dir_ff_pkt(dir_ff_pkt);
-         return rtn_stat;
+        ff_pkt->type = FT_NOOPEN;
+        ff_pkt->ff_errno = errno;
+        rtn_stat = handle_file(ff_pkt, pkt);
+        if (ff_pkt->linked) {
+           ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+        }
+        free(link);
+        free_dir_ff_pkt(dir_ff_pkt);
+        return rtn_stat;
       }
 
       /*
@@ -336,38 +336,38 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       rtn_stat = 1;
       entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
       for ( ; !job_canceled(jcr); ) {
-         char *p, *q;
-         int i;
+        char *p, *q;
+        int i;
 
-         status  = readdir_r(directory, entry, &result);
-         if (status != 0 || result == NULL) {
+        status  = readdir_r(directory, entry, &result);
+        if (status != 0 || result == NULL) {
 //          Dmsg2(99, "readdir returned stat=%d result=0x%x\n",
-//             status, (long)result);
-            break;
-         }
-         ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
-         p = entry->d_name;
+//            status, (long)result);
+           break;
+        }
+        ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
+        p = entry->d_name;
          /* Skip `.', `..', and excluded file names.  */
          if (p[0] == '\0' || (p[0] == '.' && (p[1] == '\0' ||
              (p[1] == '.' && p[2] == '\0')))) {
-            continue;
-         }
-
-         if ((int)NAMELEN(entry) + len >= link_len) {
-             link_len = len + NAMELEN(entry) + 1;
-             link = (char *)brealloc(link, link_len + 1);
-         }
-         q = link + len;
-         for (i=0; i < (int)NAMELEN(entry); i++) {
-            *q++ = *p++;
-         }
-         *q = 0;
-         if (!file_is_excluded(ff_pkt, link)) {
-            rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0);
-            if (ff_pkt->linked) {
-               ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-            }
-         }
+           continue;
+        }
+
+        if ((int)NAMELEN(entry) + len >= link_len) {
+            link_len = len + NAMELEN(entry) + 1;
+            link = (char *)brealloc(link, link_len + 1);
+        }
+        q = link + len;
+        for (i=0; i < (int)NAMELEN(entry); i++) {
+           *q++ = *p++;
+        }
+        *q = 0;
+        if (!file_is_excluded(ff_pkt, link)) {
+           rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0);
+           if (ff_pkt->linked) {
+              ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+           }
+        }
       }
       closedir(directory);
       free(link);
@@ -380,14 +380,14 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
        *  the directory modes and dates.  Temp directory values
        *  were used without this record.
        */
-      handle_file(dir_ff_pkt, pkt);       /* handle directory entry */
+      handle_file(dir_ff_pkt, pkt);      /* handle directory entry */
       if (ff_pkt->linked) {
-         ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex;
+        ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex;
       }
       free_dir_ff_pkt(dir_ff_pkt);
 
       if (ff_pkt->flags & FO_KEEPATIME) {
-         utime(fname, &restore_times);
+        utime(fname, &restore_times);
       }
       return rtn_stat;
    } /* end check for directory */
@@ -400,8 +400,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
 #ifdef HAVE_FREEBSD_OS
    /*
     * On FreeBSD, all block devices are character devices, so
-    *   to be able to read a raw disk, we need the check for
-    *   a character device.
+    *  to be able to read a raw disk, we need the check for
+    *  a character device.
     * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/ad0s3
     * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/rad0s3
     */
@@ -409,9 +409,9 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
 #else
    if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) {
 #endif
-      ff_pkt->type = FT_RAW;          /* raw partition */
+      ff_pkt->type = FT_RAW;         /* raw partition */
    } else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) &&
-              ff_pkt->flags & FO_READFIFO) {
+             ff_pkt->flags & FO_READFIFO) {
       ff_pkt->type = FT_FIFO;
    } else {
       /* The only remaining types are special (character, ...) files */
@@ -434,8 +434,8 @@ int term_find_one(FF_PKT *ff)
       lc = lp;
       lp = lp->next;
       if (lc) {
-         free(lc);
-         count++;
+        free(lc);
+        count++;
       }
    }
    return count;
index 9581567144266c37673c5d6c045a17035afa0223..669ebbdddd712b19d04097d892cabe0d88968e95 100644 (file)
@@ -341,7 +341,7 @@ int file_is_excluded(FF_PKT *ff, char *file)
       /* Match from the beginning of a component only */
       if ((p == file || (*p != '/' && *(p-1) == '/'))
           && file_in_excluded_list(ff->excluded_files_list, p)) {
-        return 1;
+        return 1;   
       }
    }
    return 0;