Commit dc0f49a4 authored by bescoto's avatar bescoto

Fixed various --restrict options, some refactoring


git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup@407 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent 5e19836b
...@@ -16,6 +16,9 @@ Fixed bug in EA/ACL restoring, noticed by Greg Freemyer. Also updated ...@@ -16,6 +16,9 @@ Fixed bug in EA/ACL restoring, noticed by Greg Freemyer. Also updated
quoting of filenames and extended attributes names to match quoting of filenames and extended attributes names to match
forthcoming attr/facl utilities. forthcoming attr/facl utilities.
Fixed problems with --restrict options that would cause proper
sessions to fail. Thanks to Randall Nortman for error report.
New in v0.13.1 (2003/08/08) New in v0.13.1 (2003/08/08)
--------------------------- ---------------------------
......
...@@ -230,14 +230,13 @@ def Main(arglist): ...@@ -230,14 +230,13 @@ def Main(arglist):
def Backup(rpin, rpout): def Backup(rpin, rpout):
"""Backup, possibly incrementally, src_path to dest_path.""" """Backup, possibly incrementally, src_path to dest_path."""
global incdir
SetConnections.BackupInitConnections(rpin.conn, rpout.conn) SetConnections.BackupInitConnections(rpin.conn, rpout.conn)
backup_check_dirs(rpin, rpout) backup_check_dirs(rpin, rpout)
backup_set_fs_globals(rpin, rpout)
if Globals.chars_to_quote:
rpout = FilenameMapping.get_quotedrpath(rpout)
SetConnections.UpdateGlobal(
'rbdir', FilenameMapping.get_quotedrpath(Globals.rbdir))
backup_set_rbdir(rpin, rpout) backup_set_rbdir(rpin, rpout)
backup_set_fs_globals(rpin, rpout)
if Globals.chars_to_quote: rpout = backup_quoted_rpaths(rpout)
backup_final_init(rpout)
backup_set_select(rpin) backup_set_select(rpin)
if prevtime: if prevtime:
rpout.conn.Main.backup_touch_curmirror_local(rpin, rpout) rpout.conn.Main.backup_touch_curmirror_local(rpin, rpout)
...@@ -248,6 +247,14 @@ def Backup(rpin, rpout): ...@@ -248,6 +247,14 @@ def Backup(rpin, rpout):
backup.Mirror(rpin, rpout) backup.Mirror(rpin, rpout)
rpout.conn.Main.backup_touch_curmirror_local(rpin, rpout) rpout.conn.Main.backup_touch_curmirror_local(rpin, rpout)
def backup_quoted_rpaths(rpout):
"""Get QuotedRPath versions of important RPaths. Return rpout"""
global incdir
SetConnections.UpdateGlobal(
'rbdir', FilenameMapping.get_quotedrpath(Globals.rbdir))
incdir = FilenameMapping.get_quotedrpath(incdir)
return FilenameMapping.get_quotedrpath(rpout)
def backup_set_select(rpin): def backup_set_select(rpin):
"""Create Select objects on source connection""" """Create Select objects on source connection"""
rpin.conn.backup.SourceStruct.set_source_select(rpin, select_opts, rpin.conn.backup.SourceStruct.set_source_select(rpin, select_opts,
...@@ -275,11 +282,9 @@ def backup_check_dirs(rpin, rpout): ...@@ -275,11 +282,9 @@ def backup_check_dirs(rpin, rpout):
def backup_set_rbdir(rpin, rpout): def backup_set_rbdir(rpin, rpout):
"""Initialize data dir and logging""" """Initialize data dir and logging"""
global incdir, prevtime global incdir
SetConnections.UpdateGlobal('rbdir', Globals.rbdir) SetConnections.UpdateGlobal('rbdir', Globals.rbdir)
checkdest_if_necessary(rpout)
incdir = Globals.rbdir.append_path("increments") incdir = Globals.rbdir.append_path("increments")
prevtime = backup_get_mirrortime()
assert rpout.lstat(), (rpout.path, rpout.lstat()) assert rpout.lstat(), (rpout.path, rpout.lstat())
if rpout.isdir() and not rpout.listdir(): # rpout is empty dir if rpout.isdir() and not rpout.listdir(): # rpout is empty dir
...@@ -296,11 +301,6 @@ want to update or overwrite it, run rdiff-backup with the --force ...@@ -296,11 +301,6 @@ want to update or overwrite it, run rdiff-backup with the --force
option.""" % rpout.path) option.""" % rpout.path)
if not Globals.rbdir.lstat(): Globals.rbdir.mkdir() if not Globals.rbdir.lstat(): Globals.rbdir.mkdir()
inc_base = Globals.rbdir.append_path("increments")
if not inc_base.lstat(): inc_base.mkdir()
if Log.verbosity > 0:
Log.open_logfile(Globals.rbdir.append("backup.log"))
ErrorLog.open(Time.curtimestr, compress = Globals.compression)
def backup_warn_if_infinite_regress(rpin, rpout): def backup_warn_if_infinite_regress(rpin, rpout):
"""Warn user if destination area contained in source area""" """Warn user if destination area contained in source area"""
...@@ -325,6 +325,21 @@ def backup_get_mirrortime(): ...@@ -325,6 +325,21 @@ def backup_get_mirrortime():
if mirror_rps: return mirror_rps[0].getinctime() if mirror_rps: return mirror_rps[0].getinctime()
else: return None else: return None
def backup_final_init(rpout):
"""Open the backup log and the error log, create increments dir"""
global prevtime
prevtime = backup_get_mirrortime()
need_check = checkdest_need_check(rpout)
if Log.verbosity > 0:
Log.open_logfile(Globals.rbdir.append("backup.log"))
ErrorLog.open(Time.curtimestr, compress = Globals.compression)
if need_check:
Log("Previous backup seems to have failed, regressing "
"destination now.", 2)
rpout.conn.regress.Regress(rpout)
inc_base = Globals.rbdir.append_path("increments")
if not inc_base.lstat(): inc_base.mkdir()
def backup_set_fs_globals(rpin, rpout): def backup_set_fs_globals(rpin, rpout):
"""Use fs_abilities to set the globals that depend on filesystem""" """Use fs_abilities to set the globals that depend on filesystem"""
def update_bool_global(attr, bool): def update_bool_global(attr, bool):
...@@ -332,10 +347,10 @@ def backup_set_fs_globals(rpin, rpout): ...@@ -332,10 +347,10 @@ def backup_set_fs_globals(rpin, rpout):
if Globals.get(attr) is None: if Globals.get(attr) is None:
SetConnections.UpdateGlobal(attr, bool) SetConnections.UpdateGlobal(attr, bool)
src_fsa = fs_abilities.FSAbilities('source').init_readonly(rpin) src_fsa = rpin.conn.fs_abilities.get_fsabilities_readonly('source', rpin)
Log(str(src_fsa), 3) Log(str(src_fsa), 3)
dest_fsa = fs_abilities.FSAbilities('destination').init_readwrite( dest_fsa = rpout.conn.fs_abilities.get_fsabilities_readwrite(
Globals.rbdir, override_chars_to_quote = Globals.chars_to_quote) 'destination', Globals.rbdir, 1, Globals.chars_to_quote)
Log(str(dest_fsa), 3) Log(str(dest_fsa), 3)
update_bool_global('read_acls', src_fsa.acls) update_bool_global('read_acls', src_fsa.acls)
...@@ -425,10 +440,10 @@ def restore_set_fs_globals(target): ...@@ -425,10 +440,10 @@ def restore_set_fs_globals(target):
"""If bool is not None, update Globals.attr accordingly""" """If bool is not None, update Globals.attr accordingly"""
if Globals.get(attr) is None: SetConnections.UpdateGlobal(attr, bool) if Globals.get(attr) is None: SetConnections.UpdateGlobal(attr, bool)
target_fsa = fs_abilities.FSAbilities('destination').init_readwrite( target_fsa = target.conn.fs_abilities.get_fsabilities_readwrite(
target, 0) 'destination', target, 0)
Log(str(target_fsa), 3) Log(str(target_fsa), 3)
mirror_fsa = fs_abilities.FSAbilities('source').init_readwrite( mirror_fsa = Globals.rbdir.conn.fs_abilities.get_fsabilities_restoresource(
Globals.rbdir) Globals.rbdir)
Log(str(mirror_fsa), 3) Log(str(mirror_fsa), 3)
...@@ -462,7 +477,8 @@ def restore_set_select(mirror_rp, target): ...@@ -462,7 +477,8 @@ def restore_set_select(mirror_rp, target):
def restore_start_log(rpin, target, time): def restore_start_log(rpin, target, time):
"""Open restore log file, log initial message""" """Open restore log file, log initial message"""
try: Log.open_logfile(Globals.rbdir.append("restore.log")) try: Log.open_logfile(Globals.rbdir.append("restore.log"))
except LoggerError, e: Log("Warning, " + str(e), 2) except (LoggerError, Security.Violation), e:
Log("Warning - Unable to open logfile: " + str(e), 2)
# Log following message at file verbosity 3, but term verbosity 4 # Log following message at file verbosity 3, but term verbosity 4
log_message = ("Starting restore of %s to %s as it was as of %s." % log_message = ("Starting restore of %s to %s as it was as of %s." %
...@@ -513,11 +529,15 @@ def restore_set_root(rpin): ...@@ -513,11 +529,15 @@ def restore_set_root(rpin):
global restore_root, restore_index, restore_root_set global restore_root, restore_index, restore_root_set
if rpin.isincfile(): relpath = rpin.getincbase().path if rpin.isincfile(): relpath = rpin.getincbase().path
else: relpath = rpin.path else: relpath = rpin.path
pathcomps = os.path.join(rpin.conn.os.getcwd(), relpath).split("/") if rpin.conn is not Globals.local_connection:
assert len(pathcomps) >= 2 # path should be relative to / # For security checking consistency, don't get absolute path
pathcomps = relpath.split('/')
else: pathcomps = os.path.join(os.getcwd(), relpath).split("/")
if not pathcomps[0]: min_len_pathcomps = 2 # treat abs paths differently
else: min_len_pathcomps = 1
i = len(pathcomps) i = len(pathcomps)
while i >= 2: while i >= min_len_pathcomps:
parent_dir = rpath.RPath(rpin.conn, "/".join(pathcomps[:i])) parent_dir = rpath.RPath(rpin.conn, "/".join(pathcomps[:i]))
if (parent_dir.isdir() and if (parent_dir.isdir() and
"rdiff-backup-data" in parent_dir.listdir()): break "rdiff-backup-data" in parent_dir.listdir()): break
...@@ -662,8 +682,14 @@ def checkdest_need_check(dest_rp): ...@@ -662,8 +682,14 @@ def checkdest_need_check(dest_rp):
The rdiff-backup data directory The rdiff-backup data directory
%s %s
exists, but we cannot find a valid current_mirror marker. You can exists, but we cannot find a valid current_mirror marker. You can
avoid this message by removing this directory; however any data in it avoid this message by removing the rdiff_backup_data directory;
will be lost. however any data in it will be lost.
Probably this error was caused because the first rdiff-backup session
into a new directory failed. If this is the case it is safe to delete
the rdiff_backup_data directory because there is no important
information in it.
""" % (Globals.rbdir.path,)) """ % (Globals.rbdir.path,))
elif len(curmir_incs) == 1: return 0 elif len(curmir_incs) == 1: return 0
else: else:
......
...@@ -117,35 +117,45 @@ def set_allowed_requests(sec_level): ...@@ -117,35 +117,45 @@ def set_allowed_requests(sec_level):
"Log.log_to_file", "Log.log_to_file",
"SetConnections.add_redirected_conn", "SetConnections.add_redirected_conn",
"RedirectedRun", "RedirectedRun",
"sys.stdout.write"] "sys.stdout.write",
"robust.install_signal_handlers"]
if sec_level == "minimal": pass if sec_level == "minimal": pass
elif sec_level == "read-only" or sec_level == "update-only": elif sec_level == "read-only" or sec_level == "update-only":
allowed_requests.extend( allowed_requests.extend(
["C.make_file_dict", ["C.make_file_dict",
"rpath.ea_get",
"rpath.acl_get",
"log.Log.log_to_file", "log.Log.log_to_file",
"os.getuid", "os.getuid",
"os.listdir", "os.listdir",
"Time.setcurtime_local", "Time.setcurtime_local",
"robust.Resume.ResumeCheck",
"backup.SourceStruct.split_initial_dsiter",
"backup.SourceStruct.get_diffs_and_finalize",
"rpath.gzip_open_local_read", "rpath.gzip_open_local_read",
"rpath.open_local_read"]) "rpath.open_local_read",
if sec_level == "update-only": "Hardlink.initialize_dictionaries"])
if sec_level == "read-only":
allowed_requests.extend( allowed_requests.extend(
["Log.open_logfile_local", "Log.close_logfile_local", ["fs_abilities.get_fsabilities_readonly",
"Log.close_logfile_allconn", "Log.log_to_file", "fs_abilities.get_fsabilities_restoresource",
"log.Log.log_to_file", "restore.MirrorStruct.set_mirror_and_rest_times",
"robust.SaveState.init_filenames", "restore.MirrorStruct.initialize_rf_cache",
"robust.SaveState.touch_last_file", "restore.MirrorStruct.get_diffs",
"backup.SourceStruct.get_source_select",
"backup.SourceStruct.set_source_select",
"backup.SourceStruct.get_diffs"])
elif sec_level == "update-only":
allowed_requests.extend(
["log.Log.open_logfile_local", "log.Log.close_logfile_local",
"log.ErrorLog.open", "log.ErrorLog.isopen",
"log.ErrorLog.close",
"backup.DestinationStruct.set_rorp_cache",
"backup.DestinationStruct.get_sigs", "backup.DestinationStruct.get_sigs",
"backup.DestinationStruct.patch_w_datadir_writes", "backup.DestinationStruct.patch_and_increment",
"backup.DestinationStruct.patch_and_finalize",
"backup.DestinationStruct.patch_increment_and_finalize",
"Main.backup_touch_curmirror_local", "Main.backup_touch_curmirror_local",
"Main.backup_remove_curmirror_local",
"Globals.ITRB.increment_stat", "Globals.ITRB.increment_stat",
"statistics.record_error", "statistics.record_error",
"log.ErrorLog.write_if_open"]) "log.ErrorLog.write_if_open",
"fs_abilities.get_fsabilities_readwrite"])
if Globals.server: if Globals.server:
allowed_requests.extend( allowed_requests.extend(
["SetConnections.init_connection_remote", ["SetConnections.init_connection_remote",
......
...@@ -27,6 +27,7 @@ import Globals, metadata, rorpiter, TempFile, Hardlink, robust, increment, \ ...@@ -27,6 +27,7 @@ import Globals, metadata, rorpiter, TempFile, Hardlink, robust, increment, \
def Mirror(src_rpath, dest_rpath): def Mirror(src_rpath, dest_rpath):
"""Turn dest_rpath into a copy of src_rpath""" """Turn dest_rpath into a copy of src_rpath"""
log.Log("Starting mirror %s to %s" % (src_rpath.path, dest_rpath.path), 4)
SourceS = src_rpath.conn.backup.SourceStruct SourceS = src_rpath.conn.backup.SourceStruct
DestS = dest_rpath.conn.backup.DestinationStruct DestS = dest_rpath.conn.backup.DestinationStruct
...@@ -38,6 +39,8 @@ def Mirror(src_rpath, dest_rpath): ...@@ -38,6 +39,8 @@ def Mirror(src_rpath, dest_rpath):
def Mirror_and_increment(src_rpath, dest_rpath, inc_rpath): def Mirror_and_increment(src_rpath, dest_rpath, inc_rpath):
"""Mirror + put increments in tree based at inc_rpath""" """Mirror + put increments in tree based at inc_rpath"""
log.Log("Starting increment operation %s to %s" %
(src_rpath.path, dest_rpath.path), 4)
SourceS = src_rpath.conn.backup.SourceStruct SourceS = src_rpath.conn.backup.SourceStruct
DestS = dest_rpath.conn.backup.DestinationStruct DestS = dest_rpath.conn.backup.DestinationStruct
......
...@@ -97,7 +97,7 @@ class FSAbilities: ...@@ -97,7 +97,7 @@ class FSAbilities:
return '\n'.join(s) return '\n'.join(s)
def init_readonly(self, rp): def init_readonly(self, rp):
"""Set variables using fs tested at RPath rp """Set variables using fs tested at RPath rp. Run locally.
This method does not write to the file system at all, and This method does not write to the file system at all, and
should be run on the file system when the file system will should be run on the file system when the file system will
...@@ -106,6 +106,7 @@ class FSAbilities: ...@@ -106,6 +106,7 @@ class FSAbilities:
Only self.acls and self.eas are set. Only self.acls and self.eas are set.
""" """
assert rp.conn is Globals.local_connection
self.root_rp = rp self.root_rp = rp
self.read_only = 1 self.read_only = 1
self.set_eas(rp, 0) self.set_eas(rp, 0)
...@@ -115,7 +116,7 @@ class FSAbilities: ...@@ -115,7 +116,7 @@ class FSAbilities:
def init_readwrite(self, rbdir, use_ctq_file = 1, def init_readwrite(self, rbdir, use_ctq_file = 1,
override_chars_to_quote = None): override_chars_to_quote = None):
"""Set variables using fs tested at rp_base """Set variables using fs tested at rp_base. Run locally.
This method creates a temp directory in rp_base and writes to This method creates a temp directory in rp_base and writes to
it in order to test various features. Use on a file system it in order to test various features. Use on a file system
...@@ -128,13 +129,14 @@ class FSAbilities: ...@@ -128,13 +129,14 @@ class FSAbilities:
file in directory. file in directory.
""" """
assert rbdir.conn is Globals.local_connection
if not rbdir.isdir(): if not rbdir.isdir():
assert not rbdir.lstat(), (rbdir.path, rbdir.lstat()) assert not rbdir.lstat(), (rbdir.path, rbdir.lstat())
rbdir.mkdir() rbdir.mkdir()
self.root_rp = rbdir self.root_rp = rbdir
self.read_only = 0 self.read_only = 0
subdir = rbdir.conn.TempFile.new_in_dir(rbdir) subdir = TempFile.new_in_dir(rbdir)
subdir.mkdir() subdir.mkdir()
self.set_ownership(subdir) self.set_ownership(subdir)
self.set_hardlinks(subdir) self.set_hardlinks(subdir)
...@@ -211,7 +213,13 @@ rdiff-backup-data/chars_to_quote. ...@@ -211,7 +213,13 @@ rdiff-backup-data/chars_to_quote.
def set_fsync_dirs(self, testdir): def set_fsync_dirs(self, testdir):
"""Set self.fsync_dirs if directories can be fsync'd""" """Set self.fsync_dirs if directories can be fsync'd"""
self.fsync_dirs = testdir.conn.fs_abilities.test_fsync_local(testdir) assert testdir.conn is Globals.local_connection
try: testdir.fsync()
except (IOError, OSError), exc:
log.Log("Directories on file system at %s are not fsyncable.\n"
"Assuming it's unnecessary." % (testdir.path,), 4)
self.fsync_dirs = 0
else: self.fsync_dirs = 1
def set_chars_to_quote(self, subdir): def set_chars_to_quote(self, subdir):
"""Set self.chars_to_quote by trying to write various paths""" """Set self.chars_to_quote by trying to write various paths"""
...@@ -259,11 +267,48 @@ rdiff-backup-data/chars_to_quote. ...@@ -259,11 +267,48 @@ rdiff-backup-data/chars_to_quote.
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"""
self.acls = rp.conn.fs_abilities.test_acls_local(rp) assert Globals.local_connection is rp.conn
assert rp.lstat()
try: import posix1e
except ImportError:
log.Log("Unable to import module posix1e from pylibacl "
"package.\nACLs not supported on filesystem at %s" %
(rp.path,), 4)
self.acls = 0
return
try: posix1e.ACL(file=rp.path)
except IOError, exc:
if exc[0] == errno.EOPNOTSUPP:
log.Log("ACLs appear not to be supported by "
"filesystem at %s" % (rp.path,), 4)
self.acls = 0
else: raise
else: self.acls = 1
def set_eas(self, rp, write): def set_eas(self, rp, write):
"""Set extended attributes from rp. Tests writing if write is true.""" """Set extended attributes from rp. Tests writing if write is true."""
self.eas = rp.conn.fs_abilities.test_eas_local(rp, write) assert Globals.local_connection is rp.conn
assert rp.lstat()
try: import xattr
except ImportError:
log.Log("Unable to import module xattr. EAs not "
"supported on filesystem at %s" % (rp.path,), 4)
self.eas = 0
return
try:
xattr.listxattr(rp.path)
if write:
xattr.setxattr(rp.path, "user.test", "test val")
assert xattr.getxattr(rp.path, "user.test") == "test val"
except IOError, exc:
if exc[0] == errno.EOPNOTSUPP:
log.Log("Extended attributes not supported by "
"filesystem at %s" % (rp.path,), 4)
self.eas = 0
else: raise
else: self.eas = 1
def set_dir_inc_perms(self, rp): def set_dir_inc_perms(self, rp):
"""See if increments can have full permissions like a directory""" """See if increments can have full permissions like a directory"""
...@@ -282,17 +327,17 @@ rdiff-backup-data/chars_to_quote. ...@@ -282,17 +327,17 @@ rdiff-backup-data/chars_to_quote.
def set_resource_fork_readwrite(self, dir_rp): def set_resource_fork_readwrite(self, dir_rp):
"""Test for resource forks by writing to regular_file/rsrc""" """Test for resource forks by writing to regular_file/rsrc"""
assert dir_rp.conn is Globals.local_connection
reg_rp = dir_rp.append('regfile') reg_rp = dir_rp.append('regfile')
reg_rp.touch() reg_rp.touch()
s = 'test string---this should end up in resource fork' s = 'test string---this should end up in resource fork'
try: try:
fp_write = reg_rp.conn.open(os.path.join(reg_rp.path, 'rsrc'), fp_write = open(os.path.join(reg_rp.path, 'rsrc'), 'wb')
'wb')
fp_write.write(s) fp_write.write(s)
assert not fp_write.close() assert not fp_write.close()
fp_read = reg_rp.conn.open(os.path.join(reg_rp.path, 'rsrc'), 'rb') fp_read = open(os.path.join(reg_rp.path, 'rsrc'), 'rb')
s_back = fp_read.read() s_back = fp_read.read()
assert not fp_read.close() assert not fp_read.close()
except (OSError, IOError), e: self.resource_forks = 0 except (OSError, IOError), e: self.resource_forks = 0
...@@ -322,56 +367,23 @@ rdiff-backup-data/chars_to_quote. ...@@ -322,56 +367,23 @@ rdiff-backup-data/chars_to_quote.
self.resource_forks = 0 self.resource_forks = 0
def test_eas_local(rp, write): def get_fsabilities_readonly(desc_string, rp):
"""Test ea support. Must be called locally. Usedy by set_eas above.""" """Return an FSAbilities object with given description_string
assert Globals.local_connection is rp.conn
assert rp.lstat()
try: import xattr
except ImportError:
log.Log("Unable to import module xattr. EAs not "
"supported on filesystem at %s" % (rp.path,), 4)
return 0
try: Will be initialized read_only with given RPath rp.
xattr.listxattr(rp.path)
if write:
xattr.setxattr(rp.path, "user.test", "test val")
assert xattr.getxattr(rp.path, "user.test") == "test val"
except IOError, exc:
if exc[0] == errno.EOPNOTSUPP:
log.Log("Extended attributes not supported by "
"filesystem at %s" % (rp.path,), 4)
return 0
else: raise
else: return 1
def test_acls_local(rp):
"""Test acl support. Call locally. Does not write."""
assert Globals.local_connection is rp.conn
assert rp.lstat()
try: import posix1e
except ImportError:
log.Log("Unable to import module posix1e from pylibacl "
"package.\nACLs not supported on filesystem at %s" %
(rp.path,), 4)
return 0
try: posix1e.ACL(file=rp.path)
except IOError, exc:
if exc[0] == errno.EOPNOTSUPP:
log.Log("ACLs appear not to be supported by "
"filesystem at %s" % (rp.path,), 4)
return 0
else: raise
else: return 1
def test_fsync_local(rp):
"""Test fsyncing directories locally"""
assert rp.conn is Globals.local_connection
try: rp.fsync()
except (IOError, OSError), exc:
log.Log("Directories on file system at %s are not "
"fsyncable.\nAssuming it's unnecessary." % (rp.path,), 4)
return 0
else: return 1
"""
return FSAbilities(desc_string).init_readonly(rp)
def get_fsabilities_readwrite(desc_string, rb, use_ctq_file = 1, ctq = None):
"""Like above but initialize read/write and pass other arguments"""
return FSAbilities(desc_string).init_readwrite(
rb, use_ctq_file = use_ctq_file, override_chars_to_quote = ctq)
def get_fsabilities_restoresource(rp):
"""Used when restoring, get abilities of source directory"""
fsa = FSAbilities('source').init_readonly(rp)
ctq_rp = rp.append("chars_to_quote")
if ctq_rp.lstat(): fsa.chars_to_quote = ctq_rp.get_data()
else: fsa.chars_to_quote = ""
return fsa
...@@ -623,8 +623,10 @@ class RPath(RORPath): ...@@ -623,8 +623,10 @@ class RPath(RORPath):
def setdata(self): def setdata(self):
"""Set data dictionary using C extension""" """Set data dictionary using C extension"""
self.data = self.conn.C.make_file_dict(self.path) self.data = self.conn.C.make_file_dict(self.path)
if Globals.read_eas and self.lstat(): self.get_ea() if Globals.read_eas and self.lstat():
if Globals.read_acls and self.lstat(): self.get_acl() self.data['ea'] = self.conn.rpath.ea_get(self)
if Globals.read_acls and self.lstat():
self.data['acl'] = self.conn.rpath.acl_get(self)
if Globals.read_resource_forks and self.isreg(): if Globals.read_resource_forks and self.isreg():
self.get_resource_fork() self.get_resource_fork()
......
...@@ -272,6 +272,12 @@ class Final(PathSetter): ...@@ -272,6 +272,12 @@ class Final(PathSetter):
# Back up increment3 # Back up increment3
self.exec_rb(30000, 'testfiles/win-increment3', 'testfiles/output') self.exec_rb(30000, 'testfiles/win-increment3', 'testfiles/output')
# Now check to make sure no ":" in output directory
popen_fp = os.popen("find testfiles/output -name '*:*' | wc")
wc_output = popen_fp.read()
popen_fp.close()
assert wc_output.split() == ["0", "0", "0"], wc_output
# Start restore of increment 2 # Start restore of increment 2
Globals.chars_to_quote = '^a-z0-9_ -.' Globals.chars_to_quote = '^a-z0-9_ -.'
inc_paths = self.getinc_paths("increments.", inc_paths = self.getinc_paths("increments.",
...@@ -289,12 +295,6 @@ class Final(PathSetter): ...@@ -289,12 +295,6 @@ class Final(PathSetter):
compare_hardlinks = 0) compare_hardlinks = 0)
self.rb_schema = old_schema self.rb_schema = old_schema
# Now check to make sure no ":" in output directory
popen_fp = os.popen("find testfiles/output -name '*:*' | wc")
wc_output = popen_fp.read()
popen_fp.close()
assert wc_output.split() == ["0", "0", "0"], wc_output
def testLegacy(self): def testLegacy(self):
"""Test restoring directory with no mirror_metadata file""" """Test restoring directory with no mirror_metadata file"""
self.delete_tmpdirs() self.delete_tmpdirs()
......
...@@ -386,8 +386,9 @@ class MirrorTest(PathSetter): ...@@ -386,8 +386,9 @@ class MirrorTest(PathSetter):
assert not rpout.append("rdiff-backup-data").lstat() assert not rpout.append("rdiff-backup-data").lstat()
Main.misc_setup([rpin, rpout]) Main.misc_setup([rpin, rpout])
Main.backup_check_dirs(rpin, rpout) Main.backup_check_dirs(rpin, rpout)
Main.backup_set_fs_globals(rpin, rpout)
Main.backup_set_rbdir(rpin, rpout) Main.backup_set_rbdir(rpin, rpout)
Main.backup_set_fs_globals(rpin, rpout)
Main.backup_final_init(rpout)
Main.backup_set_select(rpin) Main.backup_set_select(rpin)
backup.Mirror(rpin, rpout) backup.Mirror(rpin, rpout)
log.ErrorLog.close() log.ErrorLog.close()
......
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