From 671c53e9534340ff10e61507d5e1ecbdbd440aa5 Mon Sep 17 00:00:00 2001 From: ben Date: Fri, 4 Oct 2002 00:02:23 +0000 Subject: Added --exclude-special-files and --{include|exclude}-globbing-filelist options to selection. git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@212 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109 --- rdiff-backup/rdiff_backup/Main.py | 35 ++++++++++++-------- rdiff-backup/rdiff_backup/selection.py | 59 ++++++++++++++++++++++++++++------ rdiff-backup/src/Main.py | 35 ++++++++++++-------- rdiff-backup/src/selection.py | 59 ++++++++++++++++++++++++++++------ 4 files changed, 144 insertions(+), 44 deletions(-) diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py index 60435be..5569bbe 100644 --- a/rdiff-backup/rdiff_backup/Main.py +++ b/rdiff-backup/rdiff_backup/Main.py @@ -43,16 +43,18 @@ def parse_cmdlineoptions(arglist): "change-source-perms", "chars-to-quote=", "checkpoint-interval=", "current-time=", "exclude=", "exclude-device-files", "exclude-filelist=", - "exclude-filelist-stdin", "exclude-mirror=", - "exclude-other-filesystems", "exclude-regexp=", "force", + "exclude-filelist-stdin", "exclude-globbing-filelist", + "exclude-mirror=", "exclude-other-filesystems", + "exclude-regexp=", "exclude-special-files", "force", "include=", "include-filelist=", "include-filelist-stdin", - "include-regexp=", "list-increments", "mirror-only", - "no-compression", "no-compression-regexp=", "no-hard-links", - "no-resume", "null-separator", "parsable-output", - "print-statistics", "quoting-char=", "remote-cmd=", - "remote-schema=", "remove-older-than=", "restore-as-of=", - "restrict=", "restrict-read-only=", "restrict-update-only=", - "resume", "resume-window=", "server", "sleep-ratio=", + "include-globbing-filelist", "include-regexp=", + "list-increments", "mirror-only", "no-compression", + "no-compression-regexp=", "no-hard-links", "no-resume", + "null-separator", "parsable-output", "print-statistics", + "quoting-char=", "remote-cmd=", "remote-schema=", + "remove-older-than=", "restore-as-of=", "restrict=", + "restrict-read-only=", "restrict-update-only=", "resume", + "resume-window=", "server", "sleep-ratio=", "ssh-no-compression", "terminal-verbosity=", "test-server", "verbosity=", "version", "windows-mode", "windows-time-format"]) @@ -79,11 +81,14 @@ def parse_cmdlineoptions(arglist): elif opt == "--exclude-filelist-stdin": select_opts.append(("--exclude-filelist", "standard input")) select_files.append(sys.stdin) + elif opt == "--exclude-globbing-filelist": + select_opts.append((opt, arg)) + select_files.append(sel_fl(arg)) elif opt == "--exclude-mirror": select_mirror_opts.append(("--exclude", arg)) - elif opt == "--exclude-other-filesystems": - select_opts.append((opt, arg)) - elif opt == "--exclude-regexp": select_opts.append((opt, arg)) + elif (opt == "--exclude-other-filesystems" or + opt == "--exclude-regexp" or + opt == "--exclude-special-files"): select_opts.append((opt, arg)) elif opt == "--force": force = 1 elif opt == "--include": select_opts.append((opt, arg)) elif opt == "--include-filelist": @@ -92,6 +97,9 @@ def parse_cmdlineoptions(arglist): elif opt == "--include-filelist-stdin": select_opts.append(("--include-filelist", "standard input")) select_files.append(sys.stdin) + elif opt == "--include-globbing-filelist": + select_opts.append((opt, arg)) + select_files.append(sel_fl(arg)) elif opt == "--include-regexp": select_opts.append((opt, arg)) elif opt == "-l" or opt == "--list-increments": action = "list-increments" @@ -140,8 +148,9 @@ def parse_cmdlineoptions(arglist): elif opt == "-v" or opt == "--verbosity": Log.setverbosity(arg) elif opt == "--windows-mode": Globals.set('time_separator', "_") - Globals.set('chars_to_quote', ":") + Globals.set('chars_to_quote', "A-Z:") Globals.set('quoting_enabled', 1) + select_opts.append(("--exclude-special-files", None)) elif opt == '--windows-time-format': Globals.set('time_separator', "_") else: Log.FatalError("Unknown option %s" % opt) diff --git a/rdiff-backup/rdiff_backup/selection.py b/rdiff-backup/rdiff_backup/selection.py index 20a7fa3..6305b02 100644 --- a/rdiff-backup/rdiff_backup/selection.py +++ b/rdiff-backup/rdiff_backup/selection.py @@ -252,21 +252,33 @@ class Select: if opt == "--exclude": self.add_selection_func(self.glob_get_sf(arg, 0)) elif opt == "--exclude-device-files": - self.add_selection_func(self.devfiles_get_sf()) + self.add_selection_func(self.devfiles_get_sf(0)) elif opt == "--exclude-filelist": self.add_selection_func(self.filelist_get_sf( filelists[filelists_index], 0, arg)) filelists_index += 1 + elif opt == "--exclude-globbing-filelist": + map(self.add_selection_func, + self.filelist_globbing_get_sfs( + filelists[filelists_index], 0, arg)) + filelists_index += 1 elif opt == "--exclude-other-filesystems": self.add_selection_func(self.other_filesystems_get_sf(0)) elif opt == "--exclude-regexp": self.add_selection_func(self.regexp_get_sf(arg, 0)) + elif opt == "--exclude-special-files": + self.add_selection_func(self.special_get_sf(0)) elif opt == "--include": self.add_selection_func(self.glob_get_sf(arg, 1)) elif opt == "--include-filelist": self.add_selection_func(self.filelist_get_sf( filelists[filelists_index], 1, arg)) filelists_index += 1 + elif opt == "--include-globbing-filelist": + map(self.add_selection_func, + self.filelist_globbing_get_sfs( + filelists[filelists_index], 1, arg)) + filelists_index += 1 elif opt == "--include-regexp": self.add_selection_func(self.regexp_get_sf(arg, 1)) else: assert 0, "Bad selection option %s" % opt @@ -281,9 +293,9 @@ class Select: if isinstance(exc, FilePrefixError): Log.FatalError( """Fatal Error: The file specification - %s +' %s' cannot match any files in the base directory - %s +' %s' Useful file specifications begin with the base directory or some pattern (such as '**') which matches the base directory.""" % (exc, self.prefix)) @@ -381,7 +393,6 @@ probably isn't what you meant.""" % prefix is the string that the index is relative to. """ - line = line.strip() if line[:2] == "+ ": # Check for "+ "/"- " syntax include = 1 line = line[2:] @@ -419,6 +430,23 @@ probably isn't what you meant.""" % else: return (None, None) # dsrp greater, not initial sequence else: assert 0, "Include is %s, should be 0 or 1" % (include,) + def filelist_globbing_get_sfs(self, filelist_fp, inc_default, list_name): + """Return list of selection functions by reading fileobj + + filelist_fp should be an open file object + inc_default is true iff this is an include list + list_name is just the name of the list, used for logging + See the man page on --[include/exclude]-globbing-filelist + + """ + Log("Reading globbing filelist %s" % list_name, 4) + separator = Globals.null_separator and "\0" or "\n" + for line in filelist_fp.read().split(separator): + if not line: continue # skip blanks + if line[:2] == "+ ": yield self.glob_get_sf(line[2:], 1) + elif line[:2] == "- ": yield self.glob_get_sf(line[2:], 0) + else: yield self.glob_get_sf(line, inc_default) + def other_filesystems_get_sf(self, include): """Return selection function matching files on other filesystems""" assert include == 0 or include == 1 @@ -446,16 +474,29 @@ probably isn't what you meant.""" % sel_func.name = "Regular expression: %s" % regexp_string return sel_func - def devfiles_get_sf(self): - """Return a selection function to exclude all dev files""" + def devfiles_get_sf(self, include): + """Return a selection function matching all dev files""" if self.selection_functions: Log("Warning: exclude-device-files is not the first " "selector.\nThis may not be what you intended", 3) def sel_func(dsrp): - if dsrp.isdev(): return 0 + if dsrp.isdev(): return include + else: return None + sel_func.exclude = not include + sel_func.name = (include and "include" or "exclude") + " device files" + return sel_func + + def special_get_sf(self, include): + """Return sel function matching sockets, symlinks, sockets, devs""" + if self.selection_functions: + Log("Warning: exclude-special-files is not the first " + "selector.\nThis may not be what you intended", 3) + def sel_func(dsrp): + if dsrp.issym() or dsrp.issock() or dsrp.isfifo() or dsrp.isdev(): + return include else: return None - sel_func.exclude = 1 - sel_func.name = "Exclude device files" + sel_func.exclude = not include + sel_func.name = (include and "include" or "exclude") + " special files" return sel_func def glob_get_sf(self, glob_str, include): diff --git a/rdiff-backup/src/Main.py b/rdiff-backup/src/Main.py index 60435be..5569bbe 100644 --- a/rdiff-backup/src/Main.py +++ b/rdiff-backup/src/Main.py @@ -43,16 +43,18 @@ def parse_cmdlineoptions(arglist): "change-source-perms", "chars-to-quote=", "checkpoint-interval=", "current-time=", "exclude=", "exclude-device-files", "exclude-filelist=", - "exclude-filelist-stdin", "exclude-mirror=", - "exclude-other-filesystems", "exclude-regexp=", "force", + "exclude-filelist-stdin", "exclude-globbing-filelist", + "exclude-mirror=", "exclude-other-filesystems", + "exclude-regexp=", "exclude-special-files", "force", "include=", "include-filelist=", "include-filelist-stdin", - "include-regexp=", "list-increments", "mirror-only", - "no-compression", "no-compression-regexp=", "no-hard-links", - "no-resume", "null-separator", "parsable-output", - "print-statistics", "quoting-char=", "remote-cmd=", - "remote-schema=", "remove-older-than=", "restore-as-of=", - "restrict=", "restrict-read-only=", "restrict-update-only=", - "resume", "resume-window=", "server", "sleep-ratio=", + "include-globbing-filelist", "include-regexp=", + "list-increments", "mirror-only", "no-compression", + "no-compression-regexp=", "no-hard-links", "no-resume", + "null-separator", "parsable-output", "print-statistics", + "quoting-char=", "remote-cmd=", "remote-schema=", + "remove-older-than=", "restore-as-of=", "restrict=", + "restrict-read-only=", "restrict-update-only=", "resume", + "resume-window=", "server", "sleep-ratio=", "ssh-no-compression", "terminal-verbosity=", "test-server", "verbosity=", "version", "windows-mode", "windows-time-format"]) @@ -79,11 +81,14 @@ def parse_cmdlineoptions(arglist): elif opt == "--exclude-filelist-stdin": select_opts.append(("--exclude-filelist", "standard input")) select_files.append(sys.stdin) + elif opt == "--exclude-globbing-filelist": + select_opts.append((opt, arg)) + select_files.append(sel_fl(arg)) elif opt == "--exclude-mirror": select_mirror_opts.append(("--exclude", arg)) - elif opt == "--exclude-other-filesystems": - select_opts.append((opt, arg)) - elif opt == "--exclude-regexp": select_opts.append((opt, arg)) + elif (opt == "--exclude-other-filesystems" or + opt == "--exclude-regexp" or + opt == "--exclude-special-files"): select_opts.append((opt, arg)) elif opt == "--force": force = 1 elif opt == "--include": select_opts.append((opt, arg)) elif opt == "--include-filelist": @@ -92,6 +97,9 @@ def parse_cmdlineoptions(arglist): elif opt == "--include-filelist-stdin": select_opts.append(("--include-filelist", "standard input")) select_files.append(sys.stdin) + elif opt == "--include-globbing-filelist": + select_opts.append((opt, arg)) + select_files.append(sel_fl(arg)) elif opt == "--include-regexp": select_opts.append((opt, arg)) elif opt == "-l" or opt == "--list-increments": action = "list-increments" @@ -140,8 +148,9 @@ def parse_cmdlineoptions(arglist): elif opt == "-v" or opt == "--verbosity": Log.setverbosity(arg) elif opt == "--windows-mode": Globals.set('time_separator', "_") - Globals.set('chars_to_quote', ":") + Globals.set('chars_to_quote', "A-Z:") Globals.set('quoting_enabled', 1) + select_opts.append(("--exclude-special-files", None)) elif opt == '--windows-time-format': Globals.set('time_separator', "_") else: Log.FatalError("Unknown option %s" % opt) diff --git a/rdiff-backup/src/selection.py b/rdiff-backup/src/selection.py index 20a7fa3..6305b02 100644 --- a/rdiff-backup/src/selection.py +++ b/rdiff-backup/src/selection.py @@ -252,21 +252,33 @@ class Select: if opt == "--exclude": self.add_selection_func(self.glob_get_sf(arg, 0)) elif opt == "--exclude-device-files": - self.add_selection_func(self.devfiles_get_sf()) + self.add_selection_func(self.devfiles_get_sf(0)) elif opt == "--exclude-filelist": self.add_selection_func(self.filelist_get_sf( filelists[filelists_index], 0, arg)) filelists_index += 1 + elif opt == "--exclude-globbing-filelist": + map(self.add_selection_func, + self.filelist_globbing_get_sfs( + filelists[filelists_index], 0, arg)) + filelists_index += 1 elif opt == "--exclude-other-filesystems": self.add_selection_func(self.other_filesystems_get_sf(0)) elif opt == "--exclude-regexp": self.add_selection_func(self.regexp_get_sf(arg, 0)) + elif opt == "--exclude-special-files": + self.add_selection_func(self.special_get_sf(0)) elif opt == "--include": self.add_selection_func(self.glob_get_sf(arg, 1)) elif opt == "--include-filelist": self.add_selection_func(self.filelist_get_sf( filelists[filelists_index], 1, arg)) filelists_index += 1 + elif opt == "--include-globbing-filelist": + map(self.add_selection_func, + self.filelist_globbing_get_sfs( + filelists[filelists_index], 1, arg)) + filelists_index += 1 elif opt == "--include-regexp": self.add_selection_func(self.regexp_get_sf(arg, 1)) else: assert 0, "Bad selection option %s" % opt @@ -281,9 +293,9 @@ class Select: if isinstance(exc, FilePrefixError): Log.FatalError( """Fatal Error: The file specification - %s +' %s' cannot match any files in the base directory - %s +' %s' Useful file specifications begin with the base directory or some pattern (such as '**') which matches the base directory.""" % (exc, self.prefix)) @@ -381,7 +393,6 @@ probably isn't what you meant.""" % prefix is the string that the index is relative to. """ - line = line.strip() if line[:2] == "+ ": # Check for "+ "/"- " syntax include = 1 line = line[2:] @@ -419,6 +430,23 @@ probably isn't what you meant.""" % else: return (None, None) # dsrp greater, not initial sequence else: assert 0, "Include is %s, should be 0 or 1" % (include,) + def filelist_globbing_get_sfs(self, filelist_fp, inc_default, list_name): + """Return list of selection functions by reading fileobj + + filelist_fp should be an open file object + inc_default is true iff this is an include list + list_name is just the name of the list, used for logging + See the man page on --[include/exclude]-globbing-filelist + + """ + Log("Reading globbing filelist %s" % list_name, 4) + separator = Globals.null_separator and "\0" or "\n" + for line in filelist_fp.read().split(separator): + if not line: continue # skip blanks + if line[:2] == "+ ": yield self.glob_get_sf(line[2:], 1) + elif line[:2] == "- ": yield self.glob_get_sf(line[2:], 0) + else: yield self.glob_get_sf(line, inc_default) + def other_filesystems_get_sf(self, include): """Return selection function matching files on other filesystems""" assert include == 0 or include == 1 @@ -446,16 +474,29 @@ probably isn't what you meant.""" % sel_func.name = "Regular expression: %s" % regexp_string return sel_func - def devfiles_get_sf(self): - """Return a selection function to exclude all dev files""" + def devfiles_get_sf(self, include): + """Return a selection function matching all dev files""" if self.selection_functions: Log("Warning: exclude-device-files is not the first " "selector.\nThis may not be what you intended", 3) def sel_func(dsrp): - if dsrp.isdev(): return 0 + if dsrp.isdev(): return include + else: return None + sel_func.exclude = not include + sel_func.name = (include and "include" or "exclude") + " device files" + return sel_func + + def special_get_sf(self, include): + """Return sel function matching sockets, symlinks, sockets, devs""" + if self.selection_functions: + Log("Warning: exclude-special-files is not the first " + "selector.\nThis may not be what you intended", 3) + def sel_func(dsrp): + if dsrp.issym() or dsrp.issock() or dsrp.isfifo() or dsrp.isdev(): + return include else: return None - sel_func.exclude = 1 - sel_func.name = "Exclude device files" + sel_func.exclude = not include + sel_func.name = (include and "include" or "exclude") + " special files" return sel_func def glob_get_sf(self, glob_str, include): -- cgit v1.2.1