3 bup_python="$(dirname "$0")/bup-python" || exit $?
4 exec "$bup_python" "$0" ${1+"$@"}
8 # Copyright (C) 2010 Rob Browning
10 # This code is covered under the terms of the GNU Library General
11 # Public License as described in the bup LICENSE file.
13 # TODO: Add tar-like -C option.
15 from __future__ import absolute_import
17 from bup import metadata
18 from bup import options
19 from bup.helpers import handle_ctrl_c, log, saved_errors
23 if not name or name == '-':
25 return open(name, 'r')
28 def open_output(name):
29 if not name or name == '-':
31 return open(name, 'w')
35 bup meta --create [OPTION ...] <PATH ...>
36 bup meta --list [OPTION ...]
37 bup meta --extract [OPTION ...]
38 bup meta --start-extract [OPTION ...]
39 bup meta --finish-extract [OPTION ...]
40 bup meta --edit [OPTION ...] <PATH ...>
42 c,create write metadata for PATHs to stdout (or --file)
43 t,list display metadata
44 x,extract perform --start-extract followed by --finish-extract
45 start-extract build tree matching metadata provided on standard input (or --file)
46 finish-extract finish applying standard input (or --file) metadata to filesystem
47 edit alter metadata; write to stdout (or --file)
48 f,file= specify source or destination file
49 R,recurse recurse into subdirectories
50 xdev,one-file-system don't cross filesystem boundaries
51 numeric-ids apply numeric IDs (user, group, etc.) rather than names
52 symlinks handle symbolic links (default is true)
53 paths include paths in metadata (default is true)
54 set-uid= set metadata uid (via --edit)
55 set-gid= set metadata gid (via --edit)
56 set-user= set metadata user (via --edit)
57 unset-user remove metadata user (via --edit)
58 set-group= set metadata group (via --edit)
59 unset-group remove metadata group (via --edit)
60 v,verbose increase log output (can be used more than once)
61 q,quiet don't show progress meter
66 o = options.Options(optspec)
67 (opt, flags, remainder) = o.parse(['--paths', '--symlinks', '--recurse']
70 opt.verbose = opt.verbose or 0
71 opt.quiet = opt.quiet or 0
72 metadata.verbose = opt.verbose - opt.quiet
74 action_count = sum([bool(x) for x in [opt.create, opt.list, opt.extract,
75 opt.start_extract, opt.finish_extract,
78 o.fatal("bup: only one action permitted: --create --list --extract --edit")
80 o.fatal("bup: no action specified")
83 if len(remainder) < 1:
84 o.fatal("no paths specified for create")
85 output_file = open_output(opt.file)
86 metadata.save_tree(output_file,
89 write_paths=opt.paths,
90 save_symlinks=opt.symlinks,
93 if len(remainder) > 0:
94 o.fatal("cannot specify paths for --list")
95 src = open_input(opt.file)
96 metadata.display_archive(src)
97 elif opt.start_extract:
98 if len(remainder) > 0:
99 o.fatal("cannot specify paths for --start-extract")
100 src = open_input(opt.file)
101 metadata.start_extract(src, create_symlinks=opt.symlinks)
102 elif opt.finish_extract:
103 if len(remainder) > 0:
104 o.fatal("cannot specify paths for --finish-extract")
105 src = open_input(opt.file)
106 metadata.finish_extract(src, restore_numeric_ids=opt.numeric_ids)
108 if len(remainder) > 0:
109 o.fatal("cannot specify paths for --extract")
110 src = open_input(opt.file)
111 metadata.extract(src,
112 restore_numeric_ids=opt.numeric_ids,
113 create_symlinks=opt.symlinks)
115 if len(remainder) < 1:
116 o.fatal("no paths specified for edit")
117 output_file = open_output(opt.file)
119 unset_user = False # True if --unset-user was the last relevant option.
120 unset_group = False # True if --unset-group was the last relevant option.
122 if flag[0] == '--set-user':
124 elif flag[0] == '--unset-user':
126 elif flag[0] == '--set-group':
128 elif flag[0] == '--unset-group':
131 for path in remainder:
134 for m in metadata._ArchiveIterator(f):
135 if opt.set_uid is not None:
137 m.uid = int(opt.set_uid)
139 o.fatal("uid must be an integer")
141 if opt.set_gid is not None:
143 m.gid = int(opt.set_gid)
145 o.fatal("gid must be an integer")
149 elif opt.set_user is not None:
150 m.user = opt.set_user
154 elif opt.set_group is not None:
155 m.group = opt.set_group
163 log('WARNING: %d errors encountered.\n' % len(saved_errors))