Commit 5fbe5839 authored by owsla's avatar owsla

Escape trailing spaces and periods on systems which require it


git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup@961 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent 01a7f5ae
New in v1.2.3 (????/??/??)
---------------------------
Escape trailing spaces and periods on systems which require it, such as
Windows and modern Linux with FAT32. (Andrew Ferguson)
Print nicer error messages in rdiff-backup-statistics (without tracebacks).
Closes Ubuntu bug #292586. (Andrew Ferguson)
......
......@@ -85,6 +85,19 @@ def quote(path):
"""
QuotedPath = chars_to_quote_regexp.sub(quote_single, path)
if not Globals.must_escape_dos_devices \
and not Globals.must_escape_trailing_spaces:
return QuotedPath
if Globals.must_escape_dos_devices:
assert Globals.must_escape_trailing_spaces
# Escape a trailing space or period (invalid in names on FAT32 under DOS,
# Windows and modern Linux)
if len(QuotedPath) and (QuotedPath[-1] == ' ' or QuotedPath[-1] == '.'):
QuotedPath = QuotedPath[:-1] + \
"%s%03d" % (quoting_char, ord(QuotedPath[-1]))
if not Globals.must_escape_dos_devices:
return QuotedPath
......
......@@ -50,6 +50,8 @@ class FSAbilities:
high_perms = None # True if suid etc perms are (read/write) supported
escape_dos_devices = None # True if dos device files can't be created (e.g.,
# aux, con, com1, etc)
escape_trailing_spaces = None # True if files with trailing spaces or
# periods can't be created
symlink_perms = None # True if symlink perms are affected by umask
def __init__(self, name = None):
......@@ -101,6 +103,8 @@ class FSAbilities:
('Windows access control lists', self.win_acls),
('Case sensitivity', self.case_sensitive),
('Escape DOS devices', self.escape_dos_devices),
('Escape trailing spaces',
self.escape_trailing_spaces)
('Mac OS X style resource forks',
self.resource_forks),
('Mac OS X Finder information', self.carbonfile)])
......@@ -127,6 +131,7 @@ class FSAbilities:
self.set_carbonfile()
self.set_case_sensitive_readonly(rp)
self.set_escape_dos_devices(rp)
self.set_escape_trailing_spaces(rp)
return self
def init_readwrite(self, rbdir):
......@@ -161,6 +166,7 @@ class FSAbilities:
self.set_high_perms_readwrite(subdir)
self.set_symlink_perms(subdir)
self.set_escape_dos_devices(subdir)
self.set_escape_trailing_spaces(subdir)
subdir.delete()
return self
......@@ -550,7 +556,7 @@ class FSAbilities:
sym_source.delete()
def set_escape_dos_devices(self, subdir):
"""If special file aux can be stat'd, escape special files"""
"""If special file con can be stat'd, escape special files"""
try:
device_rp = subdir.append("con")
if device_rp.lstat():
......@@ -566,6 +572,25 @@ class FSAbilities:
% (subdir.path), 4)
self.escape_dos_devices = 1
def set_escape_trailing_spaces(self, subdir):
"""If file with trailing space can't be created, escape such files"""
try:
space_rp = subdir.append("test ")
if space_rp.touch() and space_rp.lstat():
log.Log("escape_trailing_spaces not required by filesystem " \
"at %s" % (subdir.path), 4)
self.escape_trailing_spaces = 0
space_rp.delete()
else:
log.Log("escape_trailing_spaces required by filesystem at %s" \
% (subdir.path), 4)
self.escape_trailing_spaces = 1
except(OSError):
log.Log("escape_trailing_spaces required by filesystem at %s" \
% (subdir.path), 4)
self.escape_trailing_spaces = 1
def get_readonly_fsa(desc_string, rp):
"""Return an fsa with given description_string
......@@ -641,6 +666,10 @@ class SetGlobals:
SetConnections.UpdateGlobal('escape_dos_devices', \
self.dest_fsa.escape_dos_devices)
def set_escape_trailing_spaces(self):
SetConnections.UpdateGlobal('escape_trailing_spaces', \
self.dest_fsa.escape_trailing_spaces)
class BackupSetGlobals(SetGlobals):
"""Functions for setting fsa related globals for backup session"""
def update_triple(self, src_support, dest_support, attr_triple):
......@@ -667,6 +696,21 @@ class BackupSetGlobals(SetGlobals):
log.Log("Backup: must_escape_dos_devices = %d" % \
(self.src_fsa.escape_dos_devices or local_edd), 4)
def set_must_escape_trailing_spaces(self, rbdir):
"""If local ets or src ets, then must escape """
try:
space_rp = rbdir.append("test ")
if space_rp.touch() and space_rp.lstat():
local_ets = 0
space_rp.delete()
else:
local_ets = 1
except (OSError): local_ets = 1
SetConnections.UpdateGlobal('must_escape_trailing_spaces', \
self.src_fsa.escape_trailing_spaces or local_ets)
log.Log("Backup: must_escape_trailing_spaces = %d" % \
(self.src_fsa.escape_trailing_spaces or local_ets), 4)
def set_chars_to_quote(self, rbdir, force):
"""Set chars_to_quote setting for backup session
......@@ -779,6 +823,25 @@ class RestoreSetGlobals(SetGlobals):
log.Log("Restore: must_escape_dos_devices = %d" % \
(src_edd or local_edd), 4)
def set_must_escape_trailing_spaces(self, rbdir):
"""If local ets or src ets, then must escape """
if getattr(self, "src_fsa", None) is not None:
src_ets = self.src_fsa.escape_trailing_spaces
else:
src_ets = 0
try:
space_rp = rbdir.append("test ")
if space_rp.touch() and space_rp.lstat():
local_ets = 0
space_rp.delete()
else:
local_ets = 1
except (OSError): local_ets = 1
SetConnections.UpdateGlobal('must_escape_trailing_spaces', \
src_ets or local_ets)
log.Log("Restore: must_escape_trailing_spaces = %d" % \
(src_ets or local_ets), 4)
def set_chars_to_quote(self, rbdir):
"""Set chars_to_quote from rdiff-backup-data dir"""
if Globals.chars_to_quote is not None: return # already overridden
......@@ -853,7 +916,9 @@ def backup_set_globals(rpin, force):
bsg.set_symlink_perms()
update_quoting = bsg.set_chars_to_quote(Globals.rbdir, force)
bsg.set_escape_dos_devices()
bsg.set_escape_trailing_spaces()
bsg.set_must_escape_dos_devices(Globals.rbdir)
bsg.set_must_escape_trailing_spaces(Globals.rbdir)
if update_quoting and force:
FilenameMapping.update_quoting(Globals.rbdir)
......@@ -881,7 +946,9 @@ def restore_set_globals(rpout):
rsg.set_symlink_perms()
rsg.set_chars_to_quote(Globals.rbdir)
rsg.set_escape_dos_devices()
rsg.set_escape_trailing_spaces()
rsg.set_must_escape_dos_devices(Globals.rbdir)
rsg.set_must_escape_trailing_spaces(Globals.rbdir)
def single_set_globals(rp, read_only = None):
"""Set fsa related globals for operation on single filesystem"""
......@@ -902,5 +969,7 @@ def single_set_globals(rp, read_only = None):
ssg.set_symlink_perms()
ssg.set_chars_to_quote(Globals.rbdir)
ssg.set_escape_dos_devices()
ssg.set_escape_trailing_spaces()
ssg.set_must_escape_dos_devices(Globals.rbdir)
ssg.set_must_escape_trailing_spaces(Globals.rbdir)
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