Application icon and .desktop file

Rearrange modules because of single-version-externally-managed
This commit is contained in:
BasioMeusPuga
2018-03-23 00:58:42 +05:30
parent 42b655862c
commit 7931f92335
139 changed files with 5844 additions and 5483 deletions

15
lector/rarfile/LICENSE Normal file
View File

@@ -0,0 +1,15 @@
Copyright (c) 2005-2016 Marko Kreen <markokr@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

556
lector/rarfile/dumprar.py Executable file
View File

@@ -0,0 +1,556 @@
#! /usr/bin/env python
"""Dump archive contents, test extraction."""
from __future__ import division, absolute_import, print_function
import io
import sys
import getopt
from datetime import datetime
import rarfile as rf
usage = """
dumprar [switches] [ARC1 ARC2 ...] [@ARCLIST]
switches:
@file read archive names from file
-pPSW set password
-Ccharset set fallback charset
-v increase verbosity
-t attempt to read all files
-x write read files out
-c show archive comment
-h show usage
-- stop switch parsing
""".strip()
os_list = ['DOS', 'OS2', 'WIN', 'UNIX', 'MACOS', 'BEOS']
block_strs = ['MARK', 'MAIN', 'FILE', 'OLD_COMMENT', 'OLD_EXTRA',
'OLD_SUB', 'OLD_RECOVERY', 'OLD_AUTH', 'SUB', 'ENDARC']
r5_block_types = {
rf.RAR5_BLOCK_MAIN: 'R5_MAIN',
rf.RAR5_BLOCK_FILE: 'R5_FILE',
rf.RAR5_BLOCK_SERVICE: 'R5_SVC',
rf.RAR5_BLOCK_ENCRYPTION: 'R5_ENC',
rf.RAR5_BLOCK_ENDARC: 'R5_ENDARC',
}
def rar3_type(btype):
"""RAR3 type code as string."""
if btype < rf.RAR_BLOCK_MARK or btype > rf.RAR_BLOCK_ENDARC:
return "*UNKNOWN*"
return block_strs[btype - rf.RAR_BLOCK_MARK]
def rar5_type(btype):
"""RAR5 type code as string."""
return r5_block_types.get(btype, '*UNKNOWN*')
main_bits = (
(rf.RAR_MAIN_VOLUME, "VOL"),
(rf.RAR_MAIN_COMMENT, "COMMENT"),
(rf.RAR_MAIN_LOCK, "LOCK"),
(rf.RAR_MAIN_SOLID, "SOLID"),
(rf.RAR_MAIN_NEWNUMBERING, "NEWNR"),
(rf.RAR_MAIN_AUTH, "AUTH"),
(rf.RAR_MAIN_RECOVERY, "RECOVERY"),
(rf.RAR_MAIN_PASSWORD, "PASSWORD"),
(rf.RAR_MAIN_FIRSTVOLUME, "FIRSTVOL"),
(rf.RAR_SKIP_IF_UNKNOWN, "SKIP"),
(rf.RAR_LONG_BLOCK, "LONG"),
)
endarc_bits = (
(rf.RAR_ENDARC_NEXT_VOLUME, "NEXTVOL"),
(rf.RAR_ENDARC_DATACRC, "DATACRC"),
(rf.RAR_ENDARC_REVSPACE, "REVSPACE"),
(rf.RAR_ENDARC_VOLNR, "VOLNR"),
(rf.RAR_SKIP_IF_UNKNOWN, "SKIP"),
(rf.RAR_LONG_BLOCK, "LONG"),
)
file_bits = (
(rf.RAR_FILE_SPLIT_BEFORE, "SPLIT_BEFORE"),
(rf.RAR_FILE_SPLIT_AFTER, "SPLIT_AFTER"),
(rf.RAR_FILE_PASSWORD, "PASSWORD"),
(rf.RAR_FILE_COMMENT, "COMMENT"),
(rf.RAR_FILE_SOLID, "SOLID"),
(rf.RAR_FILE_LARGE, "LARGE"),
(rf.RAR_FILE_UNICODE, "UNICODE"),
(rf.RAR_FILE_SALT, "SALT"),
(rf.RAR_FILE_VERSION, "VERSION"),
(rf.RAR_FILE_EXTTIME, "EXTTIME"),
(rf.RAR_FILE_EXTFLAGS, "EXTFLAGS"),
(rf.RAR_SKIP_IF_UNKNOWN, "SKIP"),
(rf.RAR_LONG_BLOCK, "LONG"),
)
generic_bits = (
(rf.RAR_SKIP_IF_UNKNOWN, "SKIP"),
(rf.RAR_LONG_BLOCK, "LONG"),
)
file_parms = ("D64", "D128", "D256", "D512",
"D1024", "D2048", "D4096", "DIR")
r5_block_flags = (
(rf.RAR5_BLOCK_FLAG_EXTRA_DATA, 'EXTRA'),
(rf.RAR5_BLOCK_FLAG_DATA_AREA, 'DATA'),
(rf.RAR5_BLOCK_FLAG_SKIP_IF_UNKNOWN, 'SKIP'),
(rf.RAR5_BLOCK_FLAG_SPLIT_BEFORE, 'SPLIT_BEFORE'),
(rf.RAR5_BLOCK_FLAG_SPLIT_AFTER, 'SPLIT_AFTER'),
(rf.RAR5_BLOCK_FLAG_DEPENDS_PREV, 'DEPENDS'),
(rf.RAR5_BLOCK_FLAG_KEEP_WITH_PARENT, 'KEEP'),
)
r5_main_flags = (
(rf.RAR5_MAIN_FLAG_ISVOL, 'ISVOL'),
(rf.RAR5_MAIN_FLAG_HAS_VOLNR, 'VOLNR'),
(rf.RAR5_MAIN_FLAG_SOLID, 'SOLID'),
(rf.RAR5_MAIN_FLAG_RECOVERY, 'RECOVERY'),
(rf.RAR5_MAIN_FLAG_LOCKED, 'LOCKED'),
)
r5_file_flags = (
(rf.RAR5_FILE_FLAG_ISDIR, 'DIR'),
(rf.RAR5_FILE_FLAG_HAS_MTIME, 'MTIME'),
(rf.RAR5_FILE_FLAG_HAS_CRC32, 'CRC32'),
(rf.RAR5_FILE_FLAG_UNKNOWN_SIZE, 'NOSIZE'),
)
r5_enc_flags = (
(rf.RAR5_ENC_FLAG_HAS_CHECKVAL, 'CHECKVAL'),
)
r5_endarc_flags = (
(rf.RAR5_ENDARC_FLAG_NEXT_VOL, 'NEXTVOL'),
)
r5_file_enc_flags = (
(rf.RAR5_XENC_CHECKVAL, 'CHECKVAL'),
(rf.RAR5_XENC_TWEAKED, 'TWEAKED'),
)
r5_file_redir_types = {
rf.RAR5_XREDIR_UNIX_SYMLINK: 'UNIX_SYMLINK',
rf.RAR5_XREDIR_WINDOWS_SYMLINK: 'WINDOWS_SYMLINK',
rf.RAR5_XREDIR_WINDOWS_JUNCTION: 'WINDOWS_JUNCTION',
rf.RAR5_XREDIR_HARD_LINK: 'HARD_LINK',
rf.RAR5_XREDIR_FILE_COPY: 'FILE_COPY',
}
r5_file_redir_flags = (
(rf.RAR5_XREDIR_ISDIR, 'DIR'),
)
def xprint(m, *args):
"""Print string to stdout.
Format unicode safely.
"""
if sys.hexversion < 0x3000000:
m = m.decode('utf8')
if args:
m = m % args
if sys.hexversion < 0x3000000:
m = m.encode('utf8')
sys.stdout.write(m)
sys.stdout.write('\n')
def render_flags(flags, bit_list):
"""Show bit names.
"""
res = []
known = 0
for bit in bit_list:
known = known | bit[0]
if flags & bit[0]:
res.append(bit[1])
unknown = flags & ~known
n = 0
while unknown:
if unknown & 1:
res.append("UNK_%04x" % (1 << n))
unknown = unknown >> 1
n += 1
if not res:
return '-'
return ",".join(res)
def get_file_flags(flags):
"""Show flag names and handle dict size.
"""
res = render_flags(flags & ~rf.RAR_FILE_DICTMASK, file_bits)
xf = (flags & rf.RAR_FILE_DICTMASK) >> 5
res += "," + file_parms[xf]
return res
def fmt_time(t):
"""Format time.
"""
if t is None:
return '(-)'
if isinstance(t, datetime):
return t.isoformat('T')
return "%04d-%02d-%02d %02d:%02d:%02d" % t
def show_item(h):
"""Show any RAR3/5 record.
"""
if isinstance(h, rf.Rar3Info):
show_item_v3(h)
elif isinstance(h, rf.Rar5Info):
show_item_v5(h)
else:
xprint('Unknown info record')
def show_item_v3(h):
"""Show any RAR3 record.
"""
st = rar3_type(h.type)
xprint("%s: hdrlen=%d datlen=%d", st, h.header_size, h.add_size)
if h.type in (rf.RAR_BLOCK_FILE, rf.RAR_BLOCK_SUB):
if h.host_os == rf.RAR_OS_UNIX:
s_mode = "0%o" % h.mode
else:
s_mode = "0x%x" % h.mode
xprint(" flags=0x%04x:%s", h.flags, get_file_flags(h.flags))
if h.host_os >= 0 and h.host_os < len(os_list):
s_os = os_list[h.host_os]
else:
s_os = "?"
xprint(" os=%d:%s ver=%d mode=%s meth=%c cmp=%d dec=%d vol=%d",
h.host_os, s_os,
h.extract_version, s_mode, h.compress_type,
h.compress_size, h.file_size, h.volume)
ucrc = (h.CRC + (1 << 32)) & ((1 << 32) - 1)
xprint(" crc=0x%08x (%d) date_time=%s", ucrc, h.CRC, fmt_time(h.date_time))
xprint(" name=%s", h.filename)
if h.mtime:
xprint(" mtime=%s", fmt_time(h.mtime))
if h.ctime:
xprint(" ctime=%s", fmt_time(h.ctime))
if h.atime:
xprint(" atime=%s", fmt_time(h.atime))
if h.arctime:
xprint(" arctime=%s", fmt_time(h.arctime))
elif h.type == rf.RAR_BLOCK_MAIN:
xprint(" flags=0x%04x:%s", h.flags, render_flags(h.flags, main_bits))
elif h.type == rf.RAR_BLOCK_ENDARC:
xprint(" flags=0x%04x:%s", h.flags, render_flags(h.flags, endarc_bits))
elif h.type == rf.RAR_BLOCK_MARK:
xprint(" flags=0x%04x:", h.flags)
else:
xprint(" flags=0x%04x:%s", h.flags, render_flags(h.flags, generic_bits))
if h.comment is not None:
cm = repr(h.comment)
if cm[0] == 'u':
cm = cm[1:]
xprint(" comment=%s", cm)
def show_item_v5(h):
"""Show any RAR5 record.
"""
st = rar5_type(h.block_type)
xprint("%s: hdrlen=%d datlen=%d hdr_extra=%d", st, h.header_size,
h.compress_size, h.block_extra_size)
xprint(" block_flags=0x%04x:%s", h.block_flags, render_flags(h.block_flags, r5_block_flags))
if h.block_type in (rf.RAR5_BLOCK_FILE, rf.RAR5_BLOCK_SERVICE):
xprint(" name=%s", h.filename)
if h.file_host_os == rf.RAR5_OS_UNIX:
s_os = 'UNIX'
s_mode = "0%o" % h.mode
else:
s_os = 'WINDOWS'
s_mode = "0x%x" % h.mode
xprint(" file_flags=0x%04x:%s", h.file_flags, render_flags(h.file_flags, r5_file_flags))
cmp_flags = h.file_compress_flags
xprint(" cmp_algo=%d cmp_meth=%d dict=%d solid=%r",
cmp_flags & 0x3f,
(cmp_flags >> 7) & 0x07,
cmp_flags >> 10,
cmp_flags & rf.RAR5_COMPR_SOLID > 0)
xprint(" os=%d:%s mode=%s cmp=%r dec=%r vol=%r",
h.file_host_os, s_os, s_mode,
h.compress_size, h.file_size, h.volume)
if h.CRC is not None:
xprint(" crc=0x%08x (%d)", h.CRC, h.CRC)
if h.blake2sp_hash is not None:
xprint(" blake2sp=%s", rf.tohex(h.blake2sp_hash))
if h.date_time is not None:
xprint(" date_time=%s", fmt_time(h.date_time))
if h.mtime:
xprint(" mtime=%s", fmt_time(h.mtime))
if h.ctime:
xprint(" ctime=%s", fmt_time(h.ctime))
if h.atime:
xprint(" atime=%s", fmt_time(h.atime))
if h.arctime:
xprint(" arctime=%s", fmt_time(h.arctime))
if h.flags & rf.RAR_FILE_PASSWORD:
enc_algo, enc_flags, kdf_count, salt, iv, checkval = h.file_encryption
algo_name = 'AES256' if enc_algo == rf.RAR5_XENC_CIPHER_AES256 else 'UnknownAlgo'
xprint(' algo=%d:%s enc_flags=%04x:%s kdf_lg=%d kdf_count=%d salt=%s iv=%s checkval=%s',
enc_algo, algo_name, enc_flags, render_flags(enc_flags, r5_file_enc_flags),
kdf_count, 1 << kdf_count, rf.tohex(salt), rf.tohex(iv),
checkval and rf.tohex(checkval) or '-')
if h.file_redir:
redir_type, redir_flags, redir_name = h.file_redir
xprint(' redir: type=%s flags=%d:%s destination=%s',
r5_file_redir_types.get(redir_type, 'Unknown'),
redir_flags, render_flags(redir_flags, r5_file_redir_flags),
redir_name)
if h.file_owner:
uname, gname, uid, gid = h.file_owner
xprint(' owner: name=%r group=%r uid=%r gid=%r',
uname, gname, uid, gid)
if h.file_version:
flags, version = h.file_version
xprint(' version: flags=%r version=%r', flags, version)
elif h.block_type == rf.RAR5_BLOCK_MAIN:
xprint(" flags=0x%04x:%s", h.flags, render_flags(h.main_flags, r5_main_flags))
elif h.block_type == rf.RAR5_BLOCK_ENDARC:
xprint(" flags=0x%04x:%s", h.flags, render_flags(h.endarc_flags, r5_endarc_flags))
elif h.block_type == rf.RAR5_BLOCK_ENCRYPTION:
algo_name = 'AES256' if h.encryption_algo == rf.RAR5_XENC_CIPHER_AES256 else 'UnknownAlgo'
xprint(" algo=%d:%s flags=0x%04x:%s", h.encryption_algo, algo_name, h.flags,
render_flags(h.encryption_flags, r5_enc_flags))
xprint(" kdf_lg=%d kdf_count=%d", h.encryption_kdf_count, 1 << h.encryption_kdf_count)
xprint(" salt=%s", rf.tohex(h.encryption_salt))
else:
xprint(" - missing info -")
if h.comment is not None:
cm = repr(h.comment)
if cm[0] == 'u':
cm = cm[1:]
xprint(" comment=%s", cm)
cf_show_comment = 0
cf_verbose = 0
cf_charset = None
cf_extract = 0
cf_test_read = 0
cf_test_unrar = 0
cf_test_memory = 0
def check_crc(f, inf, desc):
"""Compare result crc to expected value.
"""
exp = inf._md_expect
if exp is None:
return
ucrc = f._md_context.digest()
if ucrc != exp:
print('crc error - %s - exp=%r got=%r' % (desc, exp, ucrc))
def test_read_long(r, inf):
"""Test read and readinto.
"""
md_class = inf._md_class or rf.NoHashContext
bctx = md_class()
f = r.open(inf.filename)
total = 0
while 1:
data = f.read(8192)
if not data:
break
bctx.update(data)
total += len(data)
if total != inf.file_size:
xprint("\n *** %s has corrupt file: %s ***", r.rarfile, inf.filename)
xprint(" *** short read: got=%d, need=%d ***\n", total, inf.file_size)
check_crc(f, inf, 'read')
bhash = bctx.hexdigest()
if cf_verbose > 1:
if f._md_context.digest() == inf._md_expect:
#xprint(" checkhash: %r", bhash)
pass
else:
xprint(" checkhash: %r got=%r exp=%r cls=%r\n",
bhash, f._md_context.digest(), inf._md_expect, inf._md_class)
# test .seek() & .readinto()
if cf_test_read > 1:
f.seek(0, 0)
total = 0
buf = bytearray(rf.ZERO * 1024)
while 1:
res = f.readinto(buf)
if not res:
break
total += res
if inf.file_size != total:
xprint(" *** readinto failed: got=%d, need=%d ***\n", total, inf.file_size)
#check_crc(f, inf, 'readinto')
f.close()
def test_read(r, inf):
"""Test file read."""
test_read_long(r, inf)
def test_real(fn, psw):
"""Actual archive processing.
"""
xprint("Archive: %s", fn)
cb = None
if cf_verbose > 1:
cb = show_item
rfarg = fn
if cf_test_memory:
rfarg = io.BytesIO(open(fn, 'rb').read())
# check if rar
if not rf.is_rarfile(rfarg):
xprint(" --- %s is not a RAR file ---", fn)
return
# open
r = rf.RarFile(rfarg, charset=cf_charset, info_callback=cb)
# set password
if r.needs_password():
if psw:
r.setpassword(psw)
else:
xprint(" --- %s requires password ---", fn)
return
# show comment
if cf_show_comment and r.comment:
for ln in r.comment.split('\n'):
xprint(" %s", ln)
elif cf_verbose > 0 and r.comment:
cm = repr(r.comment)
if cm[0] == 'u':
cm = cm[1:]
xprint(" comment=%s", cm)
# process
for n in r.namelist():
inf = r.getinfo(n)
if inf.isdir():
continue
if cf_verbose == 1:
show_item(inf)
if cf_test_read:
test_read(r, inf)
if cf_extract:
r.extractall()
for inf in r.infolist():
r.extract(inf)
if cf_test_unrar:
r.testrar()
def test(fn, psw):
"""Process one archive with error handling.
"""
try:
test_real(fn, psw)
except rf.NeedFirstVolume:
xprint(" --- %s is middle part of multi-vol archive ---", fn)
except rf.Error:
exc, msg, tb = sys.exc_info()
xprint("\n *** %s: %s ***\n", exc.__name__, msg)
del tb
except IOError:
exc, msg, tb = sys.exc_info()
xprint("\n *** %s: %s ***\n", exc.__name__, msg)
del tb
def main():
"""Program entry point.
"""
global cf_verbose, cf_show_comment, cf_charset
global cf_extract, cf_test_read, cf_test_unrar
global cf_test_memory
psw = None
# parse args
try:
opts, args = getopt.getopt(sys.argv[1:], 'p:C:hvcxtRM')
except getopt.error as ex:
print(str(ex), file=sys.stderr)
sys.exit(1)
for o, v in opts:
if o == '-p':
psw = v
elif o == '-h':
xprint(usage)
return
elif o == '-v':
cf_verbose += 1
elif o == '-c':
cf_show_comment = 1
elif o == '-x':
cf_extract = 1
elif o == '-t':
cf_test_read += 1
elif o == '-T':
cf_test_unrar = 1
elif o == '-M':
cf_test_memory = 1
elif o == '-C':
cf_charset = v
else:
raise Exception("unhandled switch: " + o)
args2 = []
for a in args:
if a[0] == "@":
for ln in open(a[1:], 'r'):
fn = ln[:-1]
args2.append(fn)
else:
args2.append(a)
args = args2
if not args:
xprint(usage)
# pypy .readinto()+memoryview() is buggy
#if cf_test_read > 1 and hasattr(sys, 'pypy_version_info'):
# cf_test_read = 1
for fn in args:
test(fn, psw)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass

3011
lector/rarfile/rarfile.py Normal file

File diff suppressed because it is too large Load Diff