Commit cbbbb15e authored by owsla's avatar owsla

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@851 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent ab284344
New in v1.1.15 (????/??/??) 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) Permit Unicode log messages. (Andrew Ferguson)
......
...@@ -33,7 +33,8 @@ import Globals, log, TempFile, selection, robust, SetConnections, \ ...@@ -33,7 +33,8 @@ import Globals, log, TempFile, selection, robust, SetConnections, \
class FSAbilities: class FSAbilities:
"""Store capabilities of given file system""" """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 case_sensitive = None # True if "foobar" and "FoObAr" are different files
ownership = None # True if chown works on this filesystem ownership = None # True if chown works on this filesystem
acls = None # True if access control lists supported acls = None # True if access control lists supported
...@@ -91,7 +92,9 @@ class FSAbilities: ...@@ -91,7 +92,9 @@ class FSAbilities:
self.dir_inc_perms), self.dir_inc_perms),
('High-bit permissions', self.high_perms), ('High-bit permissions', self.high_perms),
('Symlink permissions', self.symlink_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), add_boolean_list([('Access control lists', self.acls),
('Extended attributes', self.eas), ('Extended attributes', self.eas),
('Case sensitivity', self.case_sensitive), ('Case sensitivity', self.case_sensitive),
...@@ -141,6 +144,7 @@ class FSAbilities: ...@@ -141,6 +144,7 @@ class FSAbilities:
subdir.mkdir() subdir.mkdir()
self.set_extended_filenames(subdir) self.set_extended_filenames(subdir)
self.set_win_reserved_filenames(subdir)
self.set_case_sensitive_readwrite(subdir) self.set_case_sensitive_readwrite(subdir)
self.set_ownership(subdir) self.set_ownership(subdir)
self.set_hardlinks(subdir) self.set_hardlinks(subdir)
...@@ -208,7 +212,7 @@ class FSAbilities: ...@@ -208,7 +212,7 @@ class FSAbilities:
ord_rp.delete() ord_rp.delete()
# Try a UTF-8 encoded character # 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 ext_rp = None
try: try:
ext_rp = subdir.append(extended_filename) ext_rp = subdir.append(extended_filename)
...@@ -230,6 +234,28 @@ class FSAbilities: ...@@ -230,6 +234,28 @@ class FSAbilities:
else: else:
self.extended_filenames = 1 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): def set_acls(self, rp):
"""Set self.acls based on rp. Does not write. Needs to be local""" """Set self.acls based on rp. Does not write. Needs to be local"""
assert Globals.local_connection is rp.conn assert Globals.local_connection is rp.conn
...@@ -564,16 +590,21 @@ class BackupSetGlobals(SetGlobals): ...@@ -564,16 +590,21 @@ class BackupSetGlobals(SetGlobals):
def get_ctq_from_fsas(self): def get_ctq_from_fsas(self):
"""Determine chars_to_quote just from filesystems, no ctq file""" """Determine chars_to_quote just from filesystems, no ctq file"""
ctq = []
if self.src_fsa.case_sensitive and not self.dest_fsa.case_sensitive: 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: if self.dest_fsa.extended_filenames:
return "A-Z;" # Quote upper case and quoting char ctq.append('\000-\037') # Quote 0 - 31
# Quote the following 0 - 31, ", *, /, :, <, >, ?, \, |, ; # Quote ", *, /, :, <, >, ?, \, |, and 127 (DEL)
# Also quote uppercase A-Z ctq.append('\"*/:<>?\\\\|\177')
else: return 'A-Z\000-\037\"*/:<>?\\\\|\177;'
if ctq: ctq.append(';') # Quote quoting char if quoting anything
if self.dest_fsa.extended_filenames: return "".join(ctq)
return "" # Don't quote anything
else: return '\000-\037\"*/:<>?\\\\|\177;'
def compare_ctq_file(self, rbdir, suggested_ctq): def compare_ctq_file(self, rbdir, suggested_ctq):
"""Compare ctq file with suggested result, return actual ctq""" """Compare ctq file with suggested result, return actual ctq"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment