3 # Copyright (C) 2010 Rob Browning
5 # This code is covered under the terms of the GNU Library General
6 # Public License as described in the bup LICENSE file.
11 from bup import metadata
12 from bup import options
14 from bup.helpers import handle_ctrl_c, saved_errors
17 def fstimestr(fstime):
18 (s, ns) = fstime.secs_nsecs()
22 return '%d.%09d' % (s, ns)
26 bup pathinfo [OPTION ...] <PATH ...>
28 v,verbose increase log output (can be used more than once)
29 q,quiet don't show progress meter
30 exclude-fields= exclude comma-separated fields
31 include-fields= include comma-separated fields (definitive if first)
35 all_fields = frozenset(['path',
49 active_fields = all_fields
53 o = options.Options('bup pathinfo', optspec)
54 (opt, flags, remainder) = o.parse(sys.argv[1:])
56 treat_include_fields_as_definitive = True
57 for flag, value in flags:
58 if flag == '--verbose' or flag == '-v':
60 elif flag == '--quiet' or flag == '-q':
62 elif flag == '--exclude-fields':
63 exclude_fields = frozenset(value.split(','))
64 for f in exclude_fields:
65 if not f in all_fields:
66 o.fatal(f + ' is not a valid field name')
67 active_fields = active_fields - exclude_fields
68 treat_include_fields_as_definitive = False
69 elif flag == '--include-fields':
70 include_fields = frozenset(value.split(','))
71 for f in include_fields:
72 if not f in all_fields:
73 o.fatal(f + ' is not a valid field name')
74 if treat_include_fields_as_definitive:
75 active_fields = include_fields
76 treat_include_fields_as_definitive = False
78 active_fields = active_fields | include_fields
80 for path in remainder:
81 m = metadata.from_path(path, archive_path = path)
82 if 'path' in active_fields:
84 if 'mode' in active_fields:
85 print 'mode:', oct(m.mode)
86 if 'link-target' in active_fields and stat.S_ISLNK(m.mode):
87 print 'link-target:', m.symlink_target
88 if 'rdev' in active_fields:
90 if 'uid' in active_fields:
92 if 'gid' in active_fields:
94 if 'owner' in active_fields:
95 print 'owner:', m.owner
96 if 'group' in active_fields:
97 print 'group:', m.group
98 if 'atime' in active_fields:
99 print 'atime: ' + fstimestr(m.atime)
100 if 'mtime' in active_fields:
101 print 'mtime: ' + fstimestr(m.mtime)
102 if 'ctime' in active_fields:
103 print 'ctime: ' + fstimestr(m.ctime)
104 if 'linux-attr' in active_fields and m.linux_attr:
105 print 'linux-attr:', hex(m.linux_attr)
106 if 'linux-xattr' in active_fields and m.linux_xattr:
107 for name, value in m.linux_xattr:
108 print 'linux-xattr: %s -> %s' % (name, repr(value))
109 if 'posix1e-acl' in active_fields and m.posix1e_acl:
110 flags = posix1e.TEXT_ABBREVIATE
111 if stat.S_ISDIR(m.mode):
112 acl = m.posix1e_acl[0]
113 default_acl = m.posix1e_acl[2]
114 print acl.to_any_text('posix1e-acl: ', '\n', flags)
115 print acl.to_any_text('posix1e-acl-default: ', '\n', flags)
117 acl = m.posix1e_acl[0]
118 print acl.to_any_text('posix1e-acl: ', '\n', flags)
121 log('WARNING: %d errors encountered.\n' % len(saved_errors))