def extract_pcaps(archivename, pcap_files, job_id, dupcount):
    """Extract the packet capture files.

    extracts files from an archive and add them to the list to be
    included with the Dalton job.
    """
    # Note: archivename already sanitized
    logger.debug(
        "Attempting to extract pcaps from  file '%s'" % os.path.basename(archivename)
    )
    if archivename.lower().endswith(".zip"):
        # Apparently python zipfile module does extraction using Python and not something
        #  like C and it is super slow for a zipfile that isn't small in size. So
        #  to speed things up, kick out to 7z on the system which is quite fast but not my
        #  first choice. Still use zipfile module to process archive and get filenames.
        try:
            if not zipfile.is_zipfile(archivename):
                msg = (
                    "File '%s' is not recognized as a valid zip file."
                    % os.path.basename(archivename)
                )
                logger.error(msg)
                return msg
            files_to_extract = []
            zf = zipfile.ZipFile(archivename, mode="r")
            for file in zf.namelist():
                logger.debug("Processing file '%s' from ZIP archive" % file)
                if file.endswith("/") or "__MACOSX/" in file:
                    continue
                filename = clean_filename(os.path.basename(file))
                if os.path.splitext(filename)[1].lower() not in [
                    ".pcap",
                    ".pcapng",
                    ".cap",
                ]:
                    logger.warning(
                        "Not adding file '%s' from archive '%s': '.pcap', '.cap', or '.pcapng' extension required."
                        % (file, os.path.basename(archivename))
                    )
                    # just skip the file, and move on (and log it)
                    continue
                files_to_extract.append(file)
            zf.close()

            if len(files_to_extract) > 0:
                # make temporary location for extracting with 7z
                tempd = tempfile.mkdtemp()
                logger.debug("temp directory for 7z: %s" % tempd)
                # try password 'infected' if password on archive
                p7z_command = [
                    "7z",
                    "x",
                    archivename,
                    "-pinfected",
                    "-y",
                    "-o%s" % tempd,
                ] + files_to_extract
                # does 7z handle invalid/filenames or should more sanitization be attempted?
                logger.debug("7z command: %s" % p7z_command)
                # I'm not convinced that 7z outputs to stderr
                p7z_out = subprocess.Popen(
                    p7z_command,
                    shell=False,
                    stderr=subprocess.STDOUT,
                    stdout=subprocess.PIPE,
                ).stdout.read()
                if b"Everything is Ok" not in p7z_out and b"Errors: " in p7z_out:
                    logger.error(
                        "Problem extracting ZIP archive '%s': %s"
                        % (os.path.basename(archivename), p7z_out)
                    )
                    raise Exception("p7zip error. See logs for details")
                logger.debug("7z out: %s" % p7z_out)

                # move files; handle duplicate filenames
                for file in files_to_extract:
                    filename = clean_filename(os.path.basename(file))
                    filename = handle_dup_names(filename, pcap_files, job_id, dupcount)
                    pcappath = os.path.join(TEMP_STORAGE_PATH, job_id, filename)
                    pcapsrc = os.path.join(tempd, file)
                    # copy
                    shutil.move(pcapsrc, pcappath)
                    pcap_files.append({"filename": filename, "pcappath": pcappath})
                    logger.debug(
                        "Successfully extracted and added pcap file '%s'"
                        % os.path.basename(filename)
                    )
                # cleanup
                shutil.rmtree(tempd)

        except Exception as e:
            msg = "Problem extracting ZIP file '%s': %s" % (
                os.path.basename(archivename),
                e,
            )
            logger.error(msg)
            logger.debug("%s" % traceback.format_exc())
            return msg
    elif os.path.splitext(archivename)[1].lower() in [
        ".gz",
        ".gzip",
    ] and os.path.splitext(os.path.splitext(archivename)[0])[1].lower() not in [".tar"]:
        # gzipped file
        try:
            filename = os.path.basename(os.path.splitext(archivename)[0])
            logger.debug("Decompressing gzipped file '%s'" % filename)
            with gzip.open(archivename, "rb") as gz:
                filename = handle_dup_names(filename, pcap_files, job_id, dupcount)
                pcappath = os.path.join(TEMP_STORAGE_PATH, job_id, filename)
                fh = open(pcappath, "wb")
                fh.write(gz.read())
                fh.close()
                pcap_files.append({"filename": filename, "pcappath": pcappath})
                logger.debug("Added %s" % filename)
        except Exception as e:
            msg = "Problem extracting gzip file '%s': %s" % (
                os.path.basename(archivename),
                e,
            )
            logger.error(msg)
            logger.debug("%s" % traceback.format_exc())
            return msg
    elif os.path.splitext(archivename)[1].lower() in [".bz2"] and os.path.splitext(
        os.path.splitext(archivename)[0]
    )[1].lower() not in [".tar"]:
        # bzip2 file
        try:
            filename = os.path.basename(os.path.splitext(archivename)[0])
            logger.debug("Decompressing bzip2 file '%s'" % filename)
            with bz2.BZ2File(archivename, "rb") as bz:
                filename = handle_dup_names(filename, pcap_files, job_id, dupcount)
                pcappath = os.path.join(TEMP_STORAGE_PATH, job_id, filename)
                fh = open(pcappath, "wb")
                fh.write(bz.read())
                fh.close()
                pcap_files.append({"filename": filename, "pcappath": pcappath})
                logger.debug("Added %s" % filename)
        except Exception as e:
            msg = "Problem extracting bzip2 file '%s': %s" % (
                os.path.basename(archivename),
                e,
            )
            logger.error(msg)
            logger.debug("%s" % traceback.format_exc())
            return msg
    else:
        try:
            archive = tarfile.open(archivename, mode="r:*")
            for file in archive.getmembers():
                logger.debug("Processing file '%s' from archive" % file.name)
                if not file.isfile():
                    logger.warning(
                        "Not adding member '%s' from archive '%s': not a file."
                        % (file.name, os.path.basename(archivename))
                    )
                    continue
                filename = clean_filename(os.path.basename(file.name))
                if os.path.splitext(filename)[1].lower() not in [
                    ".pcap",
                    ".pcapng",
                    ".cap",
                ]:
                    logger.warning(
                        "Not adding file '%s' from archive '%s': '.pcap', '.cap', or '.pcapng' extension required."
                        % (file.name, os.path.basename(archivename))
                    )
                    # just skip the file, and move on (and log it)
                    continue
                filename = handle_dup_names(filename, pcap_files, job_id, dupcount)
                pcappath = os.path.join(TEMP_STORAGE_PATH, job_id, filename)
                fh = open(pcappath, "wb")
                contentsfh = archive.extractfile(file)
                fh.write(contentsfh.read())
                fh.close()
                pcap_files.append({"filename": filename, "pcappath": pcappath})
                logger.debug("Added %s" % filename)
            archive.close()
        except Exception as e:
            msg = "Problem extracting archive file '%s': %s" % (
                os.path.basename(archivename),
                e,
            )
            logger.error(msg)
            logger.debug("%s" % traceback.format_exc())
            return msg
    return None
Extract the packet capture files.

    extracts files from an archive and add them to the list to be
    included with the Dalton job.
    
app/dalton.py