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.
8 # TODO: Add tar-like -C option.
9 # TODO: Add tar-like -v support to --list.
12 from bup import metadata
13 from bup import options
14 from bup.helpers import handle_ctrl_c, log, saved_errors
17 bup meta --create [OPTION ...] <PATH ...>
18 bup meta --extract [OPTION ...]
19 bup meta --start-extract [OPTION ...]
20 bup meta --finish-extract [OPTION ...]
22 c,create write metadata for PATHs to stdout (or --file)
23 t,list display metadata
24 x,extract perform --start-extract followed by --finish-extract
25 start-extract build tree matching metadata provided on standard input (or --file)
26 finish-extract finish applying standard input (or --file) metadata to filesystem
27 f,file= specify source or destination file
28 R,recurse recurse into subdirectories
29 xdev,one-file-system don't cross filesystem boundaries
30 numeric-ids apply numeric IDs (user, group, etc.), not names, during restore
31 symlinks handle symbolic links (default is true)
32 paths include paths in metadata (default is true)
33 v,verbose increase log output (can be used more than once)
34 q,quiet don't show progress meter
39 should_recurse = False
40 restore_numeric_ids = False
42 handle_symlinks = True
47 o = options.Options(optspec)
48 (opt, flags, remainder) = o.parse(sys.argv[1:])
50 for flag, value in flags:
51 if flag == '--create' or flag == '-c':
53 elif flag == '--list' or flag == '-t':
55 elif flag == '--extract' or flag == '-x':
57 elif flag == '--start-extract':
58 action = 'start-extract'
59 elif flag == '--finish-extract':
60 action = 'finish-extract'
61 elif flag == '--file' or flag == '-f':
62 target_filename = value
63 elif flag == '--recurse' or flag == '-R':
65 elif flag == '--no-recurse':
66 should_recurse = False
67 elif flag in frozenset(['--xdev', '--one-file-system']):
69 elif flag in frozenset(['--no-xdev', '--no-one-file-system']):
71 elif flag == '--numeric-ids':
72 restore_numeric_ids = True
73 elif flag == '--no-numeric-ids':
74 restore_numeric_ids = False
75 elif flag == '--paths':
77 elif flag == '--no-paths':
79 elif flag == '--symlinks':
80 handle_symlinks = True
81 elif flag == '--no-symlinks':
82 handle_symlinks = False
83 elif flag == '--verbose' or flag == '-v':
85 elif flag == '--quiet' or flag == '-q':
89 o.fatal("no action specified")
91 if action == 'create':
92 if len(remainder) < 1:
93 o.fatal("no paths specified for create")
94 if target_filename != '-':
95 output_file = open(target_filename, 'w')
97 output_file = sys.stdout
98 metadata.save_tree(output_file,
100 recurse=should_recurse,
101 write_paths=include_paths,
102 save_symlinks=handle_symlinks,
105 elif action == 'list':
106 if len(remainder) > 0:
107 o.fatal("cannot specify paths for --list")
108 if target_filename != '-':
109 src = open(target_filename, 'r')
112 metadata.display_archive(src)
114 elif action == 'start-extract':
115 if len(remainder) > 0:
116 o.fatal("cannot specify paths for --start-extract")
117 if target_filename != '-':
118 src = open(target_filename, 'r')
121 metadata.start_extract(src, create_symlinks=handle_symlinks)
123 elif action == 'finish-extract':
124 if len(remainder) > 0:
125 o.fatal("cannot specify paths for --finish-extract")
126 if target_filename != '-':
127 src = open(target_filename, 'r')
130 num_ids = restore_numeric_ids
131 metadata.finish_extract(src, restore_numeric_ids=num_ids)
133 elif action == 'extract':
134 if len(remainder) > 0:
135 o.fatal("cannot specify paths for --extract")
136 if target_filename != '-':
137 src = open(target_filename, 'r')
140 metadata.extract(src,
141 restore_numeric_ids=restore_numeric_ids,
142 create_symlinks=handle_symlinks)
145 log('WARNING: %d errors encountered.\n' % len(saved_errors))