[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Rdiff-backup-commits] rdiff-backup/rdiff_backup FilenameMapping.py Gl..
From: |
Josh Nisly |
Subject: |
[Rdiff-backup-commits] rdiff-backup/rdiff_backup FilenameMapping.py Gl... |
Date: |
Sat, 18 Apr 2009 21:54:18 +0000 |
CVSROOT: /sources/rdiff-backup
Module name: rdiff-backup
Changes by: Josh Nisly <joshn> 09/04/18 21:54:18
Modified files:
rdiff_backup : FilenameMapping.py Globals.py eas_acls.py
fs_abilities.py rpath.py
Log message:
Some older systems don't support unicode, so check for support before
using it.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff_backup/FilenameMapping.py?cvsroot=rdiff-backup&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff_backup/Globals.py?cvsroot=rdiff-backup&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff_backup/eas_acls.py?cvsroot=rdiff-backup&r1=1.44&r2=1.45
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff_backup/fs_abilities.py?cvsroot=rdiff-backup&r1=1.71&r2=1.72
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff_backup/rpath.py?cvsroot=rdiff-backup&r1=1.139&r2=1.140
Patches:
Index: FilenameMapping.py
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/rdiff_backup/FilenameMapping.py,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- FilenameMapping.py 9 Apr 2009 13:59:18 -0000 1.20
+++ FilenameMapping.py 18 Apr 2009 21:54:18 -0000 1.21
@@ -159,7 +159,7 @@
"""
path = self.path
- if type(path) != unicode:
+ if type(path) != unicode and Globals.use_unicode_paths:
path = unicode(path, 'utf-8')
return map(unquote, self.conn.os.listdir(path))
Index: Globals.py
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/rdiff_backup/Globals.py,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- Globals.py 3 Jan 2009 23:18:35 -0000 1.47
+++ Globals.py 18 Apr 2009 21:54:18 -0000 1.48
@@ -159,6 +159,10 @@
chars_to_quote = None
quoting_char = ';'
+
+# Some systems don't support unicode in filenames
+use_unicode_paths = None
+
# If true, the timestamps use the following format: "2008-09-01T04-49-04-07-00"
# (instead of "2008-09-01T04:49:04-07:00"). This creates timestamps which
# don't need to be escaped on Windows.
Index: eas_acls.py
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/rdiff_backup/eas_acls.py,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -b -r1.44 -r1.45
--- eas_acls.py 9 Apr 2009 13:59:18 -0000 1.44
+++ eas_acls.py 18 Apr 2009 21:54:18 -0000 1.45
@@ -38,6 +38,11 @@
# triggers a warning.
dropped_acl_names = {}
+def encode(str_):
+ if type(str_) == unicode:
+ return str_.encode('utf-8')
+ return str_
+
class ExtendedAttributes:
"""Hold a file's extended attribute information"""
def __init__(self, index, attr_dict = None):
@@ -57,7 +62,7 @@
def read_from_rp(self, rp):
"""Set the extended attributes from an rpath"""
try:
- attr_list =
rp.conn.xattr.listxattr(rp.path.encode('utf-8'),
+ attr_list = rp.conn.xattr.listxattr(encode(rp.path),
rp.issym())
except IOError, exc:
if exc[0] in (errno.EOPNOTSUPP, errno.EPERM,
errno.ETXTBSY):
@@ -75,7 +80,7 @@
continue
try:
self.attr_dict[attr] = \
-
rp.conn.xattr.getxattr(rp.path.encode('utf-8'),
+ rp.conn.xattr.getxattr(encode(rp.path),
attr, rp.issym())
except IOError, exc:
# File probably modified while reading, just
continue
@@ -88,10 +93,10 @@
def clear_rp(self, rp):
"""Delete all the extended attributes in rpath"""
try:
- for name in
rp.conn.xattr.listxattr(rp.path.encode('utf-8'),
+ for name in rp.conn.xattr.listxattr(encode(rp.path),
rp.issym()):
try:
-
rp.conn.xattr.removexattr(rp.path.encode('utf-8'),
+
rp.conn.xattr.removexattr(encode(rp.path),
name, rp.issym())
except IOError, exc:
# SELinux attributes cannot be removed,
and we don't want
@@ -115,7 +120,7 @@
self.clear_rp(rp)
for (name, value) in self.attr_dict.iteritems():
try:
- rp.conn.xattr.setxattr(rp.path.encode('utf-8'),
name,
+ rp.conn.xattr.setxattr(encode(rp.path), name,
value, 0, rp.issym())
except IOError, exc:
# Mac and Linux attributes have different
namespaces, so
@@ -154,13 +159,13 @@
def EA2Record(ea):
"""Convert ExtendedAttributes object to text record"""
- str_list = ['# file: %s' %
C.acl_quote(ea.get_indexpath().encode('utf-8'))]
+ str_list = ['# file: %s' % C.acl_quote(encode(ea.get_indexpath()))]
for (name, val) in ea.attr_dict.iteritems():
if not val: str_list.append(name)
else:
encoded_val = base64.encodestring(val).replace('\n', '')
try:
- str_list.append('%s=0s%s' %
(C.acl_quote(name.encode('utf-8')),
+ str_list.append('%s=0s%s' %
(C.acl_quote(encode(name)),
encoded_val))
except UnicodeEncodeError:
log.Log("Warning: unable to store Unicode
extended attribute %s"
@@ -175,7 +180,7 @@
raise metadata.ParsingError("Bad record beginning: " +
first[:8])
filename = first[8:]
if filename == '.': index = ()
- else: index = tuple(unicode(C.acl_unquote(filename.encode('utf-8')),
+ else: index = tuple(unicode(C.acl_unquote(encode(filename)),
'utf-8').split('/'))
ea = ExtendedAttributes(index)
@@ -201,7 +206,7 @@
def filename_to_index(self, filename):
"""Convert possibly quoted filename to index tuple"""
if filename == '.': return ()
- else: return
tuple(C.acl_unquote(filename.encode('utf-8')).split('/'))
+ else: return tuple(C.acl_unquote(encode(filename)).split('/'))
class ExtendedAttributesFile(metadata.FlatFile):
"""Store/retrieve EAs from extended_attributes file"""
@@ -386,7 +391,7 @@
else: acl = posix1e.ACL()
try:
- acl.applyto(rp.path.encode('utf-8'))
+ acl.applyto(encode(rp.path))
except IOError, exc:
if exc[0] == errno.EOPNOTSUPP:
log.Log("Warning: unable to set ACL on %s: %s" %
@@ -398,12 +403,12 @@
if default_entry_list:
def_acl = list_to_acl(default_entry_list, map_names)
else: def_acl = posix1e.ACL()
- def_acl.applyto(rp.path.encode('utf-8'),
posix1e.ACL_TYPE_DEFAULT)
+ def_acl.applyto(encode(rp.path), posix1e.ACL_TYPE_DEFAULT)
def get_acl_lists_from_rp(rp):
"""Returns (acl_list, def_acl_list) from an rpath. Call locally"""
assert rp.conn is Globals.local_connection
- try: acl = posix1e.ACL(file=rp.path.encode('utf-8'))
+ try: acl = posix1e.ACL(file=encode(rp.path))
except IOError, exc:
if exc[0] == errno.EOPNOTSUPP:
acl = None
@@ -413,7 +418,7 @@
acl = None
else: raise
if rp.isdir():
- try: def_acl = posix1e.ACL(filedef=rp.path.encode('utf-8'))
+ try: def_acl = posix1e.ACL(filedef=encode(rp.path))
except IOError, exc:
if exc[0] == errno.EOPNOTSUPP:
def_acl = None
@@ -541,7 +546,7 @@
def ACL2Record(acl):
"""Convert an AccessControlLists object into a text record"""
return '# file: %s\n%s\n' % \
- (C.acl_quote(acl.get_indexpath().encode('utf-8')), str(acl))
+ (C.acl_quote(encode(acl.get_indexpath())), str(acl))
def Record2ACL(record):
"""Convert text record to an AccessControlLists object"""
@@ -551,7 +556,7 @@
raise metadata.ParsingError("Bad record beginning: "+
first_line)
filename = first_line[8:]
if filename == '.': index = ()
- else: index = tuple(unicode(C.acl_unquote(filename.encode('utf-8')),
+ else: index = tuple(unicode(C.acl_unquote(encode(filename)),
'utf-8').split('/'))
return AccessControlLists(index, record[newline_pos:])
Index: fs_abilities.py
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/rdiff_backup/fs_abilities.py,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -b -r1.71 -r1.72
--- fs_abilities.py 8 Mar 2009 17:20:17 -0000 1.71
+++ fs_abilities.py 18 Apr 2009 21:54:18 -0000 1.72
@@ -34,6 +34,7 @@
class FSAbilities:
"""Store capabilities of given file system"""
extended_filenames = None # True if filenames can have non-ASCII chars
+ unicode_filenames = None # True if we can use unicode in paths
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
@@ -97,7 +98,8 @@
('Symlink
permissions', self.symlink_perms),
('Extended
filenames', self.extended_filenames),
('Windows reserved
filenames',
-
self.win_reserved_filenames)])
+
self.win_reserved_filenames),
+ ('Unicode filenames',
self.unicode_filenames)])
add_boolean_list([('Access control lists', self.acls),
('Extended attributes',
self.eas),
('Windows access control
lists', self.win_acls),
@@ -153,6 +155,7 @@
self.set_extended_filenames(subdir)
self.set_win_reserved_filenames(subdir)
+ self.set_unicode_filenames(subdir)
self.set_case_sensitive_readwrite(subdir)
self.set_ownership(subdir)
self.set_hardlinks(subdir)
@@ -268,6 +271,24 @@
else:
self.win_reserved_filenames = 0
+ def set_unicode_filenames(self, subdir):
+ """Set self.unicode_filenames by trying to write a path"""
+ assert not self.read_only
+
+ # Try a unicode filename
+ unicode_filename = u'\u3046\u3069\u3093\u5c4b.txt'
+ unicode_rp = None
+ try:
+ unicode_rp = subdir.append(unicode_filename)
+ unicode_rp.touch()
+ except UnicodeEncodeError:
+ if unicode_rp: assert not unicode_rp.lstat()
+ self.unicode_filenames = 0
+ else:
+ assert unicode_rp.lstat()
+ unicode_rp.delete()
+ self.unicode_filenames = 1
+
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
@@ -317,6 +338,7 @@
where the list is of the directory containing rp.
"""
+ subdir.path = unicode(subdir.path)
l = robust.listrp(subdir)
for filename in l:
if filename != filename.swapcase():
@@ -679,6 +701,10 @@
self.update_triple(self.src_fsa.win_acls,
self.dest_fsa.win_acls,
('win_acls_active', 'win_acls_write',
'win_acls_conn'))
+ def set_unicode_filenames(self):
+ SetConnections.UpdateGlobal('use_unicode_paths',
+
self.dest_fsa.unicode_filenames)
+
def set_resource_forks(self):
self.update_triple(self.src_fsa.resource_forks,
self.dest_fsa.resource_forks,
@@ -963,6 +989,7 @@
bsg.set_eas()
bsg.set_acls()
bsg.set_win_acls()
+ bsg.set_unicode_filenames()
bsg.set_resource_forks()
bsg.set_carbonfile()
bsg.set_hardlinks()
@@ -991,6 +1018,7 @@
rsg.set_eas()
rsg.set_acls()
rsg.set_win_acls()
+ rsg.set_unicode_filenames()
rsg.set_resource_forks()
rsg.set_carbonfile()
rsg.set_hardlinks()
Index: rpath.py
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/rdiff_backup/rpath.py,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -b -r1.139 -r1.140
--- rpath.py 9 Apr 2009 13:59:19 -0000 1.139
+++ rpath.py 18 Apr 2009 21:54:18 -0000 1.140
@@ -309,23 +309,23 @@
data = {}
mode = statblock[stat.ST_MODE]
- if stat.S_ISREG(mode): type = 'reg'
- elif stat.S_ISDIR(mode): type = 'dir'
+ if stat.S_ISREG(mode): type_ = 'reg'
+ elif stat.S_ISDIR(mode): type_ = 'dir'
elif stat.S_ISCHR(mode):
- type = 'dev'
+ type_ = 'dev'
s = statblock.st_rdev
data['devnums'] = ('c',) + (s >> 8, s & 0xff)
elif stat.S_ISBLK(mode):
- type = 'dev'
+ type_ = 'dev'
s = statblock.st_rdev
data['devnums'] = ('b',) + (s >> 8, s & 0xff)
- elif stat.S_ISFIFO(mode): type = 'fifo'
+ elif stat.S_ISFIFO(mode): type_ = 'fifo'
elif stat.S_ISLNK(mode):
- type = 'sym'
+ type_ = 'sym'
data['linkname'] = os.readlink(filename)
- elif stat.S_ISSOCK(mode): type = 'sock'
+ elif stat.S_ISSOCK(mode): type_ = 'sock'
else: raise C.UnknownFileError(filename)
- data['type'] = type
+ data['type'] = type_
data['size'] = statblock[stat.ST_SIZE]
data['perms'] = stat.S_IMODE(mode)
data['uid'] = statblock[stat.ST_UID]
@@ -335,12 +335,16 @@
data['nlink'] = statblock[stat.ST_NLINK]
if os.name == 'nt':
+ global type
+ if type(filename) == unicode:
attribs = win32file.GetFileAttributesW(filename)
+ else:
+ attribs = win32file.GetFileAttributes(filename)
if attribs & winnt.FILE_ATTRIBUTE_REPARSE_POINT:
data['type'] = 'sym'
data['linkname'] = None
- if not (type == 'sym' or type == 'dev'):
+ if not (type_ == 'sym' or type_ == 'dev'):
# mtimes on symlinks and dev files don't work consistently
data['mtime'] = long(statblock[stat.ST_MTIME])
data['atime'] = long(statblock[stat.ST_ATIME])
@@ -1000,7 +1004,7 @@
path = self.path
# Use pass in unicode to os.listdir, so that the returned
# entries are in unicode.
- if type(path) != unicode:
+ if type(path) != unicode and Globals.use_unicode_paths:
path = unicode(path, 'utf-8')
return self.conn.os.listdir(path)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Rdiff-backup-commits] rdiff-backup/rdiff_backup FilenameMapping.py Gl...,
Josh Nisly <=