# This code is covered under the terms of the GNU Library General
# Public License as described in the bup LICENSE file.
+from __future__ import absolute_import, print_function
+from copy import deepcopy
from errno import EACCES, EINVAL, ENOTTY, ENOSYS, EOPNOTSUPP
from io import BytesIO
+from time import gmtime, strftime
import errno, os, sys, stat, time, pwd, grp, socket, struct
from bup import vint, xstat
return self.symlink_target
def _load_symlink_target_rec(self, port):
- self.symlink_target = vint.read_bvec(port)
+ target = vint.read_bvec(port)
+ self.symlink_target = target
+ self.size = len(target)
## Hardlink targets
self.linux_xattr = None
self.posix1e_acl = None
+ def __eq__(self, other):
+ if not isinstance(other, Metadata): return False
+ if self.mode != other.mode: return False
+ if self.mtime != other.mtime: return False
+ if self.ctime != other.ctime: return False
+ if self.atime != other.atime: return False
+ if self.path != other.path: return False
+ if self.uid != other.uid: return False
+ if self.gid != other.gid: return False
+ if self.size != other.size: return False
+ if self.user != other.user: return False
+ if self.group != other.group: return False
+ if self.symlink_target != other.symlink_target: return False
+ if self.hardlink_target != other.hardlink_target: return False
+ if self.linux_attr != other.linux_attr: return False
+ if self.posix1e_acl != other.posix1e_acl: return False
+ return True
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def __hash__(self):
+ return hash((self.mode,
+ self.mtime,
+ self.ctime,
+ self.atime,
+ self.path,
+ self.uid,
+ self.gid,
+ self.size,
+ self.user,
+ self.group,
+ self.symlink_target,
+ self.hardlink_target,
+ self.linux_attr,
+ self.posix1e_acl))
+
def __repr__(self):
result = ['<%s instance at %s' % (self.__class__, hex(id(self)))]
- if self.path:
+ if self.path is not None:
result += ' path:' + repr(self.path)
- if self.mode:
+ if self.mode is not None:
result += ' mode:' + repr(xstat.mode_str(self.mode)
- + '(%s)' % hex(self.mode))
- if self.uid:
+ + '(%s)' % oct(self.mode))
+ if self.uid is not None:
result += ' uid:' + str(self.uid)
- if self.gid:
+ if self.gid is not None:
result += ' gid:' + str(self.gid)
- if self.user:
+ if self.user is not None:
result += ' user:' + repr(self.user)
- if self.group:
+ if self.group is not None:
result += ' group:' + repr(self.group)
- if self.size:
+ if self.size is not None:
result += ' size:' + repr(self.size)
for name, val in (('atime', self.atime),
('mtime', self.mtime),
('ctime', self.ctime)):
- result += ' %s:%r' \
- % (name,
- time.strftime('%Y-%m-%d %H:%M %z',
- time.gmtime(xstat.fstime_floor_secs(val))))
+ if val is not None:
+ result += ' %s:%r (%d)' \
+ % (name,
+ strftime('%Y-%m-%d %H:%M %z',
+ gmtime(xstat.fstime_floor_secs(val))),
+ val)
result += '>'
return ''.join(result)
self.write(port, include_path)
return port.getvalue()
+ def copy(self):
+ return deepcopy(self)
+
@staticmethod
def read(port):
# This method should either return a valid Metadata object,
m = from_path(p, statinfo=st, archive_path=safe_path,
save_symlinks=save_symlinks)
if verbose:
- print >> sys.stderr, m.path
+ print(m.path, file=sys.stderr)
m.write(output_file, include_path=write_paths)
else:
start_dir = os.getcwd()
m = from_path(p, statinfo=st, archive_path=safe_path,
save_symlinks=save_symlinks)
if verbose:
- print >> sys.stderr, m.path
+ print(m.path, file=sys.stderr)
m.write(output_file, include_path=write_paths)
os.chdir(dirlist_dir)
finally:
mode_str = xstat.mode_str(meta.mode)
symlink_target = meta.symlink_target
mtime_secs = xstat.fstime_floor_secs(meta.mtime)
- mtime_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(mtime_secs))
+ mtime_str = strftime('%Y-%m-%d %H:%M', time.localtime(mtime_secs))
if meta.user and not numeric_ids:
user_str = meta.user
elif meta.uid != None:
first_item = True
for meta in _ArchiveIterator(file):
if not first_item:
- print
- print detailed_str(meta)
+ print()
+ print(detailed_str(meta))
first_item = False
elif verbose > 0:
for meta in _ArchiveIterator(file):
- print summary_str(meta)
+ print(summary_str(meta))
elif verbose == 0:
for meta in _ArchiveIterator(file):
if not meta.path:
- print >> sys.stderr, \
- 'bup: no metadata path, but asked to only display path', \
- '(increase verbosity?)'
+ print('bup: no metadata path, but asked to only display path'
+ '(increase verbosity?)')
sys.exit(1)
- print meta.path
+ print(meta.path)
def start_extract(file, create_symlinks=True):
if not meta: # Hit end record.
break
if verbose:
- print >> sys.stderr, meta.path
+ print(meta.path, file=sys.stderr)
xpath = _clean_up_extract_path(meta.path)
if not xpath:
add_error(Exception('skipping risky path "%s"' % meta.path))
all_dirs.append(meta)
else:
if verbose:
- print >> sys.stderr, meta.path
+ print(meta.path, file=sys.stderr)
meta.apply_to_path(path=xpath,
restore_numeric_ids=restore_numeric_ids)
all_dirs.sort(key = lambda x : len(x.path), reverse=True)
# Don't need to check xpath -- won't be in all_dirs if not OK.
xpath = _clean_up_extract_path(dir.path)
if verbose:
- print >> sys.stderr, dir.path
+ print(dir.path, file=sys.stderr)
dir.apply_to_path(path=xpath, restore_numeric_ids=restore_numeric_ids)
else:
meta.path = xpath
if verbose:
- print >> sys.stderr, '+', meta.path
+ print('+', meta.path, file=sys.stderr)
_set_up_path(meta, create_symlinks=create_symlinks)
if os.path.isdir(meta.path):
all_dirs.append(meta)
else:
if verbose:
- print >> sys.stderr, '=', meta.path
+ print('=', meta.path, file=sys.stderr)
meta.apply_to_path(restore_numeric_ids=restore_numeric_ids)
all_dirs.sort(key = lambda x : len(x.path), reverse=True)
for dir in all_dirs:
# Don't need to check xpath -- won't be in all_dirs if not OK.
xpath = _clean_up_extract_path(dir.path)
if verbose:
- print >> sys.stderr, '=', xpath
+ print('=', xpath, file=sys.stderr)
# Shouldn't have to check for risky paths here (omitted above).
dir.apply_to_path(path=dir.path,
restore_numeric_ids=restore_numeric_ids)