3 """Dump archive contents, test extraction."""
7 from binascii
import crc32
, hexlify
8 from datetime
import datetime
15 return array
.array('B', v
)
17 rf
.UNICODE_COMMENTS
= 1
21 dumprar [switches] [ARC1 ARC2 ...] [@ARCLIST]
23 @file read archive names from file
25 -Ccharset set fallback charset
27 -t attempt to read all files
28 -x write read files out
29 -c show archive comment
31 -- stop switch parsing
34 os_list
= ['DOS', 'OS2', 'WIN', 'UNIX', 'MACOS', 'BEOS']
36 block_strs
= ['MARK', 'MAIN', 'FILE', 'OLD_COMMENT', 'OLD_EXTRA',
37 'OLD_SUB', 'OLD_RECOVERY', 'OLD_AUTH', 'SUB', 'ENDARC']
40 if type < rf
.RAR_BLOCK_MARK
or type > rf
.RAR_BLOCK_ENDARC
:
42 return block_strs
[type - rf
.RAR_BLOCK_MARK
]
45 (rf
.RAR_MAIN_VOLUME
, "VOL"),
46 (rf
.RAR_MAIN_COMMENT
, "COMMENT"),
47 (rf
.RAR_MAIN_LOCK
, "LOCK"),
48 (rf
.RAR_MAIN_SOLID
, "SOLID"),
49 (rf
.RAR_MAIN_NEWNUMBERING
, "NEWNR"),
50 (rf
.RAR_MAIN_AUTH
, "AUTH"),
51 (rf
.RAR_MAIN_RECOVERY
, "RECOVERY"),
52 (rf
.RAR_MAIN_PASSWORD
, "PASSWORD"),
53 (rf
.RAR_MAIN_FIRSTVOLUME
, "FIRSTVOL"),
54 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
55 (rf
.RAR_LONG_BLOCK
, "LONG"),
59 (rf
.RAR_ENDARC_NEXT_VOLUME
, "NEXTVOL"),
60 (rf
.RAR_ENDARC_DATACRC
, "DATACRC"),
61 (rf
.RAR_ENDARC_REVSPACE
, "REVSPACE"),
62 (rf
.RAR_ENDARC_VOLNR
, "VOLNR"),
63 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
64 (rf
.RAR_LONG_BLOCK
, "LONG"),
68 (rf
.RAR_FILE_SPLIT_BEFORE
, "SPLIT_BEFORE"),
69 (rf
.RAR_FILE_SPLIT_AFTER
, "SPLIT_AFTER"),
70 (rf
.RAR_FILE_PASSWORD
, "PASSWORD"),
71 (rf
.RAR_FILE_COMMENT
, "COMMENT"),
72 (rf
.RAR_FILE_SOLID
, "SOLID"),
73 (rf
.RAR_FILE_LARGE
, "LARGE"),
74 (rf
.RAR_FILE_UNICODE
, "UNICODE"),
75 (rf
.RAR_FILE_SALT
, "SALT"),
76 (rf
.RAR_FILE_VERSION
, "VERSION"),
77 (rf
.RAR_FILE_EXTTIME
, "EXTTIME"),
78 (rf
.RAR_FILE_EXTFLAGS
, "EXTFLAGS"),
79 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
80 (rf
.RAR_LONG_BLOCK
, "LONG"),
84 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
85 (rf
.RAR_LONG_BLOCK
, "LONG"),
88 file_parms
= ("D64", "D128", "D256", "D512",
89 "D1024", "D2048", "D4096", "DIR")
92 if sys
.hexversion
< 0x3000000:
96 if sys
.hexversion
< 0x3000000:
99 sys
.stdout
.write('\n')
101 def render_flags(flags
, bit_list
):
105 known
= known | bit
[0]
108 unknown
= flags
& ~known
112 res
.append("UNK_%04x" % (1 << n
))
113 unknown
= unknown
>> 1
118 def get_file_flags(flags
):
119 res
= render_flags(flags
& ~rf
.RAR_FILE_DICTMASK
, file_bits
)
121 xf
= (flags
& rf
.RAR_FILE_DICTMASK
) >> 5
122 res
+= "," + file_parms
[xf
]
125 def get_main_flags(flags
):
126 return render_flags(flags
, main_bits
)
128 def get_endarc_flags(flags
):
129 return render_flags(flags
, endarc_bits
)
131 def get_generic_flags(flags
):
132 return render_flags(flags
, generic_bits
)
135 if isinstance(t
, datetime
):
136 return t
.isoformat(' ')
137 return "%04d-%02d-%02d %02d:%02d:%02d" % t
141 unknown
= h
.header_size
- h
.header_base
142 xprint("%s: hdrlen=%d datlen=%d hdr_unknown=%d", st
, h
.header_size
,
144 if unknown
> 0 and cf_verbose
> 1:
145 dat
= h
.header_data
[h
.header_base
: ]
146 xprint(" unknown: %s", hexlify(dat
))
147 if h
.type in (rf
.RAR_BLOCK_FILE
, rf
.RAR_BLOCK_SUB
):
148 if h
.host_os
== rf
.RAR_OS_UNIX
:
149 s_mode
= "0%o" % h
.mode
151 s_mode
= "0x%x" % h
.mode
152 xprint(" flags=0x%04x:%s", h
.flags
, get_file_flags(h
.flags
))
153 if h
.host_os
>= 0 and h
.host_os
< len(os_list
):
154 s_os
= os_list
[h
.host_os
]
157 xprint(" os=%d:%s ver=%d mode=%s meth=%c cmp=%d dec=%d vol=%d",
159 h
.extract_version
, s_mode
, h
.compress_type
,
160 h
.compress_size
, h
.file_size
, h
.volume
)
161 ucrc
= (h
.CRC
+ (1 << 32)) & ((1 << 32) - 1)
162 xprint(" crc=0x%08x (%d) time=%s", ucrc
, h
.CRC
, fmt_time(h
.date_time
))
163 xprint(" name=%s", h
.filename
)
165 xprint(" mtime=%s", fmt_time(h
.mtime
))
167 xprint(" ctime=%s", fmt_time(h
.ctime
))
169 xprint(" atime=%s", fmt_time(h
.atime
))
171 xprint(" arctime=%s", fmt_time(h
.arctime
))
172 elif h
.type == rf
.RAR_BLOCK_MAIN
:
173 xprint(" flags=0x%04x:%s", h
.flags
, get_main_flags(h
.flags
))
174 elif h
.type == rf
.RAR_BLOCK_ENDARC
:
175 xprint(" flags=0x%04x:%s", h
.flags
, get_endarc_flags(h
.flags
))
176 elif h
.type == rf
.RAR_BLOCK_MARK
:
177 xprint(" flags=0x%04x:", h
.flags
)
179 xprint(" flags=0x%04x:%s", h
.flags
, get_generic_flags(h
.flags
))
181 if h
.comment
is not None:
185 xprint(" comment=%s", cm
)
194 def check_crc(f
, inf
):
197 ucrc
+= (long(1) << 32)
201 def test_read_long(r
, inf
):
202 f
= r
.open(inf
.filename
)
209 if total
!= inf
.file_size
:
210 xprint("\n *** %s has corrupt file: %s ***", r
.rarfile
, inf
.filename
)
211 xprint(" *** short read: got=%d, need=%d ***\n", total
, inf
.file_size
)
214 # test .seek() & .readinto()
218 # hack: re-enable crc calc
223 buf
= bytearray(rf
.ZERO
*4096)
225 res
= f
.readinto(buf
)
229 if inf
.file_size
!= total
:
230 xprint(" *** readinto failed: got=%d, need=%d ***\n", total
, inf
.file_size
)
234 def test_read(r
, inf
):
235 test_read_long(r
, inf
)
238 def test_real(fn
, psw
):
239 xprint("Archive: %s", fn
)
246 if not rf
.is_rarfile(fn
):
247 xprint(" --- %s is not a RAR file ---", fn
)
251 r
= rf
.RarFile(fn
, charset
= cf_charset
, info_callback
= cb
)
253 if r
.needs_password():
257 xprint(" --- %s requires password ---", fn
)
261 if cf_show_comment
and r
.comment
:
262 for ln
in r
.comment
.split('\n'):
264 elif cf_verbose
== 1 and r
.comment
:
268 xprint(" comment=%s", cm
)
271 for n
in r
.namelist():
282 for inf
in r
.infolist():
291 except rf
.NeedFirstVolume
:
292 xprint(" --- %s is middle part of multi-vol archive ---", fn
)
294 exc
, msg
, tb
= sys
.exc_info()
295 xprint("\n *** %s: %s ***\n", exc
.__name
__, msg
)
298 exc
, msg
, tb
= sys
.exc_info()
299 xprint("\n *** %s: %s ***\n", exc
.__name
__, msg
)
303 global cf_verbose
, cf_show_comment
, cf_charset
304 global cf_extract
, cf_test_read
, cf_test_unrar
310 for a
in sys
.argv
[1:]:
314 for ln
in open(a
[1:], 'r'):
339 raise Exception("unknown switch: "+a
)
347 if __name__
== '__main__':
350 except KeyboardInterrupt: