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
.REPORT_BAD_HEADER
= 1
18 rf
.UNICODE_COMMENTS
= 1
22 dumprar [switches] [ARC1 ARC2 ...] [@ARCLIST]
24 @file read archive names from file
26 -Ccharset set fallback charset
28 -t attemt to read all files
29 -x write read files out
30 -c show archive comment
32 -- stop switch parsing
35 os_list
= ['DOS', 'OS2', 'WIN', 'UNIX', 'MACOS', 'BEOS']
37 block_strs
= ['MARK', 'MAIN', 'FILE', 'OLD_COMMENT', 'OLD_EXTRA',
38 'OLD_SUB', 'OLD_RECOVERY', 'OLD_AUTH', 'SUB', 'ENDARC']
41 if type < rf
.RAR_BLOCK_MARK
or type > rf
.RAR_BLOCK_ENDARC
:
43 return block_strs
[type - rf
.RAR_BLOCK_MARK
]
46 (rf
.RAR_MAIN_VOLUME
, "VOL"),
47 (rf
.RAR_MAIN_COMMENT
, "COMMENT"),
48 (rf
.RAR_MAIN_LOCK
, "LOCK"),
49 (rf
.RAR_MAIN_SOLID
, "SOLID"),
50 (rf
.RAR_MAIN_NEWNUMBERING
, "NEWNR"),
51 (rf
.RAR_MAIN_AUTH
, "AUTH"),
52 (rf
.RAR_MAIN_RECOVERY
, "RECOVERY"),
53 (rf
.RAR_MAIN_PASSWORD
, "PASSWORD"),
54 (rf
.RAR_MAIN_FIRSTVOLUME
, "FIRSTVOL"),
55 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
56 (rf
.RAR_LONG_BLOCK
, "LONG"),
60 (rf
.RAR_ENDARC_NEXT_VOLUME
, "NEXTVOL"),
61 (rf
.RAR_ENDARC_DATACRC
, "DATACRC"),
62 (rf
.RAR_ENDARC_REVSPACE
, "REVSPACE"),
63 (rf
.RAR_ENDARC_VOLNR
, "VOLNR"),
64 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
65 (rf
.RAR_LONG_BLOCK
, "LONG"),
69 (rf
.RAR_FILE_SPLIT_BEFORE
, "SPLIT_BEFORE"),
70 (rf
.RAR_FILE_SPLIT_AFTER
, "SPLIT_AFTER"),
71 (rf
.RAR_FILE_PASSWORD
, "PASSWORD"),
72 (rf
.RAR_FILE_COMMENT
, "COMMENT"),
73 (rf
.RAR_FILE_SOLID
, "SOLID"),
74 (rf
.RAR_FILE_LARGE
, "LARGE"),
75 (rf
.RAR_FILE_UNICODE
, "UNICODE"),
76 (rf
.RAR_FILE_SALT
, "SALT"),
77 (rf
.RAR_FILE_VERSION
, "VERSION"),
78 (rf
.RAR_FILE_EXTTIME
, "EXTTIME"),
79 (rf
.RAR_FILE_EXTFLAGS
, "EXTFLAGS"),
80 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
81 (rf
.RAR_LONG_BLOCK
, "LONG"),
85 (rf
.RAR_SKIP_IF_UNKNOWN
, "SKIP"),
86 (rf
.RAR_LONG_BLOCK
, "LONG"),
89 file_parms
= ("D64", "D128", "D256", "D512",
90 "D1024", "D2048", "D4096", "DIR")
93 if sys
.hexversion
< 0x3000000:
94 if isinstance(m
, unicode):
97 sys
.stdout
.write('\n')
99 def render_flags(flags
, bit_list
):
103 known
= known | bit
[0]
106 unknown
= flags
& ~known
110 res
.append("UNK_%04x" % (1 << n
))
111 unknown
= unknown
>> 1
116 def get_file_flags(flags
):
117 res
= render_flags(flags
& ~rf
.RAR_FILE_DICTMASK
, file_bits
)
119 xf
= (flags
& rf
.RAR_FILE_DICTMASK
) >> 5
120 res
+= "," + file_parms
[xf
]
123 def get_main_flags(flags
):
124 return render_flags(flags
, main_bits
)
126 def get_endarc_flags(flags
):
127 return render_flags(flags
, endarc_bits
)
129 def get_generic_flags(flags
):
130 return render_flags(flags
, generic_bits
)
133 if isinstance(t
, datetime
):
134 return t
.isoformat(' ')
135 return "%04d-%02d-%02d %02d:%02d:%02d" % t
139 unknown
= h
.header_size
- h
.header_base
140 xprint("%s: hdrlen=%d datlen=%d hdr_unknown=%d" % (st
, h
.header_size
,
141 h
.add_size
, unknown
))
142 if unknown
> 0 and cf_verbose
> 1:
143 dat
= h
.header_data
[h
.header_base
: ]
144 xprint(" unknown: %s" % hexlify(dat
))
145 if h
.type in (rf
.RAR_BLOCK_FILE
, rf
.RAR_BLOCK_SUB
):
146 if h
.host_os
== rf
.RAR_OS_UNIX
:
147 s_mode
= "0%o" % h
.mode
149 s_mode
= "0x%x" % h
.mode
150 xprint(" flags=0x%04x:%s" % (h
.flags
, get_file_flags(h
.flags
)))
151 if h
.host_os
>= 0 and h
.host_os
< len(os_list
):
152 s_os
= os_list
[h
.host_os
]
155 xprint(" os=%d:%s ver=%d mode=%s meth=%c cmp=%d dec=%d vol=%d" % (
157 h
.extract_version
, s_mode
, h
.compress_type
,
158 h
.compress_size
, h
.file_size
, h
.volume
))
159 ucrc
= (h
.CRC
+ (1 << 32)) & ((1 << 32) - 1)
160 xprint(" crc=0x%08x (%d) time=%s" % (ucrc
, h
.CRC
, fmt_time(h
.date_time
)))
161 xprint(" name=%s" % h
.filename
)
163 xprint(" mtime=%s" % fmt_time(h
.mtime
))
165 xprint(" ctime=%s" % fmt_time(h
.ctime
))
167 xprint(" atime=%s" % fmt_time(h
.atime
))
169 xprint(" arctime=%s" % fmt_time(h
.arctime
))
170 elif h
.type == rf
.RAR_BLOCK_MAIN
:
171 xprint(" flags=0x%04x:%s" % (h
.flags
, get_main_flags(h
.flags
)))
172 elif h
.type == rf
.RAR_BLOCK_ENDARC
:
173 xprint(" flags=0x%04x:%s" % (h
.flags
, get_endarc_flags(h
.flags
)))
174 elif h
.type == rf
.RAR_BLOCK_MARK
:
175 xprint(" flags=0x%04x:" % (h
.flags
,))
177 xprint(" flags=0x%04x:%s" % (h
.flags
, get_generic_flags(h
.flags
)))
179 if h
.comment
is not None:
183 xprint(" comment=%s" % cm
)
192 def check_crc(f
, inf
):
195 ucrc
+= (long(1) << 32)
199 def test_read_long(r
, inf
):
200 f
= r
.open(inf
.filename
)
207 if total
!= inf
.file_size
:
208 xprint("\n *** %s has corrupt file: %s ***" % (r
.rarfile
, inf
.filename
))
209 xprint(" *** short read: got=%d, need=%d ***\n" % (total
, inf
.file_size
))
212 # test .seek() & .readinto()
216 # hack: re-enable crc calc
221 buf
= bytearray(rf
.ZERO
*4096)
223 res
= f
.readinto(buf
)
227 if inf
.file_size
!= total
:
228 xprint(" *** readinto failed: got=%d, need=%d ***\n" % (total
, inf
.file_size
))
232 def test_read(r
, inf
):
233 test_read_long(r
, inf
)
236 def test_real(fn
, psw
):
237 xprint("Archive: %s" % fn
)
244 if not rf
.is_rarfile(fn
):
245 xprint(" --- %s is not a RAR file ---" % fn
)
249 r
= rf
.RarFile(fn
, charset
= cf_charset
, info_callback
= cb
)
251 if r
.needs_password():
255 xprint(" --- %s requires password ---" % fn
)
259 if cf_show_comment
and r
.comment
:
260 for ln
in r
.comment
.split('\n'):
262 elif cf_verbose
== 1 and r
.comment
:
266 xprint(" comment=%s" % cm
)
269 for n
in r
.namelist():
280 for inf
in r
.infolist():
289 except rf
.NeedFirstVolume
:
290 xprint(" --- %s is middle part of multi-vol archive ---" % fn
)
292 exc
, msg
, tb
= sys
.exc_info()
293 xprint("\n *** %s: %s ***\n" % (exc
.__name
__, msg
))
296 exc
, msg
, tb
= sys
.exc_info()
297 xprint("\n *** %s: %s ***\n" % (exc
.__name
__, msg
))
301 global cf_verbose
, cf_show_comment
, cf_charset
302 global cf_extract
, cf_test_read
, cf_test_unrar
308 for a
in sys
.argv
[1:]:
312 for ln
in open(a
[1:], 'r'):
337 raise Exception("unknown switch: "+a
)
345 if __name__
== '__main__':
348 except KeyboardInterrupt: