From cc13a22e73ca732cc0be2f268812ee30ad629932 Mon Sep 17 00:00:00 2001 From: owsla Date: Tue, 14 Aug 2007 19:47:48 +0000 Subject: New quoting logic to check for non-ASCII chars and Windows special chars independently. git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@851 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109 --- rdiff-backup/CHANGELOG | 3 ++ rdiff-backup/rdiff_backup/fs_abilities.py | 53 ++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG index 4f38864..049cb02 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -1,6 +1,9 @@ New in v1.1.15 (????/??/??) --------------------------- +Rewrite quoting logic to independently check for escaping Windows special +characters, non-ASCII chars, and uppercase chars. (Andrew Ferguson) + Permit Unicode log messages. (Andrew Ferguson) diff --git a/rdiff-backup/rdiff_backup/fs_abilities.py b/rdiff-backup/rdiff_backup/fs_abilities.py index 25871bf..b2c921b 100644 --- a/rdiff-backup/rdiff_backup/fs_abilities.py +++ b/rdiff-backup/rdiff_backup/fs_abilities.py @@ -33,7 +33,8 @@ import Globals, log, TempFile, selection, robust, SetConnections, \ class FSAbilities: """Store capabilities of given file system""" - extended_filenames = None # True if filenames can handle ":" etc. + extended_filenames = None # True if filenames can have non-ASCII chars + win_reserved_filenames = None # True if filenames can't have ",*,: etc. case_sensitive = None # True if "foobar" and "FoObAr" are different files ownership = None # True if chown works on this filesystem acls = None # True if access control lists supported @@ -91,7 +92,9 @@ class FSAbilities: self.dir_inc_perms), ('High-bit permissions', self.high_perms), ('Symlink permissions', self.symlink_perms), - ('Extended filenames', self.extended_filenames)]) + ('Extended filenames', self.extended_filenames), + ('Windows reserved filenames', + self.win_reserved_filenames)]) add_boolean_list([('Access control lists', self.acls), ('Extended attributes', self.eas), ('Case sensitivity', self.case_sensitive), @@ -141,6 +144,7 @@ class FSAbilities: subdir.mkdir() self.set_extended_filenames(subdir) + self.set_win_reserved_filenames(subdir) self.set_case_sensitive_readwrite(subdir) self.set_ownership(subdir) self.set_hardlinks(subdir) @@ -208,7 +212,7 @@ class FSAbilities: ord_rp.delete() # Try a UTF-8 encoded character - extended_filename = ':\\ ' + chr(225) + chr(132) + chr(137) + extended_filename = 'uni' + chr(225) + chr(132) + chr(137) ext_rp = None try: ext_rp = subdir.append(extended_filename) @@ -230,6 +234,28 @@ class FSAbilities: else: self.extended_filenames = 1 + def set_win_reserved_filenames(self, subdir): + """Set self.win_reserved_filenames by trying to write a path""" + assert not self.read_only + + # Try Windows reserved characters + win_reserved_filename = ':\\"' + win_rp = None + try: + win_rp = subdir.append(win_reserved_filename) + win_rp.touch() + except (IOError, OSError): + if win_rp: assert not win_rp.lstat() + self.win_reserved_filenames = 1 + else: + assert win_rp.lstat() + try: + win_rp.delete() + except (IOError, OSError): + self.win_reserved_filenames = 1 + else: + self.win_reserved_filenames = 0 + def set_acls(self, rp): """Set self.acls based on rp. Does not write. Needs to be local""" assert Globals.local_connection is rp.conn @@ -564,16 +590,21 @@ class BackupSetGlobals(SetGlobals): def get_ctq_from_fsas(self): """Determine chars_to_quote just from filesystems, no ctq file""" + ctq = [] + if self.src_fsa.case_sensitive and not self.dest_fsa.case_sensitive: + ctq.append("A-Z") # Quote upper case + if not self.dest_fsa.extended_filenames: + ctq.append('\000-\037') # Quote 0 - 31 + ctq.append('\200-\377') # Quote non-ASCII characters 0x80 - 0xFF + if self.dest_fsa.win_reserved_filenames: if self.dest_fsa.extended_filenames: - return "A-Z;" # Quote upper case and quoting char - # Quote the following 0 - 31, ", *, /, :, <, >, ?, \, |, ; - # Also quote uppercase A-Z - else: return 'A-Z\000-\037\"*/:<>?\\\\|\177;' - - if self.dest_fsa.extended_filenames: - return "" # Don't quote anything - else: return '\000-\037\"*/:<>?\\\\|\177;' + ctq.append('\000-\037') # Quote 0 - 31 + # Quote ", *, /, :, <, >, ?, \, |, and 127 (DEL) + ctq.append('\"*/:<>?\\\\|\177') + + if ctq: ctq.append(';') # Quote quoting char if quoting anything + return "".join(ctq) def compare_ctq_file(self, rbdir, suggested_ctq): """Compare ctq file with suggested result, return actual ctq""" -- cgit v1.2.1