diff --git a/doc/README.txt b/doc/README.txt
index 0a0ce09..8aa3a9a 100644
--- a/doc/README.txt
+++ b/doc/README.txt
@@ -30,6 +30,9 @@ Examples
# Extract several archives with different formats
patool extract archive.zip otherarchive.rar
+# Extract archive with password
+patool extract --password somepassword archive.rar
+
# Test archive integrity
patool test --verbose dist.tar.gz
@@ -39,6 +42,9 @@ patool list package.deb
# Create a new archive
patool create --verbose /path/to/myfiles.zip file1.txt dir/
+# Create a new archive with password
+patool create --verbose --password somepassword /path/to/myfiles.zip file1.txt dir/
+
# Show differences between two archives
patool diff release1.0.tar.gz release2.0.zip
diff --git a/patool b/patool
index 0bc523d..6e9c83d 100755
--- a/patool
+++ b/patool
@@ -30,7 +30,7 @@ def run_extract(args):
res = 0
for archive in args.archive:
try:
- patoolib.extract_archive(archive, verbosity=args.verbosity, interactive=args.interactive, outdir=args.outdir)
+ patoolib.extract_archive(archive, verbosity=args.verbosity, interactive=args.interactive, outdir=args.outdir, password=args.password)
except PatoolError as msg:
log_error("error extracting %s: %s" % (archive, msg))
res += 1
@@ -44,7 +44,7 @@ def run_list(args):
try:
# increase default verbosity since the listing output should be visible
verbosity = args.verbosity + 1
- patoolib.list_archive(archive, verbosity=verbosity, interactive=args.interactive)
+ patoolib.list_archive(archive, verbosity=verbosity, interactive=args.interactive, password=args.password)
except PatoolError as msg:
log_error("error listing %s: %s" % (archive, msg))
res += 1
@@ -56,7 +56,7 @@ def run_test(args):
res = 0
for archive in args.archive:
try:
- patoolib.test_archive(archive, verbosity=args.verbosity, interactive=args.interactive)
+ patoolib.test_archive(archive, verbosity=args.verbosity, interactive=args.interactive, password=args.password)
except PatoolError as msg:
log_error("error testing %s: %s" % (archive, msg))
res += 1
@@ -67,7 +67,7 @@ def run_create(args):
"""Create an archive from given files."""
res = 0
try:
- patoolib.create_archive(args.archive, args.filename, verbosity=args.verbosity, interactive=args.interactive)
+ patoolib.create_archive(args.archive, args.filename, verbosity=args.verbosity, interactive=args.interactive, password=args.password)
except PatoolError as msg:
log_error("error creating %s: %s" % (args.archive, msg))
res = 1
@@ -87,7 +87,7 @@ def run_diff(args):
def run_search(args):
"""Search for pattern in given archive."""
try:
- res = patoolib.search_archive(args.pattern, args.archive, verbosity=args.verbosity, interactive=args.interactive)
+ res = patoolib.search_archive(args.pattern, args.archive, verbosity=args.verbosity, interactive=args.interactive, password=args.password)
except PatoolError as msg:
log_error("error searching %s: %s" % (args.archive, msg))
res = 2
@@ -109,7 +109,7 @@ def run_recompress(args):
"""Recompress an archive to smaller size."""
res = 0
try:
- patoolib.recompress_archive(args.archive, verbosity=args.verbosity, interactive=args.interactive)
+ patoolib.recompress_archive(args.archive, verbosity=args.verbosity, interactive=args.interactive, password=args.password)
except PatoolError as msg:
log_error("error recompressing %s: %s" % (args.archive, msg))
res = 1
@@ -164,16 +164,20 @@ def create_argparser():
# extract
parser_extract = subparsers.add_parser('extract', help='extract one or more archives')
parser_extract.add_argument('--outdir', help="output directory to extract to")
+ parser_extract.add_argument('--password', help="password for encrypted files")
parser_extract.add_argument('archive', nargs='+', help="an archive file")
# list
parser_list = subparsers.add_parser('list', help='list members or one or more archives')
+ parser_list.add_argument('--password', help="password for encrypted files")
parser_list.add_argument('archive', nargs='+', help="an archive file")
# create
parser_create = subparsers.add_parser('create', help='create an archive')
+ parser_create.add_argument('--password', help="password to encrypt files")
parser_create.add_argument('archive', help="the archive file; the file extension determines the archive program")
parser_create.add_argument('filename', nargs='+', help="a file or directory to add to the archive; note that some archive programs do not support directories")
# test
parser_test = subparsers.add_parser('test', help='test an archive')
+ parser_test.add_argument('--password', help="password for encrypted files")
parser_test.add_argument('archive', nargs='+', help='an archive file')
# repack
parser_repack = subparsers.add_parser('repack', help='repack an archive to a different format')
@@ -181,6 +185,7 @@ def create_argparser():
parser_repack.add_argument('archive_dst', help='target archive file')
# recompress
parser_recompress = subparsers.add_parser('recompress', help='recompress an archive to smaller size')
+ parser_recompress.add_argument('--password', help="password for encrypted files")
parser_recompress.add_argument('archive', help='an archive file')
# diff
parser_diff = subparsers.add_parser('diff', help='show differences between two archives')
@@ -188,6 +193,7 @@ def create_argparser():
parser_diff.add_argument('archive2', help='the second archive file')
# search
parser_search = subparsers.add_parser('search', help="search contents of archive members")
+ parser_search.add_argument('--password', help="password for encrypted files")
parser_search.add_argument('pattern', help='the grep(1) compatible search pattern')
parser_search.add_argument('archive', help='the archive file')
# formats
diff --git a/patoolib/__init__.py b/patoolib/__init__.py
index 1b15d0a..1c2e423 100644
--- a/patoolib/__init__.py
+++ b/patoolib/__init__.py
@@ -14,6 +14,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
from __future__ import print_function
+
+import inspect
import sys
if not hasattr(sys, "version_info") or sys.version_info < (2, 7, 0, "final", 0):
raise SystemExit("This program requires Python 2.7 or later.")
@@ -273,6 +275,46 @@ ArchivePrograms = {
},
}
+# List of programs by archive type, which don't support password use
+NoPasswordSupportArchivePrograms = {
+ 'bzip2': {
+ None: ('7z', )
+ },
+ 'cab': {
+ None: ('7z', )
+ },
+ 'zip': {
+ 'create': ('py_zipfile', ),
+ },
+ 'arj': {
+ None: ('7z',)
+ },
+ 'gzip': {
+ None: ('7z',)
+ },
+ 'iso': {
+ None: ('7z',)
+ },
+ 'cpio': {
+ None: ('7z', )
+ },
+ 'rpm': {
+ None: ('7z', )
+ },
+ 'deb': {
+ None: ('7z', )
+ },
+ 'lzma': {
+ None: ('7z', )
+ },
+ 'vhd': {
+ None: ('7z', )
+ },
+ 'xz': {
+ None: ('7z',)
+ },
+}
+
# List those programs that have different python module names because of
# Python module naming restrictions.
ProgramModules = {
@@ -322,7 +364,7 @@ def check_archive_format (format, compression):
raise util.PatoolError("unkonwn archive compression `%s'" % compression)
-def find_archive_program (format, command, program=None):
+def find_archive_program (format, command, program=None, password=None):
"""Find suitable archive program for given format and mode."""
commands = ArchivePrograms[format]
programs = []
@@ -333,6 +375,8 @@ def find_archive_program (format, command, program=None):
for key in (None, command):
if key in commands:
programs.extend(commands[key])
+ if password is not None:
+ programs = _remove_command_without_password_support(programs, format, command)
if not programs:
raise util.PatoolError("%s archive format `%s' is not supported" % (command, format))
# return the first existing program
@@ -349,6 +393,26 @@ def find_archive_program (format, command, program=None):
raise util.PatoolError("could not find an executable program to %s format %s; candidates are (%s)," % (command, format, ",".join(programs)))
+def _remove_command_without_password_support(programs, format, command):
+ """Remove programs if they don't support work with password for current
+ format and command."""
+ if format not in NoPasswordSupportArchivePrograms:
+ return programs
+ no_password_support_commands = NoPasswordSupportArchivePrograms[format]
+ no_password_support_programs = set()
+ for key in (None, command):
+ if key in no_password_support_commands:
+ for program in no_password_support_commands[key]:
+ no_password_support_programs.add(program)
+ programs_with_support = []
+ for program in programs:
+ if program not in no_password_support_programs:
+ programs_with_support.append(program)
+ if not programs_with_support and programs:
+ raise util.PatoolError("%s archive format `%s' with password is not supported" % (command, format))
+ return programs_with_support
+
+
def list_formats ():
"""Print information about available archive formats to stdout."""
print("Archive programs of", App)
@@ -463,14 +527,14 @@ def cleanup_outdir (outdir, archive):
def _extract_archive(archive, verbosity=0, interactive=True, outdir=None,
- program=None, format=None, compression=None):
+ program=None, format=None, compression=None, password=None):
"""Extract an archive.
@return: output directory if command is 'extract', else None
"""
if format is None:
format, compression = get_archive_format(archive)
check_archive_format(format, compression)
- program = find_archive_program(format, 'extract', program=program)
+ program = find_archive_program(format, 'extract', program=program, password=password)
check_program_compression(archive, 'extract', program, compression)
get_archive_cmdlist = get_archive_cmdlist_func(program, 'extract', format)
if outdir is None:
@@ -479,7 +543,7 @@ def _extract_archive(archive, verbosity=0, interactive=True, outdir=None,
else:
do_cleanup_outdir = False
try:
- cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, outdir)
+ cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, outdir, password=password)
if cmdlist:
# an empty command list means the get_archive_cmdlist() function
# already handled the command (eg. when it's a builtin Python
@@ -502,12 +566,12 @@ def _extract_archive(archive, verbosity=0, interactive=True, outdir=None,
def _create_archive(archive, filenames, verbosity=0, interactive=True,
- program=None, format=None, compression=None):
+ program=None, format=None, compression=None, password=None):
"""Create an archive."""
if format is None:
format, compression = get_archive_format(archive)
check_archive_format(format, compression)
- program = find_archive_program(format, 'create', program=program)
+ program = find_archive_program(format, 'create', program=program, password=password)
check_program_compression(archive, 'create', program, compression)
get_archive_cmdlist = get_archive_cmdlist_func(program, 'create', format)
origarchive = None
@@ -516,7 +580,7 @@ def _create_archive(archive, filenames, verbosity=0, interactive=True,
# the arc program mangles the archive name if it contains ".arc"
origarchive = archive
archive = util.tmpfile(dir=os.path.dirname(archive), suffix=".arc")
- cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, filenames)
+ cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, filenames, password=password)
if cmdlist:
# an empty command list means the get_archive_cmdlist() function
# already handled the command (eg. when it's a builtin Python
@@ -527,18 +591,18 @@ def _create_archive(archive, filenames, verbosity=0, interactive=True,
def _handle_archive(archive, command, verbosity=0, interactive=True,
- program=None, format=None, compression=None):
+ program=None, format=None, compression=None, password=None):
"""Test and list archives."""
if format is None:
format, compression = get_archive_format(archive)
check_archive_format(format, compression)
if command not in ('list', 'test'):
raise util.PatoolError("invalid archive command `%s'" % command)
- program = find_archive_program(format, command, program=program)
+ program = find_archive_program(format, command, program=program, password=password)
check_program_compression(archive, command, program, compression)
get_archive_cmdlist = get_archive_cmdlist_func(program, command, format)
# prepare keyword arguments for command list
- cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive)
+ cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, password=password)
if cmdlist:
# an empty command list means the get_archive_cmdlist() function
# already handled the command (eg. when it's a builtin Python
@@ -558,7 +622,23 @@ def get_archive_cmdlist_func (program, command, format):
raise util.PatoolError(msg)
# get archive handler function (eg. patoolib.programs.star.extract_tar)
try:
- return getattr(module, '%s_%s' % (command, format))
+ archive_cmdlist_func = getattr(module, '%s_%s' % (command, format))
+ def check_for_password_before_cmdlist_func_call(*args, **kwargs):
+ """ If password is None, or not set, run command as usual.
+ If password is set, but can't be accepted raise appropriate
+ message.
+ """
+ util.log_info("... cmdlist_func = %s %s" % (archive_cmdlist_func, ''))
+ util.log_info("... kwargs=%s args=%s" % (kwargs, args))
+ if 'password' in kwargs and kwargs['password'] is None:
+ kwargs.pop('password')
+ if 'password' not in kwargs:
+ return archive_cmdlist_func(*args, **kwargs)
+ else:
+ if 'password' in inspect.signature(archive_cmdlist_func).parameters:
+ return archive_cmdlist_func(*args, **kwargs)
+ raise util.PatoolError('There is no support for password in %s' % program)
+ return check_for_password_before_cmdlist_func_call
except AttributeError as msg:
raise util.PatoolError(msg)
@@ -593,7 +673,7 @@ def _diff_archives (archive1, archive2, verbosity=0, interactive=True):
shutil.rmtree(tmpdir1, onerror=rmtree_log_error)
-def _search_archive(pattern, archive, verbosity=0, interactive=True):
+def _search_archive(pattern, archive, verbosity=0, interactive=True, password=None):
"""Search for given pattern in an archive."""
grep = util.find_program("grep")
if not grep:
@@ -601,13 +681,13 @@ def _search_archive(pattern, archive, verbosity=0, interactive=True):
raise util.PatoolError(msg)
tmpdir = util.tmpdir()
try:
- path = _extract_archive(archive, outdir=tmpdir, verbosity=-1)
+ path = _extract_archive(archive, outdir=tmpdir, verbosity=-1, password=password)
return util.run_checked([grep, "-r", "-e", pattern, "."], ret_ok=(0, 1), verbosity=1, cwd=path)
finally:
shutil.rmtree(tmpdir, onerror=rmtree_log_error)
-def _repack_archive (archive1, archive2, verbosity=0, interactive=True):
+def _repack_archive (archive1, archive2, verbosity=0, interactive=True, password=None):
"""Repackage an archive to a different format."""
format1, compression1 = get_archive_format(archive1)
format2, compression2 = get_archive_format(archive2)
@@ -617,7 +697,7 @@ def _repack_archive (archive1, archive2, verbosity=0, interactive=True):
return
tmpdir = util.tmpdir()
try:
- kwargs = dict(verbosity=verbosity, outdir=tmpdir)
+ kwargs = dict(verbosity=verbosity, outdir=tmpdir, password=password)
same_format = (format1 == format2 and compression1 and compression2)
if same_format:
# only decompress since the format is the same
@@ -628,7 +708,7 @@ def _repack_archive (archive1, archive2, verbosity=0, interactive=True):
olddir = os.getcwd()
os.chdir(path)
try:
- kwargs = dict(verbosity=verbosity, interactive=interactive)
+ kwargs = dict(verbosity=verbosity, interactive=interactive, password=password)
if same_format:
# only compress since the format is the same
kwargs['format'] = compression2
@@ -639,7 +719,7 @@ def _repack_archive (archive1, archive2, verbosity=0, interactive=True):
shutil.rmtree(tmpdir, onerror=rmtree_log_error)
-def _recompress_archive(archive, verbosity=0, interactive=True):
+def _recompress_archive(archive, verbosity=0, interactive=True, password=None):
"""Try to recompress an archive to smaller size."""
format, compression = get_archive_format(archive)
if compression:
@@ -651,13 +731,13 @@ def _recompress_archive(archive, verbosity=0, interactive=True):
archive2 = util.get_single_outfile(tmpdir2, base, extension=ext)
try:
# extract
- kwargs = dict(verbosity=verbosity, format=format, outdir=tmpdir)
+ kwargs = dict(verbosity=verbosity, format=format, outdir=tmpdir, password=password)
path = _extract_archive(archive, **kwargs)
# compress to new file
olddir = os.getcwd()
os.chdir(path)
try:
- kwargs = dict(verbosity=verbosity, interactive=interactive, format=format)
+ kwargs = dict(verbosity=verbosity, interactive=interactive, format=format, password=password)
files = tuple(os.listdir(path))
_create_archive(archive2, files, **kwargs)
finally:
@@ -679,44 +759,43 @@ def _recompress_archive(archive, verbosity=0, interactive=True):
# the patool library API
-def extract_archive(archive, verbosity=0, outdir=None, program=None, interactive=True):
+def extract_archive(archive, verbosity=0, outdir=None, program=None, interactive=True, password=None):
"""Extract given archive."""
util.check_existing_filename(archive)
if verbosity >= 0:
util.log_info("Extracting %s ..." % archive)
- return _extract_archive(archive, verbosity=verbosity, interactive=interactive, outdir=outdir, program=program)
+ return _extract_archive(archive, verbosity=verbosity, interactive=interactive, outdir=outdir, program=program, password=password)
-def list_archive(archive, verbosity=1, program=None, interactive=True):
+def list_archive(archive, verbosity=1, program=None, interactive=True, password=None):
"""List given archive."""
# Set default verbosity to 1 since the listing output should be visible.
util.check_existing_filename(archive)
if verbosity >= 0:
util.log_info("Listing %s ..." % archive)
- return _handle_archive(archive, 'list', verbosity=verbosity,
- interactive=interactive, program=program)
+ return _handle_archive(archive, 'list', verbosity=verbosity, interactive=interactive, program=program, password=password)
-def test_archive(archive, verbosity=0, program=None, interactive=True):
+def test_archive(archive, verbosity=0, program=None, interactive=True, password=None):
"""Test given archive."""
util.check_existing_filename(archive)
if verbosity >= 0:
util.log_info("Testing %s ..." % archive)
res = _handle_archive(archive, 'test', verbosity=verbosity,
- interactive=interactive, program=program)
+ interactive=interactive, program=program, password=password)
if verbosity >= 0:
util.log_info("... tested ok.")
return res
-def create_archive(archive, filenames, verbosity=0, program=None, interactive=True):
+def create_archive(archive, filenames, verbosity=0, program=None, interactive=True, password=None):
"""Create given archive with given files."""
util.check_new_filename(archive)
util.check_archive_filelist(filenames)
if verbosity >= 0:
util.log_info("Creating %s ..." % archive)
res = _create_archive(archive, filenames, verbosity=verbosity,
- interactive=interactive, program=program)
+ interactive=interactive, program=program, password=password)
if verbosity >= 0:
util.log_info("... %s created." % archive)
return res
@@ -733,38 +812,38 @@ def diff_archives(archive1, archive2, verbosity=0, interactive=True):
util.log_info("... no differences found.")
-def search_archive(pattern, archive, verbosity=0, interactive=True):
+def search_archive(pattern, archive, verbosity=0, interactive=True, password=None):
"""Search pattern in archive members."""
if not pattern:
raise util.PatoolError("empty search pattern")
util.check_existing_filename(archive)
if verbosity >= 0:
util.log_info("Searching %r in %s ..." % (pattern, archive))
- res = _search_archive(pattern, archive, verbosity=verbosity, interactive=interactive)
+ res = _search_archive(pattern, archive, verbosity=verbosity, interactive=interactive, password=password)
if res == 1 and verbosity >= 0:
util.log_info("... %r not found" % pattern)
return res
-def repack_archive (archive, archive_new, verbosity=0, interactive=True):
+def repack_archive (archive, archive_new, verbosity=0, interactive=True, password=None):
"""Repack archive to different file and/or format."""
util.check_existing_filename(archive)
util.check_new_filename(archive_new)
if verbosity >= 0:
util.log_info("Repacking %s to %s ..." % (archive, archive_new))
- res = _repack_archive(archive, archive_new, verbosity=verbosity, interactive=interactive)
+ res = _repack_archive(archive, archive_new, verbosity=verbosity, interactive=interactive, password=password)
if verbosity >= 0:
util.log_info("... repacking successful.")
return res
-def recompress_archive(archive, verbosity=0, interactive=True):
+def recompress_archive(archive, verbosity=0, interactive=True, password=None):
"""Recompress an archive to hopefully smaller size."""
util.check_existing_filename(archive)
util.check_writable_filename(archive)
if verbosity >= 0:
util.log_info("Recompressing %s ..." % (archive,))
- res = _recompress_archive(archive, verbosity=verbosity, interactive=interactive)
+ res = _recompress_archive(archive, verbosity=verbosity, interactive=interactive, password=password)
if res and verbosity >= 0:
util.log_info(res)
return 0
diff --git a/patoolib/programs/arc.py b/patoolib/programs/arc.py
index cce9679..8eadaf2 100644
--- a/patoolib/programs/arc.py
+++ b/patoolib/programs/arc.py
@@ -15,30 +15,46 @@
# along with this program. If not, see .
"""Archive commands for the arc program."""
import os
+from ..util import PatoolError
-def extract_arc (archive, compression, cmd, verbosity, interactive, outdir):
+
+def _add_password_to_options(options, password):
+ """Check password and add it to ARC options."""
+ if password is None:
+ return options
+ if ' ' in password:
+ raise PatoolError("Password for ARC can't contain spaces.")
+ options += 'g%s' % password
+ return options
+
+
+def extract_arc (archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a ARC archive."""
# Since extracted files will be placed in the current directory,
# the cwd argument has to be the output directory.
- cmdlist = [cmd, 'x', os.path.abspath(archive)]
+ options = _add_password_to_options('x', password)
+ cmdlist = [cmd, options, os.path.abspath(archive)]
return (cmdlist, {'cwd': outdir})
-def list_arc (archive, compression, cmd, verbosity, interactive):
+
+def list_arc (archive, compression, cmd, verbosity, interactive, password=None):
"""List a ARC archive."""
cmdlist = [cmd]
if verbosity > 1:
- cmdlist.append('v')
+ cmdlist.append(_add_password_to_options('v', password))
else:
- cmdlist.append('l')
+ cmdlist.append(_add_password_to_options('l', password))
cmdlist.append(archive)
return cmdlist
-def test_arc (archive, compression, cmd, verbosity, interactive):
- """Test a ARC archive."""
- return [cmd, 't', archive]
-def create_arc (archive, compression, cmd, verbosity, interactive, filenames):
+def test_arc (archive, compression, cmd, verbosity, interactive, password=None):
+ """Test a ARC archive."""
+ return [cmd, _add_password_to_options('t', password), archive]
+
+
+def create_arc (archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create a ARC archive."""
- cmdlist = [cmd, 'a', archive]
+ cmdlist = [cmd, _add_password_to_options('a', password), archive]
cmdlist.extend(filenames)
return cmdlist
diff --git a/patoolib/programs/arj.py b/patoolib/programs/arj.py
index 2547c0e..9fb751f 100644
--- a/patoolib/programs/arj.py
+++ b/patoolib/programs/arj.py
@@ -14,19 +14,33 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
"""Archive commands for the arj program."""
+from ..util import PatoolError
-def extract_arj (archive, compression, cmd, verbosity, interactive, outdir):
+def _get_password_switch(password):
+ """Check password and return password switch for ARJ."""
+ if ' ' in password:
+ raise PatoolError("Password for ARJ can't contain spaces.")
+ return '-g%s' % password
+
+def _maybe_add_password(cmdlist, password):
+ if password:
+ cmdlist.append(_get_password_switch(password))
+
+
+def extract_arj (archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract an ARJ archive."""
cmdlist = [cmd, 'x', '-r']
+ _maybe_add_password(cmdlist, password)
if not interactive:
cmdlist.append('-y')
cmdlist.extend([archive, outdir])
return cmdlist
-def list_arj (archive, compression, cmd, verbosity, interactive):
+def list_arj (archive, compression, cmd, verbosity, interactive, password=None):
"""List an ARJ archive."""
cmdlist = [cmd]
+ _maybe_add_password(cmdlist, password)
if verbosity > 1:
cmdlist.append('v')
else:
@@ -37,18 +51,20 @@ def list_arj (archive, compression, cmd, verbosity, interactive):
return cmdlist
-def test_arj (archive, compression, cmd, verbosity, interactive):
+def test_arj (archive, compression, cmd, verbosity, interactive, password=None):
"""Test an ARJ archive."""
cmdlist = [cmd, 't', '-r']
+ _maybe_add_password(cmdlist, password)
if not interactive:
cmdlist.append('-y')
cmdlist.append(archive)
return cmdlist
-def create_arj (archive, compression, cmd, verbosity, interactive, filenames):
+def create_arj (archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create an ARJ archive."""
cmdlist = [cmd, 'a', '-r']
+ _maybe_add_password(cmdlist, password)
if not interactive:
cmdlist.append('-y')
cmdlist.append(archive)
diff --git a/patoolib/programs/p7zip.py b/patoolib/programs/p7zip.py
index dd23c77..ee1865a 100644
--- a/patoolib/programs/p7zip.py
+++ b/patoolib/programs/p7zip.py
@@ -15,21 +15,27 @@
# along with this program. If not, see .
"""Archive commands for the 7z program."""
-def extract_7z(archive, compression, cmd, verbosity, interactive, outdir):
+def _maybe_add_password(cmdlist, password):
+ if password:
+ cmdlist.append('-p%s' % password)
+
+def extract_7z(archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a 7z archive."""
cmdlist = [cmd, 'x']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['-o%s' % outdir, '--', archive])
return cmdlist
-def extract_7z_singlefile(archive, compression, cmd, verbosity, interactive, outdir):
+def extract_7z_singlefile(archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a singlefile archive (eg. gzip or bzip2) with '7z e'.
This makes sure a single file and no subdirectories are created,
which would cause errors with patool repack."""
cmdlist = [cmd, 'e']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['-o%s' % outdir, '--', archive])
return cmdlist
@@ -51,11 +57,12 @@ extract_zip = \
extract_vhd = \
extract_7z
-def list_7z (archive, compression, cmd, verbosity, interactive):
+def list_7z (archive, compression, cmd, verbosity, interactive, password=None):
"""List a 7z archive."""
cmdlist = [cmd, 'l']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['--', archive])
return cmdlist
@@ -76,11 +83,12 @@ list_bzip2 = \
list_7z
-def test_7z (archive, compression, cmd, verbosity, interactive):
+def test_7z (archive, compression, cmd, verbosity, interactive, password=None):
"""Test a 7z archive."""
cmdlist = [cmd, 't']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['--', archive])
return cmdlist
@@ -101,51 +109,56 @@ test_bzip2 = \
test_7z
-def create_7z(archive, compression, cmd, verbosity, interactive, filenames):
+def create_7z(archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create a 7z archive."""
cmdlist = [cmd, 'a']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['-t7z', '-mx=9', '--', archive])
cmdlist.extend(filenames)
return cmdlist
-def create_zip(archive, compression, cmd, verbosity, interactive, filenames):
+def create_zip(archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create a ZIP archive."""
cmdlist = [cmd, 'a']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['-tzip', '-mx=9', '--', archive])
cmdlist.extend(filenames)
return cmdlist
-def create_xz(archive, compression, cmd, verbosity, interactive, filenames):
+def create_xz(archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create an XZ archive."""
cmdlist = [cmd, 'a']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['-txz', '-mx=9', '--', archive])
cmdlist.extend(filenames)
return cmdlist
-def create_gzip(archive, compression, cmd, verbosity, interactive, filenames):
+def create_gzip(archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create a GZIP archive."""
cmdlist = [cmd, 'a']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['-tgzip', '-mx=9', '--', archive])
cmdlist.extend(filenames)
return cmdlist
-def create_bzip2(archive, compression, cmd, verbosity, interactive, filenames):
+def create_bzip2(archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create a BZIP2 archive."""
cmdlist = [cmd, 'a']
if not interactive:
cmdlist.append('-y')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['-tbzip2', '-mx=9', '--', archive])
cmdlist.extend(filenames)
return cmdlist
diff --git a/patoolib/programs/py_zipfile.py b/patoolib/programs/py_zipfile.py
index 73daf98..4529036 100644
--- a/patoolib/programs/py_zipfile.py
+++ b/patoolib/programs/py_zipfile.py
@@ -22,10 +22,12 @@ import os
READ_SIZE_BYTES = 1024*1024
-def list_zip(archive, compression, cmd, verbosity, interactive):
+def list_zip(archive, compression, cmd, verbosity, interactive, password=None):
"""List member of a ZIP archive with the zipfile Python module."""
try:
with zipfile.ZipFile(archive, "r") as zfile:
+ if password:
+ zfile.setpassword(pwd=password.encode())
for name in zfile.namelist():
if verbosity >= 0:
print(name)
@@ -36,11 +38,13 @@ def list_zip(archive, compression, cmd, verbosity, interactive):
test_zip = list_zip
-def extract_zip(archive, compression, cmd, verbosity, interactive, outdir):
+def extract_zip(archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a ZIP archive with the zipfile Python module."""
try:
+ if password:
+ password = password.encode()
with zipfile.ZipFile(archive) as zfile:
- zfile.extractall(outdir)
+ zfile.extractall(outdir, pwd=password)
except Exception as err:
msg = "error extracting %s: %s" % (archive, err)
raise util.PatoolError(msg)
diff --git a/patoolib/programs/rar.py b/patoolib/programs/rar.py
index b635e7c..96d1f46 100644
--- a/patoolib/programs/rar.py
+++ b/patoolib/programs/rar.py
@@ -16,15 +16,17 @@
"""Archive commands for the rar program."""
import os
-def extract_rar (archive, compression, cmd, verbosity, interactive, outdir):
+def extract_rar (archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a RAR archive."""
cmdlist = [cmd, 'x']
if not interactive:
cmdlist.extend(['-p-', '-y'])
+ if password:
+ cmdlist.append('-p%s' % password)
cmdlist.extend(['--', os.path.abspath(archive)])
return (cmdlist, {'cwd': outdir})
-def list_rar (archive, compression, cmd, verbosity, interactive):
+def list_rar (archive, compression, cmd, verbosity, interactive, password=None):
"""List a RAR archive."""
cmdlist = [cmd]
if verbosity > 1:
@@ -33,22 +35,28 @@ def list_rar (archive, compression, cmd, verbosity, interactive):
cmdlist.append('l')
if not interactive:
cmdlist.extend(['-p-', '-y'])
+ if password:
+ cmdlist.append('-p%s' % password)
cmdlist.extend(['--', archive])
return cmdlist
-def test_rar (archive, compression, cmd, verbosity, interactive):
+def test_rar (archive, compression, cmd, verbosity, interactive, password=None):
"""Test a RAR archive."""
cmdlist = [cmd, 't']
if not interactive:
cmdlist.extend(['-p-', '-y'])
+ if password:
+ cmdlist.append('-p%s' % password)
cmdlist.extend(['--', archive])
return cmdlist
-def create_rar (archive, compression, cmd, verbosity, interactive, filenames):
+def create_rar (archive, compression, cmd, verbosity, interactive, filenames, password=None):
"""Create a RAR archive."""
cmdlist = [cmd, 'a']
if not interactive:
cmdlist.append('-y')
+ if password:
+ cmdlist.append('-p%s' % password)
cmdlist.extend(['-r', '-m5', '--', archive])
cmdlist.extend(filenames)
return cmdlist
diff --git a/patoolib/programs/unace.py b/patoolib/programs/unace.py
index 845b985..2daf232 100644
--- a/patoolib/programs/unace.py
+++ b/patoolib/programs/unace.py
@@ -15,24 +15,32 @@
# along with this program. If not, see .
"""Archive commands for the unace program."""
-def extract_ace (archive, compression, cmd, verbosity, interactive, outdir):
+def extract_ace (archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract an ACE archive."""
cmdlist = [cmd, 'x']
if not outdir.endswith('/'):
outdir += '/'
+ if password:
+ cmdlist.append('-p%s' % password)
cmdlist.extend([archive, outdir])
return cmdlist
-def list_ace (archive, compression, cmd, verbosity, interactive):
+def list_ace (archive, compression, cmd, verbosity, interactive, password=None):
"""List an ACE archive."""
cmdlist = [cmd]
if verbosity > 1:
cmdlist.append('v')
else:
cmdlist.append('l')
+ if password:
+ cmdlist.append('-p%s' % password)
cmdlist.append(archive)
return cmdlist
-def test_ace (archive, compression, cmd, verbosity, interactive):
+def test_ace (archive, compression, cmd, verbosity, interactive, password=None):
"""Test an ACE archive."""
- return [cmd, 't', archive]
+ cmdlist = [cmd, 't']
+ if password:
+ cmdlist.append('-p%s' % password)
+ cmdlist.append(archive)
+ return cmdlist
diff --git a/patoolib/programs/unalz.py b/patoolib/programs/unalz.py
index 4255f26..4bb64d2 100644
--- a/patoolib/programs/unalz.py
+++ b/patoolib/programs/unalz.py
@@ -15,13 +15,24 @@
# along with this program. If not, see .
"""Archive commands for the unalz program."""
-def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir):
+def _maybe_add_password(cmdlist, password):
+ if password:
+ cmdlist.extend(['-pwd', password])
+
+
+def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a ALZIP archive."""
- return [cmd, '-d', outdir, archive]
+ cmdlist = [cmd, '-d', outdir]
+ _maybe_add_password(cmdlist, password)
+ cmdlist.append(archive)
+ return cmdlist
-def list_alzip (archive, compression, cmd, verbosity, interactive):
+def list_alzip (archive, compression, cmd, verbosity, interactive, password=None):
"""List a ALZIP archive."""
- return [cmd, '-l', archive]
+ cmdlist = [cmd, '-l']
+ _maybe_add_password(cmdlist, password)
+ cmdlist.append(archive)
+ return cmdlist
test_alzip = list_alzip
diff --git a/patoolib/programs/unzip.py b/patoolib/programs/unzip.py
index 1768f72..b87e497 100644
--- a/patoolib/programs/unzip.py
+++ b/patoolib/programs/unzip.py
@@ -15,26 +15,33 @@
# along with this program. If not, see .
"""Archive commands for the unzip program."""
-def extract_zip (archive, compression, cmd, verbosity, interactive, outdir):
+def _maybe_add_password(cmdlist, password):
+ if password:
+ cmdlist.extend(['-P', password])
+
+def extract_zip (archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a ZIP archive."""
cmdlist = [cmd]
if verbosity > 1:
cmdlist.append('-v')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['--', archive, '-d', outdir])
return cmdlist
-def list_zip (archive, compression, cmd, verbosity, interactive):
+def list_zip (archive, compression, cmd, verbosity, interactive, password=None):
"""List a ZIP archive."""
cmdlist = [cmd, '-l']
if verbosity > 1:
cmdlist.append('-v')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['--', archive])
return cmdlist
-def test_zip (archive, compression, cmd, verbosity, interactive):
+def test_zip (archive, compression, cmd, verbosity, interactive, password=None):
"""Test a ZIP archive."""
cmdlist = [cmd, '-t']
if verbosity > 1:
cmdlist.append('-v')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['--', archive])
return cmdlist
diff --git a/patoolib/programs/xdms.py b/patoolib/programs/xdms.py
index c1935f3..a05fe8f 100644
--- a/patoolib/programs/xdms.py
+++ b/patoolib/programs/xdms.py
@@ -17,26 +17,38 @@
from .. import util
-def extract_dms (archive, compression, cmd, verbosity, interactive, outdir):
+def _maybe_add_password(cmdlist, password):
+ if password:
+ cmdlist.extend(['-p', password])
+
+
+def extract_dms (archive, compression, cmd, verbosity, interactive, outdir, password=None):
"""Extract a DMS archive."""
check_archive_ext(archive)
cmdlist = [cmd, '-d', outdir]
if verbosity > 1:
cmdlist.append('-v')
+ _maybe_add_password(cmdlist, password)
cmdlist.extend(['u', archive])
return cmdlist
-def list_dms (archive, compression, cmd, verbosity, interactive):
+def list_dms (archive, compression, cmd, verbosity, interactive, password=None):
"""List a DMS archive."""
check_archive_ext(archive)
- return [cmd, 'v', archive]
+ cmdlist = [cmd, 'v']
+ _maybe_add_password(cmdlist, password)
+ cmdlist.append(archive)
+ return cmdlist
-def test_dms (archive, compression, cmd, verbosity, interactive):
+def test_dms (archive, compression, cmd, verbosity, interactive, password=None):
"""Test a DMS archive."""
check_archive_ext(archive)
- return [cmd, 't', archive]
+ cmdlist = [cmd, 't']
+ _maybe_add_password(cmdlist, password)
+ cmdlist.append(archive)
+ return cmdlist
def check_archive_ext (archive):
diff --git a/tests/archives/__init__.py b/tests/archives/__init__.py
index 5e03f6e..cd33439 100644
--- a/tests/archives/__init__.py
+++ b/tests/archives/__init__.py
@@ -49,6 +49,10 @@ class ArchiveTest (unittest.TestCase):
# set program to use for archive handling in subclass
program = None
+ # set password for test with password
+ password = None
+ # default archive basename to check
+ filename = 't'
def archive_commands (self, filename, **kwargs):
"""Run archive commands list, test, extract and create.
@@ -75,7 +79,7 @@ class ArchiveTest (unittest.TestCase):
try:
olddir = patoolib.util.chdir(tmpdir)
try:
- output = patoolib.extract_archive(archive, program=self.program, verbosity=verbosity, interactive=False)
+ output = patoolib.extract_archive(archive, program=self.program, verbosity=verbosity, interactive=False, password=self.password)
if check:
self.check_extracted_archive(archive, output, check)
finally:
@@ -117,13 +121,13 @@ class ArchiveTest (unittest.TestCase):
"""Test archive listing."""
archive = os.path.join(datadir, filename)
for verbosity in (-1, 0, 1, 2):
- patoolib.list_archive(archive, program=self.program, verbosity=verbosity, interactive=False)
+ patoolib.list_archive(archive, program=self.program, verbosity=verbosity, interactive=False, password=self.password)
def archive_test (self, filename):
"""Test archive testing."""
archive = os.path.join(datadir, filename)
for verbosity in (-1, 0, 1, 2):
- patoolib.test_archive(archive, program=self.program, verbosity=verbosity, interactive=False)
+ patoolib.test_archive(archive, program=self.program, verbosity=verbosity, interactive=False, password=self.password)
def archive_create (self, archive, srcfiles=None, check=Content.Recursive):
"""Test archive creation."""
@@ -156,7 +160,7 @@ class ArchiveTest (unittest.TestCase):
try:
archive = os.path.join(tmpdir, archive)
self.assertTrue(os.path.isabs(archive), "archive path is not absolute: %r" % archive)
- patoolib.create_archive(archive, srcfiles, verbosity=verbosity, interactive=False, program=program)
+ patoolib.create_archive(archive, srcfiles, verbosity=verbosity, interactive=False, program=program, password=self.password)
self.assertTrue(os.path.isfile(archive))
self.check_created_archive_with_test(archive)
self.check_created_archive_with_diff(archive, srcfiles)
@@ -184,7 +188,7 @@ class ArchiveTest (unittest.TestCase):
program = '7z'
elif self.program == 'shar':
return
- command(archive, program=program)
+ command(archive, program=program, password=self.password)
def check_created_archive_with_diff(self, archive, srcfiles):
"""Extract created archive again and compare the contents."""
@@ -208,7 +212,7 @@ class ArchiveTest (unittest.TestCase):
try:
olddir = patoolib.util.chdir(tmpdir)
try:
- output = patoolib.extract_archive(archive, program=program, interactive=False)
+ output = patoolib.extract_archive(archive, program=program, interactive=False, password=self.password)
if len(srcfiles) == 1:
source = os.path.join(datadir, srcfiles[0])
patoolib.util.run_checked([diff, "-urN", source, output])
diff --git a/tests/archives/test_7z.py b/tests/archives/test_7z.py
index 318549a..f2a91f5 100644
--- a/tests/archives/test_7z.py
+++ b/tests/archives/test_7z.py
@@ -116,6 +116,47 @@ class Test7z (ArchiveTest):
@needs_codec(program, 'rar')
def test_7z_rar_file (self):
# only succeeds with the rar module for 7z installed
- self.archive_list('t.rar.foo')
- self.archive_extract('t.rar.foo')
- self.archive_test('t.rar.foo')
+ self.archive_list(self.filename + '.rar.foo')
+ self.archive_extract(self.filename + '.rar.foo')
+ self.archive_test(self.filename + '.rar.foo')
+
+
+class Test7zPassword(ArchiveTest):
+
+ program = '7z'
+ password = 'thereisnotry'
+
+ @needs_program(program)
+ def test_7z (self):
+ self.archive_commands('p .7z')
+ self.archive_commands('p.zip')
+ self.archive_commands('p.cbz')
+ self.archive_list('p.arj')
+ self.archive_extract('p.arj')
+ self.archive_test('p.arj')
+
+ @needs_codec(program, 'rar')
+ def test_7z_rar (self):
+ # only succeeds with the rar module for 7z installed
+ self.archive_list('p.rar')
+ self.archive_extract('p.rar')
+ self.archive_test('p.rar')
+
+ @needs_program('file')
+ @needs_program(program)
+ def test_7z_file (self):
+ self.archive_commands('p.7z.foo', skip_create=True)
+ self.archive_commands('p.zip.foo', skip_create=True)
+ self.archive_commands('p.cbz.foo', skip_create=True)
+ self.archive_list('p.arj.foo')
+ self.archive_extract('p.arj.foo')
+ self.archive_test('p.arj.foo')
+
+ @needs_program('file')
+ @needs_codec(program, 'rar')
+ def test_7z_rar_file (self):
+ # only succeeds with the rar module for 7z installed
+ self.archive_list('p.rar.foo')
+ self.archive_extract('p.rar.foo')
+ self.archive_test('p.rar.foo')
+
diff --git a/tests/archives/test_arc.py b/tests/archives/test_arc.py
index a4ff847..3091b39 100644
--- a/tests/archives/test_arc.py
+++ b/tests/archives/test_arc.py
@@ -22,10 +22,15 @@ class TestArc(ArchiveTest):
@needs_program(program)
def test_arc(self):
- self.archive_commands('t.arc', check=Content.Multifile)
+ self.archive_commands(self.filename + '.arc', check=Content.Multifile)
@needs_program('file')
@needs_program(program)
def test_arc_file(self):
- self.archive_commands('t.arc.foo', check=Content.Multifile, skip_create=True)
+ self.archive_commands(self.filename + '.arc.foo', check=Content.Multifile, skip_create=True)
+
+class TestArcPassword(TestArc):
+
+ password = 'thereisnotry'
+ filename = 'p'
diff --git a/tests/archives/test_arj.py b/tests/archives/test_arj.py
index 9d60661..cddc315 100644
--- a/tests/archives/test_arj.py
+++ b/tests/archives/test_arj.py
@@ -22,10 +22,15 @@ class TestArj (ArchiveTest):
@needs_program(program)
def test_arj(self):
- self.archive_commands('t.arj')
+ self.archive_commands(self.filename + '.arj')
@needs_program('file')
@needs_program(program)
def test_arj_file(self):
- self.archive_commands('t.arj.foo', skip_create=True)
+ self.archive_commands(self.filename + '.arj.foo', skip_create=True)
+
+class TestArjPassword(TestArj):
+
+ password = 'thereisnotry'
+ filename = 'p'
diff --git a/tests/archives/test_pyzipfile.py b/tests/archives/test_pyzipfile.py
index 2be701b..3e87bc4 100644
--- a/tests/archives/test_pyzipfile.py
+++ b/tests/archives/test_pyzipfile.py
@@ -21,11 +21,15 @@ class TestPyzipfile (ArchiveTest):
program = 'py_zipfile'
def test_py_zipfile(self):
- self.archive_commands('t.zip')
- self.archive_commands('t.cbz')
+ self.archive_commands(self.filename + '.zip')
+ self.archive_commands(self.filename + '.cbz')
@needs_program('file')
def test_py_zipfile_file(self):
- self.archive_commands('t.zip.foo', skip_create=True)
- self.archive_commands('t.cbz.foo', skip_create=True)
+ self.archive_commands(self.filename + '.zip.foo', skip_create=True)
+ self.archive_commands(self.filename + '.cbz.foo', skip_create=True)
+class TestPyzipPasswordfile (TestPyzipfile):
+
+ filename = 'p'
+ password = 'thereisnotry'
diff --git a/tests/archives/test_rar.py b/tests/archives/test_rar.py
index e7c41c6..820f275 100644
--- a/tests/archives/test_rar.py
+++ b/tests/archives/test_rar.py
@@ -22,12 +22,17 @@ class TestRar (ArchiveTest):
@needs_program(program)
def test_rar(self):
- self.archive_commands('t.rar')
- self.archive_commands('t.cbr')
+ self.archive_commands(self.filename + '.rar')
+ self.archive_commands(self.filename + '.cbr')
@needs_program('file')
@needs_program(program)
def test_rar_file(self):
- self.archive_commands('t.rar.foo', skip_create=True)
- self.archive_commands('t.cbr.foo', skip_create=True)
+ self.archive_commands(self.filename + '.rar.foo', skip_create=True)
+ self.archive_commands(self.filename + '.cbr.foo', skip_create=True)
+
+class TestRarPassword (TestRar):
+
+ filename = 'p'
+ password = 'thereisnotry'
diff --git a/tests/archives/test_unace.py b/tests/archives/test_unace.py
index 3691d8d..3b45953 100644
--- a/tests/archives/test_unace.py
+++ b/tests/archives/test_unace.py
@@ -22,19 +22,26 @@ class TestUnace (ArchiveTest):
@needs_program(program)
def test_unace(self):
- self.archive_list('t.ace')
- self.archive_test('t.ace')
- self.archive_extract('t.ace')
- self.archive_list('t.cba')
- self.archive_test('t.cba')
- self.archive_extract('t.cba')
+ self.archive_list(self.filename + '.ace')
+ self.archive_test(self.filename + '.ace')
+ self.archive_extract(self.filename + '.ace')
+ self.archive_list(self.filename + '.cba')
+ self.archive_test(self.filename + '.cba')
+ self.archive_extract(self.filename + '.cba')
@needs_program('file')
@needs_program(program)
def test_unace_file(self):
- self.archive_list('t.ace.foo')
- self.archive_test('t.ace.foo')
- self.archive_extract('t.ace.foo')
- self.archive_list('t.cba.foo')
- self.archive_test('t.cba.foo')
- self.archive_extract('t.cba.foo')
+ self.archive_list(self.filename + '.ace.foo')
+ self.archive_test(self.filename + '.ace.foo')
+ self.archive_extract(self.filename + '.ace.foo')
+ self.archive_list(self.filename + '.cba.foo')
+ self.archive_test(self.filename + '.cba.foo')
+ self.archive_extract(self.filename + '.cba.foo')
+
+
+# TODO: add p.ace, p.ace.foo, p.cba, p.cba.foo with password to repository
+# class TestUnacePassword (TestUnace):
+#
+# filename = 'p'
+# password = 'thereisnotry'
diff --git a/tests/archives/test_unzip.py b/tests/archives/test_unzip.py
index a25885a..91b046f 100644
--- a/tests/archives/test_unzip.py
+++ b/tests/archives/test_unzip.py
@@ -56,3 +56,28 @@ class TestUnzip (ArchiveTest):
self.archive_extract('t.apk.foo', check=None)
self.archive_list('t.apk.foo')
self.archive_test('t.apk.foo')
+
+
+class TestUnzipPassword (ArchiveTest):
+
+ program = 'unzip'
+ password = 'thereisnotry'
+
+ @needs_program(program)
+ def test_unzip (self):
+ self.archive_extract('p.zip', check=None)
+ self.archive_list('p.zip')
+ self.archive_test('p.zip')
+ self.archive_extract('p.cbz', check=None)
+ self.archive_list('p.cbz')
+ self.archive_test('p.cbz')
+
+ @needs_program('file')
+ @needs_program(program)
+ def test_unzip_file (self):
+ self.archive_extract('p.zip.foo', check=None)
+ self.archive_list('p.zip.foo')
+ self.archive_test('p.zip.foo')
+ self.archive_extract('p.cbz.foo', check=None)
+ self.archive_list('p.cbz.foo')
+ self.archive_test('p.cbz.foo')
diff --git a/tests/data/p .7z b/tests/data/p .7z
new file mode 100644
index 0000000..ff9f05c
Binary files /dev/null and b/tests/data/p .7z differ
diff --git a/tests/data/p.7z.foo b/tests/data/p.7z.foo
new file mode 100644
index 0000000..ff9f05c
Binary files /dev/null and b/tests/data/p.7z.foo differ
diff --git a/tests/data/p.arc b/tests/data/p.arc
new file mode 100644
index 0000000..390e076
Binary files /dev/null and b/tests/data/p.arc differ
diff --git a/tests/data/p.arc.foo b/tests/data/p.arc.foo
new file mode 100644
index 0000000..390e076
Binary files /dev/null and b/tests/data/p.arc.foo differ
diff --git a/tests/data/p.arj b/tests/data/p.arj
new file mode 100644
index 0000000..7d5b342
Binary files /dev/null and b/tests/data/p.arj differ
diff --git a/tests/data/p.arj.foo b/tests/data/p.arj.foo
new file mode 100644
index 0000000..7d5b342
Binary files /dev/null and b/tests/data/p.arj.foo differ
diff --git a/tests/data/p.cbz b/tests/data/p.cbz
new file mode 100644
index 0000000..57ea283
Binary files /dev/null and b/tests/data/p.cbz differ
diff --git a/tests/data/p.cbz.foo b/tests/data/p.cbz.foo
new file mode 100644
index 0000000..57ea283
Binary files /dev/null and b/tests/data/p.cbz.foo differ
diff --git a/tests/data/p.rar b/tests/data/p.rar
new file mode 100644
index 0000000..05b663a
Binary files /dev/null and b/tests/data/p.rar differ
diff --git a/tests/data/p.rar.foo b/tests/data/p.rar.foo
new file mode 100644
index 0000000..05b663a
Binary files /dev/null and b/tests/data/p.rar.foo differ
diff --git a/tests/data/p.zip b/tests/data/p.zip
new file mode 100644
index 0000000..a8330c2
Binary files /dev/null and b/tests/data/p.zip differ
diff --git a/tests/data/p.zip.foo b/tests/data/p.zip.foo
new file mode 100644
index 0000000..a8330c2
Binary files /dev/null and b/tests/data/p.zip.foo differ