Update pycatfile.py
[PyCatFile.git] / pycatfile.py
blob14f7fa0575e0f4175f4395477a8edea992f704e2
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 '''
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the Revised BSD License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 Revised BSD License for more details.
13 Copyright 2018-2024 Cool Dude 2k - http://idb.berlios.de/
14 Copyright 2018-2024 Game Maker 2k - http://intdb.sourceforge.net/
15 Copyright 2018-2024 Kazuki Przyborowski - https://github.com/KazukiPrzyborowski
17 $FileInfo: pycatfile.py - Last Update: 11/17/2024 Ver. 0.14.6 RC 1 - Author: cooldude2k $
18 '''
20 from __future__ import absolute_import, division, print_function, unicode_literals, generators, with_statement, nested_scopes
21 import io
22 import os
23 import re
24 import sys
25 import time
26 import stat
27 import zlib
28 import base64
29 import shutil
30 import socket
31 import hashlib
32 import inspect
33 import datetime
34 import logging
35 import binascii
36 import zipfile
37 import platform
38 try:
39 from backports import tempfile
40 except ImportError:
41 import tempfile
42 # FTP Support
43 ftpssl = True
44 try:
45 from ftplib import FTP, FTP_TLS
46 except ImportError:
47 ftpssl = False
48 from ftplib import FTP
50 try:
51 import ujson as json
52 except ImportError:
53 try:
54 import simplejson as json
55 except ImportError:
56 import json
58 try:
59 import configparser
60 except ImportError:
61 try:
62 import SafeConfigParser as configparser
63 except ImportError:
64 import ConfigParser as configparser
66 try:
67 basestring
68 except NameError:
69 basestring = str
71 baseint = []
72 try:
73 baseint.append(long)
74 baseint.insert(0, int)
75 except NameError:
76 baseint.append(int)
77 baseint = tuple(baseint)
79 # URL Parsing
80 try:
81 from urllib.parse import urlparse, urlunparse
82 except ImportError:
83 from urlparse import urlparse, urlunparse
85 # Windows-specific setup
86 if os.name == 'nt':
87 if sys.version_info[0] == 2:
88 import codecs
89 sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
90 sys.stderr = codecs.getwriter('utf-8')(sys.stderr)
91 else:
92 sys.stdout = io.TextIOWrapper(
93 sys.stdout.buffer, encoding='utf-8', errors='replace', line_buffering=True)
94 sys.stderr = io.TextIOWrapper(
95 sys.stderr.buffer, encoding='utf-8', errors='replace', line_buffering=True)
97 hashlib_guaranteed = False
98 # Environment setup
99 os.environ["PYTHONIOENCODING"] = "UTF-8"
100 os.environ["LC_CTYPE"] = "UTF-8"
102 # Reload sys to set default encoding to UTF-8 (Python 2 only)
103 if sys.version_info[0] == 2:
104 try:
105 reload(sys)
106 sys.setdefaultencoding('UTF-8')
107 except (NameError, AttributeError):
108 pass
110 # CRC32 import
111 try:
112 from zlib import crc32
113 except ImportError:
114 from binascii import crc32
116 # Define FileNotFoundError for Python 2
117 try:
118 FileNotFoundError
119 except NameError:
120 FileNotFoundError = IOError
122 # RAR file support
123 rarfile_support = False
124 try:
125 import rarfile
126 rarfile_support = True
127 except ImportError:
128 pass
130 # 7z file support
131 py7zr_support = False
132 try:
133 import py7zr
134 py7zr_support = True
135 except ImportError:
136 pass
138 # TAR file checking
139 try:
140 from xtarfile import is_tarfile
141 except ImportError:
142 try:
143 from safetar import is_tarfile
144 except ImportError:
145 from tarfile import is_tarfile
147 # TAR file module
148 try:
149 import xtarfile as tarfile
150 except ImportError:
151 try:
152 import safetar as tarfile
153 except ImportError:
154 import tarfile
156 # Paramiko support
157 haveparamiko = False
158 try:
159 import paramiko
160 haveparamiko = True
161 except ImportError:
162 pass
164 # PySFTP support
165 havepysftp = False
166 try:
167 import pysftp
168 havepysftp = True
169 except ImportError:
170 pass
172 # Requests support
173 haverequests = False
174 try:
175 import requests
176 haverequests = True
177 import urllib3
178 logging.getLogger("urllib3").setLevel(logging.WARNING)
179 except ImportError:
180 pass
182 # HTTPX support
183 havehttpx = False
184 try:
185 import httpx
186 havehttpx = True
187 logging.getLogger("httpx").setLevel(logging.WARNING)
188 logging.getLogger("httpcore").setLevel(logging.WARNING)
189 except ImportError:
190 pass
192 # HTTP and URL parsing
193 try:
194 from urllib.request import Request, build_opener, HTTPBasicAuthHandler
195 from urllib.parse import urlparse
196 except ImportError:
197 from urllib2 import Request, build_opener, HTTPBasicAuthHandler
198 from urlparse import urlparse
200 # StringIO and BytesIO
201 try:
202 from io import StringIO, BytesIO
203 except ImportError:
204 try:
205 from cStringIO import StringIO
206 from cStringIO import StringIO as BytesIO
207 except ImportError:
208 from StringIO import StringIO
209 from StringIO import StringIO as BytesIO
211 def get_importing_script_path():
212 # Inspect the stack and get the frame of the caller
213 stack = inspect.stack()
214 for frame_info in stack:
215 # In Python 2, frame_info is a tuple; in Python 3, it's a named tuple
216 filename = frame_info[1] if isinstance(frame_info, tuple) else frame_info.filename
217 if filename != __file__: # Ignore current module's file
218 return os.path.abspath(filename)
219 return None
221 __use_pysftp__ = False
222 __use_alt_format__ = False
223 scriptconf = os.path.join(os.path.dirname(get_importing_script_path()), "catfile.ini")
224 if os.path.exists(scriptconf):
225 __config_file__ = scriptconf
226 else:
227 __config_file__ = os.path.join(os.path.dirname(os.path.realpath(__file__)), "catfile.ini")
228 __use_ini_file__ = True
229 if(not havepysftp):
230 __use_pysftp__ = False
231 __use_http_lib__ = "httpx"
232 if(__use_http_lib__ == "httpx" and haverequests and not havehttpx):
233 __use_http_lib__ = "requests"
234 if(__use_http_lib__ == "requests" and havehttpx and not haverequests):
235 __use_http_lib__ = "httpx"
236 if((__use_http_lib__ == "httpx" or __use_http_lib__ == "requests") and not havehttpx and not haverequests):
237 __use_http_lib__ = "urllib"
238 if os.path.exists(__config_file__) and __use_ini_file__:
239 # Create a ConfigParser object
240 config = configparser.ConfigParser()
241 # Read the configuration file
242 config.read(__config_file__)
243 # Accessing values from the config file
244 __file_format_name__ = config['main']['name']
245 __program_name__ = config['main']['proname']
246 __file_format_lower__ = config['main']['lower']
247 __file_format_magic__ = config['main']['magic'].encode("UTF-8").decode('unicode_escape')
248 __file_format_len__ = int(config['main']['len'])
249 __file_format_hex__ = config['main']['hex']
250 __file_format_delimiter__ = config['main']['delimiter'].encode("UTF-8").decode('unicode_escape')
251 __file_format_ver__ = config['main']['ver']
252 __use_new_style__ = config.getboolean('main', 'newstyle')
253 __use_advanced_list__ = config.getboolean('main', 'advancedlist')
254 __use_alt_inode__ = config.getboolean('main', 'altinode')
255 __file_format_extension__ = config['main']['extension']
256 else:
257 if not __use_alt_format__:
258 # Format Info by Kazuki Przyborowski
259 __file_format_name__ = "CatFile"
260 __program_name__ = "Py" + __file_format_name__
261 __file_format_lower__ = __file_format_name__.lower()
262 __file_format_magic__ = __file_format_name__
263 __file_format_len__ = len(__file_format_magic__)
264 __file_format_hex__ = binascii.hexlify(
265 __file_format_magic__.encode("UTF-8")).decode("UTF-8")
266 __file_format_delimiter__ = "\x00"
267 __file_format_ver__ = "001"
268 __use_new_style__ = True
269 __use_advanced_list__ = True
270 __use_alt_inode__ = False
271 __file_format_extension__ = ".cat"
272 else:
273 # Format Info Generated by ChatGPT
274 __file_format_name__ = "FastArchive"
275 __program_name__ = "Py" + __file_format_name__
276 __file_format_lower__ = __file_format_name__.lower()
277 __file_format_magic__ = "FstArch"
278 __file_format_len__ = len(__file_format_magic__)
279 __file_format_hex__ = binascii.hexlify(
280 __file_format_magic__.encode("UTF-8")).decode("UTF-8")
281 # Using a non-printable ASCII character as delimiter
282 __file_format_delimiter__ = "\x1F"
283 __file_format_ver__ = "001"
284 __use_new_style__ = True
285 __use_advanced_list__ = False
286 __use_alt_inode__ = False
287 __file_format_extension__ = ".fast"
288 __file_format_list__ = [__file_format_name__, __file_format_magic__, __file_format_lower__, __file_format_len__,
289 __file_format_hex__, __file_format_delimiter__, __file_format_ver__, __use_new_style__, __use_advanced_list__, __use_alt_inode__]
290 __file_format_dict__ = {'format_name': __file_format_name__, 'format_magic': __file_format_magic__, 'format_lower': __file_format_lower__, 'format_len': __file_format_len__, 'format_hex': __file_format_hex__,
291 'format_delimiter': __file_format_delimiter__, 'format_ver': __file_format_ver__, 'new_style': __use_new_style__, 'use_advanced_list': __use_advanced_list__, 'use_alt_inode': __use_alt_inode__}
292 __project__ = __program_name__
293 __project_url__ = "https://github.com/GameMaker2k/PyCatFile"
294 __version_info__ = (0, 14, 6, "RC 1", 1)
295 __version_date_info__ = (2024, 11, 17, "RC 1", 1)
296 __version_date__ = str(__version_date_info__[0]) + "." + str(
297 __version_date_info__[1]).zfill(2) + "." + str(__version_date_info__[2]).zfill(2)
298 __revision__ = __version_info__[3]
299 __revision_id__ = "$Id$"
300 if(__version_info__[4] is not None):
301 __version_date_plusrc__ = __version_date__ + \
302 "-" + str(__version_date_info__[4])
303 if(__version_info__[4] is None):
304 __version_date_plusrc__ = __version_date__
305 if(__version_info__[3] is not None):
306 __version__ = str(__version_info__[0]) + "." + str(__version_info__[
307 1]) + "." + str(__version_info__[2]) + " " + str(__version_info__[3])
308 if(__version_info__[3] is None):
309 __version__ = str(__version_info__[
310 0]) + "." + str(__version_info__[1]) + "." + str(__version_info__[2])
312 PyBitness = platform.architecture()
313 if(PyBitness == "32bit" or PyBitness == "32"):
314 PyBitness = "32"
315 elif(PyBitness == "64bit" or PyBitness == "64"):
316 PyBitness = "64"
317 else:
318 PyBitness = "32"
320 geturls_ua_pycatfile_python = "Mozilla/5.0 (compatible; {proname}/{prover}; +{prourl})".format(
321 proname=__project__, prover=__version__, prourl=__project_url__)
322 if(platform.python_implementation() != ""):
323 py_implementation = platform.python_implementation()
324 if(platform.python_implementation() == ""):
325 py_implementation = "Python"
326 geturls_ua_pycatfile_python_alt = "Mozilla/5.0 ({osver}; {archtype}; +{prourl}) {pyimp}/{pyver} (KHTML, like Gecko) {proname}/{prover}".format(osver=platform.system(
327 )+" "+platform.release(), archtype=platform.machine(), prourl=__project_url__, pyimp=py_implementation, pyver=platform.python_version(), proname=__project__, prover=__version__)
328 geturls_ua_googlebot_google = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
329 geturls_ua_googlebot_google_old = "Googlebot/2.1 (+http://www.google.com/bot.html)"
330 geturls_headers_pycatfile_python = {'Referer': "http://google.com/", 'User-Agent': geturls_ua_pycatfile_python, 'Accept-Encoding': "none", 'Accept-Language': "en-US,en;q=0.8,en-CA,en-GB;q=0.6", 'Accept-Charset': "ISO-8859-1,ISO-8859-15,utf-8;q=0.7,*;q=0.7", 'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 'Connection': "close",
331 'SEC-CH-UA': "\""+__project__+"\";v=\""+str(__version__)+"\", \"Not;A=Brand\";v=\"8\", \""+py_implementation+"\";v=\""+str(platform.release())+"\"", 'SEC-CH-UA-FULL-VERSION': str(__version__), 'SEC-CH-UA-PLATFORM': ""+py_implementation+"", 'SEC-CH-UA-ARCH': ""+platform.machine()+"", 'SEC-CH-UA-PLATFORM': str(__version__), 'SEC-CH-UA-BITNESS': str(PyBitness)}
332 geturls_headers_pycatfile_python_alt = {'Referer': "http://google.com/", 'User-Agent': geturls_ua_pycatfile_python_alt, 'Accept-Encoding': "none", 'Accept-Language': "en-US,en;q=0.8,en-CA,en-GB;q=0.6", 'Accept-Charset': "ISO-8859-1,ISO-8859-15,utf-8;q=0.7,*;q=0.7", 'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 'Connection': "close",
333 'SEC-CH-UA': "\""+__project__+"\";v=\""+str(__version__)+"\", \"Not;A=Brand\";v=\"8\", \""+py_implementation+"\";v=\""+str(platform.release())+"\"", 'SEC-CH-UA-FULL-VERSION': str(__version__), 'SEC-CH-UA-PLATFORM': ""+py_implementation+"", 'SEC-CH-UA-ARCH': ""+platform.machine()+"", 'SEC-CH-UA-PLATFORM': str(__version__), 'SEC-CH-UA-BITNESS': str(PyBitness)}
334 geturls_headers_googlebot_google = {'Referer': "http://google.com/", 'User-Agent': geturls_ua_googlebot_google, 'Accept-Encoding': "none", 'Accept-Language': "en-US,en;q=0.8,en-CA,en-GB;q=0.6",
335 'Accept-Charset': "ISO-8859-1,ISO-8859-15,utf-8;q=0.7,*;q=0.7", 'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 'Connection': "close"}
336 geturls_headers_googlebot_google_old = {'Referer': "http://google.com/", 'User-Agent': geturls_ua_googlebot_google_old, 'Accept-Encoding': "none", 'Accept-Language': "en-US,en;q=0.8,en-CA,en-GB;q=0.6",
337 'Accept-Charset': "ISO-8859-1,ISO-8859-15,utf-8;q=0.7,*;q=0.7", 'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 'Connection': "close"}
339 compressionsupport = []
340 try:
341 import gzip
342 compressionsupport.append("gz")
343 compressionsupport.append("gzip")
344 except ImportError:
345 pass
346 try:
347 import bz2
348 compressionsupport.append("bz2")
349 compressionsupport.append("bzip2")
350 except ImportError:
351 pass
352 try:
353 import lz4
354 import lz4.frame
355 compressionsupport.append("lz4")
356 except ImportError:
357 pass
358 try:
359 import lzo
360 compressionsupport.append("lzo")
361 compressionsupport.append("lzop")
362 except ImportError:
363 pass
364 try:
365 import zstandard
366 compressionsupport.append("zstd")
367 compressionsupport.append("zstandard")
368 except ImportError:
369 pass
370 try:
371 import lzma
372 compressionsupport.append("lzma")
373 compressionsupport.append("xz")
374 except ImportError:
375 try:
376 from backports import lzma
377 compressionsupport.append("lzma")
378 compressionsupport.append("xz")
379 except ImportError:
380 pass
381 compressionsupport.append("zlib")
383 compressionlist = ['auto']
384 compressionlistalt = []
385 outextlist = []
386 outextlistwd = []
387 if('gzip' in compressionsupport):
388 compressionlist.append('gzip')
389 compressionlistalt.append('gzip')
390 outextlist.append('gz')
391 outextlistwd.append('.gz')
392 if('bzip2' in compressionsupport):
393 compressionlist.append('bzip2')
394 compressionlistalt.append('bzip2')
395 outextlist.append('bz2')
396 outextlistwd.append('.bz2')
397 if('zstd' in compressionsupport):
398 compressionlist.append('zstd')
399 compressionlistalt.append('zstd')
400 outextlist.append('zst')
401 outextlistwd.append('.zst')
402 if('lz4' in compressionsupport):
403 compressionlist.append('lz4')
404 compressionlistalt.append('lz4')
405 outextlist.append('lz4')
406 outextlistwd.append('.lz4')
407 if('lzo' in compressionsupport):
408 compressionlist.append('lzo')
409 compressionlistalt.append('lzo')
410 outextlist.append('lzo')
411 outextlistwd.append('.lzo')
412 if('lzop' in compressionsupport):
413 compressionlist.append('lzop')
414 compressionlistalt.append('lzop')
415 outextlist.append('lzop')
416 outextlistwd.append('.lzop')
417 if('lzma' in compressionsupport):
418 compressionlist.append('lzma')
419 compressionlistalt.append('lzma')
420 outextlist.append('lzma')
421 outextlistwd.append('.lzma')
422 if('xz' in compressionsupport):
423 compressionlist.append('xz')
424 compressionlistalt.append('xz')
425 outextlist.append('xz')
426 outextlistwd.append('.xz')
427 if('zlib' in compressionsupport):
428 compressionlist.append('zlib')
429 compressionlistalt.append('zlib')
430 outextlist.append('zz')
431 outextlistwd.append('.zz')
432 outextlist.append('zl')
433 outextlistwd.append('.zl')
434 outextlist.append('zlib')
435 outextlistwd.append('.zlib')
437 tarfile_mimetype = "application/tar"
438 tarfile_tar_mimetype = tarfile_mimetype
439 zipfile_mimetype = "application/zip"
440 zipfile_zip_mimetype = zipfile_mimetype
441 rarfile_mimetype = "application/rar"
442 rarfile_rar_mimetype = rarfile_mimetype
443 archivefile_mimetype = "application/x-"+__file_format_dict__['format_lower']+""
444 archivefile_cat_mimetype = archivefile_mimetype
445 archivefile_gzip_mimetype = "application/x-" + \
446 __file_format_dict__['format_lower']+"+gzip"
447 archivefile_gz_mimetype = archivefile_gzip_mimetype
448 archivefile_bzip2_mimetype = "application/x-" + \
449 __file_format_dict__['format_lower']+"+bzip2"
450 archivefile_bz2_mimetype = archivefile_bzip2_mimetype
451 archivefile_lz4_mimetype = "application/x-" + \
452 __file_format_dict__['format_lower']+"+lz4"
453 archivefile_lzop_mimetype = "application/x-" + \
454 __file_format_dict__['format_lower']+"+lzop"
455 archivefile_lzo_mimetype = archivefile_lzop_mimetype
456 archivefile_zstandard_mimetype = "application/x-" + \
457 __file_format_dict__['format_lower']+"+zstandard"
458 archivefile_zstd_mimetype = archivefile_zstandard_mimetype
459 archivefile_lzma_mimetype = "application/x-" + \
460 __file_format_dict__['format_lower']+"+lzma"
461 archivefile_xz_mimetype = "application/x-" + \
462 __file_format_dict__['format_lower']+"+xz"
463 archivefile_zlib_mimetype = "application/x-" + \
464 __file_format_dict__['format_lower']+"+zlib"
465 archivefile_zz_mimetype = archivefile_zlib_mimetype
466 archivefile_zl_mimetype = archivefile_zlib_mimetype
467 archivefile_extensions = [__file_format_extension__, __file_format_extension__+".gz", __file_format_extension__+".bz2", __file_format_extension__+".zst", __file_format_extension__+".lz4", __file_format_extension__ +
468 ".lzo", __file_format_extension__+".lzop", __file_format_extension__+".lzma", __file_format_extension__+".xz", __file_format_extension__+".zz", __file_format_extension__+".zl", __file_format_extension__+".zlib"]
470 if __name__ == "__main__":
471 import subprocess
472 curscrpath = os.path.dirname(sys.argv[0])
473 if(curscrpath == ""):
474 curscrpath = "."
475 if(os.sep == "\\"):
476 curscrpath = curscrpath.replace(os.sep, "/")
477 curscrpath = curscrpath + "/"
478 scrfile = curscrpath + "catfile.py"
479 if(os.path.exists(scrfile) and os.path.isfile(scrfile)):
480 scrcmd = subprocess.Popen([sys.executable, scrfile] + sys.argv[1:])
481 scrcmd.wait()
484 def VerbosePrintOut(dbgtxt, outtype="log", dbgenable=True, dgblevel=20):
485 if(not dbgenable):
486 return True
487 log_functions = {
488 "print": print,
489 "log": logging.info,
490 "warning": logging.warning,
491 "error": logging.error,
492 "critical": logging.critical,
493 "exception": logging.exception,
494 "logalt": lambda x: logging.log(dgblevel, x),
495 "debug": logging.debug
497 log_function = log_functions.get(outtype)
498 if(log_function):
499 log_function(dbgtxt)
500 return True
501 return False
504 def VerbosePrintOutReturn(dbgtxt, outtype="log", dbgenable=True, dgblevel=20):
505 VerbosePrintOut(dbgtxt, outtype, dbgenable, dgblevel)
506 return dbgtxt
509 def RemoveWindowsPath(dpath):
510 if(dpath is None):
511 dpath = ""
512 if(os.sep != "/"):
513 dpath = dpath.replace(os.path.sep, "/")
514 dpath = dpath.rstrip("/")
515 if(dpath == "." or dpath == ".."):
516 dpath = dpath + "/"
517 return dpath
520 def NormalizeRelativePath(inpath):
521 inpath = RemoveWindowsPath(inpath)
522 if(os.path.isabs(inpath)):
523 outpath = inpath
524 else:
525 if(inpath.startswith("./") or inpath.startswith("../")):
526 outpath = inpath
527 else:
528 outpath = "./" + inpath
529 return outpath
532 def PrependPath(base_dir, child_path):
533 # Check if base_dir is None or empty, if so, return child_path as is
534 if not base_dir:
535 return child_path
536 # Ensure base_dir ends with exactly one slash
537 if not base_dir.endswith('/'):
538 base_dir += '/'
539 # Check if child_path starts with ./ or ../ (indicating a relative path)
540 if child_path.startswith('./') or child_path.startswith('../'):
541 # For relative paths, we don't alter the child_path
542 return base_dir + child_path
543 else:
544 # For non-relative paths, ensure there's no starting slash on child_path to avoid double slashes
545 return base_dir + child_path.lstrip('/')
548 def ListDir(dirpath, followlink=False, duplicates=False):
549 if isinstance(dirpath, (list, tuple, )):
550 dirpath = list(filter(None, dirpath))
551 elif isinstance(dirpath, str):
552 dirpath = list(filter(None, [dirpath]))
553 retlist = []
554 fs_encoding = sys.getfilesystemencoding()
555 for mydirfile in dirpath:
556 if not os.path.exists(mydirfile):
557 return False
558 mydirfile = NormalizeRelativePath(mydirfile)
559 if os.path.exists(mydirfile) and os.path.islink(mydirfile):
560 mydirfile = RemoveWindowsPath(os.path.realpath(mydirfile))
561 if os.path.exists(mydirfile) and os.path.isdir(mydirfile):
562 for root, dirs, filenames in os.walk(mydirfile):
563 dpath = root
564 dpath = RemoveWindowsPath(dpath)
565 if fs_encoding != 'utf-8':
566 dpath = dpath.encode(fs_encoding).decode('utf-8')
567 if dpath not in retlist and not duplicates:
568 retlist.append(dpath)
569 if duplicates:
570 retlist.append(dpath)
571 for file in filenames:
572 fpath = os.path.join(root, file)
573 fpath = RemoveWindowsPath(fpath)
574 if fs_encoding != 'utf-8':
575 fpath = fpath.encode(fs_encoding).decode('utf-8')
576 if fpath not in retlist and not duplicates:
577 retlist.append(fpath)
578 if duplicates:
579 retlist.append(fpath)
580 else:
581 path = RemoveWindowsPath(mydirfile)
582 if fs_encoding != 'utf-8':
583 path = path.encode(fs_encoding).decode('utf-8')
584 retlist.append(path)
585 return retlist
588 def ListDirAdvanced(dirpath, followlink=False, duplicates=False):
589 if isinstance(dirpath, (list, tuple, )):
590 dirpath = list(filter(None, dirpath))
591 elif isinstance(dirpath, str):
592 dirpath = list(filter(None, [dirpath]))
593 retlist = []
594 fs_encoding = sys.getfilesystemencoding()
595 for mydirfile in dirpath:
596 if not os.path.exists(mydirfile):
597 return False
598 mydirfile = NormalizeRelativePath(mydirfile)
599 if os.path.exists(mydirfile) and os.path.islink(mydirfile) and followlink:
600 mydirfile = RemoveWindowsPath(os.path.realpath(mydirfile))
601 if os.path.exists(mydirfile) and os.path.isdir(mydirfile):
602 for root, dirs, filenames in os.walk(mydirfile):
603 # Sort dirs and filenames alphabetically in place
604 dirs.sort(key=lambda x: x.lower())
605 filenames.sort(key=lambda x: x.lower())
606 dpath = RemoveWindowsPath(root)
607 if fs_encoding != 'utf-8':
608 dpath = dpath.encode(fs_encoding).decode('utf-8')
609 if not duplicates and dpath not in retlist:
610 retlist.append(dpath)
611 elif duplicates:
612 retlist.append(dpath)
613 for file in filenames:
614 fpath = os.path.join(root, file)
615 fpath = RemoveWindowsPath(fpath)
616 if fs_encoding != 'utf-8':
617 fpath = fpath.encode(fs_encoding).decode('utf-8')
618 if not duplicates and fpath not in retlist:
619 retlist.append(fpath)
620 elif duplicates:
621 retlist.append(fpath)
622 else:
623 path = RemoveWindowsPath(mydirfile)
624 if fs_encoding != 'utf-8':
625 path = path.encode(fs_encoding).decode('utf-8')
626 retlist.append(path)
627 return retlist
630 def create_alias_function(prefix, base_name, suffix, target_function):
631 # Define a new function that wraps the target function
632 def alias_function(*args, **kwargs):
633 return target_function(*args, **kwargs)
634 # Create the function name by combining the prefix, base name, and the suffix
635 function_name = "{}{}{}".format(prefix, base_name, suffix)
636 # Add the new function to the global namespace
637 globals()[function_name] = alias_function
640 def create_alias_function_alt(prefix, base_name, suffix, target_function):
641 # Create the function name by combining the prefix, base name, and the suffix
642 # Use the format method for string formatting, compatible with Python 2 and 3
643 function_name = "{}{}{}".format(prefix, base_name, suffix)
644 # Add the new function (alias of the target_function) to the global namespace
645 # This line is compatible as-is with both Python 2 and 3
646 globals()[function_name] = target_function
649 def FormatSpecsListToDict(formatspecs=__file_format_list__):
650 if(isinstance(formatspecs, (list, tuple, ))):
651 return {'format_name': formatspecs[0], 'format_magic': formatspecs[1], 'format_lower': formatspecs[2], 'format_len': formatspecs[3], 'format_hex': formatspecs[4], 'format_delimiter': formatspecs[5], 'format_ver': formatspecs[6], 'new_style': formatspecs[7], 'use_advanced_list': formatspecs[8], 'use_alt_inode': formatspecs[9]}
652 elif(isinstance(formatspecs, (dict, ))):
653 return formatspecs
654 else:
655 return __file_format_dict__
656 return __file_format_dict__
659 class ZlibFile:
660 def __init__(self, file_path=None, fileobj=None, mode='rb', level=9, wbits=15, encoding=None, errors=None, newline=None):
661 if file_path is None and fileobj is None:
662 raise ValueError("Either file_path or fileobj must be provided")
663 if file_path is not None and fileobj is not None:
664 raise ValueError(
665 "Only one of file_path or fileobj should be provided")
667 self.file_path = file_path
668 self.fileobj = fileobj
669 self.mode = mode
670 self.level = level
671 self.wbits = wbits
672 self.encoding = encoding
673 self.errors = errors
674 self.newline = newline
675 self._compressed_data = b''
676 self._decompressed_data = b''
677 self._position = 0
678 self._text_mode = 't' in mode
680 # Force binary mode for internal handling
681 internal_mode = mode.replace('t', 'b')
683 if 'w' in mode or 'a' in mode or 'x' in mode:
684 self.file = open(
685 file_path, internal_mode) if file_path else fileobj
686 self._compressor = zlib.compressobj(level, zlib.DEFLATED, wbits)
687 elif 'r' in mode:
688 if file_path:
689 if os.path.exists(file_path):
690 self.file = open(file_path, internal_mode)
691 self._load_file()
692 else:
693 raise FileNotFoundError(
694 "No such file: '{}'".format(file_path))
695 elif fileobj:
696 self.file = fileobj
697 self._load_file()
698 else:
699 raise ValueError("Mode should be 'rb' or 'wb'")
701 def _load_file(self):
702 self.file.seek(0)
703 self._compressed_data = self.file.read()
704 if not self._compressed_data.startswith((b'\x78\x01', b'\x78\x5E', b'\x78\x9C', b'\x78\xDA')):
705 raise ValueError("Invalid zlib file header")
706 self._decompressed_data = zlib.decompress(
707 self._compressed_data, self.wbits)
708 if self._text_mode:
709 self._decompressed_data = self._decompressed_data.decode(
710 self.encoding or 'utf-8', self.errors or 'strict')
712 def write(self, data):
713 if self._text_mode:
714 data = data.encode(self.encoding or 'utf-8',
715 self.errors or 'strict')
716 compressed_data = self._compressor.compress(
717 data) + self._compressor.flush(zlib.Z_SYNC_FLUSH)
718 self.file.write(compressed_data)
720 def read(self, size=-1):
721 if size == -1:
722 size = len(self._decompressed_data) - self._position
723 data = self._decompressed_data[self._position:self._position + size]
724 self._position += size
725 return data
727 def seek(self, offset, whence=0):
728 if whence == 0: # absolute file positioning
729 self._position = offset
730 elif whence == 1: # seek relative to the current position
731 self._position += offset
732 elif whence == 2: # seek relative to the file's end
733 self._position = len(self._decompressed_data) + offset
734 else:
735 raise ValueError("Invalid value for whence")
737 # Ensure the position is within bounds
738 self._position = max(
739 0, min(self._position, len(self._decompressed_data)))
741 def tell(self):
742 return self._position
744 def flush(self):
745 self.file.flush()
747 def fileno(self):
748 if hasattr(self.file, 'fileno'):
749 return self.file.fileno()
750 raise OSError("The underlying file object does not support fileno()")
752 def isatty(self):
753 if hasattr(self.file, 'isatty'):
754 return self.file.isatty()
755 return False
757 def truncate(self, size=None):
758 if hasattr(self.file, 'truncate'):
759 return self.file.truncate(size)
760 raise OSError("The underlying file object does not support truncate()")
762 def close(self):
763 if 'w' in self.mode or 'a' in self.mode or 'x' in self.mode:
764 self.file.write(self._compressor.flush(zlib.Z_FINISH))
765 if self.file_path:
766 self.file.close()
768 def __enter__(self):
769 return self
771 def __exit__(self, exc_type, exc_value, traceback):
772 self.close()
775 class GzipFile:
776 def __init__(self, file_path=None, fileobj=None, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None):
777 if file_path is None and fileobj is None:
778 raise ValueError("Either file_path or fileobj must be provided")
779 if file_path is not None and fileobj is not None:
780 raise ValueError(
781 "Only one of file_path or fileobj should be provided")
783 self.file_path = file_path
784 self.fileobj = fileobj
785 self.mode = mode
786 self.compresslevel = compresslevel
787 self.encoding = encoding
788 self.errors = errors
789 self.newline = newline
790 self._compressed_data = b''
791 self._decompressed_data = b''
792 self._position = 0
793 self._text_mode = 't' in mode
795 # Force binary mode for internal handling
796 internal_mode = mode.replace('t', 'b')
798 if 'w' in mode or 'a' in mode or 'x' in mode:
799 self.file = gzip.open(file_path, internal_mode, compresslevel=compresslevel) if file_path else gzip.GzipFile(
800 fileobj=fileobj, mode=internal_mode, compresslevel=compresslevel)
801 self._compressor = gzip.GzipFile(
802 fileobj=self.file, mode=internal_mode, compresslevel=compresslevel)
803 elif 'r' in mode:
804 if file_path:
805 if os.path.exists(file_path):
806 self.file = gzip.open(file_path, internal_mode)
807 self._load_file()
808 else:
809 raise FileNotFoundError(
810 "No such file: '{}'".format(file_path))
811 elif fileobj:
812 self.file = gzip.GzipFile(fileobj=fileobj, mode=internal_mode)
813 self._load_file()
814 else:
815 raise ValueError("Mode should be 'rb' or 'wb'")
817 def _load_file(self):
818 self.file.seek(0)
819 self._compressed_data = self.file.read()
820 if not self._compressed_data.startswith(b'\x1f\x8b'):
821 raise ValueError("Invalid gzip file header")
822 self._decompressed_data = gzip.decompress(self._compressed_data)
823 if self._text_mode:
824 self._decompressed_data = self._decompressed_data.decode(
825 self.encoding or 'utf-8', self.errors or 'strict')
827 def write(self, data):
828 if self._text_mode:
829 data = data.encode(self.encoding or 'utf-8',
830 self.errors or 'strict')
831 compressed_data = self._compressor.compress(data)
832 self.file.write(compressed_data)
833 self.file.flush()
835 def read(self, size=-1):
836 if size == -1:
837 size = len(self._decompressed_data) - self._position
838 data = self._decompressed_data[self._position:self._position + size]
839 self._position += size
840 return data
842 def seek(self, offset, whence=0):
843 if whence == 0: # absolute file positioning
844 self._position = offset
845 elif whence == 1: # seek relative to the current position
846 self._position += offset
847 elif whence == 2: # seek relative to the file's end
848 self._position = len(self._decompressed_data) + offset
849 else:
850 raise ValueError("Invalid value for whence")
852 # Ensure the position is within bounds
853 self._position = max(
854 0, min(self._position, len(self._decompressed_data)))
856 def tell(self):
857 return self._position
859 def flush(self):
860 self.file.flush()
862 def fileno(self):
863 if hasattr(self.file, 'fileno'):
864 return self.file.fileno()
865 raise OSError("The underlying file object does not support fileno()")
867 def isatty(self):
868 if hasattr(self.file, 'isatty'):
869 return self.file.isatty()
870 return False
872 def truncate(self, size=None):
873 if hasattr(self.file, 'truncate'):
874 return self.file.truncate(size)
875 raise OSError("The underlying file object does not support truncate()")
877 def close(self):
878 if 'w' in self.mode or 'a' in self.mode or 'x' in self.mode:
879 self.file.write(self._compressor.flush())
880 if self.file_path:
881 self.file.close()
883 def __enter__(self):
884 return self
886 def __exit__(self, exc_type, exc_value, traceback):
887 self.close()
891 class BloscFile:
892 def __init__(self, file_path=None, fileobj=None, mode='rb', level=9, encoding=None, errors=None, newline=None):
893 if file_path is None and fileobj is None:
894 raise ValueError("Either file_path or fileobj must be provided");
895 if file_path is not None and fileobj is not None:
896 raise ValueError("Only one of file_path or fileobj should be provided");
898 self.file_path = file_path;
899 self.fileobj = fileobj;
900 self.mode = mode;
901 self.level = level;
902 self.encoding = encoding;
903 self.errors = errors;
904 self.newline = newline;
905 self._compressed_data = b'';
906 self._decompressed_data = b'';
907 self._position = 0;
908 self._text_mode = 't' in mode;
910 # Force binary mode for internal handling
911 internal_mode = mode.replace('t', 'b');
913 if 'w' in mode or 'a' in mode or 'x' in mode:
914 self.file = open(file_path, internal_mode) if file_path else fileobj;
915 self._compressor = blosc.Blosc(level);
916 elif 'r' in mode:
917 if file_path:
918 if os.path.exists(file_path):
919 self.file = open(file_path, internal_mode);
920 self._load_file();
921 else:
922 raise FileNotFoundError("No such file: '{}'".format(file_path));
923 elif fileobj:
924 self.file = fileobj;
925 self._load_file();
926 else:
927 raise ValueError("Mode should be 'rb' or 'wb'");
929 def _load_file(self):
930 self.file.seek(0);
931 self._compressed_data = self.file.read();
932 if not self._compressed_data:
933 raise ValueError("Invalid blosc file header");
934 self._decompressed_data = blosc.decompress(self._compressed_data);
935 if self._text_mode:
936 self._decompressed_data = self._decompressed_data.decode(self.encoding or 'utf-8', self.errors or 'strict');
938 def write(self, data):
939 if self._text_mode:
940 data = data.encode(self.encoding or 'utf-8', self.errors or 'strict');
941 compressed_data = blosc.compress(data, cname='blosclz', clevel=self.level);
942 self.file.write(compressed_data);
943 self.file.flush();
945 def read(self, size=-1):
946 if size == -1:
947 size = len(self._decompressed_data) - self._position;
948 data = self._decompressed_data[self._position:self._position + size];
949 self._position += size;
950 return data;
952 def seek(self, offset, whence=0):
953 if whence == 0: # absolute file positioning
954 self._position = offset;
955 elif whence == 1: # seek relative to the current position
956 self._position += offset;
957 elif whence == 2: # seek relative to the file's end
958 self._position = len(self._decompressed_data) + offset;
959 else:
960 raise ValueError("Invalid value for whence");
962 # Ensure the position is within bounds
963 self._position = max(0, min(self._position, len(self._decompressed_data)));
965 def tell(self):
966 return self._position;
968 def flush(self):
969 self.file.flush();
971 def fileno(self):
972 if hasattr(self.file, 'fileno'):
973 return self.file.fileno();
974 raise OSError("The underlying file object does not support fileno()");
976 def isatty(self):
977 if hasattr(self.file, 'isatty'):
978 return self.file.isatty();
979 return False;
981 def truncate(self, size=None):
982 if hasattr(self.file, 'truncate'):
983 return self.file.truncate(size);
984 raise OSError("The underlying file object does not support truncate()");
986 def close(self):
987 if 'w' in self.mode or 'a' in self.mode or 'x' in self.mode:
988 self.file.write(blosc.compress(self._compressor.flush(), cname='blosclz', clevel=self.level));
989 if self.file_path:
990 self.file.close();
992 def __enter__(self):
993 return self;
995 def __exit__(self, exc_type, exc_value, traceback):
996 self.close();
998 class BrotliFile:
999 def __init__(self, file_path=None, fileobj=None, mode='rb', level=11, encoding=None, errors=None, newline=None):
1000 if file_path is None and fileobj is None:
1001 raise ValueError("Either file_path or fileobj must be provided");
1002 if file_path is not None and fileobj is not None:
1003 raise ValueError("Only one of file_path or fileobj should be provided");
1005 self.file_path = file_path;
1006 self.fileobj = fileobj;
1007 self.mode = mode;
1008 self.level = level;
1009 self.encoding = encoding;
1010 self.errors = errors;
1011 self.newline = newline;
1012 self._compressed_data = b'';
1013 self._decompressed_data = b'';
1014 self._position = 0;
1015 self._text_mode = 't' in mode;
1017 # Force binary mode for internal handling
1018 internal_mode = mode.replace('t', 'b');
1020 if 'w' in mode or 'a' in mode or 'x' in mode:
1021 self.file = open(file_path, internal_mode) if file_path else fileobj;
1022 self._compressor = brotli.Compressor(quality=self.level);
1023 elif 'r' in mode:
1024 if file_path:
1025 if os.path.exists(file_path):
1026 self.file = open(file_path, internal_mode);
1027 self._load_file();
1028 else:
1029 raise FileNotFoundError("No such file: '{}'".format(file_path));
1030 elif fileobj:
1031 self.file = fileobj;
1032 self._load_file();
1033 else:
1034 raise ValueError("Mode should be 'rb' or 'wb'");
1036 def _load_file(self):
1037 self.file.seek(0);
1038 self._compressed_data = self.file.read();
1039 if not self._compressed_data:
1040 raise ValueError("Invalid brotli file header");
1041 self._decompressed_data = brotli.decompress(self._compressed_data);
1042 if self._text_mode:
1043 self._decompressed_data = self._decompressed_data.decode(self.encoding or 'utf-8', self.errors or 'strict');
1045 def write(self, data):
1046 if self._text_mode:
1047 data = data.encode(self.encoding or 'utf-8', self.errors or 'strict');
1048 compressed_data = self._compressor.process(data);
1049 self.file.write(compressed_data);
1050 self.file.flush();
1052 def read(self, size=-1):
1053 if size == -1:
1054 size = len(self._decompressed_data) - self._position;
1055 data = self._decompressed_data[self._position:self._position + size];
1056 self._position += size;
1057 return data;
1059 def seek(self, offset, whence=0):
1060 if whence == 0: # absolute file positioning
1061 self._position = offset;
1062 elif whence == 1: # seek relative to the current position
1063 self._position += offset;
1064 elif whence == 2: # seek relative to the file's end
1065 self._position = len(self._decompressed_data) + offset;
1066 else:
1067 raise ValueError("Invalid value for whence");
1069 # Ensure the position is within bounds
1070 self._position = max(0, min(self._position, len(self._decompressed_data)));
1072 def tell(self):
1073 return self._position;
1075 def flush(self):
1076 self.file.flush();
1078 def fileno(self):
1079 if hasattr(self.file, 'fileno'):
1080 return self.file.fileno();
1081 raise OSError("The underlying file object does not support fileno()");
1083 def isatty(self):
1084 if hasattr(self.file, 'isatty'):
1085 return self.file.isatty();
1086 return False;
1088 def truncate(self, size=None):
1089 if hasattr(self.file, 'truncate'):
1090 return self.file.truncate(size);
1091 raise OSError("The underlying file object does not support truncate()");
1093 def close(self):
1094 if 'w' in self.mode or 'a' in self.mode or 'x' in self.mode:
1095 self.file.write(self._compressor.finish());
1096 if self.file_path:
1097 self.file.close();
1099 def __enter__(self):
1100 return self;
1102 def __exit__(self, exc_type, exc_value, traceback):
1103 self.close();
1107 def TarFileCheck(infile):
1108 try:
1109 if is_tarfile(infile):
1110 return True
1111 else:
1112 return False
1113 except TypeError:
1114 try:
1115 # Check if the input is a file object
1116 if hasattr(infile, 'read'):
1117 # Save the current file position
1118 current_position = infile.tell()
1119 # Attempt to open the file object as a tar file
1120 tar = tarfile.open(fileobj=infile)
1121 tar.close()
1122 # Restore the file position
1123 infile.seek(current_position)
1124 return True
1125 else:
1126 # Assume it's a filename
1127 tar = tarfile.open(name=infile)
1128 tar.close()
1129 return True
1130 except tarfile.TarError:
1131 return False
1134 def TarFileCheckAlt(infile):
1135 try:
1136 if is_tarfile(infile):
1137 return True
1138 except TypeError:
1139 pass
1140 try:
1141 # Check if the input is a file-like object
1142 if hasattr(infile, 'read'):
1143 # Save the current file position
1144 current_position = infile.tell()
1145 # Attempt to open the file object as a tar file
1146 with tarfile.open(fileobj=infile) as tar:
1147 pass
1148 # Restore the file position
1149 infile.seek(current_position)
1150 else:
1151 # Assume it's a filename and attempt to open it as a tar file
1152 with tarfile.open(name=infile) as tar:
1153 pass
1154 return True
1155 except (tarfile.TarError, AttributeError, IOError):
1156 return False
1159 def ZipFileCheck(infile):
1160 try:
1161 if zipfile.is_zipfile(infile):
1162 return True
1163 except TypeError:
1164 pass
1165 try:
1166 # Check if the input is a file-like object
1167 if hasattr(infile, 'read'):
1168 # Save the current file position
1169 current_position = infile.tell()
1170 # Attempt to open the file object as a zip file
1171 with zipfile.ZipFile(infile) as zipf:
1172 pass
1173 # Restore the file position
1174 infile.seek(current_position)
1175 else:
1176 # Assume it's a filename and attempt to open it as a zip file
1177 with zipfile.ZipFile(infile) as zipf:
1178 pass
1179 return True
1180 except (zipfile.BadZipFile, AttributeError, IOError):
1181 return False
1184 def RarFileCheck(infile):
1185 try:
1186 if rarfile.is_rarfile(infile):
1187 return True
1188 except TypeError:
1189 pass
1190 try:
1191 # Check if the input is a file-like object
1192 if hasattr(infile, 'read'):
1193 # Save the current file position
1194 current_position = infile.tell()
1195 # Attempt to open the file object as a rar file
1196 with rarfile.RarFile(infile) as rarf:
1197 pass
1198 # Restore the file position
1199 infile.seek(current_position)
1200 else:
1201 # Assume it's a filename and attempt to open it as a rar file
1202 with rarfile.RarFile(infile) as rarf:
1203 pass
1204 return True
1205 except (rarfile.Error, AttributeError, IOError):
1206 return False
1209 def SevenZipFileCheck(infile):
1210 try:
1211 # Check if the input is a file-like object
1212 if hasattr(infile, 'read'):
1213 # Save the current file position
1214 current_position = infile.tell()
1215 # Attempt to open the file object as a 7z file
1216 with py7zr.SevenZipFile(infile, 'r') as archive:
1217 pass
1218 # Restore the file position
1219 infile.seek(current_position)
1220 else:
1221 # Assume it's a filename and attempt to open it as a 7z file
1222 with py7zr.SevenZipFile(infile, 'r') as archive:
1223 pass
1224 return True
1225 except (py7zr.Bad7zFile, AttributeError, IOError):
1226 return False
1228 # initial_value can be 0xFFFF or 0x0000
1231 def crc16_ansi(msg, initial_value=0xFFFF):
1232 # CRC-16-IBM / CRC-16-ANSI polynomial and initial value
1233 poly = 0x8005 # Polynomial for CRC-16-IBM / CRC-16-ANSI
1234 crc = initial_value # Initial value
1235 for b in msg:
1236 crc ^= b << 8 # XOR byte into CRC top byte
1237 for _ in range(8): # Process each bit
1238 if crc & 0x8000: # If the top bit is set
1239 # Shift left and XOR with the polynomial
1240 crc = (crc << 1) ^ poly
1241 else:
1242 crc = crc << 1 # Just shift left
1243 crc &= 0xFFFF # Ensure CRC remains 16-bit
1244 return crc
1246 # initial_value can be 0xFFFF or 0x0000
1249 def crc16_ibm(msg, initial_value=0xFFFF):
1250 return crc16_ansi(msg, initial_value)
1252 # initial_value is 0xFFFF
1255 def crc16(msg):
1256 return crc16_ansi(msg, 0xFFFF)
1258 # initial_value can be 0xFFFF, 0x1D0F or 0x0000
1261 def crc16_ccitt(msg, initial_value=0xFFFF):
1262 # CRC-16-CCITT polynomial
1263 poly = 0x1021 # Polynomial for CRC-16-CCITT
1264 # Use the specified initial value
1265 crc = initial_value
1266 for b in msg:
1267 crc ^= b << 8 # XOR byte into CRC top byte
1268 for _ in range(8): # Process each bit
1269 if crc & 0x8000: # If the top bit is set
1270 # Shift left and XOR with the polynomial
1271 crc = (crc << 1) ^ poly
1272 else:
1273 crc = crc << 1 # Just shift left
1274 crc &= 0xFFFF # Ensure CRC remains 16-bit
1275 return crc
1277 # initial_value can be 0x42F0E1EBA9EA3693 or 0x0000000000000000
1280 def crc64_ecma(msg, initial_value=0x0000000000000000):
1281 # CRC-64-ECMA polynomial and initial value
1282 poly = 0x42F0E1EBA9EA3693
1283 crc = initial_value # Initial value for CRC-64-ECMA
1284 for b in msg:
1285 crc ^= b << 56 # XOR byte into the most significant byte of the CRC
1286 for _ in range(8): # Process each bit
1287 if crc & (1 << 63): # Check if the leftmost (most significant) bit is set
1288 # Shift left and XOR with poly if the MSB is 1
1289 crc = (crc << 1) ^ poly
1290 else:
1291 crc <<= 1 # Just shift left if the MSB is 0
1292 crc &= 0xFFFFFFFFFFFFFFFF # Ensure CRC remains 64-bit
1293 return crc
1295 # initial_value can be 0x000000000000001B or 0xFFFFFFFFFFFFFFFF
1298 def crc64_iso(msg, initial_value=0xFFFFFFFFFFFFFFFF):
1299 # CRC-64-ISO polynomial and initial value
1300 poly = 0x000000000000001B
1301 crc = initial_value # Common initial value for CRC-64-ISO
1302 for b in msg:
1303 crc ^= b << 56 # XOR byte into the most significant byte of the CRC
1304 for _ in range(8): # Process each bit
1305 if crc & (1 << 63): # Check if the leftmost (most significant) bit is set
1306 # Shift left and XOR with poly if the MSB is 1
1307 crc = (crc << 1) ^ poly
1308 else:
1309 crc <<= 1 # Just shift left if the MSB is 0
1310 crc &= 0xFFFFFFFFFFFFFFFF # Ensure CRC remains 64-bit
1311 return crc
1314 def GetDataFromArray(data, path, default=None):
1315 element = data
1316 try:
1317 for key in path:
1318 element = element[key]
1319 return element
1320 except (KeyError, TypeError, IndexError):
1321 return default
1324 def GetDataFromArrayAlt(structure, path, default=None):
1325 element = structure
1326 for key in path:
1327 if isinstance(element, dict) and key in element:
1328 element = element[key]
1329 elif isinstance(element, list) and isinstance(key, int) and -len(element) <= key < len(element):
1330 element = element[key]
1331 else:
1332 return default
1333 return element
1336 def GetHeaderChecksum(inlist=[], checksumtype="crc32", encodedata=True, formatspecs=__file_format_dict__):
1337 formatspecs = FormatSpecsListToDict(formatspecs)
1338 fileheader = AppendNullBytes(inlist, formatspecs['format_delimiter']) if isinstance(
1339 inlist, list) else AppendNullByte(inlist, formatspecs['format_delimiter'])
1340 if encodedata:
1341 fileheader = fileheader.encode('UTF-8')
1342 checksum_methods = {
1343 "crc16": lambda data: format(crc16(data) & 0xffff, '04x').lower(),
1344 "crc16_ansi": lambda data: format(crc16(data) & 0xffff, '04x').lower(),
1345 "crc16_ibm": lambda data: format(crc16(data) & 0xffff, '04x').lower(),
1346 "crc16_ccitt": lambda data: format(crc16_ccitt(data) & 0xffff, '04x').lower(),
1347 "adler32": lambda data: format(zlib.adler32(data) & 0xffffffff, '08x').lower(),
1348 "crc32": lambda data: format(crc32(data) & 0xffffffff, '08x').lower(),
1349 "crc64_ecma": lambda data: format(crc64_ecma(data) & 0xffffffffffffffff, '016x').lower(),
1350 "crc64": lambda data: format(crc64_iso(data) & 0xffffffffffffffff, '016x').lower(),
1351 "crc64_iso": lambda data: format(crc64_iso(data) & 0xffffffffffffffff, '016x').lower(),
1353 if checksumtype in checksum_methods:
1354 return checksum_methods[checksumtype](fileheader)
1355 elif CheckSumSupportAlt(checksumtype, hashlib_guaranteed):
1356 checksumoutstr = hashlib.new(checksumtype)
1357 checksumoutstr.update(fileheader)
1358 return checksumoutstr.hexdigest().lower()
1359 return format(0, 'x').lower()
1362 def GetFileChecksum(instr, checksumtype="crc32", encodedata=True, formatspecs=__file_format_dict__):
1363 formatspecs = FormatSpecsListToDict(formatspecs)
1364 if encodedata:
1365 instr = instr.encode('UTF-8')
1366 checksum_methods = {
1367 "crc16": lambda data: format(crc16(data) & 0xffff, '04x').lower(),
1368 "crc16_ansi": lambda data: format(crc16(data) & 0xffff, '04x').lower(),
1369 "crc16_ibm": lambda data: format(crc16(data) & 0xffff, '04x').lower(),
1370 "crc16_ccitt": lambda data: format(crc16_ccitt(data) & 0xffff, '04x').lower(),
1371 "adler32": lambda data: format(zlib.adler32(data) & 0xffffffff, '08x').lower(),
1372 "crc32": lambda data: format(crc32(data) & 0xffffffff, '08x').lower(),
1373 "crc64_ecma": lambda data: format(crc64_ecma(data) & 0xffffffffffffffff, '016x').lower(),
1374 "crc64": lambda data: format(crc64_iso(data) & 0xffffffffffffffff, '016x').lower(),
1375 "crc64_iso": lambda data: format(crc64_iso(data) & 0xffffffffffffffff, '016x').lower(),
1377 if checksumtype in checksum_methods:
1378 return checksum_methods[checksumtype](instr)
1379 elif CheckSumSupportAlt(checksumtype, hashlib_guaranteed):
1380 checksumoutstr = hashlib.new(checksumtype)
1381 checksumoutstr.update(instr)
1382 return checksumoutstr.hexdigest().lower()
1383 return format(0, 'x').lower()
1386 def ValidateHeaderChecksum(inlist=[], checksumtype="crc32", inchecksum="0", formatspecs=__file_format_dict__):
1387 formatspecs = FormatSpecsListToDict(formatspecs)
1388 catfileheadercshex = GetHeaderChecksum(
1389 inlist, checksumtype, True, formatspecs).lower()
1390 return inchecksum.lower() == catfileheadercshex
1393 def ValidateFileChecksum(infile, checksumtype="crc32", inchecksum="0", formatspecs=__file_format_dict__):
1394 formatspecs = FormatSpecsListToDict(formatspecs)
1395 catinfilecshex = GetFileChecksum(
1396 infile, checksumtype, True, formatspecs).lower()
1397 return inchecksum.lower() == catinfilecshex
1400 def ReadTillNullByteOld(fp, delimiter=__file_format_dict__['format_delimiter']):
1401 curbyte = b""
1402 curfullbyte = b""
1403 nullbyte = delimiter.encode("UTF-8")
1404 while(True):
1405 curbyte = fp.read(1)
1406 if(curbyte == nullbyte or not curbyte):
1407 break
1408 curfullbyte = curfullbyte + curbyte
1409 return curfullbyte.decode('UTF-8')
1412 def ReadUntilNullByteOld(fp, delimiter=__file_format_dict__['format_delimiter']):
1413 return ReadTillNullByteOld(fp, delimiter)
1416 def ReadTillNullByteAlt(fp, delimiter=__file_format_dict__['format_delimiter'], chunk_size=1024, max_read=1024000):
1417 delimiter = delimiter.encode('UTF-8') # Ensure the delimiter is in bytes
1418 buffer = bytearray()
1419 total_read = 0
1420 delimiter_length = len(delimiter)
1421 while True:
1422 chunk = fp.read(chunk_size)
1423 if not chunk:
1424 # End of file reached without finding the delimiter
1425 break
1426 buffer.extend(chunk)
1427 total_read += len(chunk)
1428 if delimiter in buffer:
1429 # Delimiter found, calculate where to reset the file pointer
1430 index = buffer.find(delimiter)
1431 # Calculate how many extra bytes were read after the delimiter
1432 extra_bytes_read = len(buffer) - (index + delimiter_length)
1433 # Move the file pointer back to just after the delimiter
1434 fp.seek(-extra_bytes_read, 1)
1435 buffer = buffer[:index]
1436 break
1437 if total_read >= max_read:
1438 # Stop reading if max limit is reached to prevent excessive memory usage
1439 raise MemoryError(
1440 "Maximum read limit reached without finding the delimiter.")
1441 # Check for incomplete UTF-8 sequences at the end of the buffer
1442 if len(buffer) > 1 and 128 <= buffer[-1] < 192:
1443 # This suggests that the last byte might be the start of a multi-byte character
1444 # Try to read one more byte to complete the character
1445 extra_byte = fp.read(1)
1446 if extra_byte:
1447 buffer.extend(extra_byte)
1448 else:
1449 # No more data available
1450 break
1451 try:
1452 return buffer.decode('UTF-8', errors='replace')
1453 except UnicodeDecodeError:
1454 return buffer.decode('UTF-8', errors='replace')
1457 def ReadUntilNullByteAlt(fp, delimiter=__file_format_dict__['format_delimiter'], chunk_size=1024, max_read=1024000):
1458 return ReadTillNullByteAlt(fp, delimiter, chunk_size, max_read)
1461 def ReadTillNullByte(fp, delimiter=__file_format_dict__['format_delimiter'], max_read=1024000):
1462 curfullbyte = bytearray()
1463 nullbyte = delimiter.encode("UTF-8")
1464 total_read = 0 # Track the total number of bytes read
1465 while True:
1466 curbyte = fp.read(1)
1467 if curbyte == nullbyte or not curbyte:
1468 break
1469 curfullbyte.extend(curbyte)
1470 total_read += 1
1471 if total_read >= max_read:
1472 raise MemoryError(
1473 "Maximum read limit reached without finding the delimiter.")
1474 # Decode the full byte array to string once out of the loop
1475 try:
1476 return curfullbyte.decode('UTF-8')
1477 except UnicodeDecodeError:
1478 # Handle potential partial UTF-8 characters
1479 for i in range(1, 4):
1480 try:
1481 return curfullbyte[:-i].decode('UTF-8')
1482 except UnicodeDecodeError:
1483 continue
1484 raise # Re-raise if decoding fails even after trimming
1487 def ReadUntilNullByte(fp, delimiter=__file_format_dict__['format_delimiter'], max_read=1024000):
1488 return ReadTillNullByte(fp, delimiter, max_read)
1491 def ReadTillNullByteByNum(fp, delimiter=__file_format_dict__['format_delimiter'], num_delimiters=1, chunk_size=1024, max_read=1024000):
1492 delimiter = delimiter.encode('UTF-8') # Ensure the delimiter is in bytes
1493 buffer = bytearray()
1494 total_read = 0
1495 delimiter_length = len(delimiter)
1496 results = []
1497 while len(results) < num_delimiters:
1498 chunk = fp.read(chunk_size)
1499 if not chunk:
1500 # End of file reached; decode whatever is collected if it's the last needed part
1501 if len(buffer) > 0:
1502 results.append(buffer.decode('UTF-8', errors='replace'))
1503 break
1504 buffer.extend(chunk)
1505 total_read += len(chunk)
1506 # Check if we have found the delimiter
1507 while delimiter in buffer:
1508 index = buffer.find(delimiter)
1509 # Decode the section before the delimiter
1510 results.append(buffer[:index].decode('UTF-8', errors='replace'))
1511 # Remove the processed part from the buffer
1512 buffer = buffer[index + delimiter_length:]
1513 if len(results) == num_delimiters:
1514 # If reached the required number of delimiters, adjust the file pointer and stop
1515 fp.seek(-len(buffer), 1)
1516 return results
1517 if total_read >= max_read:
1518 # Stop reading if max limit is reached to prevent excessive memory usage
1519 raise MemoryError(
1520 "Maximum read limit reached without finding the delimiter.")
1521 # Check for incomplete UTF-8 sequences at the end of the buffer
1522 if len(buffer) > 1 and 128 <= buffer[-1] < 192:
1523 # This suggests that the last byte might be the start of a multi-byte character
1524 # Try to read one more byte to complete the character
1525 extra_byte = fp.read(1)
1526 if extra_byte:
1527 buffer.extend(extra_byte)
1528 else:
1529 # No more data available
1530 break
1531 # Process remaining buffer if less than the required number of delimiters were found
1532 if len(buffer) > 0 and len(results) < num_delimiters:
1533 results.append(buffer.decode('UTF-8', errors='replace'))
1534 return results
1537 def ReadUntilNullByteByNum(fp, delimiter=__file_format_dict__['format_delimiter'], num_delimiters=1, chunk_size=1024, max_read=1024000):
1538 return ReadTillNullByteByNum(fp, delimiter, num_delimiters, chunk_size, max_read)
1541 def SeekToEndOfFile(fp):
1542 lasttell = 0
1543 while(True):
1544 fp.seek(1, 1)
1545 if(lasttell == fp.tell()):
1546 break
1547 lasttell = fp.tell()
1548 return True
1551 def ReadFileHeaderData(fp, rounds=0, delimiter=__file_format_dict__['format_delimiter']):
1552 rocount = 0
1553 roend = int(rounds)
1554 HeaderOut = []
1555 while(rocount < roend):
1556 HeaderOut.append(ReadTillNullByte(fp, delimiter))
1557 rocount = rocount + 1
1558 return HeaderOut
1561 def ReadFileHeaderDataBySize(fp, delimiter=__file_format_dict__['format_delimiter']):
1562 headerpresize = ReadTillNullByte(fp, delimiter)
1563 headersize = int(headerpresize, 16)
1564 if(headersize <= 0):
1565 return []
1566 headercontent = str(fp.read(headersize).decode('UTF-8')).split(delimiter)
1567 fp.seek(1, 1)
1568 rocount = 0
1569 roend = int(len(headercontent))
1570 HeaderOut = [headerpresize]
1571 while(rocount < roend):
1572 HeaderOut.append(headercontent[rocount])
1573 rocount = rocount + 1
1574 return HeaderOut
1577 def ReadFileHeaderDataWoSize(fp, delimiter=__file_format_dict__['format_delimiter']):
1578 preheaderdata = ReadFileHeaderData(fp, 2, delimiter)
1579 headersize = int(preheaderdata[0], 16)
1580 headernumfields = int(preheaderdata[1], 16)
1581 if(headersize <= 0 or headernumfields <= 0):
1582 return []
1583 headerdata = ReadTillNullByteByNum(fp, delimiter, headernumfields)
1584 #headerdata = ReadFileHeaderData(fp, headernumfields, delimiter);
1585 HeaderOut = preheaderdata + headerdata
1586 return HeaderOut
1589 def ReadFileHeaderDataBySizeWithContent(fp, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
1590 formatspecs = FormatSpecsListToDict(formatspecs)
1591 delimiter = formatspecs['format_delimiter']
1592 fheaderstart = fp.tell()
1593 HeaderOut = ReadFileHeaderDataBySize(fp, delimiter)
1594 if(len(HeaderOut) == 0):
1595 return False
1596 if(re.findall("^[.|/]", HeaderOut[3])):
1597 fname = HeaderOut[3]
1598 else:
1599 fname = "./"+HeaderOut[3]
1600 fcs = HeaderOut[-2].lower()
1601 fccs = HeaderOut[-1].lower()
1602 fsize = int(HeaderOut[5], 16)
1603 fcompression = HeaderOut[12]
1604 fcsize = int(HeaderOut[13], 16)
1605 fseeknextfile = HeaderOut[25]
1606 newfcs = GetHeaderChecksum(
1607 HeaderOut[:-2], HeaderOut[-4].lower(), True, formatspecs)
1608 if(fcs != newfcs and not skipchecksum):
1609 VerbosePrintOut("File Header Checksum Error with file " +
1610 fname + " at offset " + str(fheaderstart))
1611 VerbosePrintOut("'" + str(fcs) + "' != " + "'" + str(newfcs) + "'")
1612 return False
1613 fhend = fp.tell() - 1
1614 fcontentstart = fp.tell()
1615 fcontents = BytesIO()
1616 if(fsize > 0 and not listonly):
1617 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1618 fcontents.write(fp.read(fsize))
1619 else:
1620 fcontents.write(fp.read(fcsize))
1621 elif(fsize > 0 and listonly):
1622 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1623 fp.seek(fsize, 1)
1624 else:
1625 fp.seek(fcsize, 1)
1626 fcontents.seek(0, 0)
1627 newfccs = GetFileChecksum(
1628 fcontents.read(), HeaderOut[-3].lower(), False, formatspecs)
1629 if(fccs != newfccs and not skipchecksum and not listonly):
1630 VerbosePrintOut("File Content Checksum Error with file " +
1631 fname + " at offset " + str(fcontentstart))
1632 VerbosePrintOut("'" + str(fccs) + "' != " + "'" + str(newfccs) + "'")
1633 return False
1634 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1635 pass
1636 else:
1637 fcontents.seek(0, 0)
1638 if(uncompress):
1639 fcontents = UncompressArchiveFile(fcontents, formatspecs)
1640 fcontentend = fp.tell()
1641 if(re.findall("^\\+([0-9]+)", fseeknextfile)):
1642 fseeknextasnum = int(fseeknextfile.replace("+", ""))
1643 if(abs(fseeknextasnum) == 0):
1644 pass
1645 fp.seek(fseeknextasnum, 1)
1646 elif(re.findall("^\\-([0-9]+)", fseeknextfile)):
1647 fseeknextasnum = int(fseeknextfile)
1648 if(abs(fseeknextasnum) == 0):
1649 pass
1650 fp.seek(fseeknextasnum, 1)
1651 elif(re.findall("^([0-9]+)", fseeknextfile)):
1652 fseeknextasnum = int(fseeknextfile)
1653 if(abs(fseeknextasnum) == 0):
1654 pass
1655 fp.seek(fseeknextasnum, 0)
1656 else:
1657 return False
1658 HeaderOut.append(fcontents)
1659 return HeaderOut
1662 def ReadFileHeaderDataBySizeWithContentToArray(fp, listonly=False, contentasfile=True, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
1663 formatspecs = FormatSpecsListToDict(formatspecs)
1664 delimiter = formatspecs['format_delimiter']
1665 fheaderstart = fp.tell()
1666 if(formatspecs['new_style']):
1667 HeaderOut = ReadFileHeaderDataBySize(fp, delimiter)
1668 else:
1669 HeaderOut = ReadFileHeaderDataWoSize(fp, delimiter)
1670 if(len(HeaderOut) == 0):
1671 return False
1672 fheadsize = int(HeaderOut[0], 16)
1673 fnumfields = int(HeaderOut[1], 16)
1674 ftype = int(HeaderOut[2], 16)
1675 if(re.findall("^[.|/]", HeaderOut[3])):
1676 fname = HeaderOut[3]
1677 else:
1678 fname = "./"+HeaderOut[3]
1679 fbasedir = os.path.dirname(fname)
1680 flinkname = HeaderOut[4]
1681 fsize = int(HeaderOut[5], 16)
1682 fatime = int(HeaderOut[6], 16)
1683 fmtime = int(HeaderOut[7], 16)
1684 fctime = int(HeaderOut[8], 16)
1685 fbtime = int(HeaderOut[9], 16)
1686 fmode = int(HeaderOut[10], 16)
1687 fchmode = stat.S_IMODE(fmode)
1688 ftypemod = stat.S_IFMT(fmode)
1689 fwinattributes = int(HeaderOut[11], 16)
1690 fcompression = HeaderOut[12]
1691 fcsize = int(HeaderOut[13], 16)
1692 fuid = int(HeaderOut[14], 16)
1693 funame = HeaderOut[15]
1694 fgid = int(HeaderOut[16], 16)
1695 fgname = HeaderOut[17]
1696 fid = int(HeaderOut[18], 16)
1697 finode = int(HeaderOut[19], 16)
1698 flinkcount = int(HeaderOut[20], 16)
1699 fdev_minor = int(HeaderOut[21], 16)
1700 fdev_major = int(HeaderOut[22], 16)
1701 frdev_minor = int(HeaderOut[23], 16)
1702 frdev_major = int(HeaderOut[24], 16)
1703 fseeknextfile = HeaderOut[25]
1704 fextrasize = int(HeaderOut[26], 16)
1705 fextrafields = int(HeaderOut[27], 16)
1706 extrafieldslist = []
1707 extrastart = 28
1708 extraend = extrastart + fextrafields
1709 extrafieldslist = []
1710 if(extrastart < extraend):
1711 extrafieldslist.append(HeaderOut[extrastart])
1712 extrastart = extrastart + 1
1713 fcs = HeaderOut[-2].lower()
1714 fccs = HeaderOut[-1].lower()
1715 newfcs = GetHeaderChecksum(
1716 HeaderOut[:-2], HeaderOut[-4].lower(), True, formatspecs)
1717 if(fcs != newfcs and not skipchecksum):
1718 VerbosePrintOut("File Header Checksum Error with file " +
1719 fname + " at offset " + str(fheaderstart))
1720 VerbosePrintOut("'" + str(fcs) + "' != " + "'" + str(newfcs) + "'")
1721 return False
1722 fhend = fp.tell() - 1
1723 fcontentstart = fp.tell()
1724 fcontents = BytesIO()
1725 pyhascontents = False
1726 if(fsize > 0 and not listonly):
1727 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1728 fcontents.write(fp.read(fsize))
1729 else:
1730 fcontents.write(fp.read(fcsize))
1731 pyhascontents = True
1732 elif(fsize > 0 and listonly):
1733 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1734 fp.seek(fsize, 1)
1735 else:
1736 fp.seek(fcsize, 1)
1737 pyhascontents = False
1738 fcontents.seek(0, 0)
1739 newfccs = GetFileChecksum(
1740 fcontents.read(), HeaderOut[-3].lower(), False, formatspecs)
1741 if(fccs != newfccs and not skipchecksum and not listonly):
1742 VerbosePrintOut("File Content Checksum Error with file " +
1743 fname + " at offset " + str(fcontentstart))
1744 VerbosePrintOut("'" + str(fccs) + "' != " + "'" + str(newfccs) + "'")
1745 return False
1746 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1747 pass
1748 else:
1749 fcontents.seek(0, 0)
1750 if(uncompress):
1751 fcontents = UncompressArchiveFile(fcontents, formatspecs)
1752 fcontents.seek(0, 0)
1753 fccs = GetFileChecksum(
1754 fcontents.read(), HeaderOut[-3].lower(), False, formatspecs)
1755 fcontentend = fp.tell() - 1
1756 if(re.findall("^\\+([0-9]+)", fseeknextfile)):
1757 fseeknextasnum = int(fseeknextfile.replace("+", ""))
1758 if(abs(fseeknextasnum) == 0):
1759 pass
1760 fp.seek(fseeknextasnum, 1)
1761 elif(re.findall("^\\-([0-9]+)", fseeknextfile)):
1762 fseeknextasnum = int(fseeknextfile)
1763 if(abs(fseeknextasnum) == 0):
1764 pass
1765 fp.seek(fseeknextasnum, 1)
1766 elif(re.findall("^([0-9]+)", fseeknextfile)):
1767 fseeknextasnum = int(fseeknextfile)
1768 if(abs(fseeknextasnum) == 0):
1769 pass
1770 fp.seek(fseeknextasnum, 0)
1771 else:
1772 return False
1773 fcontents.seek(0, 0)
1774 if(not contentasfile):
1775 fcontents = fcontents.read()
1776 catlist = {'fheadersize': fheadsize, 'fhstart': fheaderstart, 'fhend': fhend, 'ftype': ftype, 'fname': fname, 'fbasedir': fbasedir, 'flinkname': flinkname, 'fsize': fsize, 'fatime': fatime, 'fmtime': fmtime, 'fctime': fctime, 'fbtime': fbtime, 'fmode': fmode, 'fchmode': fchmode, 'ftypemod': ftypemod, 'fwinattributes': fwinattributes, 'fcompression': fcompression, 'fcsize': fcsize, 'fuid': fuid, 'funame': funame, 'fgid': fgid, 'fgname': fgname, 'finode': finode, 'flinkcount': flinkcount, 'fminor': fdev_minor,
1777 'fmajor': fdev_major, 'frminor': frdev_minor, 'frmajor': frdev_major, 'fseeknextfile': fseeknextfile, 'fheaderchecksumtype': HeaderOut[-4], 'fcontentchecksumtype': HeaderOut[-3], 'fnumfields': fnumfields + 2, 'frawheader': HeaderOut, 'fextrafields': fextrafields, 'fextrafieldsize': fextrasize, 'fextralist': extrafieldslist, 'fheaderchecksum': fcs, 'fcontentchecksum': fccs, 'fhascontents': pyhascontents, 'fcontentstart': fcontentstart, 'fcontentend': fcontentend, 'fcontentasfile': contentasfile, 'fcontents': fcontents}
1778 return catlist
1781 def ReadFileHeaderDataBySizeWithContentToList(fp, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
1782 formatspecs = FormatSpecsListToDict(formatspecs)
1783 delimiter = formatspecs['format_delimiter']
1784 fheaderstart = fp.tell()
1785 if(formatspecs['new_style']):
1786 HeaderOut = ReadFileHeaderDataBySize(fp, delimiter)
1787 else:
1788 HeaderOut = ReadFileHeaderDataWoSize(fp, delimiter)
1789 if(len(HeaderOut) == 0):
1790 return False
1791 fheadsize = int(HeaderOut[0], 16)
1792 fnumfields = int(HeaderOut[1], 16)
1793 ftype = int(HeaderOut[2], 16)
1794 if(re.findall("^[.|/]", HeaderOut[3])):
1795 fname = HeaderOut[3]
1796 else:
1797 fname = "./"+HeaderOut[3]
1798 fbasedir = os.path.dirname(fname)
1799 flinkname = HeaderOut[4]
1800 fsize = int(HeaderOut[5], 16)
1801 fatime = int(HeaderOut[6], 16)
1802 fmtime = int(HeaderOut[7], 16)
1803 fctime = int(HeaderOut[8], 16)
1804 fbtime = int(HeaderOut[9], 16)
1805 fmode = int(HeaderOut[10], 16)
1806 fchmode = stat.S_IMODE(fmode)
1807 ftypemod = stat.S_IFMT(fmode)
1808 fwinattributes = int(HeaderOut[11], 16)
1809 fcompression = HeaderOut[12]
1810 fcsize = int(HeaderOut[13], 16)
1811 fuid = int(HeaderOut[14], 16)
1812 funame = HeaderOut[15]
1813 fgid = int(HeaderOut[16], 16)
1814 fgname = HeaderOut[17]
1815 fid = int(HeaderOut[18], 16)
1816 finode = int(HeaderOut[19], 16)
1817 flinkcount = int(HeaderOut[20], 16)
1818 fdev_minor = int(HeaderOut[21], 16)
1819 fdev_major = int(HeaderOut[22], 16)
1820 frdev_minor = int(HeaderOut[23], 16)
1821 frdev_major = int(HeaderOut[24], 16)
1822 fseeknextfile = HeaderOut[25]
1823 fextrasize = int(HeaderOut[26], 16)
1824 fextrafields = int(HeaderOut[27], 16)
1825 extrafieldslist = []
1826 extrastart = 28
1827 extraend = extrastart + fextrafields
1828 extrafieldslist = []
1829 if(extrastart < extraend):
1830 extrafieldslist.append(HeaderOut[extrastart])
1831 extrastart = extrastart + 1
1832 fheaderchecksumtype = HeaderOut[extrastart].lower()
1833 fcontentchecksumtype = HeaderOut[extrastart + 1].lower()
1834 fcs = HeaderOut[-2].lower()
1835 fccs = HeaderOut[-1].lower()
1836 newfcs = GetHeaderChecksum(
1837 HeaderOut[:-2], HeaderOut[-4].lower(), True, formatspecs)
1838 if(fcs != newfcs and not skipchecksum):
1839 VerbosePrintOut("File Header Checksum Error with file " +
1840 fname + " at offset " + str(fheaderstart))
1841 VerbosePrintOut("'" + str(fcs) + "' != " + "'" + str(newfcs) + "'")
1842 return False
1843 fhend = fp.tell() - 1
1844 fcontentstart = fp.tell()
1845 fcontents = BytesIO()
1846 pyhascontents = False
1847 if(fsize > 0 and not listonly):
1848 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1849 fcontents.write(fp.read(fsize))
1850 else:
1851 fcontents.write(fp.read(fcsize))
1852 pyhascontents = True
1853 elif(fsize > 0 and listonly):
1854 if(fcompression == "none" or fcompression == "" or fcompression == "atuo"):
1855 fp.seek(fsize, 1)
1856 else:
1857 fp.seek(fcsize, 1)
1858 pyhascontents = False
1859 fcontents.seek(0, 0)
1860 newfccs = GetFileChecksum(
1861 fcontents.read(), HeaderOut[-3].lower(), False, formatspecs)
1862 if(fccs != newfccs and not skipchecksum and not listonly):
1863 VerbosePrintOut("File Content Checksum Error with file " +
1864 fname + " at offset " + str(fcontentstart))
1865 VerbosePrintOut("'" + str(fccs) + "' != " + "'" + str(newfccs) + "'")
1866 return False
1867 if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
1868 pass
1869 else:
1870 fcontents.seek(0, 0)
1871 if(uncompress):
1872 fcontents = UncompressArchiveFile(fcontents, formatspecs)
1873 fcontents.seek(0, 0)
1874 fcontentend = fp.tell() - 1
1875 if(re.findall("^\\+([0-9]+)", fseeknextfile)):
1876 fseeknextasnum = int(fseeknextfile.replace("+", ""))
1877 if(abs(fseeknextasnum) == 0):
1878 pass
1879 fp.seek(fseeknextasnum, 1)
1880 elif(re.findall("^\\-([0-9]+)", fseeknextfile)):
1881 fseeknextasnum = int(fseeknextfile)
1882 if(abs(fseeknextasnum) == 0):
1883 pass
1884 fp.seek(fseeknextasnum, 1)
1885 elif(re.findall("^([0-9]+)", fseeknextfile)):
1886 fseeknextasnum = int(fseeknextfile)
1887 if(abs(fseeknextasnum) == 0):
1888 pass
1889 fp.seek(fseeknextasnum, 0)
1890 else:
1891 return False
1892 catlist = [ftype, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression, fcsize, fuid, funame, fgid, fgname, fid,
1893 finode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, fseeknextfile, extrafieldslist, fheaderchecksumtype, fcontentchecksumtype, fcontents]
1894 return catlist
1897 def ReadFileDataBySizeWithContent(fp, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
1898 formatspecs = FormatSpecsListToDict(formatspecs)
1899 delimiter = formatspecs['format_delimiter']
1900 curloc = fp.tell()
1901 if(curloc > 0):
1902 fp.seek(0, 0)
1903 catheader = ReadFileHeaderData(fp, 4, delimiter)
1904 if(curloc > 0):
1905 fp.seek(curloc, 0)
1906 headercheck = ValidateHeaderChecksum(
1907 catheader[:-1], catheader[2], catheader[3], formatspecs)
1908 newfcs = GetHeaderChecksum(catheader[:-2], catheader[2], True, formatspecs)
1909 if(not headercheck and not skipchecksum):
1910 VerbosePrintOut(
1911 "File Header Checksum Error with file at offset " + str(0))
1912 VerbosePrintOut("'" + str(newfcs) + "' != " +
1913 "'" + str(catheader[3]) + "'")
1914 return False
1915 fnumfiles = int(catheader[1], 16)
1916 countnum = 0
1917 flist = []
1918 while(countnum < fnumfiles):
1919 HeaderOut = ReadFileHeaderDataBySizeWithContent(
1920 fp, listonly, uncompress, skipchecksum, formatspecs)
1921 if(len(HeaderOut) == 0):
1922 break
1923 flist.append(HeaderOut)
1924 countnum = countnum + 1
1925 return flist
1928 def ReadFileDataBySizeWithContentToArray(fp, seekstart=0, seekend=0, listonly=False, contentasfile=True, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
1929 formatspecs = FormatSpecsListToDict(formatspecs)
1930 delimiter = formatspecs['format_delimiter']
1931 curloc = fp.tell()
1932 if(curloc > 0):
1933 fp.seek(0, 0)
1934 catheader = ReadFileHeaderData(fp, 4, delimiter)
1935 if(curloc > 0):
1936 fp.seek(curloc, 0)
1937 headercheck = ValidateHeaderChecksum(
1938 catheader[:-1], catheader[2], catheader[3], formatspecs)
1939 newfcs = GetHeaderChecksum(catheader[:-2], catheader[2], True, formatspecs)
1940 if(not headercheck and not skipchecksum):
1941 VerbosePrintOut(
1942 "File Header Checksum Error with file at offset " + str(0))
1943 VerbosePrintOut("'" + str(newfcs) + "' != " +
1944 "'" + str(catheader[3]) + "'")
1945 return False
1946 catstring = catheader[0]
1947 catversion = re.findall("([\\d]+)", catstring)
1948 catversions = re.search('(.*?)(\\d+)', catstring).groups()
1949 fprenumfiles = catheader[1]
1950 fnumfiles = int(fprenumfiles, 16)
1951 fprechecksumtype = catheader[2]
1952 fprechecksum = catheader[3]
1953 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
1954 'fformatspecs': formatspecs, 'fchecksumtype': fprechecksumtype, 'fheaderchecksum': fprechecksum, 'ffilelist': []}
1955 if(seekstart < 0 and seekstart > fnumfiles):
1956 seekstart = 0
1957 if(seekend == 0 or seekend > fnumfiles and seekend < seekstart):
1958 seekend = fnumfiles
1959 elif(seekend < 0 and abs(seekend) <= fnumfiles and abs(seekend) >= seekstart):
1960 seekend = fnumfiles - abs(seekend)
1961 if(seekstart > 0):
1962 il = 0
1963 while(il < seekstart):
1964 prefhstart = fp.tell()
1965 preheaderdata = ReadFileHeaderDataBySize(
1966 fp, formatspecs['format_delimiter'])
1967 if(len(preheaderdata) == 0):
1968 break
1969 prefsize = int(preheaderdata[5], 16)
1970 prefseeknextfile = preheaderdata[25]
1971 prenewfcs = GetHeaderChecksum(
1972 preheaderdata[:-2], preheaderdata[-4].lower(), True, formatspecs)
1973 prefcs = preheaderdata[-2]
1974 if(prefcs != prenewfcs and not skipchecksum):
1975 VVerbosePrintOut("File Header Checksum Error with file " +
1976 prefname + " at offset " + str(prefhstart))
1977 VerbosePrintOut("'" + str(prefcs) + "' != " +
1978 "'" + str(prenewfcs) + "'")
1979 return False
1980 valid_archive = False
1981 invalid_archive = True
1982 prefhend = fp.tell() - 1
1983 prefcontentstart = fp.tell()
1984 prefcontents = BytesIO()
1985 pyhascontents = False
1986 if(prefsize > 0):
1987 prefcontents.write(fp.read(prefsize))
1988 prefcontents.seek(0, 0)
1989 prenewfccs = GetFileChecksum(
1990 prefcontents.read(), preheaderdata[-3].lower(), False, formatspecs)
1991 prefccs = preheaderdata[-1]
1992 pyhascontents = True
1993 if(prefccs != prenewfccs and not skipchecksum):
1994 VerbosePrintOut("File Content Checksum Error with file " +
1995 prefname + " at offset " + str(prefcontentstart))
1996 VerbosePrintOut("'" + str(prefccs) +
1997 "' != " + "'" + str(prenewfccs) + "'")
1998 return False
1999 if(re.findall("^\\+([0-9]+)", prefseeknextfile)):
2000 fseeknextasnum = int(prefseeknextfile.replace("+", ""))
2001 if(abs(fseeknextasnum) == 0):
2002 pass
2003 fp.seek(fseeknextasnum, 1)
2004 elif(re.findall("^\\-([0-9]+)", prefseeknextfile)):
2005 fseeknextasnum = int(prefseeknextfile)
2006 if(abs(fseeknextasnum) == 0):
2007 pass
2008 fp.seek(fseeknextasnum, 1)
2009 elif(re.findall("^([0-9]+)", prefseeknextfile)):
2010 fseeknextasnum = int(prefseeknextfile)
2011 if(abs(fseeknextasnum) == 0):
2012 pass
2013 fp.seek(fseeknextasnum, 0)
2014 else:
2015 return False
2016 il = il + 1
2017 realidnum = 0
2018 countnum = seekstart
2019 while(countnum < seekend):
2020 HeaderOut = ReadFileHeaderDataBySizeWithContentToArray(
2021 fp, listonly, contentasfile, uncompress, skipchecksum, formatspecs)
2022 if(len(HeaderOut) == 0):
2023 break
2024 HeaderOut.update({'fid': realidnum, 'fidalt': realidnum})
2025 catlist['ffilelist'].append(HeaderOut)
2026 countnum = countnum + 1
2027 realidnum = realidnum + 1
2028 return catlist
2031 def ReadFileDataBySizeWithContentToList(fp, seekstart=0, seekend=0, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
2032 formatspecs = FormatSpecsListToDict(formatspecs)
2033 delimiter = formatspecs['format_delimiter']
2034 curloc = fp.tell()
2035 if(curloc > 0):
2036 fp.seek(0, 0)
2037 catheader = ReadFileHeaderData(fp, 4, delimiter)
2038 if(curloc > 0):
2039 fp.seek(curloc, 0)
2040 headercheck = ValidateHeaderChecksum(
2041 catheader[:-1], catheader[2], catheader[3], formatspecs)
2042 newfcs = GetHeaderChecksum(catheader[:-2], catheader[2], True, formatspecs)
2043 if(not headercheck and not skipchecksum):
2044 VerbosePrintOut(
2045 "File Header Checksum Error with file at offset " + str(0))
2046 VerbosePrintOut("'" + str(newfcs) + "' != " +
2047 "'" + str(catheader[3]) + "'")
2048 return False
2049 catstring = catheader[0]
2050 catversion = re.findall("([\\d]+)", catstring)
2051 catversions = re.search('(.*?)(\\d+)', catstring).groups()
2052 fprenumfiles = catheader[1]
2053 fnumfiles = int(fprenumfiles, 16)
2054 fprechecksumtype = catheader[2]
2055 fprechecksum = catheader[3]
2056 catlist = []
2057 if(seekstart < 0 and seekstart > fnumfiles):
2058 seekstart = 0
2059 if(seekend == 0 or seekend > fnumfiles and seekend < seekstart):
2060 seekend = fnumfiles
2061 elif(seekend < 0 and abs(seekend) <= fnumfiles and abs(seekend) >= seekstart):
2062 seekend = fnumfiles - abs(seekend)
2063 if(seekstart > 0):
2064 il = 0
2065 while(il < seekstart):
2066 prefhstart = fp.tell()
2067 preheaderdata = ReadFileHeaderDataBySize(
2068 fp, formatspecs['format_delimiter'])
2069 if(len(preheaderdata) == 0):
2070 break
2071 prefsize = int(preheaderdata[5], 16)
2072 prefcompression = preheaderdata[12]
2073 prefcsize = int(preheaderdata[13], 16)
2074 prefseeknextfile = HeaderOut[25]
2075 prenewfcs = GetHeaderChecksum(
2076 preheaderdata[:-2], preheaderdata[-4].lower(), True, formatspecs)
2077 prefcs = preheaderdata[-2]
2078 if(prefcs != prenewfcs and not skipchecksum):
2079 VerbosePrintOut("File Header Checksum Error with file " +
2080 prefname + " at offset " + str(prefhstart))
2081 VerbosePrintOut("'" + str(prefcs) + "' != " +
2082 "'" + str(prenewfcs) + "'")
2083 return False
2084 valid_archive = False
2085 invalid_archive = True
2086 prefhend = fp.tell() - 1
2087 prefcontentstart = fp.tell()
2088 prefcontents = ""
2089 pyhascontents = False
2090 if(prefsize > 0):
2091 if(prefcompression == "none" or prefcompression == "" or prefcompression == "auto"):
2092 prefcontents = catfp.read(prefsize)
2093 else:
2094 prefcontents = catfp.read(prefcsize)
2095 prenewfccs = GetFileChecksum(
2096 prefcontents, preheaderdata[-3].lower(), False, formatspecs)
2097 prefccs = preheaderdata[-1]
2098 pyhascontents = True
2099 if(prefccs != prenewfccs and not skipchecksum):
2100 VerbosePrintOut("File Content Checksum Error with file " +
2101 prefname + " at offset " + str(prefcontentstart))
2102 VerbosePrintOut("'" + str(prefccs) +
2103 "' != " + "'" + str(prenewfccs) + "'")
2104 return False
2105 if(re.findall("^\\+([0-9]+)", prefseeknextfile)):
2106 fseeknextasnum = int(prefseeknextfile.replace("+", ""))
2107 if(abs(fseeknextasnum) == 0):
2108 pass
2109 catfp.seek(fseeknextasnum, 1)
2110 elif(re.findall("^\\-([0-9]+)", prefseeknextfile)):
2111 fseeknextasnum = int(prefseeknextfile)
2112 if(abs(fseeknextasnum) == 0):
2113 pass
2114 catfp.seek(fseeknextasnum, 1)
2115 elif(re.findall("^([0-9]+)", prefseeknextfile)):
2116 fseeknextasnum = int(prefseeknextfile)
2117 if(abs(fseeknextasnum) == 0):
2118 pass
2119 catfp.seek(fseeknextasnum, 0)
2120 else:
2121 return False
2122 il = il + 1
2123 realidnum = 0
2124 countnum = seekstart
2125 while(countnum < seekend):
2126 HeaderOut = ReadFileHeaderDataBySizeWithContentToList(
2127 fp, listonly, uncompress, skipchecksum, formatspecs)
2128 if(len(HeaderOut) == 0):
2129 break
2130 catlist.append(HeaderOut)
2131 countnum = countnum + 1
2132 realidnum = realidnum + 1
2133 return catlist
2136 def ReadInFileBySizeWithContentToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
2137 formatspecs = FormatSpecsListToDict(formatspecs)
2138 delimiter = formatspecs['format_delimiter']
2139 if(hasattr(infile, "read") or hasattr(infile, "write")):
2140 fp = infile
2141 fp.seek(0, 0)
2142 fp = UncompressArchiveFile(fp, formatspecs)
2143 checkcompressfile = CheckCompressionSubType(fp, formatspecs, True)
2144 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
2145 return False
2146 if(not fp):
2147 return False
2148 fp.seek(0, 0)
2149 elif(infile == "-"):
2150 fp = BytesIO()
2151 if(hasattr(sys.stdin, "buffer")):
2152 shutil.copyfileobj(sys.stdin.buffer, fp)
2153 else:
2154 shutil.copyfileobj(sys.stdin, fp)
2155 fp.seek(0, 0)
2156 fp = UncompressArchiveFile(fp, formatspecs)
2157 if(not fp):
2158 return False
2159 fp.seek(0, 0)
2160 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
2161 fp = download_file_from_internet_file(infile)
2162 fp = UncompressArchiveFile(fp, formatspecs)
2163 fp.seek(0, 0)
2164 if(not fp):
2165 return False
2166 fp.seek(0, 0)
2167 else:
2168 infile = RemoveWindowsPath(infile)
2169 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
2170 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
2171 return False
2172 compresscheck = CheckCompressionType(infile, formatspecs, True)
2173 if(not compresscheck):
2174 fextname = os.path.splitext(infile)[1]
2175 if(fextname == ".gz"):
2176 compresscheck = "gzip"
2177 elif(fextname == ".bz2"):
2178 compresscheck = "bzip2"
2179 elif(fextname == ".zst"):
2180 compresscheck = "zstd"
2181 elif(fextname == ".lz4" or fextname == ".clz4"):
2182 compresscheck = "lz4"
2183 elif(fextname == ".lzo" or fextname == ".lzop"):
2184 compresscheck = "lzo"
2185 elif(fextname == ".lzma"):
2186 compresscheck = "lzma"
2187 elif(fextname == ".xz"):
2188 compresscheck = "xz"
2189 elif(fextname == ".zz" or fextname == ".zl" or fextname == ".zlib"):
2190 compresscheck = "zlib"
2191 else:
2192 return False
2193 if(not compresscheck):
2194 return False
2195 fp = UncompressFile(infile, formatspecs, "rb")
2196 return ReadFileDataBySizeWithContentToArray(fp, seekstart, seekend, listonly, contentasfile, uncompress, skipchecksum, formatspecs)
2199 def ReadInFileBySizeWithContentToList(infile, seekstart=0, seekend=0, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__):
2200 formatspecs = FormatSpecsListToDict(formatspecs)
2201 delimiter = formatspecs['format_delimiter']
2202 if(hasattr(infile, "read") or hasattr(infile, "write")):
2203 fp = infile
2204 fp.seek(0, 0)
2205 fp = UncompressArchiveFile(fp, formatspecs)
2206 checkcompressfile = CheckCompressionSubType(fp, formatspecs, True)
2207 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
2208 return False
2209 if(not fp):
2210 return False
2211 fp.seek(0, 0)
2212 elif(infile == "-"):
2213 fp = BytesIO()
2214 if(hasattr(sys.stdin, "buffer")):
2215 shutil.copyfileobj(sys.stdin.buffer, fp)
2216 else:
2217 shutil.copyfileobj(sys.stdin, fp)
2218 fp.seek(0, 0)
2219 fp = UncompressArchiveFile(fp, formatspecs)
2220 if(not fp):
2221 return False
2222 fp.seek(0, 0)
2223 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
2224 fp = download_file_from_internet_file(infile)
2225 fp = UncompressArchiveFile(fp, formatspecs)
2226 fp.seek(0, 0)
2227 if(not fp):
2228 return False
2229 fp.seek(0, 0)
2230 else:
2231 infile = RemoveWindowsPath(infile)
2232 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
2233 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
2234 return False
2235 compresscheck = CheckCompressionType(infile, formatspecs, True)
2236 if(not compresscheck):
2237 fextname = os.path.splitext(infile)[1]
2238 if(fextname == ".gz"):
2239 compresscheck = "gzip"
2240 elif(fextname == ".bz2"):
2241 compresscheck = "bzip2"
2242 elif(fextname == ".zst"):
2243 compresscheck = "zstd"
2244 elif(fextname == ".lz4" or fextname == ".clz4"):
2245 compresscheck = "lz4"
2246 elif(fextname == ".lzo" or fextname == ".lzop"):
2247 compresscheck = "lzo"
2248 elif(fextname == ".lzma"):
2249 compresscheck = "lzma"
2250 elif(fextname == ".xz"):
2251 compresscheck = "xz"
2252 elif(fextname == ".zz" or fextname == ".zl" or fextname == ".zlib"):
2253 compresscheck = "zlib"
2254 else:
2255 return False
2256 if(not compresscheck):
2257 return False
2258 fp = UncompressFile(infile, formatspecs, "rb")
2259 return ReadFileDataBySizeWithContentToList(fp, seekstart, seekend, listonly, uncompress, skipchecksum, formatspecs)
2262 def AppendNullByte(indata, delimiter=__file_format_dict__['format_delimiter']):
2263 outdata = str(indata) + delimiter
2264 return outdata
2267 def AppendNullBytes(indata=[], delimiter=__file_format_dict__['format_delimiter']):
2268 outdata = ""
2269 inum = 0
2270 il = len(indata)
2271 while(inum < il):
2272 outdata = outdata + AppendNullByte(indata[inum], delimiter)
2273 inum = inum + 1
2274 return outdata
2277 def AppendFileHeader(fp, numfiles, checksumtype="crc32", formatspecs=__file_format_dict__):
2278 formatspecs = FormatSpecsListToDict(formatspecs)
2279 delimiter = formatspecs['format_delimiter']
2280 catver = formatspecs['format_ver']
2281 fileheaderver = str(int(catver.replace(".", "")))
2282 fileheader = AppendNullByte(
2283 formatspecs['format_magic'] + fileheaderver, formatspecs['format_delimiter'])
2284 fp.write(fileheader.encode('UTF-8'))
2285 fnumfiles = format(int(numfiles), 'x').lower()
2286 fnumfilesa = AppendNullBytes(
2287 [fnumfiles, checksumtype], formatspecs['format_delimiter'])
2288 catfileheadercshex = GetFileChecksum(
2289 fileheader + fnumfilesa, checksumtype, True, formatspecs)
2290 fnumfilesa = fnumfilesa + \
2291 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
2292 fp.write(fnumfilesa.encode('UTF-8'))
2293 try:
2294 fp.flush()
2295 os.fsync(fp.fileno())
2296 except io.UnsupportedOperation:
2297 pass
2298 except AttributeError:
2299 pass
2300 except OSError as e:
2301 pass
2302 return fp
2305 def MakeEmptyFilePointer(fp, checksumtype="crc32", formatspecs=__file_format_dict__):
2306 formatspecs = FormatSpecsListToDict(formatspecs)
2307 AppendFileHeader(fp, 0, checksumtype, formatspecs)
2308 return fp
2311 def MakeEmptyFile(outfile, compression="auto", compressionlevel=None, checksumtype="crc32", formatspecs=__file_format_dict__, returnfp=False):
2312 formatspecs = FormatSpecsListToDict(formatspecs)
2313 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
2314 if(os.path.exists(outfile)):
2315 try:
2316 os.unlink(outfile)
2317 except OSError as e:
2318 pass
2319 if(outfile == "-"):
2320 verbose = False
2321 catfpfp = BytesIO()
2322 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
2323 catfp = outfile
2324 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
2325 catfp = BytesIO()
2326 else:
2327 fbasename = os.path.splitext(outfile)[0]
2328 fextname = os.path.splitext(outfile)[1]
2329 if(not compresswholefile and fextname in outextlistwd):
2330 compresswholefile = True
2331 catfp = CompressOpenFile(outfile, True, compressionlevel)
2332 catfp = AppendFileHeader(catfp, 0, checksumtype, formatspecs)
2333 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
2334 catfp = CompressArchiveFile(
2335 catfp, compression, compressionlevel, formatspecs)
2336 try:
2337 catfp.flush()
2338 os.fsync(catfp.fileno())
2339 except io.UnsupportedOperation:
2340 pass
2341 except AttributeError:
2342 pass
2343 except OSError as e:
2344 pass
2345 if(outfile == "-"):
2346 catfp.seek(0, 0)
2347 if(hasattr(sys.stdout, "buffer")):
2348 shutil.copyfileobj(catfp, sys.stdout.buffer)
2349 else:
2350 shutil.copyfileobj(catfp, sys.stdout)
2351 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
2352 catfp = CompressArchiveFile(
2353 catfp, compression, compressionlevel, formatspecs)
2354 catfp.seek(0, 0)
2355 upload_file_to_internet_file(catfp, outfile)
2356 if(returnfp):
2357 catfp.seek(0, 0)
2358 return catfp
2359 else:
2360 catfp.close()
2361 return True
2364 def AppendFileHeaderWithContent(fp, filevalues=[], extradata=[], filecontent="", checksumtype="crc32", formatspecs=__file_format_dict__):
2365 formatspecs = FormatSpecsListToDict(formatspecs)
2366 extrafields = format(len(extradata), 'x').lower()
2367 extrasizestr = AppendNullByte(extrafields, formatspecs['format_delimiter'])
2368 if(len(extradata) > 0):
2369 extrasizestr = extrasizestr + \
2370 AppendNullBytes(extradata, formatspecs['format_delimiter'])
2371 extrasizelen = format(len(extrasizestr), 'x').lower()
2372 catoutlen = len(filevalues) + len(extradata) + 5
2373 catoutlenhex = format(catoutlen, 'x').lower()
2374 catoutlist = filevalues
2375 catoutlist.insert(0, catoutlenhex)
2376 catoutlist.append(extrasizelen)
2377 catoutlist.append(extrafields)
2378 catfileoutstr = AppendNullBytes(
2379 catoutlist, formatspecs['format_delimiter'])
2380 if(len(extradata) > 0):
2381 catfileoutstr = catfileoutstr + \
2382 AppendNullBytes(extradata, formatspecs['format_delimiter'])
2383 if(len(filecontent) == 0):
2384 checksumlist = [checksumtype, "none"]
2385 else:
2386 checksumlist = [checksumtype, checksumtype]
2387 catfileoutstr = catfileoutstr + \
2388 AppendNullBytes(checksumlist, formatspecs['format_delimiter'])
2389 catfileheadercshex = GetFileChecksum(
2390 catfileoutstr, checksumtype, True, formatspecs)
2391 if(len(filecontent) == 0):
2392 catfilecontentcshex = GetFileChecksum(
2393 filecontent, "none", False, formatspecs)
2394 else:
2395 catfilecontentcshex = GetFileChecksum(
2396 filecontent, checksumtype, False, formatspecs)
2397 tmpfileoutstr = catfileoutstr + \
2398 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
2399 formatspecs['format_delimiter'])
2400 catheaersize = format(int(len(tmpfileoutstr) - 1), 'x').lower()
2401 catfileoutstr = AppendNullByte(
2402 catheaersize, formatspecs['format_delimiter']) + catfileoutstr
2403 catfileheadercshex = GetFileChecksum(
2404 catfileoutstr, checksumtype, True, formatspecs)
2405 catfileoutstr = catfileoutstr + \
2406 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
2407 formatspecs['format_delimiter'])
2408 catfileoutstrecd = catfileoutstr.encode('UTF-8')
2409 nullstrecd = formatspecs['format_delimiter'].encode('UTF-8')
2410 catfileout = catfileoutstrecd + filecontent + nullstrecd
2411 fp.write(catfileout)
2412 try:
2413 fp.flush()
2414 os.fsync(fp.fileno())
2415 except io.UnsupportedOperation:
2416 pass
2417 except AttributeError:
2418 pass
2419 except OSError as e:
2420 pass
2421 return fp
2424 def AppendFilesWithContent(infiles, fp, dirlistfromtxt=False, filevalues=[], extradata=[], compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False):
2425 formatspecs = FormatSpecsListToDict(formatspecs)
2426 advancedlist = formatspecs['use_advanced_list']
2427 altinode = formatspecs['use_alt_inode']
2428 if(verbose):
2429 logging.basicConfig(format="%(message)s",
2430 stream=sys.stdout, level=logging.DEBUG)
2431 if(infiles == "-"):
2432 for line in sys.stdin:
2433 infilelist.append(line.strip())
2434 infilelist = list(filter(None, infilelist))
2435 elif(infiles != "-" and dirlistfromtxt and os.path.exists(infiles) and (os.path.isfile(infiles) or infiles == "/dev/null" or infiles == "NUL")):
2436 if(not os.path.exists(infiles) or not os.path.isfile(infiles)):
2437 return False
2438 with UncompressFile(infiles, formatspecs, "r") as finfile:
2439 for line in finfile:
2440 infilelist.append(line.strip())
2441 infilelist = list(filter(None, infilelist))
2442 else:
2443 if(isinstance(infiles, (list, tuple, ))):
2444 infilelist = list(filter(None, infiles))
2445 elif(isinstance(infiles, (str, ))):
2446 infilelist = list(filter(None, [infiles]))
2447 if(advancedlist):
2448 GetDirList = ListDirAdvanced(infilelist, followlink, False)
2449 else:
2450 GetDirList = ListDir(infilelist, followlink, False)
2451 if(not GetDirList):
2452 return False
2453 curinode = 0
2454 curfid = 0
2455 inodelist = []
2456 inodetofile = {}
2457 filetoinode = {}
2458 inodetocatinode = {}
2459 numfiles = int(len(GetDirList))
2460 fnumfiles = format(numfiles, 'x').lower()
2461 AppendFileHeader(fp, fnumfiles, checksumtype, formatspecs)
2462 for curfname in GetDirList:
2463 if(re.findall("^[.|/]", curfname)):
2464 fname = curfname
2465 else:
2466 fname = "./"+curfname
2467 if(verbose):
2468 VerbosePrintOut(fname)
2469 if(not followlink or followlink is None):
2470 fstatinfo = os.lstat(fname)
2471 else:
2472 fstatinfo = os.stat(fname)
2473 fpremode = fstatinfo.st_mode
2474 finode = fstatinfo.st_ino
2475 flinkcount = fstatinfo.st_nlink
2476 ftype = 0
2477 if(stat.S_ISREG(fpremode)):
2478 ftype = 0
2479 elif(stat.S_ISLNK(fpremode)):
2480 ftype = 2
2481 elif(stat.S_ISCHR(fpremode)):
2482 ftype = 3
2483 elif(stat.S_ISBLK(fpremode)):
2484 ftype = 4
2485 elif(stat.S_ISDIR(fpremode)):
2486 ftype = 5
2487 elif(stat.S_ISFIFO(fpremode)):
2488 ftype = 6
2489 elif(stat.S_ISSOCK(fpremode)):
2490 ftype = 8
2491 elif(hasattr(stat, "S_ISDOOR") and stat.S_ISDOOR(fpremode)):
2492 ftype = 9
2493 elif(hasattr(stat, "S_ISPORT") and stat.S_ISPORT(fpremode)):
2494 ftype = 10
2495 elif(hasattr(stat, "S_ISWHT") and stat.S_ISWHT(fpremode)):
2496 ftype = 11
2497 else:
2498 ftype = 0
2499 flinkname = ""
2500 fcurfid = format(int(curfid), 'x').lower()
2501 if(not followlink and finode != 0):
2502 if(ftype != 1):
2503 if(finode in inodelist):
2504 ftype = 1
2505 flinkname = inodetofile[finode]
2506 if(altinode):
2507 fcurinode = format(int(finode), 'x').lower()
2508 else:
2509 fcurinode = format(
2510 int(inodetocatinode[finode]), 'x').lower()
2511 if(finode not in inodelist):
2512 inodelist.append(finode)
2513 inodetofile.update({finode: fname})
2514 inodetocatinode.update({finode: curinode})
2515 if(altinode):
2516 fcurinode = format(int(finode), 'x').lower()
2517 else:
2518 fcurinode = format(int(curinode), 'x').lower()
2519 curinode = curinode + 1
2520 else:
2521 fcurinode = format(int(curinode), 'x').lower()
2522 curinode = curinode + 1
2523 curfid = curfid + 1
2524 if(ftype == 2):
2525 flinkname = os.readlink(fname)
2526 fdev = fstatinfo.st_dev
2527 getfdev = GetDevMajorMinor(fdev)
2528 fdev_minor = getfdev[0]
2529 fdev_major = getfdev[1]
2530 frdev = fstatinfo.st_dev
2531 if(hasattr(fstatinfo, "st_rdev")):
2532 frdev = fstatinfo.st_rdev
2533 else:
2534 frdev = fstatinfo.st_dev
2535 getfrdev = GetDevMajorMinor(frdev)
2536 frdev_minor = getfrdev[0]
2537 frdev_major = getfrdev[1]
2538 if(ftype == 1 or ftype == 2 or ftype == 3 or ftype == 4 or ftype == 5 or ftype == 6):
2539 fsize = format(int("0"), 'x').lower()
2540 elif(ftype == 0 or ftype == 7):
2541 fsize = format(int(fstatinfo.st_size), 'x').lower()
2542 else:
2543 fsize = format(int(fstatinfo.st_size)).lower()
2544 fatime = format(int(fstatinfo.st_atime), 'x').lower()
2545 fmtime = format(int(fstatinfo.st_mtime), 'x').lower()
2546 fctime = format(int(fstatinfo.st_ctime), 'x').lower()
2547 if(hasattr(fstatinfo, "st_birthtime")):
2548 fbtime = format(int(fstatinfo.st_birthtime), 'x').lower()
2549 else:
2550 fbtime = format(int(fstatinfo.st_ctime), 'x').lower()
2551 fmode = format(int(fstatinfo.st_mode), 'x').lower()
2552 fchmode = format(int(stat.S_IMODE(fstatinfo.st_mode)), 'x').lower()
2553 ftypemod = format(int(stat.S_IFMT(fstatinfo.st_mode)), 'x').lower()
2554 fuid = format(int(fstatinfo.st_uid), 'x').lower()
2555 fgid = format(int(fstatinfo.st_gid), 'x').lower()
2556 funame = ""
2557 try:
2558 import pwd
2559 try:
2560 userinfo = pwd.getpwuid(fstatinfo.st_uid)
2561 funame = userinfo.pw_name
2562 except KeyError:
2563 funame = ""
2564 except ImportError:
2565 funame = ""
2566 fgname = ""
2567 try:
2568 import grp
2569 try:
2570 groupinfo = grp.getgrgid(fstatinfo.st_gid)
2571 fgname = groupinfo.gr_name
2572 except KeyError:
2573 fgname = ""
2574 except ImportError:
2575 fgname = ""
2576 fdev_minor = format(int(fdev_minor), 'x').lower()
2577 fdev_major = format(int(fdev_major), 'x').lower()
2578 frdev_minor = format(int(frdev_minor), 'x').lower()
2579 frdev_major = format(int(frdev_major), 'x').lower()
2580 finode = format(int(finode), 'x').lower()
2581 flinkcount = format(int(flinkcount), 'x').lower()
2582 if(hasattr(fstatinfo, "st_file_attributes")):
2583 fwinattributes = format(
2584 int(fstatinfo.st_file_attributes), 'x').lower()
2585 else:
2586 fwinattributes = format(int(0), 'x').lower()
2587 fcompression = ""
2588 fcsize = format(int(0), 'x').lower()
2589 fcontents = BytesIO()
2590 chunk_size = 1024
2591 if(ftype == 0 or ftype == 7):
2592 with open(fname, "rb") as fpc:
2593 shutil.copyfileobj(fpc, fcontents)
2594 if(not compresswholefile):
2595 fcontents.seek(0, 2)
2596 ucfsize = fcontents.tell()
2597 fcontents.seek(0, 0)
2598 if(compression == "auto"):
2599 ilsize = len(compressionlistalt)
2600 ilmin = 0
2601 ilcsize = []
2602 while(ilmin < ilsize):
2603 cfcontents = BytesIO()
2604 shutil.copyfileobj(fcontents, cfcontents)
2605 fcontents.seek(0, 0)
2606 cfcontents.seek(0, 0)
2607 cfcontents = CompressArchiveFile(
2608 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
2609 if(cfcontents):
2610 cfcontents.seek(0, 2)
2611 ilcsize.append(cfcontents.tell())
2612 cfcontents.close()
2613 else:
2614 try:
2615 ilcsize.append(sys.maxint)
2616 except AttributeError:
2617 ilcsize.append(sys.maxsize)
2618 ilmin = ilmin + 1
2619 ilcmin = ilcsize.index(min(ilcsize))
2620 compression = compressionlistalt[ilcmin]
2621 fcontents.seek(0, 0)
2622 cfcontents = BytesIO()
2623 shutil.copyfileobj(fcontents, cfcontents)
2624 cfcontents.seek(0, 0)
2625 cfcontents = CompressArchiveFile(
2626 cfcontents, compression, compressionlevel, formatspecs)
2627 cfcontents.seek(0, 2)
2628 cfsize = cfcontents.tell()
2629 if(ucfsize > cfsize):
2630 fcsize = format(int(cfsize), 'x').lower()
2631 fcompression = compression
2632 fcontents.close()
2633 fcontents = cfcontents
2634 if(followlink and (ftype == 1 or ftype == 2)):
2635 flstatinfo = os.stat(flinkname)
2636 with open(flinkname, "rb") as fpc:
2637 shutil.copyfileobj(fpc, fcontents)
2638 if(not compresswholefile):
2639 fcontents.seek(0, 2)
2640 ucfsize = fcontents.tell()
2641 fcontents.seek(0, 0)
2642 if(compression == "auto"):
2643 ilsize = len(compressionlistalt)
2644 ilmin = 0
2645 ilcsize = []
2646 while(ilmin < ilsize):
2647 cfcontents = BytesIO()
2648 shutil.copyfileobj(fcontents, cfcontents)
2649 fcontents.seek(0, 0)
2650 cfcontents.seek(0, 0)
2651 cfcontents = CompressArchiveFile(
2652 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
2653 if(cfcontents):
2654 cfcontents.seek(0, 2)
2655 ilcsize.append(cfcontents.tell())
2656 cfcontents.close()
2657 else:
2658 try:
2659 ilcsize.append(sys.maxint)
2660 except AttributeError:
2661 ilcsize.append(sys.maxsize)
2662 ilmin = ilmin + 1
2663 ilcmin = ilcsize.index(min(ilcsize))
2664 compression = compressionlistalt[ilcmin]
2665 fcontents.seek(0, 0)
2666 cfcontents = BytesIO()
2667 shutil.copyfileobj(fcontents, cfcontents)
2668 cfcontents.seek(0, 0)
2669 cfcontents = CompressArchiveFile(
2670 cfcontents, compression, compressionlevel, formatspecs)
2671 cfcontents.seek(0, 2)
2672 cfsize = cfcontents.tell()
2673 if(ucfsize > cfsize):
2674 fcsize = format(int(cfsize), 'x').lower()
2675 fcompression = compression
2676 fcontents.close()
2677 fcontents = cfcontents
2678 if(fcompression == "none"):
2679 fcompression = ""
2680 fcontents.seek(0, 0)
2681 ftypehex = format(ftype, 'x').lower()
2682 catoutlist = [ftypehex, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression,
2683 fcsize, fuid, funame, fgid, fgname, fcurfid, fcurinode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, "+1"]
2684 fp = AppendFileHeaderWithContent(
2685 fp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
2686 if(numfiles > 0):
2687 catfp.write(AppendNullBytes(
2688 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
2689 fp.seek(0, 0)
2690 return fp
2693 def AppendListsWithContent(inlist, fp, dirlistfromtxt=False, filevalues=[], extradata=[], compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False):
2694 formatspecs = FormatSpecsListToDict(formatspecs)
2695 if(verbose):
2696 logging.basicConfig(format="%(message)s",
2697 stream=sys.stdout, level=logging.DEBUG)
2698 GetDirList = inlist
2699 if(not GetDirList):
2700 return False
2701 curinode = 0
2702 curfid = 0
2703 inodelist = []
2704 inodetofile = {}
2705 filetoinode = {}
2706 inodetocatinode = {}
2707 numfiles = int(len(GetDirList))
2708 fnumfiles = format(numfiles, 'x').lower()
2709 AppendFileHeader(fp, fnumfiles, checksumtype, formatspecs)
2710 for curfname in GetDirList:
2711 ftype = format(curfname[0], 'x').lower()
2712 if(re.findall("^[.|/]", curfname[1])):
2713 fname = curfname[1]
2714 else:
2715 fname = "./"+curfname[1]
2716 fbasedir = os.path.dirname(fname)
2717 flinkname = curfname[2]
2718 fsize = format(curfname[3], 'x').lower()
2719 fatime = format(curfname[4], 'x').lower()
2720 fmtime = format(curfname[5], 'x').lower()
2721 fctime = format(curfname[6], 'x').lower()
2722 fbtime = format(curfname[7], 'x').lower()
2723 fmode = format(curfname[8], 'x').lower()
2724 fwinattributes = format(curfname[9], 'x').lower()
2725 fcompression = curfname[10]
2726 fcsize = format(curfname[11], 'x').lower()
2727 fuid = format(curfname[12], 'x').lower()
2728 funame = curfname[13]
2729 fgid = format(curfname[14], 'x').lower()
2730 fgname = curfname[15]
2731 fid = format(curfname[16], 'x').lower()
2732 finode = format(curfname[17], 'x').lower()
2733 flinkcount = format(curfname[18], 'x').lower()
2734 fdev_minor = format(curfname[19], 'x').lower()
2735 fdev_major = format(curfname[20], 'x').lower()
2736 frdev_minor = format(curfname[21], 'x').lower()
2737 frdev_major = format(curfname[22], 'x').lower()
2738 fseeknextfile = curfname[23]
2739 extradata = curfname[24]
2740 fheaderchecksumtype = curfname[25]
2741 fcontentchecksumtype = curfname[26]
2742 fcontents = curfname[27]
2743 catoutlist = [ftype, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression, fcsize,
2744 fuid, funame, fgid, fgname, fid, finode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, fseeknextfile]
2745 fcontents.seek(0, 0)
2746 fp = AppendFileHeaderWithContent(
2747 fp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
2748 if(numfiles > 0):
2749 fp.write(AppendNullBytes(
2750 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
2751 return fp
2754 def AppendInFileWithContent(infile, fp, dirlistfromtxt=False, filevalues=[], extradata=[], followlink=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False):
2755 formatspecs = FormatSpecsListToDict(formatspecs)
2756 inlist = ReadInFileBySizeWithContentToList(
2757 infile, 0, 0, False, True, False, formatspecs)
2758 return AppendListsWithContent(inlist, fp, dirlistfromtxt, filevalues, extradata, followlink, checksumtype, formatspecs, verbose)
2761 def AppendFilesWithContentToOutFile(infiles, outfile, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, filevalues=[], extradata=[], followlink=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False, returnfp=False):
2762 formatspecs = FormatSpecsListToDict(formatspecs)
2763 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
2764 if(os.path.exists(outfile)):
2765 try:
2766 os.unlink(outfile)
2767 except OSError as e:
2768 pass
2769 if(outfile == "-"):
2770 verbose = False
2771 catfpfp = BytesIO()
2772 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
2773 catfp = outfile
2774 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
2775 catfp = BytesIO()
2776 else:
2777 fbasename = os.path.splitext(outfile)[0]
2778 fextname = os.path.splitext(outfile)[1]
2779 if(not compresswholefile and fextname in outextlistwd):
2780 compresswholefile = True
2781 catfp = CompressOpenFile(outfile, compresswholefile, compressionlevel)
2782 catfp = AppendFilesWithContent(infiles, catfp, dirlistfromtxt, filevalues, extradata, compression,
2783 compresswholefile, compressionlevel, followlink, checksumtype, formatspecs, verbose)
2784 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
2785 catfp = CompressArchiveFile(
2786 catfp, compression, compressionlevel, formatspecs)
2787 try:
2788 catfp.flush()
2789 os.fsync(catfp.fileno())
2790 except io.UnsupportedOperation:
2791 pass
2792 except AttributeError:
2793 pass
2794 except OSError as e:
2795 pass
2796 if(outfile == "-"):
2797 catfp.seek(0, 0)
2798 if(hasattr(sys.stdout, "buffer")):
2799 shutil.copyfileobj(catfp, sys.stdout.buffer)
2800 else:
2801 shutil.copyfileobj(catfp, sys.stdout)
2802 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
2803 catfp = CompressArchiveFile(
2804 catfp, compression, compressionlevel, formatspecs)
2805 catfp.seek(0, 0)
2806 upload_file_to_internet_file(catfp, outfile)
2807 if(returnfp):
2808 catfp.seek(0, 0)
2809 return catfp
2810 else:
2811 catfp.close()
2812 return True
2815 def AppendListsWithContentToOutFile(inlist, outfile, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, filevalues=[], extradata=[], followlink=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False, returnfp=False):
2816 formatspecs = FormatSpecsListToDict(formatspecs)
2817 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
2818 if(os.path.exists(outfile)):
2819 try:
2820 os.unlink(outfile)
2821 except OSError as e:
2822 pass
2823 if(outfile == "-"):
2824 verbose = False
2825 catfpfp = BytesIO()
2826 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
2827 catfp = outfile
2828 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
2829 catfp = BytesIO()
2830 else:
2831 fbasename = os.path.splitext(outfile)[0]
2832 fextname = os.path.splitext(outfile)[1]
2833 if(not compresswholefile and fextname in outextlistwd):
2834 compresswholefile = True
2835 catfp = CompressOpenFile(outfile, compresswholefile, compressionlevel)
2836 catfp = AppendListsWithContent(inlist, catfp, dirlistfromtxt, filevalues, extradata, compression,
2837 compresswholefile, compressionlevel, followlink, checksumtype, formatspecs, verbose)
2838 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
2839 catfp = CompressArchiveFile(
2840 catfp, compression, compressionlevel, formatspecs)
2841 try:
2842 catfp.flush()
2843 os.fsync(catfp.fileno())
2844 except io.UnsupportedOperation:
2845 pass
2846 except AttributeError:
2847 pass
2848 except OSError as e:
2849 pass
2850 if(outfile == "-"):
2851 catfp.seek(0, 0)
2852 if(hasattr(sys.stdout, "buffer")):
2853 shutil.copyfileobj(catfp, sys.stdout.buffer)
2854 else:
2855 shutil.copyfileobj(catfp, sys.stdout)
2856 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
2857 catfp = CompressArchiveFile(
2858 catfp, compression, compressionlevel, formatspecs)
2859 catfp.seek(0, 0)
2860 upload_file_to_internet_file(catfp, outfile)
2861 if(returnfp):
2862 catfp.seek(0, 0)
2863 return catfp
2864 else:
2865 catfp.close()
2866 return True
2869 def AppendInFileWithContentToOutFile(infile, outfile, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, filevalues=[], extradata=[], followlink=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False, returnfp=False):
2870 formatspecs = FormatSpecsListToDict(formatspecs)
2871 inlist = ReadInFileBySizeWithContentToList(
2872 infile, 0, 0, False, True, False, formatspecs)
2873 return AppendListsWithContentToOutFile(inlist, outfile, dirlistfromtxt, compression, compresswholefile, compressionlevel, filevalues, extradata, followlink, checksumtype, formatspecs, verbose, returnfp)
2876 def PrintPermissionString(fchmode, ftype):
2877 permissions = {'access': {'0': ('---'), '1': ('--x'), '2': ('-w-'), '3': ('-wx'), '4': (
2878 'r--'), '5': ('r-x'), '6': ('rw-'), '7': ('rwx')}, 'roles': {0: 'owner', 1: 'group', 2: 'other'}}
2879 permissionstr = ""
2880 for fmodval in str(oct(fchmode))[-3:]:
2881 permissionstr = permissionstr + \
2882 permissions['access'].get(fmodval, '---')
2883 if(ftype == 0 or ftype == 7):
2884 permissionstr = "-" + permissionstr
2885 if(ftype == 1):
2886 permissionstr = "h" + permissionstr
2887 if(ftype == 2):
2888 permissionstr = "l" + permissionstr
2889 if(ftype == 3):
2890 permissionstr = "c" + permissionstr
2891 if(ftype == 4):
2892 permissionstr = "b" + permissionstr
2893 if(ftype == 5):
2894 permissionstr = "d" + permissionstr
2895 if(ftype == 6):
2896 permissionstr = "f" + permissionstr
2897 if(ftype == 8):
2898 permissionstr = "D" + permissionstr
2899 if(ftype == 9):
2900 permissionstr = "p" + permissionstr
2901 if(ftype == 10):
2902 permissionstr = "w" + permissionstr
2903 try:
2904 permissionoutstr = stat.filemode(fchmode)
2905 except AttributeError:
2906 permissionoutstr = permissionstr
2907 except KeyError:
2908 permissionoutstr = permissionstr
2909 return permissionoutstr
2912 def PrintPermissionStringAlt(fchmode, ftype):
2913 permissions = {
2914 '0': '---', '1': '--x', '2': '-w-', '3': '-wx',
2915 '4': 'r--', '5': 'r-x', '6': 'rw-', '7': 'rwx'
2917 # Translate file mode into permission string
2918 permissionstr = ''.join([permissions[i] for i in str(oct(fchmode))[-3:]])
2919 # Append file type indicator
2920 type_indicators = {
2921 0: '-', 1: 'h', 2: 'l', 3: 'c', 4: 'b',
2922 5: 'd', 6: 'f', 8: 'D', 9: 'p', 10: 'w'
2924 file_type = type_indicators.get(ftype, '-')
2925 permissionstr = file_type + permissionstr
2926 try:
2927 permissionoutstr = stat.filemode(fchmode)
2928 except AttributeError:
2929 permissionoutstr = permissionstr
2930 return permissionoutstr
2933 def GzipCompressData(data, compresslevel=9):
2934 try:
2935 # Try using modern gzip.compress if available
2936 compressed_data = gzip.compress(data, compresslevel=compresslevel)
2937 except AttributeError:
2938 # Fallback to older method for Python 2.x and older 3.x versions
2939 out = BytesIO()
2940 with gzip.GzipFile(fileobj=out, mode="wb", compresslevel=compresslevel) as f:
2941 f.write(data)
2942 compressed_data = out.getvalue()
2943 return compressed_data
2946 def GzipDecompressData(compressed_data):
2947 try:
2948 # Try using modern gzip.decompress if available
2949 decompressed_data = gzip.decompress(compressed_data)
2950 except AttributeError:
2951 # Fallback to older method for Python 2.x and older 3.x versions
2952 inp = BytesIO(compressed_data)
2953 with gzip.GzipFile(fileobj=inp, mode="rb") as f:
2954 decompressed_data = f.read()
2955 return decompressed_data
2958 def BzipCompressData(data, compresslevel=9):
2959 try:
2960 # Try using modern bz2.compress if available
2961 compressed_data = bz2.compress(data, compresslevel=compresslevel)
2962 except AttributeError:
2963 # Fallback to older method for Python 2.x and older 3.x versions
2964 compressor = bz2.BZ2Compressor(compresslevel)
2965 compressed_data = compressor.compress(data)
2966 compressed_data += compressor.flush()
2967 return compressed_data
2970 def BzipDecompressData(compressed_data):
2971 try:
2972 # Try using modern bz2.decompress if available
2973 decompressed_data = bz2.decompress(compressed_data)
2974 except AttributeError:
2975 # Fallback to older method for Python 2.x and older 3.x versions
2976 decompressor = bz2.BZ2Decompressor()
2977 decompressed_data = decompressor.decompress(compressed_data)
2978 return decompressed_data
2981 def CheckCompressionType(infile, formatspecs=__file_format_dict__, closefp=True):
2982 formatspecs = FormatSpecsListToDict(formatspecs)
2983 if(hasattr(infile, "read") or hasattr(infile, "write")):
2984 catfp = infile
2985 else:
2986 try:
2987 catfp = open(infile, "rb")
2988 except FileNotFoundError:
2989 return False
2990 filetype = False
2991 catfp.seek(0, 0)
2992 prefp = catfp.read(2)
2993 if(prefp == binascii.unhexlify("1f8b")):
2994 filetype = "gzip"
2995 if(prefp == binascii.unhexlify("7801")):
2996 filetype = "zlib"
2997 if(prefp == binascii.unhexlify("785e")):
2998 filetype = "zlib"
2999 if(prefp == binascii.unhexlify("789c")):
3000 filetype = "zlib"
3001 if(prefp == binascii.unhexlify("78da")):
3002 filetype = "zlib"
3003 catfp.seek(0, 0)
3004 prefp = catfp.read(3)
3005 if(prefp == binascii.unhexlify("425a68")):
3006 filetype = "bzip2"
3007 if(prefp == binascii.unhexlify("5d0000")):
3008 filetype = "lzma"
3009 catfp.seek(0, 0)
3010 prefp = catfp.read(4)
3011 if(prefp == binascii.unhexlify("28b52ffd")):
3012 filetype = "zstd"
3013 if(prefp == binascii.unhexlify("04224d18")):
3014 filetype = "lz4"
3015 if(prefp == binascii.unhexlify("504B0304")):
3016 filetype = "zipfile"
3017 catfp.seek(0, 0)
3018 prefp = catfp.read(5)
3019 if(prefp == binascii.unhexlify("7573746172")):
3020 filetype = "tarfile"
3021 catfp.seek(0, 0)
3022 prefp = catfp.read(6)
3023 if(prefp == binascii.unhexlify("fd377a585a00")):
3024 filetype = "lzma"
3025 if(prefp == binascii.unhexlify("377abcaf271c")):
3026 filetype = "7zipfile"
3027 catfp.seek(0, 0)
3028 prefp = catfp.read(7)
3029 if(prefp == binascii.unhexlify("526172211a0700")):
3030 filetype = "rarfile"
3031 if(prefp == binascii.unhexlify("43617446696c65")):
3032 filetype = "catfile"
3033 catfp.seek(0, 0)
3034 prefp = catfp.read(8)
3035 if(prefp == binascii.unhexlify("526172211a070100")):
3036 filetype = "rarfile"
3037 catfp.seek(0, 0)
3038 prefp = catfp.read(formatspecs['format_len'])
3039 if(prefp == binascii.unhexlify(formatspecs['format_hex'])):
3040 filetype = formatspecs['format_lower']
3041 catfp.seek(0, 0)
3042 prefp = catfp.read(9)
3043 if(prefp == binascii.unhexlify("894c5a4f000d0a1a0a")):
3044 filetype = "lzo"
3045 catfp.seek(0, 0)
3046 prefp = catfp.read(10)
3047 if(prefp == binascii.unhexlify("7061785f676c6f62616c")):
3048 filetype = "tarfile"
3049 catfp.seek(0, 0)
3050 if(filetype == "gzip" or filetype == "bzip2" or filetype == "lzma" or filetype == "zstd" or filetype == "lz4" or filetype == "zlib"):
3051 if(TarFileCheck(catfp)):
3052 filetype = "tarfile"
3053 if(not filetype):
3054 if(TarFileCheck(catfp)):
3055 filetype = "tarfile"
3056 elif(zipfile.is_zipfile(catfp)):
3057 filetype = "zipfile"
3058 elif(rarfile_support and (rarfile.is_rarfile(catfp) or rarfile.is_rarfile_sfx(catfp))):
3059 filetype = "rarile"
3060 elif(py7zr_support and py7zr.is_7zfile(catfp)):
3061 return "7zipfile"
3062 else:
3063 filetype = False
3064 catfp.seek(0, 0)
3065 if(closefp):
3066 catfp.close()
3067 return filetype
3070 def CheckCompressionTypeFromString(instring, formatspecs=__file_format_dict__, closefp=True):
3071 formatspecs = FormatSpecsListToDict(formatspecs)
3072 try:
3073 instringsfile = BytesIO(instring)
3074 except TypeError:
3075 instringsfile = BytesIO(instring.encode("UTF-8"))
3076 return CheckCompressionType(instringsfile, formatspecs, closefp)
3079 def GetCompressionMimeType(infile, formatspecs=__file_format_dict__):
3080 formatspecs = FormatSpecsListToDict(formatspecs)
3081 compresscheck = CheckCompressionType(fp, formatspecs, False)
3082 if(compresscheck == "gzip" or compresscheck == "gz"):
3083 return archivefile_gzip_mimetype
3084 if(compresscheck == "zlib" or (compresscheck == "zz" or compresscheck == "zl" or compresscheck == "zlib")):
3085 return archivefile_zlib_mimetype
3086 if(compresscheck == "bzip2" or compresscheck == "bz2"):
3087 return archivefile_bzip2_mimetype
3088 if(compresscheck == "zstd" or compresscheck == "zstandard"):
3089 return archivefile_zstandard_mimetype
3090 if(compresscheck == "lz4"):
3091 return archivefile_lz4_mimetype
3092 if(compresscheck == "lzo" or compresscheck == "lzop"):
3093 return archivefile_lzop_mimetype
3094 if(compresscheck == "lzma"):
3095 return archivefile_lzma_mimetype
3096 if(compresscheck == "xz"):
3097 return archivefile_xz_mimetype
3098 if(compresscheck == "catfile" or compresscheck == "cat" or compresscheck == formatspecs['format_lower']):
3099 return archivefile_cat_mimetype
3100 if(not compresscheck):
3101 return False
3102 return False
3105 def UncompressArchiveFile(fp, formatspecs=__file_format_dict__):
3106 formatspecs = FormatSpecsListToDict(formatspecs)
3107 if(not hasattr(fp, "read") and not hasattr(fp, "write")):
3108 return False
3109 compresscheck = CheckCompressionType(fp, formatspecs, False)
3110 if(compresscheck == "gzip" and compresscheck in compressionsupport):
3111 catfp = gzip.GzipFile(fileobj=fp, mode="rb")
3112 elif(compresscheck == "bzip2" and compresscheck in compressionsupport):
3113 catfp = bz2.BZ2File(fp)
3114 elif(compresscheck == "zstd" and compresscheck in compressionsupport):
3115 catfp = zstd.ZstdDecompressor().stream_reader(fp)
3116 elif(compresscheck == "lz4" and compresscheck in compressionsupport):
3117 catfp = lz4.frame.open_fp(fp, mode='rb')
3118 elif((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
3119 catfp = BytesIO()
3120 catfp.write(lzo.decompress(fp.read()))
3121 elif((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
3122 catfp = lzma.LZMAFile(fp)
3123 elif(compresscheck == "zlib" and compresscheck in compressionsupport):
3124 catfp = ZlibFile(fileobj=fp, mode="rb")
3125 if(compresscheck == "catfile" or compresscheck == formatspecs['format_lower']):
3126 catfp = fp
3127 if(not compresscheck):
3128 try:
3129 import lzma
3130 except ImportError:
3131 try:
3132 from backports import lzma
3133 except ImportError:
3134 return False
3135 catfp = BytesIO()
3136 with fp as fpcontent:
3137 try:
3138 catfp.write(lzma.decompress(fp.read()))
3139 except lzma.LZMAError:
3140 return False
3141 if(compresscheck != "catfile" or compresscheck != formatspecs['format_lower']):
3142 fp.close()
3143 return catfp
3146 create_alias_function("Uncompress", __file_format_name__,
3147 "", UncompressArchiveFile)
3150 def UncompressFile(infile, formatspecs=__file_format_dict__, mode="rb"):
3151 formatspecs = FormatSpecsListToDict(formatspecs)
3152 compresscheck = CheckCompressionType(infile, formatspecs, False)
3153 if(sys.version_info[0] == 2 and compresscheck):
3154 if(mode == "rt"):
3155 mode = "r"
3156 if(mode == "wt"):
3157 mode = "w"
3158 try:
3159 if(compresscheck == "gzip" and compresscheck in compressionsupport):
3160 try:
3161 filefp = gzip.open(infile, mode, encoding="UTF-8")
3162 except (ValueError, TypeError) as e:
3163 filefp = gzip.open(infile, mode)
3164 if(compresscheck == "bzip2" and compresscheck in compressionsupport):
3165 try:
3166 filefp = bz2.open(infile, mode, encoding="UTF-8")
3167 except (ValueError, TypeError) as e:
3168 filefp = bz2.open(infile, mode)
3169 if(compresscheck == "zstd" and compresscheck in compressionsupport):
3170 try:
3171 filefp = zstandard.open(infile, mode, encoding="UTF-8")
3172 except (ValueError, TypeError) as e:
3173 filefp = zstandard.open(infile, mode)
3174 if(compresscheck == "lz4" and compresscheck in compressionsupport):
3175 try:
3176 filefp = lz4.frame.open(infile, mode, encoding="UTF-8")
3177 except (ValueError, TypeError) as e:
3178 filefp = lz4.frame.open(infile, mode)
3179 if((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
3180 try:
3181 filefp = lzo.open(infile, mode, encoding="UTF-8")
3182 except (ValueError, TypeError) as e:
3183 filefp = lzo.open(infile, mode)
3184 if((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
3185 try:
3186 filefp = lzma.open(infile, mode, encoding="UTF-8")
3187 except (ValueError, TypeError) as e:
3188 filefp = lzma.open(infile, mode)
3189 if(compresscheck == "zlib" and compresscheck in compressionsupport):
3190 filefp = ZlibFile(infile, mode=mode)
3191 if(compresscheck == "catfile" or compresscheck == formatspecs['format_lower']):
3192 try:
3193 filefp = open(infile, mode, encoding="UTF-8")
3194 except (ValueError, TypeError) as e:
3195 filefp = open(infile, mode)
3196 if(not compresscheck):
3197 try:
3198 filefp = open(infile, mode, encoding="UTF-8")
3199 except (ValueError, TypeError) as e:
3200 filefp = open(infile, mode)
3201 except FileNotFoundError:
3202 return False
3203 try:
3204 filefp.write_through = True
3205 except AttributeError:
3206 pass
3207 return filefp
3210 def UncompressString(infile):
3211 compresscheck = CheckCompressionTypeFromString(infile, formatspecs, False)
3212 if(compresscheck == "gzip" and compresscheck in compressionsupport):
3213 fileuz = GzipDecompressData(infile)
3214 if(compresscheck == "bzip2" and compresscheck in compressionsupport):
3215 fileuz = BzipDecompressData(infile)
3216 if(compresscheck == "zstd" and compresscheck in compressionsupport):
3217 try:
3218 import zstandard
3219 except ImportError:
3220 return False
3221 fileuz = zstandard.decompress(infile)
3222 if(compresscheck == "lz4" and compresscheck in compressionsupport):
3223 fileuz = lz4.frame.decompress(infile)
3224 if((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
3225 fileuz = lzo.decompress(infile)
3226 if((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
3227 fileuz = lzma.decompress(infile)
3228 if(compresscheck == "zlib" and compresscheck in compressionsupport):
3229 fileuz = zlib.decompress(infile)
3230 if(not compresscheck):
3231 fileuz = infile
3232 if(hasattr(fileuz, 'decode')):
3233 fileuz = fileuz.decode("UTF-8")
3234 return fileuz
3237 def UncompressStringAlt(infile):
3238 filefp = StringIO()
3239 outstring = UncompressString(infile)
3240 filefp.write(outstring)
3241 filefp.seek(0, 0)
3242 return filefp
3245 def CheckCompressionSubType(infile, formatspecs=__file_format_dict__, closefp=True):
3246 formatspecs = FormatSpecsListToDict(formatspecs)
3247 compresscheck = CheckCompressionType(infile, formatspecs, False)
3248 if(not compresscheck):
3249 fextname = os.path.splitext(infile)[1]
3250 if(fextname == ".gz"):
3251 compresscheck = "gzip"
3252 elif(fextname == ".bz2"):
3253 compresscheck = "bzip2"
3254 elif(fextname == ".zst"):
3255 compresscheck = "zstd"
3256 elif(fextname == ".lz4"):
3257 compresscheck = "lz4"
3258 elif(fextname == ".lzo" or fextname == ".lzop"):
3259 compresscheck = "lzo"
3260 elif(fextname == ".lzma"):
3261 compresscheck = "lzma"
3262 elif(fextname == ".xz"):
3263 compresscheck = "xz"
3264 elif(fextname == ".zz" or fextname == ".zl" or fextname == ".zlib"):
3265 compresscheck = "zlib"
3266 else:
3267 return False
3268 if(compresscheck == "gzip" or compresscheck == "bzip2" or compresscheck == "lzma" or compresscheck == "zstd" or compresscheck == "lz4" or compresscheck == "zlib"):
3269 if(TarFileCheck(infile)):
3270 filetype = "tarfile"
3271 if(not compresscheck):
3272 if(TarFileCheck(infile)):
3273 return "tarfile"
3274 elif(zipfile.is_zipfile(infile)):
3275 return "zipfile"
3276 elif(rarfile_support and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
3277 return "rarile"
3278 elif(py7zr_support and py7zr.is_7zfile(infile)):
3279 return "7zipfile"
3280 else:
3281 return False
3282 return False
3283 if(compresscheck == "catfile"):
3284 return "catfile"
3285 if(compresscheck == formatspecs['format_lower']):
3286 return formatspecs['format_lower']
3287 if(compresscheck == "tarfile"):
3288 return "tarfile"
3289 if(compresscheck == "zipfile"):
3290 return "zipfile"
3291 if(rarfile_support and compresscheck == "rarfile"):
3292 return "rarfile"
3293 if(py7zr_support and compresscheck == "7zipfile" and py7zr.is_7zfile(infile)):
3294 return "7zipfile"
3295 if(hasattr(infile, "read") or hasattr(infile, "write")):
3296 catfp = UncompressArchiveFile(infile, formatspecs['format_lower'])
3297 else:
3298 try:
3299 if(compresscheck == "gzip" and compresscheck in compressionsupport):
3300 catfp = gzip.GzipFile(infile, "rb")
3301 elif(compresscheck == "bzip2" and compresscheck in compressionsupport):
3302 catfp = bz2.BZ2File(infile, "rb")
3303 elif(compresscheck == "lz4" and compresscheck in compressionsupport):
3304 catfp = lz4.frame.open(infile, "rb")
3305 elif(compresscheck == "zstd" and compresscheck in compressionsupport):
3306 catfp = zstandard.open(infile, "rb")
3307 elif((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
3308 catfp = lzo.open(infile, "rb")
3309 elif((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
3310 catfp = lzma.open(infile, "rb")
3311 elif(compresscheck == "zlib" and compresscheck in compressionsupport):
3312 catfp = ZlibFile(infile, mode="rb")
3313 else:
3314 catfp = open(infile, "rb")
3315 except FileNotFoundError:
3316 return False
3317 filetype = False
3318 prefp = catfp.read(5)
3319 if(prefp == binascii.unhexlify("7573746172")):
3320 filetype = "tarfile"
3321 catfp.seek(0, 0)
3322 prefp = catfp.read(7)
3323 if(prefp == binascii.unhexlify("43617446696c65")):
3324 filetype = "catfile"
3325 catfp.seek(0, 0)
3326 prefp = catfp.read(formatspecs['format_len'])
3327 if(prefp == binascii.unhexlify(formatspecs['format_hex'])):
3328 filetype = formatspecs['format_lower']
3329 catfp.seek(0, 0)
3330 prefp = catfp.read(10)
3331 if(prefp == binascii.unhexlify("7061785f676c6f62616c")):
3332 filetype = "tarfile"
3333 catfp.seek(0, 0)
3334 if(closefp):
3335 catfp.close()
3336 return filetype
3339 def GZipCompress(data, compresslevel=9):
3340 if("gzip" not in compressionsupport):
3341 return False
3342 tmpfp = tempfile.NamedTemporaryFile("wb", delete=False)
3343 tmpfp.close()
3344 tmpfp = gzip.GzipFile(tmpfp.name, mode="wb", compresslevel=compresslevel)
3345 tmpfp.write(data)
3346 tmpfp.close()
3347 try:
3348 catfp = open(tmpfp.name, "rb")
3349 except FileNotFoundError:
3350 return False
3351 catdata = catfp.read()
3352 catfp.close()
3353 return catdata
3356 def CompressArchiveFile(fp, compression="auto", compressionlevel=None, formatspecs=__file_format_dict__):
3357 formatspecs = FormatSpecsListToDict(formatspecs)
3358 if(not hasattr(fp, "read") and not hasattr(fp, "write")):
3359 return False
3360 fp.seek(0, 0)
3361 if(not compression or compression == "catfile" or compression == formatspecs['format_lower']):
3362 compression = "auto"
3363 if(compression not in compressionlist and compression is None):
3364 compression = "auto"
3365 if(compression == "gzip" and compression in compressionsupport):
3366 catfp = BytesIO()
3367 if(compressionlevel is None):
3368 compressionlevel = 9
3369 else:
3370 compressionlevel = int(compressionlevel)
3371 catfp.write(GzipCompressData(
3372 fp.read(), compresslevel=compressionlevel))
3373 if(compression == "bzip2" and compression in compressionsupport):
3374 catfp = BytesIO()
3375 if(compressionlevel is None):
3376 compressionlevel = 9
3377 else:
3378 compressionlevel = int(compressionlevel)
3379 catfp.write(BzipCompressData(
3380 fp.read(), compresslevel=compressionlevel))
3381 if(compression == "lz4" and compression in compressionsupport):
3382 catfp = BytesIO()
3383 if(compressionlevel is None):
3384 compressionlevel = 9
3385 else:
3386 compressionlevel = int(compressionlevel)
3387 catfp.write(lz4.frame.compress(
3388 fp.read(), compression_level=compressionlevel))
3389 if((compression == "lzo" or compression == "lzop") and compression in compressionsupport):
3390 catfp = BytesIO()
3391 if(compressionlevel is None):
3392 compressionlevel = 9
3393 else:
3394 compressionlevel = int(compressionlevel)
3395 catfp.write(lzo.compress(fp.read(), compresslevel=compressionlevel))
3396 if(compression == "zstd" and compression in compressionsupport):
3397 catfp = BytesIO()
3398 if(compressionlevel is None):
3399 compressionlevel = 10
3400 else:
3401 compressionlevel = int(compressionlevel)
3402 catfp.write(zstandard.compress(fp.read(), level=compressionlevel))
3403 if(compression == "lzma" and compression in compressionsupport):
3404 catfp = BytesIO()
3405 if(compressionlevel is None):
3406 compressionlevel = 9
3407 else:
3408 compressionlevel = int(compressionlevel)
3409 catfp.write(lzma.compress(fp.read(), format=lzma.FORMAT_ALONE, filters=[
3410 {"id": lzma.FILTER_LZMA1, "preset": compressionlevel}]))
3411 if(compression == "xz" and compression in compressionsupport):
3412 catfp = BytesIO()
3413 if(compressionlevel is None):
3414 compressionlevel = 9
3415 else:
3416 compressionlevel = int(compressionlevel)
3417 catfp.write(lzma.compress(fp.read(), format=lzma.FORMAT_XZ, filters=[
3418 {"id": lzma.FILTER_LZMA2, "preset": compressionlevel}]))
3419 if(compression == "zlib" and compression in compressionsupport):
3420 catfp = BytesIO()
3421 if(compressionlevel is None):
3422 compressionlevel = 9
3423 else:
3424 compressionlevel = int(compressionlevel)
3425 catfp.write(zlib.compress(fp.read(), compressionlevel))
3426 if(compression == "auto" or compression is None):
3427 catfp = fp
3428 catfp.seek(0, 0)
3429 return catfp
3432 create_alias_function("Compress", __file_format_name__,
3433 "", CompressArchiveFile)
3436 def CompressOpenFile(outfile, compressionenable=True, compressionlevel=None):
3437 if(outfile is None):
3438 return False
3439 fbasename = os.path.splitext(outfile)[0]
3440 fextname = os.path.splitext(outfile)[1]
3441 if(compressionlevel is None and fextname != ".zst"):
3442 compressionlevel = 9
3443 elif(compressionlevel is None and fextname == ".zst"):
3444 compressionlevel = 10
3445 else:
3446 compressionlevel = int(compressionlevel)
3447 if(sys.version_info[0] == 2):
3448 mode = "w"
3449 else:
3450 mode = "wb"
3451 try:
3452 if(fextname not in outextlistwd or not compressionenable):
3453 try:
3454 outfp = open(outfile, "wb", encoding="UTF-8")
3455 except (ValueError, TypeError) as e:
3456 outfp = open(outfile, "wb")
3457 elif(fextname == ".gz" and "gzip" in compressionsupport):
3458 try:
3459 outfp = gzip.open(
3460 outfile, mode, compressionlevel, encoding="UTF-8")
3461 except (ValueError, TypeError) as e:
3462 outfp = gzip.open(outfile, mode, compressionlevel)
3463 elif(fextname == ".bz2" and "bzip2" in compressionsupport):
3464 try:
3465 outfp = bz2.open(
3466 outfile, mode, compressionlevel, encoding="UTF-8")
3467 except (ValueError, TypeError) as e:
3468 outfp = bz2.open(outfile, mode, compressionlevel)
3469 elif(fextname == ".zst" and "zstandard" in compressionsupport):
3470 try:
3471 outfp = zstandard.open(outfile, mode, zstandard.ZstdCompressor(
3472 level=compressionlevel), encoding="UTF-8")
3473 except (ValueError, TypeError) as e:
3474 outfp = zstandard.open(
3475 outfile, mode, zstandard.ZstdCompressor(level=compressionlevel))
3476 elif(fextname == ".xz" and "xz" in compressionsupport):
3477 try:
3478 outfp = lzma.open(outfile, mode, format=lzma.FORMAT_XZ, filters=[
3479 {"id": lzma.FILTER_LZMA2, "preset": compressionlevel}], encoding="UTF-8")
3480 except (ValueError, TypeError) as e:
3481 outfp = lzma.open(outfile, mode, format=lzma.FORMAT_XZ, filters=[
3482 {"id": lzma.FILTER_LZMA2, "preset": compressionlevel}])
3483 elif(fextname == ".lz4" and "lz4" in compressionsupport):
3484 try:
3485 outfp = lz4.frame.open(
3486 outfile, mode, compression_level=compressionlevel, encoding="UTF-8")
3487 except (ValueError, TypeError) as e:
3488 outfp = lz4.frame.open(
3489 outfile, mode, compression_level=compressionlevel)
3490 elif(fextname == ".lzo" and "lzop" in compressionsupport):
3491 try:
3492 outfp = lzo.open(
3493 outfile, mode, compresslevel=compressionlevel, encoding="UTF-8")
3494 except (ValueError, TypeError) as e:
3495 outfp = lzo.open(outfile, mode, compresslevel=compressionlevel)
3496 elif(fextname == ".lzma" and "lzma" in compressionsupport):
3497 try:
3498 outfp = lzma.open(outfile, mode, format=lzma.FORMAT_ALONE, filters=[
3499 {"id": lzma.FILTER_LZMA1, "preset": compressionlevel}], encoding="UTF-8")
3500 except (ValueError, TypeError) as e:
3501 outfp = lzma.open(outfile, mode, format=lzma.FORMAT_ALONE, filters=[
3502 {"id": lzma.FILTER_LZMA1, "preset": compressionlevel}])
3503 elif((fextname == ".zz" or fextname == ".zl" or fextname == ".zlib") and "zlib" in compressionsupport):
3504 outfp = ZlibFile(outfile, mode=mode, level=compressionlevel)
3505 except FileNotFoundError:
3506 return False
3507 try:
3508 outfp.write_through = True
3509 except AttributeError:
3510 pass
3511 return outfp
3514 def GetDevMajorMinor(fdev):
3515 retdev = []
3516 if(hasattr(os, "minor")):
3517 retdev.append(os.minor(fdev))
3518 else:
3519 retdev.append(0)
3520 if(hasattr(os, "major")):
3521 retdev.append(os.major(fdev))
3522 else:
3523 retdev.append(0)
3524 return retdev
3527 def CheckSumSupport(checkfor, guaranteed=True):
3528 if(guaranteed):
3529 try:
3530 hash_list = sorted(list(hashlib.algorithms_guaranteed))
3531 except AttributeError:
3532 hash_list = sorted(list(hashlib.algorithms))
3533 else:
3534 try:
3535 hash_list = sorted(list(hashlib.algorithms_available))
3536 except AttributeError:
3537 hash_list = sorted(list(hashlib.algorithms))
3538 checklistout = sorted(hash_list + ['adler32', 'crc16', 'crc16_ansi', 'crc16_ibm',
3539 'crc16_ccitt', 'crc32', 'crc64', 'crc64_ecma', 'crc64_iso', 'none'])
3540 if(checkfor in checklistout):
3541 return True
3542 else:
3543 return False
3546 def CheckSumSupportAlt(checkfor, guaranteed=True):
3547 if(guaranteed):
3548 try:
3549 hash_list = sorted(list(hashlib.algorithms_guaranteed))
3550 except AttributeError:
3551 hash_list = sorted(list(hashlib.algorithms))
3552 else:
3553 try:
3554 hash_list = sorted(list(hashlib.algorithms_available))
3555 except AttributeError:
3556 hash_list = sorted(list(hashlib.algorithms))
3557 checklistout = hash_list
3558 if(checkfor in checklistout):
3559 return True
3560 else:
3561 return False
3564 def PackArchiveFile(infiles, outfile, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
3565 formatspecs = FormatSpecsListToDict(formatspecs)
3566 advancedlist = formatspecs['use_advanced_list']
3567 altinode = formatspecs['use_alt_inode']
3568 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
3569 outfile = RemoveWindowsPath(outfile)
3570 checksumtype = checksumtype.lower()
3571 if(not CheckSumSupport(checksumtype, hashlib_guaranteed)):
3572 checksumtype = "crc32"
3573 if(checksumtype == "none"):
3574 checksumtype = ""
3575 if(not compression or compression == "catfile" or compression == formatspecs['format_lower']):
3576 compression = "auto"
3577 if(compression not in compressionlist and compression is None):
3578 compression = "auto"
3579 if(verbose):
3580 logging.basicConfig(format="%(message)s",
3581 stream=sys.stdout, level=logging.DEBUG)
3582 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
3583 if(os.path.exists(outfile)):
3584 try:
3585 os.unlink(outfile)
3586 except OSError as e:
3587 pass
3588 if(outfile == "-"):
3589 verbose = False
3590 catfp = BytesIO()
3591 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
3592 catfp = outfile
3593 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
3594 catfp = BytesIO()
3595 else:
3596 fbasename = os.path.splitext(outfile)[0]
3597 fextname = os.path.splitext(outfile)[1]
3598 if(not compresswholefile and fextname in outextlistwd):
3599 compresswholefile = True
3600 catfp = CompressOpenFile(outfile, compresswholefile, compressionlevel)
3601 catver = formatspecs['format_ver']
3602 fileheaderver = str(int(catver.replace(".", "")))
3603 infilelist = []
3604 if(infiles == "-"):
3605 for line in sys.stdin:
3606 infilelist.append(line.strip())
3607 infilelist = list(filter(None, infilelist))
3608 elif(infiles != "-" and dirlistfromtxt and os.path.exists(infiles) and (os.path.isfile(infiles) or infiles == "/dev/null" or infiles == "NUL")):
3609 if(not os.path.exists(infiles) or not os.path.isfile(infiles)):
3610 return False
3611 with UncompressFile(infiles, formatspecs, "r") as finfile:
3612 for line in finfile:
3613 infilelist.append(line.strip())
3614 infilelist = list(filter(None, infilelist))
3615 else:
3616 if(isinstance(infiles, (list, tuple, ))):
3617 infilelist = list(filter(None, infiles))
3618 elif(isinstance(infiles, (str, ))):
3619 infilelist = list(filter(None, [infiles]))
3620 if(advancedlist):
3621 GetDirList = ListDirAdvanced(infilelist, followlink, False)
3622 else:
3623 GetDirList = ListDir(infilelist, followlink, False)
3624 if(not GetDirList):
3625 return False
3626 curinode = 0
3627 curfid = 0
3628 inodelist = []
3629 inodetofile = {}
3630 filetoinode = {}
3631 inodetocatinode = {}
3632 numfiles = int(len(GetDirList))
3633 catfp = AppendFileHeader(catfp, numfiles, checksumtype, formatspecs)
3634 for curfname in GetDirList:
3635 if(re.findall("^[.|/]", curfname)):
3636 fname = curfname
3637 else:
3638 fname = "./"+curfname
3639 if(verbose):
3640 VerbosePrintOut(fname)
3641 if(not followlink or followlink is None):
3642 fstatinfo = os.lstat(fname)
3643 else:
3644 fstatinfo = os.stat(fname)
3645 fpremode = fstatinfo.st_mode
3646 finode = fstatinfo.st_ino
3647 flinkcount = fstatinfo.st_nlink
3648 ftype = 0
3649 if(stat.S_ISREG(fpremode)):
3650 ftype = 0
3651 elif(stat.S_ISLNK(fpremode)):
3652 ftype = 2
3653 elif(stat.S_ISCHR(fpremode)):
3654 ftype = 3
3655 elif(stat.S_ISBLK(fpremode)):
3656 ftype = 4
3657 elif(stat.S_ISDIR(fpremode)):
3658 ftype = 5
3659 elif(stat.S_ISFIFO(fpremode)):
3660 ftype = 6
3661 elif(stat.S_ISSOCK(fpremode)):
3662 ftype = 8
3663 elif(hasattr(stat, "S_ISDOOR") and stat.S_ISDOOR(fpremode)):
3664 ftype = 9
3665 elif(hasattr(stat, "S_ISPORT") and stat.S_ISPORT(fpremode)):
3666 ftype = 10
3667 elif(hasattr(stat, "S_ISWHT") and stat.S_ISWHT(fpremode)):
3668 ftype = 11
3669 else:
3670 ftype = 0
3671 flinkname = ""
3672 fcurfid = format(int(curfid), 'x').lower()
3673 if(not followlink and finode != 0):
3674 if(ftype != 1):
3675 if(finode in inodelist):
3676 ftype = 1
3677 flinkname = inodetofile[finode]
3678 if(altinode):
3679 fcurinode = format(int(finode), 'x').lower()
3680 else:
3681 fcurinode = format(
3682 int(inodetocatinode[finode]), 'x').lower()
3683 if(finode not in inodelist):
3684 inodelist.append(finode)
3685 inodetofile.update({finode: fname})
3686 inodetocatinode.update({finode: curinode})
3687 if(altinode):
3688 fcurinode = format(int(finode), 'x').lower()
3689 else:
3690 fcurinode = format(int(curinode), 'x').lower()
3691 curinode = curinode + 1
3692 else:
3693 fcurinode = format(int(curinode), 'x').lower()
3694 curinode = curinode + 1
3695 curfid = curfid + 1
3696 if(ftype == 2):
3697 flinkname = os.readlink(fname)
3698 fdev = fstatinfo.st_dev
3699 getfdev = GetDevMajorMinor(fdev)
3700 fdev_minor = getfdev[0]
3701 fdev_major = getfdev[1]
3702 frdev = fstatinfo.st_dev
3703 if(hasattr(fstatinfo, "st_rdev")):
3704 frdev = fstatinfo.st_rdev
3705 else:
3706 frdev = fstatinfo.st_dev
3707 getfrdev = GetDevMajorMinor(frdev)
3708 frdev_minor = getfrdev[0]
3709 frdev_major = getfrdev[1]
3710 if(ftype == 1 or ftype == 2 or ftype == 3 or ftype == 4 or ftype == 5 or ftype == 6):
3711 fsize = format(int("0"), 'x').lower()
3712 elif(ftype == 0 or ftype == 7):
3713 fsize = format(int(fstatinfo.st_size), 'x').lower()
3714 else:
3715 fsize = format(int(fstatinfo.st_size)).lower()
3716 fatime = format(int(fstatinfo.st_atime), 'x').lower()
3717 fmtime = format(int(fstatinfo.st_mtime), 'x').lower()
3718 fctime = format(int(fstatinfo.st_ctime), 'x').lower()
3719 if(hasattr(fstatinfo, "st_birthtime")):
3720 fbtime = format(int(fstatinfo.st_birthtime), 'x').lower()
3721 else:
3722 fbtime = format(int(fstatinfo.st_ctime), 'x').lower()
3723 fmode = format(int(fstatinfo.st_mode), 'x').lower()
3724 fchmode = format(int(stat.S_IMODE(fstatinfo.st_mode)), 'x').lower()
3725 ftypemod = format(int(stat.S_IFMT(fstatinfo.st_mode)), 'x').lower()
3726 fuid = format(int(fstatinfo.st_uid), 'x').lower()
3727 fgid = format(int(fstatinfo.st_gid), 'x').lower()
3728 funame = ""
3729 try:
3730 import pwd
3731 try:
3732 userinfo = pwd.getpwuid(fstatinfo.st_uid)
3733 funame = userinfo.pw_name
3734 except KeyError:
3735 funame = ""
3736 except ImportError:
3737 funame = ""
3738 fgname = ""
3739 try:
3740 import grp
3741 try:
3742 groupinfo = grp.getgrgid(fstatinfo.st_gid)
3743 fgname = groupinfo.gr_name
3744 except KeyError:
3745 fgname = ""
3746 except ImportError:
3747 fgname = ""
3748 fdev_minor = format(int(fdev_minor), 'x').lower()
3749 fdev_major = format(int(fdev_major), 'x').lower()
3750 frdev_minor = format(int(frdev_minor), 'x').lower()
3751 frdev_major = format(int(frdev_major), 'x').lower()
3752 finode = format(int(finode), 'x').lower()
3753 flinkcount = format(int(flinkcount), 'x').lower()
3754 if(hasattr(fstatinfo, "st_file_attributes")):
3755 fwinattributes = format(
3756 int(fstatinfo.st_file_attributes), 'x').lower()
3757 else:
3758 fwinattributes = format(int(0), 'x').lower()
3759 fcompression = ""
3760 fcsize = format(int(0), 'x').lower()
3761 fcontents = BytesIO()
3762 if(ftype == 0 or ftype == 7):
3763 with open(fname, "rb") as fpc:
3764 shutil.copyfileobj(fpc, fcontents)
3765 if(not compresswholefile):
3766 fcontents.seek(0, 2)
3767 ucfsize = fcontents.tell()
3768 fcontents.seek(0, 0)
3769 if(compression == "auto"):
3770 ilsize = len(compressionlistalt)
3771 ilmin = 0
3772 ilcsize = []
3773 while(ilmin < ilsize):
3774 cfcontents = BytesIO()
3775 shutil.copyfileobj(fcontents, cfcontents)
3776 fcontents.seek(0, 0)
3777 cfcontents.seek(0, 0)
3778 cfcontents = CompressArchiveFile(
3779 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
3780 if(cfcontents):
3781 cfcontents.seek(0, 2)
3782 ilcsize.append(cfcontents.tell())
3783 cfcontents.close()
3784 else:
3785 try:
3786 ilcsize.append(sys.maxint)
3787 except AttributeError:
3788 ilcsize.append(sys.maxsize)
3789 ilmin = ilmin + 1
3790 ilcmin = ilcsize.index(min(ilcsize))
3791 compression = compressionlistalt[ilcmin]
3792 fcontents.seek(0, 0)
3793 cfcontents = BytesIO()
3794 shutil.copyfileobj(fcontents, cfcontents)
3795 cfcontents.seek(0, 0)
3796 cfcontents = CompressArchiveFile(
3797 cfcontents, compression, compressionlevel, formatspecs)
3798 cfcontents.seek(0, 2)
3799 cfsize = cfcontents.tell()
3800 if(ucfsize > cfsize):
3801 fcsize = format(int(cfsize), 'x').lower()
3802 fcompression = compression
3803 fcontents.close()
3804 fcontents = cfcontents
3805 if(fcompression == "none"):
3806 fcompression = ""
3807 if(followlink and (ftype == 1 or ftype == 2)):
3808 flstatinfo = os.stat(flinkname)
3809 with open(flinkname, "rb") as fpc:
3810 shutil.copyfileobj(fpc, fcontents)
3811 if(not compresswholefile):
3812 fcontents.seek(0, 2)
3813 ucfsize = fcontents.tell()
3814 fcontents.seek(0, 0)
3815 if(compression == "auto"):
3816 ilsize = len(compressionlistalt)
3817 ilmin = 0
3818 ilcsize = []
3819 while(ilmin < ilsize):
3820 cfcontents = BytesIO()
3821 shutil.copyfileobj(fcontents, cfcontents)
3822 fcontents.seek(0, 0)
3823 cfcontents.seek(0, 0)
3824 cfcontents = CompressArchiveFile(
3825 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
3826 if(cfcontents):
3827 cfcontents.seek(0, 2)
3828 ilcsize.append(cfcontents.tell())
3829 cfcontents.close()
3830 else:
3831 try:
3832 ilcsize.append(sys.maxint)
3833 except AttributeError:
3834 ilcsize.append(sys.maxsize)
3835 ilmin = ilmin + 1
3836 ilcmin = ilcsize.index(min(ilcsize))
3837 compression = compressionlistalt[ilcmin]
3838 fcontents.seek(0, 0)
3839 cfcontents = BytesIO()
3840 shutil.copyfileobj(fcontents, cfcontents)
3841 cfcontents.seek(0, 0)
3842 cfcontents = CompressArchiveFile(
3843 cfcontents, compression, compressionlevel, formatspecs)
3844 cfcontents.seek(0, 2)
3845 cfsize = cfcontents.tell()
3846 if(ucfsize > cfsize):
3847 fcsize = format(int(cfsize), 'x').lower()
3848 fcompression = compression
3849 fcontents.close()
3850 fcontents = cfcontents
3851 fcontents.seek(0, 0)
3852 ftypehex = format(ftype, 'x').lower()
3853 catoutlist = [ftypehex, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression,
3854 fcsize, fuid, funame, fgid, fgname, fcurfid, fcurinode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, "+1"]
3855 catfp = AppendFileHeaderWithContent(
3856 catfp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
3857 fcontents.close()
3858 if(numfiles > 0):
3859 catfp.write(AppendNullBytes(
3860 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
3861 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
3862 catfp = CompressArchiveFile(
3863 catfp, compression, compressionlevel, formatspecs)
3864 try:
3865 catfp.flush()
3866 os.fsync(catfp.fileno())
3867 except io.UnsupportedOperation:
3868 pass
3869 except AttributeError:
3870 pass
3871 except OSError as e:
3872 pass
3873 if(outfile == "-"):
3874 catfp.seek(0, 0)
3875 if(hasattr(sys.stdout, "buffer")):
3876 shutil.copyfileobj(catfp, sys.stdout.buffer)
3877 else:
3878 shutil.copyfileobj(catfp, sys.stdout)
3879 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
3880 catfp = CompressArchiveFile(
3881 catfp, compression, compressionlevel, formatspecs)
3882 catfp.seek(0, 0)
3883 upload_file_to_internet_file(catfp, outfile)
3884 if(returnfp):
3885 catfp.seek(0, 0)
3886 return catfp
3887 else:
3888 catfp.close()
3889 return True
3892 create_alias_function("Pack", __file_format_name__, "", PackArchiveFile)
3894 if(hasattr(shutil, "register_archive_format")):
3895 def PackArchiveFileFunc(archive_name, source_dir, **kwargs):
3896 return PackArchiveFile(source_dir, archive_name, False, "auto", True, None, False, "crc32", [], __file_format_dict__['format_delimiter'], False, False)
3897 create_alias_function("Pack", __file_format_name__,
3898 "Func", PackArchiveFileFunc)
3901 def PackArchiveFileFromDirList(infiles, outfile, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
3902 formatspecs = FormatSpecsListToDict(formatspecs)
3903 return PackArchiveFile(infiles, outfile, dirlistfromtxt, compression, compresswholefile, compressionlevel, followlink, checksumtype, extradata, formatspecs, verbose, returnfp)
3906 create_alias_function("Pack", __file_format_name__,
3907 "FromDirList", PackArchiveFileFromDirList)
3910 def PackArchiveFileFromTarFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
3911 formatspecs = FormatSpecsListToDict(formatspecs)
3912 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
3913 outfile = RemoveWindowsPath(outfile)
3914 checksumtype = checksumtype.lower()
3915 if(not CheckSumSupport(checksumtype, hashlib_guaranteed)):
3916 checksumtype = "crc32"
3917 if(checksumtype == "none"):
3918 checksumtype = ""
3919 if(not compression or compression == "catfile" or compression == formatspecs['format_lower']):
3920 compression = "auto"
3921 if(compression not in compressionlist and compression is None):
3922 compression = "auto"
3923 if(verbose):
3924 logging.basicConfig(format="%(message)s",
3925 stream=sys.stdout, level=logging.DEBUG)
3926 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
3927 if(os.path.exists(outfile)):
3928 try:
3929 os.unlink(outfile)
3930 except OSError as e:
3931 pass
3932 if(outfile == "-"):
3933 verbose = False
3934 catfp = BytesIO()
3935 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
3936 catfp = outfile
3937 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
3938 catfp = BytesIO()
3939 else:
3940 fbasename = os.path.splitext(outfile)[0]
3941 fextname = os.path.splitext(outfile)[1]
3942 if(not compresswholefile and fextname in outextlistwd):
3943 compresswholefile = True
3944 catfp = CompressOpenFile(outfile, compresswholefile, compressionlevel)
3945 catver = formatspecs['format_ver']
3946 fileheaderver = str(int(catver.replace(".", "")))
3947 curinode = 0
3948 curfid = 0
3949 inodelist = []
3950 inodetofile = {}
3951 filetoinode = {}
3952 inodetocatinode = {}
3953 if(infile == "-"):
3954 infile = BytesIO()
3955 if(hasattr(sys.stdin, "buffer")):
3956 shutil.copyfileobj(sys.stdin.buffer, infile)
3957 else:
3958 shutil.copyfileobj(sys.stdin, infile)
3959 infile.seek(0, 0)
3960 if(not infile):
3961 return False
3962 infile.seek(0, 0)
3963 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
3964 infile = download_file_from_internet_file(infile)
3965 infile.seek(0, 0)
3966 if(not infile):
3967 return False
3968 infile.seek(0, 0)
3969 elif(not os.path.exists(infile) or not os.path.isfile(infile)):
3970 return False
3971 elif(os.path.exists(infile) and os.path.isfile(infile)):
3972 try:
3973 if(not tarfile.TarFileCheck(infile)):
3974 return False
3975 except AttributeError:
3976 if(not TarFileCheck(infile)):
3977 return False
3978 try:
3979 if(hasattr(infile, "read") or hasattr(infile, "write")):
3980 tarfp = tarfile.open(fileobj=infile, mode="r")
3981 else:
3982 tarfp = tarfile.open(infile, "r")
3983 except FileNotFoundError:
3984 return False
3985 numfiles = int(len(tarfp.getmembers()))
3986 catfp = AppendFileHeader(catfp, numfiles, checksumtype, formatspecs)
3987 for member in sorted(tarfp.getmembers(), key=lambda x: x.name):
3988 if(re.findall("^[.|/]", member.name)):
3989 fname = member.name
3990 else:
3991 fname = "./"+member.name
3992 if(verbose):
3993 VerbosePrintOut(fname)
3994 fpremode = member.mode
3995 ffullmode = member.mode
3996 flinkcount = 0
3997 ftype = 0
3998 if(member.isreg()):
3999 ffullmode = member.mode + stat.S_IFREG
4000 ftype = 0
4001 elif(member.isdev()):
4002 ffullmode = member.mode
4003 ftype = 7
4004 elif(member.islnk()):
4005 ffullmode = member.mode + stat.S_IFREG
4006 ftype = 1
4007 elif(member.issym()):
4008 ffullmode = member.mode + stat.S_IFLNK
4009 ftype = 2
4010 elif(member.ischr()):
4011 ffullmode = member.mode + stat.S_IFCHR
4012 ftype = 3
4013 elif(member.isblk()):
4014 ffullmode = member.mode + stat.S_IFBLK
4015 ftype = 4
4016 elif(member.isdir()):
4017 ffullmode = member.mode + stat.S_IFDIR
4018 ftype = 5
4019 elif(member.isfifo()):
4020 ffullmode = member.mode + stat.S_IFIFO
4021 ftype = 6
4022 elif(member.issparse()):
4023 ffullmode = member.mode
4024 ftype = 12
4025 else:
4026 ffullmode = member.mode
4027 ftype = 0
4028 flinkname = ""
4029 fcurfid = format(int(curfid), 'x').lower()
4030 fcurinode = format(int(curfid), 'x').lower()
4031 curfid = curfid + 1
4032 if(ftype == 2):
4033 flinkname = member.linkname
4034 fdev_minor = format(int(member.devminor), 'x').lower()
4035 fdev_major = format(int(member.devmajor), 'x').lower()
4036 frdev_minor = format(int(member.devminor), 'x').lower()
4037 frdev_major = format(int(member.devmajor), 'x').lower()
4038 if(ftype == 1 or ftype == 2 or ftype == 3 or ftype == 4 or ftype == 5 or ftype == 6):
4039 fsize = format(int("0"), 'x').lower()
4040 elif(ftype == 0 or ftype == 7):
4041 fsize = format(int(member.size), 'x').lower()
4042 else:
4043 fsize = format(int(member.size), 'x').lower()
4044 fatime = format(int(member.mtime), 'x').lower()
4045 fmtime = format(int(member.mtime), 'x').lower()
4046 fctime = format(int(member.mtime), 'x').lower()
4047 fbtime = format(int(member.mtime), 'x').lower()
4048 fmode = format(int(ffullmode), 'x').lower()
4049 fchmode = format(int(stat.S_IMODE(ffullmode)), 'x').lower()
4050 ftypemod = format(int(stat.S_IFMT(ffullmode)), 'x').lower()
4051 fuid = format(int(member.uid), 'x').lower()
4052 fgid = format(int(member.gid), 'x').lower()
4053 funame = member.uname
4054 fgname = member.gname
4055 flinkcount = format(int(flinkcount), 'x').lower()
4056 fwinattributes = format(int(0), 'x').lower()
4057 fcompression = ""
4058 fcsize = format(int(0), 'x').lower()
4059 fcontents = BytesIO()
4060 if(ftype == 0 or ftype == 7):
4061 with tarfp.extractfile(member) as fpc:
4062 shutil.copyfileobj(fpc, fcontents)
4063 if(not compresswholefile):
4064 fcontents.seek(0, 2)
4065 ucfsize = fcontents.tell()
4066 fcontents.seek(0, 0)
4067 if(compression == "auto"):
4068 ilsize = len(compressionlistalt)
4069 ilmin = 0
4070 ilcsize = []
4071 while(ilmin < ilsize):
4072 cfcontents = BytesIO()
4073 shutil.copyfileobj(fcontents, cfcontents)
4074 fcontents.seek(0, 0)
4075 cfcontents.seek(0, 0)
4076 cfcontents = CompressArchiveFile(
4077 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
4078 if(cfcontents):
4079 cfcontents.seek(0, 2)
4080 ilcsize.append(cfcontents.tell())
4081 cfcontents.close()
4082 else:
4083 try:
4084 ilcsize.append(sys.maxint)
4085 except AttributeError:
4086 ilcsize.append(sys.maxsize)
4087 ilmin = ilmin + 1
4088 ilcmin = ilcsize.index(min(ilcsize))
4089 compression = compressionlistalt[ilcmin]
4090 fcontents.seek(0, 0)
4091 cfcontents = BytesIO()
4092 shutil.copyfileobj(fcontents, cfcontents)
4093 cfcontents.seek(0, 0)
4094 cfcontents = CompressArchiveFile(
4095 cfcontents, compression, compressionlevel, formatspecs)
4096 cfcontents.seek(0, 2)
4097 cfsize = cfcontents.tell()
4098 if(ucfsize > cfsize):
4099 fcsize = format(int(cfsize), 'x').lower()
4100 fcompression = compression
4101 fcontents.close()
4102 fcontents = cfcontents
4103 if(fcompression == "none"):
4104 fcompression = ""
4105 fcontents.seek(0, 0)
4106 ftypehex = format(ftype, 'x').lower()
4107 catoutlist = [ftypehex, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression,
4108 fcsize, fuid, funame, fgid, fgname, fcurfid, fcurinode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, "+1"]
4109 catfp = AppendFileHeaderWithContent(
4110 catfp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
4111 fcontents.close()
4112 if(numfiles > 0):
4113 catfp.write(AppendNullBytes(
4114 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
4115 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
4116 catfp = CompressArchiveFile(
4117 catfp, compression, compressionlevel, formatspecs)
4118 try:
4119 catfp.flush()
4120 os.fsync(catfp.fileno())
4121 except io.UnsupportedOperation:
4122 pass
4123 except AttributeError:
4124 pass
4125 except OSError as e:
4126 pass
4127 if(outfile == "-"):
4128 catfp.seek(0, 0)
4129 if(hasattr(sys.stdout, "buffer")):
4130 shutil.copyfileobj(catfp, sys.stdout.buffer)
4131 else:
4132 shutil.copyfileobj(catfp, sys.stdout)
4133 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
4134 catfp = CompressArchiveFile(
4135 catfp, compression, compressionlevel, formatspecs)
4136 catfp.seek(0, 0)
4137 upload_file_to_internet_file(catfp, outfile)
4138 if(returnfp):
4139 catfp.seek(0, 0)
4140 return catfp
4141 else:
4142 catfp.close()
4143 return True
4146 create_alias_function("Pack", __file_format_name__,
4147 "FromTarFile", PackArchiveFileFromTarFile)
4150 def PackArchiveFileFromZipFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
4151 formatspecs = FormatSpecsListToDict(formatspecs)
4152 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
4153 outfile = RemoveWindowsPath(outfile)
4154 checksumtype = checksumtype.lower()
4155 if(not CheckSumSupport(checksumtype, hashlib_guaranteed)):
4156 checksumtype = "crc32"
4157 if(checksumtype == "none"):
4158 checksumtype = ""
4159 if(not compression or compression == "catfile" or compression == formatspecs['format_lower']):
4160 compression = "auto"
4161 if(compression not in compressionlist and compression is None):
4162 compression = "auto"
4163 if(verbose):
4164 logging.basicConfig(format="%(message)s",
4165 stream=sys.stdout, level=logging.DEBUG)
4166 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
4167 if(os.path.exists(outfile)):
4168 try:
4169 os.unlink(outfile)
4170 except OSError as e:
4171 pass
4172 if(outfile == "-"):
4173 verbose = False
4174 catfp = BytesIO()
4175 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
4176 catfp = outfile
4177 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
4178 catfp = BytesIO()
4179 else:
4180 fbasename = os.path.splitext(outfile)[0]
4181 fextname = os.path.splitext(outfile)[1]
4182 if(not compresswholefile and fextname in outextlistwd):
4183 compresswholefile = True
4184 catfp = CompressOpenFile(outfile, compresswholefile, compressionlevel)
4185 catver = formatspecs['format_ver']
4186 fileheaderver = str(int(catver.replace(".", "")))
4187 curinode = 0
4188 curfid = 0
4189 inodelist = []
4190 inodetofile = {}
4191 filetoinode = {}
4192 inodetocatinode = {}
4193 if(infile == "-"):
4194 infile = BytesIO()
4195 if(hasattr(sys.stdin, "buffer")):
4196 shutil.copyfileobj(sys.stdin.buffer, infile)
4197 else:
4198 shutil.copyfileobj(sys.stdin, infile)
4199 infile.seek(0, 0)
4200 if(not infile):
4201 return False
4202 infile.seek(0, 0)
4203 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
4204 infile = download_file_from_internet_file(infile)
4205 infile.seek(0, 0)
4206 if(not infile):
4207 return False
4208 infile.seek(0, 0)
4209 elif(not os.path.exists(infile) or not os.path.isfile(infile)):
4210 return False
4211 if(not zipfile.is_zipfile(infile)):
4212 return False
4213 try:
4214 zipfp = zipfile.ZipFile(infile, "r", allowZip64=True)
4215 except FileNotFoundError:
4216 return False
4217 ziptest = zipfp.testzip()
4218 if(ziptest):
4219 VerbosePrintOut("Bad file found!")
4220 numfiles = int(len(zipfp.infolist()))
4221 catfp = AppendFileHeader(catfp, numfiles, checksumtype, formatspecs)
4222 for member in sorted(zipfp.infolist(), key=lambda x: x.filename):
4223 if(re.findall("^[.|/]", member.filename)):
4224 fname = member.filename
4225 else:
4226 fname = "./"+member.filename
4227 zipinfo = zipfp.getinfo(member.filename)
4228 if(verbose):
4229 VerbosePrintOut(fname)
4230 if(not member.is_dir()):
4231 fpremode = int(stat.S_IFREG + 438)
4232 elif(member.is_dir()):
4233 fpremode = int(stat.S_IFDIR + 511)
4234 flinkcount = 0
4235 ftype = 0
4236 if(not member.is_dir()):
4237 ftype = 0
4238 elif(member.is_dir()):
4239 ftype = 5
4240 flinkname = ""
4241 fcurfid = format(int(curfid), 'x').lower()
4242 fcurinode = format(int(curfid), 'x').lower()
4243 curfid = curfid + 1
4244 fdev_minor = format(int(0), 'x').lower()
4245 fdev_major = format(int(0), 'x').lower()
4246 frdev_minor = format(int(0), 'x').lower()
4247 frdev_major = format(int(0), 'x').lower()
4248 if(ftype == 5):
4249 fsize = format(int("0"), 'x').lower()
4250 elif(ftype == 0):
4251 fsize = format(int(member.file_size), 'x').lower()
4252 else:
4253 fsize = format(int(member.file_size), 'x').lower()
4254 fatime = format(
4255 int(time.mktime(member.date_time + (0, 0, -1))), 'x').lower()
4256 fmtime = format(
4257 int(time.mktime(member.date_time + (0, 0, -1))), 'x').lower()
4258 fctime = format(
4259 int(time.mktime(member.date_time + (0, 0, -1))), 'x').lower()
4260 fbtime = format(
4261 int(time.mktime(member.date_time + (0, 0, -1))), 'x').lower()
4262 if(zipinfo.create_system == 0 or zipinfo.create_system == 10):
4263 fwinattributes = format(int(zipinfo.external_attr), 'x').lower()
4264 if(not member.is_dir()):
4265 fmode = format(int(stat.S_IFREG + 438), 'x').lower()
4266 fchmode = stat.S_IMODE(int(stat.S_IFREG + 438))
4267 ftypemod = stat.S_IFMT(int(stat.S_IFREG + 438))
4268 elif(member.is_dir()):
4269 fmode = format(int(stat.S_IFDIR + 511), 'x').lower()
4270 fchmode = stat.S_IMODE(int(stat.S_IFDIR + 511))
4271 ftypemod = stat.S_IFMT(int(stat.S_IFDIR + 511))
4272 elif(zipinfo.create_system == 3):
4273 fwinattributes = format(int(0), 'x').lower()
4274 try:
4275 fmode = format(int(zipinfo.external_attr), 'x').lower()
4276 prefmode = int(zipinfo.external_attr)
4277 fchmode = stat.S_IMODE(prefmode)
4278 ftypemod = stat.S_IFMT(prefmode)
4279 except OverflowError:
4280 fmode = format(int(zipinfo.external_attr >> 16), 'x').lower()
4281 prefmode = int(zipinfo.external_attr >> 16)
4282 fchmode = stat.S_IMODE(prefmode)
4283 ftypemod = stat.S_IFMT(prefmode)
4284 else:
4285 fwinattributes = format(int(0), 'x').lower()
4286 if(not member.is_dir()):
4287 fmode = format(int(stat.S_IFREG + 438), 'x').lower()
4288 prefmode = int(stat.S_IFREG + 438)
4289 fchmode = stat.S_IMODE(prefmode)
4290 ftypemod = stat.S_IFMT(prefmode)
4291 elif(member.is_dir()):
4292 fmode = format(int(stat.S_IFDIR + 511), 'x').lower()
4293 prefmode = int(stat.S_IFDIR + 511)
4294 fchmode = stat.S_IMODE(prefmode)
4295 ftypemod = stat.S_IFMT(prefmode)
4296 fcompression = ""
4297 fcsize = format(int(0), 'x').lower()
4298 try:
4299 fuid = format(int(os.getuid()), 'x').lower()
4300 except AttributeError:
4301 fuid = format(int(0), 'x').lower()
4302 except KeyError:
4303 fuid = format(int(0), 'x').lower()
4304 try:
4305 fgid = format(int(os.getgid()), 'x').lower()
4306 except AttributeError:
4307 fgid = format(int(0), 'x').lower()
4308 except KeyError:
4309 fgid = format(int(0), 'x').lower()
4310 try:
4311 import pwd
4312 try:
4313 userinfo = pwd.getpwuid(os.getuid())
4314 funame = userinfo.pw_name
4315 except KeyError:
4316 funame = ""
4317 except AttributeError:
4318 funame = ""
4319 except ImportError:
4320 funame = ""
4321 fgname = ""
4322 try:
4323 import grp
4324 try:
4325 groupinfo = grp.getgrgid(os.getgid())
4326 fgname = groupinfo.gr_name
4327 except KeyError:
4328 fgname = ""
4329 except AttributeError:
4330 fgname = ""
4331 except ImportError:
4332 fgname = ""
4333 fcontents = BytesIO()
4334 if(ftype == 0):
4335 fcontents.write(zipfp.read(member.filename))
4336 if(not compresswholefile):
4337 fcontents.seek(0, 2)
4338 ucfsize = fcontents.tell()
4339 fcontents.seek(0, 0)
4340 if(compression == "auto"):
4341 ilsize = len(compressionlistalt)
4342 ilmin = 0
4343 ilcsize = []
4344 while(ilmin < ilsize):
4345 cfcontents = BytesIO()
4346 shutil.copyfileobj(fcontents, cfcontents)
4347 fcontents.seek(0, 0)
4348 cfcontents.seek(0, 0)
4349 cfcontents = CompressArchiveFile(
4350 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
4351 cfcontents.seek(0, 2)
4352 ilcsize.append(cfcontents.tell())
4353 cfcontents.close()
4354 ilmin = ilmin + 1
4355 ilcmin = ilcsize.index(min(ilcsize))
4356 compression = compressionlistalt[ilcmin]
4357 fcontents.seek(0, 0)
4358 cfcontents = BytesIO()
4359 shutil.copyfileobj(fcontents, cfcontents)
4360 cfcontents.seek(0, 0)
4361 cfcontents = CompressArchiveFile(
4362 cfcontents, compression, compressionlevel, formatspecs)
4363 cfcontents.seek(0, 2)
4364 cfsize = cfcontents.tell()
4365 if(ucfsize > cfsize):
4366 fcsize = format(int(cfsize), 'x').lower()
4367 fcompression = compression
4368 fcontents.close()
4369 fcontents = cfcontents
4370 if(fcompression == "none"):
4371 fcompression = ""
4372 fcontents.seek(0, 0)
4373 ftypehex = format(ftype, 'x').lower()
4374 catoutlist = [ftypehex, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression,
4375 fcsize, fuid, funame, fgid, fgname, fcurfid, fcurinode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, "+1"]
4376 catfp = AppendFileHeaderWithContent(
4377 catfp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
4378 fcontents.close()
4379 if(numfiles > 0):
4380 catfp.write(AppendNullBytes(
4381 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
4382 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
4383 catfp = CompressArchiveFile(
4384 catfp, compression, compressionlevel, formatspecs)
4385 try:
4386 catfp.flush()
4387 os.fsync(catfp.fileno())
4388 except io.UnsupportedOperation:
4389 pass
4390 except AttributeError:
4391 pass
4392 except OSError as e:
4393 pass
4394 if(outfile == "-"):
4395 catfp.seek(0, 0)
4396 if(hasattr(sys.stdout, "buffer")):
4397 shutil.copyfileobj(catfp, sys.stdout.buffer)
4398 else:
4399 shutil.copyfileobj(catfp, sys.stdout)
4400 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
4401 catfp = CompressArchiveFile(
4402 catfp, compression, compressionlevel, formatspecs)
4403 catfp.seek(0, 0)
4404 upload_file_to_internet_file(catfp, outfile)
4405 if(returnfp):
4406 catfp.seek(0, 0)
4407 return catfp
4408 else:
4409 catfp.close()
4410 return True
4413 create_alias_function("Pack", __file_format_name__,
4414 "FromZipFile", PackArchiveFileFromZipFile)
4416 if(not rarfile_support):
4417 def PackArchiveFileFromRarFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
4418 return False
4420 if(rarfile_support):
4421 def PackArchiveFileFromRarFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
4422 formatspecs = FormatSpecsListToDict(formatspecs)
4423 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
4424 outfile = RemoveWindowsPath(outfile)
4425 checksumtype = checksumtype.lower()
4426 if(not CheckSumSupport(checksumtype, hashlib_guaranteed)):
4427 checksumtype = "crc32"
4428 if(checksumtype == "none"):
4429 checksumtype = ""
4430 if(not compression or compression == "catfile" or compression == formatspecs['format_lower']):
4431 compression = "auto"
4432 if(compression not in compressionlist and compression is None):
4433 compression = "auto"
4434 if(verbose):
4435 logging.basicConfig(format="%(message)s",
4436 stream=sys.stdout, level=logging.DEBUG)
4437 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
4438 if(os.path.exists(outfile)):
4439 try:
4440 os.unlink(outfile)
4441 except OSError as e:
4442 pass
4443 if(outfile == "-"):
4444 verbose = False
4445 catfp = BytesIO()
4446 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
4447 catfp = outfile
4448 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
4449 catfp = BytesIO()
4450 else:
4451 fbasename = os.path.splitext(outfile)[0]
4452 fextname = os.path.splitext(outfile)[1]
4453 if(not compresswholefile and fextname in outextlistwd):
4454 compresswholefile = True
4455 catfp = CompressOpenFile(
4456 outfile, compresswholefile, compressionlevel)
4457 catver = formatspecs['format_ver']
4458 fileheaderver = str(int(catver.replace(".", "")))
4459 curinode = 0
4460 curfid = 0
4461 inodelist = []
4462 inodetofile = {}
4463 filetoinode = {}
4464 inodetocatinode = {}
4465 if(not os.path.exists(infile) or not os.path.isfile(infile)):
4466 return False
4467 if(not rarfile.is_rarfile(infile) and not rarfile.is_rarfile_sfx(infile)):
4468 return False
4469 rarfp = rarfile.RarFile(infile, "r")
4470 rartest = rarfp.testrar()
4471 if(rartest):
4472 VerbosePrintOut("Bad file found!")
4473 numfiles = int(len(rarfp.infolist()))
4474 catfp = AppendFileHeader(catfp, numfiles, checksumtype, formatspecs)
4475 try:
4476 catfp.flush()
4477 os.fsync(catfp.fileno())
4478 except io.UnsupportedOperation:
4479 pass
4480 except AttributeError:
4481 pass
4482 except OSError as e:
4483 pass
4484 for member in sorted(rarfp.infolist(), key=lambda x: x.filename):
4485 is_unix = False
4486 is_windows = False
4487 if(member.host_os == rarfile.RAR_OS_UNIX):
4488 is_windows = False
4489 try:
4490 member.external_attr
4491 is_unix = True
4492 except AttributeError:
4493 is_unix = False
4494 elif(member.host_os == rarfile.RAR_OS_WIN32):
4495 is_unix = False
4496 try:
4497 member.external_attr
4498 is_windows = True
4499 except AttributeError:
4500 is_windows = False
4501 else:
4502 is_unix = False
4503 is_windows = False
4504 if(re.findall("^[.|/]", member.filename)):
4505 fname = member.filename
4506 else:
4507 fname = "./"+member.filename
4508 rarinfo = rarfp.getinfo(member.filename)
4509 if(verbose):
4510 VerbosePrintOut(fname)
4511 if(is_unix and member.external_attr != 0):
4512 fpremode = int(member.external_attr)
4513 elif(member.is_file()):
4514 fpremode = int(stat.S_IFREG + 438)
4515 elif(member.is_symlink()):
4516 fpremode = int(stat.S_IFLNK + 438)
4517 elif(member.is_dir()):
4518 fpremode = int(stat.S_IFDIR + 511)
4519 if(is_windows and member.external_attr != 0):
4520 fwinattributes = format(int(member.external_attr), 'x').lower()
4521 else:
4522 fwinattributes = format(int(0), 'x').lower()
4523 fcompression = ""
4524 fcsize = format(int(0), 'x').lower()
4525 flinkcount = 0
4526 ftype = 0
4527 if(member.is_file()):
4528 ftype = 0
4529 elif(member.is_symlink()):
4530 ftype = 2
4531 elif(member.is_dir()):
4532 ftype = 5
4533 flinkname = ""
4534 if(ftype == 2):
4535 flinkname = rarfp.read(member.filename).decode("UTF-8")
4536 fcurfid = format(int(curfid), 'x').lower()
4537 fcurinode = format(int(curfid), 'x').lower()
4538 curfid = curfid + 1
4539 fdev_minor = format(int(0), 'x').lower()
4540 fdev_major = format(int(0), 'x').lower()
4541 frdev_minor = format(int(0), 'x').lower()
4542 frdev_major = format(int(0), 'x').lower()
4543 if(ftype == 5):
4544 fsize = format(int("0"), 'x').lower()
4545 elif(ftype == 0):
4546 fsize = format(int(member.file_size), 'x').lower()
4547 else:
4548 fsize = format(int(member.file_size), 'x').lower()
4549 try:
4550 if(member.atime):
4551 fatime = format(int(member.atime.timestamp()), 'x').lower()
4552 else:
4553 fatime = format(int(member.mtime.timestamp()), 'x').lower()
4554 except AttributeError:
4555 fatime = format(int(member.mtime.timestamp()), 'x').lower()
4556 fmtime = format(int(member.mtime.timestamp()), 'x').lower()
4557 try:
4558 if(member.ctime):
4559 fctime = format(int(member.ctime.timestamp()), 'x').lower()
4560 else:
4561 fctime = format(int(member.mtime.timestamp()), 'x').lower()
4562 except AttributeError:
4563 fctime = format(int(member.mtime.timestamp()), 'x').lower()
4564 fbtime = format(int(member.mtime.timestamp()), 'x').lower()
4565 if(is_unix and member.external_attr != 0):
4566 fmode = format(int(member.external_attr), 'x').lower()
4567 fchmode = format(
4568 int(stat.S_IMODE(member.external_attr)), 'x').lower()
4569 ftypemod = format(
4570 int(stat.S_IFMT(member.external_attr)), 'x').lower()
4571 elif(member.is_file()):
4572 fmode = format(int(stat.S_IFREG + 438), 'x').lower()
4573 fchmode = format(
4574 int(stat.S_IMODE(int(stat.S_IFREG + 438))), 'x').lower()
4575 ftypemod = format(
4576 int(stat.S_IFMT(int(stat.S_IFREG + 438))), 'x').lower()
4577 elif(member.is_symlink()):
4578 fmode = format(int(stat.S_IFLNK + 438), 'x').lower()
4579 fchmode = format(
4580 int(stat.S_IMODE(int(stat.S_IFREG + 438))), 'x').lower()
4581 ftypemod = format(
4582 int(stat.S_IFMT(int(stat.S_IFREG + 438))), 'x').lower()
4583 elif(member.is_dir()):
4584 fmode = format(int(stat.S_IFDIR + 511), 'x').lower()
4585 fchmode = format(
4586 int(stat.S_IMODE(int(stat.S_IFDIR + 511))), 'x').lower()
4587 ftypemod = format(
4588 int(stat.S_IFMT(int(stat.S_IFDIR + 511))), 'x').lower()
4589 try:
4590 fuid = format(int(os.getuid()), 'x').lower()
4591 except AttributeError:
4592 fuid = format(int(0), 'x').lower()
4593 except KeyError:
4594 fuid = format(int(0), 'x').lower()
4595 try:
4596 fgid = format(int(os.getgid()), 'x').lower()
4597 except AttributeError:
4598 fgid = format(int(0), 'x').lower()
4599 except KeyError:
4600 fgid = format(int(0), 'x').lower()
4601 try:
4602 import pwd
4603 try:
4604 userinfo = pwd.getpwuid(os.getuid())
4605 funame = userinfo.pw_name
4606 except KeyError:
4607 funame = ""
4608 except AttributeError:
4609 funame = ""
4610 except ImportError:
4611 funame = ""
4612 fgname = ""
4613 try:
4614 import grp
4615 try:
4616 groupinfo = grp.getgrgid(os.getgid())
4617 fgname = groupinfo.gr_name
4618 except KeyError:
4619 fgname = ""
4620 except AttributeError:
4621 fgname = ""
4622 except ImportError:
4623 fgname = ""
4624 fcontents = BytesIO()
4625 if(ftype == 0):
4626 fcontents.write(rarfp.read(member.filename))
4627 if(not compresswholefile):
4628 fcontents.seek(0, 2)
4629 ucfsize = fcontents.tell()
4630 fcontents.seek(0, 0)
4631 if(compression == "auto"):
4632 ilsize = len(compressionlistalt)
4633 ilmin = 0
4634 ilcsize = []
4635 while(ilmin < ilsize):
4636 cfcontents = BytesIO()
4637 shutil.copyfileobj(fcontents, cfcontents)
4638 fcontents.seek(0, 0)
4639 cfcontents.seek(0, 0)
4640 cfcontents = CompressArchiveFile(
4641 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
4642 if(cfcontents):
4643 cfcontents.seek(0, 2)
4644 ilcsize.append(cfcontents.tell())
4645 cfcontents.close()
4646 else:
4647 try:
4648 ilcsize.append(sys.maxint)
4649 except AttributeError:
4650 ilcsize.append(sys.maxsize)
4651 ilmin = ilmin + 1
4652 ilcmin = ilcsize.index(min(ilcsize))
4653 compression = compressionlistalt[ilcmin]
4654 fcontents.seek(0, 0)
4655 cfcontents = BytesIO()
4656 shutil.copyfileobj(fcontents, cfcontents)
4657 cfcontents.seek(0, 0)
4658 cfcontents = CompressArchiveFile(
4659 cfcontents, compression, compressionlevel, formatspecs)
4660 cfcontents.seek(0, 2)
4661 cfsize = cfcontents.tell()
4662 if(ucfsize > cfsize):
4663 fcsize = format(int(cfsize), 'x').lower()
4664 fcompression = compression
4665 fcontents.close()
4666 fcontents = cfcontents
4667 if(fcompression == "none"):
4668 fcompression = ""
4669 fcontents.seek(0, 0)
4670 ftypehex = format(ftype, 'x').lower()
4671 catoutlist = [ftypehex, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression,
4672 fcsize, fuid, funame, fgid, fgname, fcurfid, fcurinode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, "+1"]
4673 catfp = AppendFileHeaderWithContent(
4674 catfp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
4675 fcontents.close()
4676 if(numfiles > 0):
4677 catfp.write(AppendNullBytes(
4678 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
4679 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
4680 catfp = CompressArchiveFile(
4681 catfp, compression, compressionlevel, formatspecs)
4682 try:
4683 catfp.flush()
4684 os.fsync(catfp.fileno())
4685 except io.UnsupportedOperation:
4686 pass
4687 except AttributeError:
4688 pass
4689 except OSError as e:
4690 pass
4691 if(outfile == "-"):
4692 catfp.seek(0, 0)
4693 if(hasattr(sys.stdout, "buffer")):
4694 shutil.copyfileobj(catfp, sys.stdout.buffer)
4695 else:
4696 shutil.copyfileobj(catfp, sys.stdout)
4697 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
4698 catfp = CompressArchiveFile(
4699 catfp, compression, compressionlevel, formatspecs)
4700 catfp.seek(0, 0)
4701 upload_file_to_internet_file(catfp, outfile)
4702 if(returnfp):
4703 catfp.seek(0, 0)
4704 return catfp
4705 else:
4706 catfp.close()
4707 return True
4709 create_alias_function("Pack", __file_format_name__,
4710 "FromRarFile", PackArchiveFileFromRarFile)
4712 if(not py7zr_support):
4713 def PackArchiveFileFromSevenZipFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
4714 return False
4716 if(py7zr_support):
4717 def PackArchiveFileFromSevenZipFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
4718 formatspecs = FormatSpecsListToDict(formatspecs)
4719 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
4720 outfile = RemoveWindowsPath(outfile)
4721 checksumtype = checksumtype.lower()
4722 if(not CheckSumSupport(checksumtype, hashlib_guaranteed)):
4723 checksumtype = "crc32"
4724 if(checksumtype == "none"):
4725 checksumtype = ""
4726 if(not compression or compression == "catfile" or compression == formatspecs['format_lower']):
4727 compression = "auto"
4728 if(compression not in compressionlist and compression is None):
4729 compression = "auto"
4730 if(verbose):
4731 logging.basicConfig(format="%(message)s",
4732 stream=sys.stdout, level=logging.DEBUG)
4733 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
4734 if(os.path.exists(outfile)):
4735 try:
4736 os.unlink(outfile)
4737 except OSError as e:
4738 pass
4739 if(outfile == "-"):
4740 verbose = False
4741 catfp = BytesIO()
4742 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
4743 catfp = outfile
4744 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
4745 catfp = BytesIO()
4746 else:
4747 fbasename = os.path.splitext(outfile)[0]
4748 fextname = os.path.splitext(outfile)[1]
4749 if(not compresswholefile and fextname in outextlistwd):
4750 compresswholefile = True
4751 catfp = CompressOpenFile(
4752 outfile, compresswholefile, compressionlevel)
4753 catver = formatspecs['format_ver']
4754 fileheaderver = str(int(catver.replace(".", "")))
4755 curinode = 0
4756 curfid = 0
4757 inodelist = []
4758 inodetofile = {}
4759 filetoinode = {}
4760 inodetocatinode = {}
4761 if(not os.path.exists(infile) or not os.path.isfile(infile)):
4762 return False
4763 szpfp = py7zr.SevenZipFile(infile, mode="r")
4764 file_content = szpfp.readall()
4765 #sztest = szpfp.testzip();
4766 sztestalt = szpfp.test()
4767 if(sztestalt):
4768 VerbosePrintOut("Bad file found!")
4769 numfiles = int(len(szpfp.list()))
4770 AppendFileHeader(catfp, numfiles, checksumtype, formatspecs)
4771 for member in sorted(szpfp.list(), key=lambda x: x.filename):
4772 if(re.findall("^[.|/]", member.filename)):
4773 fname = member.filename
4774 else:
4775 fname = "./"+member.filename
4776 if(verbose):
4777 VerbosePrintOut(fname)
4778 if(not member.is_directory):
4779 fpremode = int(stat.S_IFREG + 438)
4780 elif(member.is_directory):
4781 fpremode = int(stat.S_IFDIR + 511)
4782 fwinattributes = format(int(0), 'x').lower()
4783 fcompression = ""
4784 fcsize = format(int(0), 'x').lower()
4785 flinkcount = 0
4786 ftype = 0
4787 if(member.is_directory):
4788 ftype = 5
4789 else:
4790 ftype = 0
4791 flinkname = ""
4792 fcurfid = format(int(curfid), 'x').lower()
4793 fcurinode = format(int(curfid), 'x').lower()
4794 curfid = curfid + 1
4795 fdev_minor = format(int(0), 'x').lower()
4796 fdev_major = format(int(0), 'x').lower()
4797 frdev_minor = format(int(0), 'x').lower()
4798 frdev_major = format(int(0), 'x').lower()
4799 if(ftype == 5):
4800 fsize = format(int("0"), 'x').lower()
4801 fatime = format(int(member.creationtime.timestamp()), 'x').lower()
4802 fmtime = format(int(member.creationtime.timestamp()), 'x').lower()
4803 fctime = format(int(member.creationtime.timestamp()), 'x').lower()
4804 fbtime = format(int(member.creationtime.timestamp()), 'x').lower()
4805 if(member.is_directory):
4806 fmode = format(int(stat.S_IFDIR + 511), 'x').lower()
4807 fchmode = format(
4808 int(stat.S_IMODE(int(stat.S_IFDIR + 511))), 'x').lower()
4809 ftypemod = format(
4810 int(stat.S_IFMT(int(stat.S_IFDIR + 511))), 'x').lower()
4811 else:
4812 fmode = format(int(stat.S_IFREG + 438), 'x').lower()
4813 fchmode = format(
4814 int(stat.S_IMODE(int(stat.S_IFREG + 438))), 'x').lower()
4815 ftypemod = format(
4816 int(stat.S_IFMT(int(stat.S_IFREG + 438))), 'x').lower()
4817 try:
4818 fuid = format(int(os.getuid()), 'x').lower()
4819 except AttributeError:
4820 fuid = format(int(0), 'x').lower()
4821 except KeyError:
4822 fuid = format(int(0), 'x').lower()
4823 try:
4824 fgid = format(int(os.getgid()), 'x').lower()
4825 except AttributeError:
4826 fgid = format(int(0), 'x').lower()
4827 except KeyError:
4828 fgid = format(int(0), 'x').lower()
4829 try:
4830 import pwd
4831 try:
4832 userinfo = pwd.getpwuid(os.getuid())
4833 funame = userinfo.pw_name
4834 except KeyError:
4835 funame = ""
4836 except AttributeError:
4837 funame = ""
4838 except ImportError:
4839 funame = ""
4840 fgname = ""
4841 try:
4842 import grp
4843 try:
4844 groupinfo = grp.getgrgid(os.getgid())
4845 fgname = groupinfo.gr_name
4846 except KeyError:
4847 fgname = ""
4848 except AttributeError:
4849 fgname = ""
4850 except ImportError:
4851 fgname = ""
4852 fcontents = BytesIO()
4853 if(ftype == 0):
4854 fcontents.write(file_content[member.filename].read())
4855 fsize = format(fcontents.tell(), 'x').lower()
4856 file_content[member.filename].close()
4857 if(not compresswholefile):
4858 fcontents.seek(0, 2)
4859 ucfsize = fcontents.tell()
4860 fcontents.seek(0, 0)
4861 if(compression == "auto"):
4862 ilsize = len(compressionlistalt)
4863 ilmin = 0
4864 ilcsize = []
4865 while(ilmin < ilsize):
4866 cfcontents = BytesIO()
4867 shutil.copyfileobj(fcontents, cfcontents)
4868 fcontents.seek(0, 0)
4869 cfcontents.seek(0, 0)
4870 cfcontents = CompressArchiveFile(
4871 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
4872 if(cfcontents):
4873 cfcontents.seek(0, 2)
4874 ilcsize.append(cfcontents.tell())
4875 cfcontents.close()
4876 else:
4877 try:
4878 ilcsize.append(sys.maxint)
4879 except AttributeError:
4880 ilcsize.append(sys.maxsize)
4881 ilmin = ilmin + 1
4882 ilcmin = ilcsize.index(min(ilcsize))
4883 compression = compressionlistalt[ilcmin]
4884 fcontents.seek(0, 0)
4885 cfcontents = BytesIO()
4886 shutil.copyfileobj(fcontents, cfcontents)
4887 cfcontents.seek(0, 0)
4888 cfcontents = CompressArchiveFile(
4889 cfcontents, compression, compressionlevel, formatspecs)
4890 cfcontents.seek(0, 2)
4891 cfsize = cfcontents.tell()
4892 if(ucfsize > cfsize):
4893 fcsize = format(int(cfsize), 'x').lower()
4894 fcompression = compression
4895 fcontents.close()
4896 fcontents = cfcontents
4897 if(fcompression == "none"):
4898 fcompression = ""
4899 fcontents.seek(0, 0)
4900 ftypehex = format(ftype, 'x').lower()
4901 catoutlist = [ftypehex, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression,
4902 fcsize, fuid, funame, fgid, fgname, fcurfid, fcurinode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, "+1"]
4903 catfp = AppendFileHeaderWithContent(
4904 catfp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
4905 fcontents.close()
4906 if(numfiles > 0):
4907 catfp.write(AppendNullBytes(
4908 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
4909 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
4910 catfp = CompressArchiveFile(
4911 catfp, compression, compressionlevel, formatspecs)
4912 try:
4913 catfp.flush()
4914 os.fsync(catfp.fileno())
4915 except io.UnsupportedOperation:
4916 pass
4917 except AttributeError:
4918 pass
4919 except OSError as e:
4920 pass
4921 if(outfile == "-"):
4922 catfp.seek(0, 0)
4923 if(hasattr(sys.stdout, "buffer")):
4924 shutil.copyfileobj(catfp, sys.stdout.buffer)
4925 else:
4926 shutil.copyfileobj(catfp, sys.stdout)
4927 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
4928 catfp = CompressArchiveFile(
4929 catfp, compression, compressionlevel, formatspecs)
4930 catfp.seek(0, 0)
4931 upload_file_to_internet_file(catfp, outfile)
4932 if(returnfp):
4933 catfp.seek(0, 0)
4934 return catfp
4935 else:
4936 catfp.close()
4937 return True
4939 create_alias_function("Pack", __file_format_name__,
4940 "FromSevenZipFile", PackArchiveFileFromSevenZipFile)
4943 def PackArchiveFileFromInFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
4944 formatspecs = FormatSpecsListToDict(formatspecs)
4945 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
4946 if(verbose):
4947 logging.basicConfig(format="%(message)s",
4948 stream=sys.stdout, level=logging.DEBUG)
4949 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
4950 return PackArchiveFileFromTarFile(infile, outfile, compression, compresswholefile, compressionlevel, checksumtype, extradata, formatspecs, verbose, returnfp)
4951 elif(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
4952 return PackArchiveFileFromZipFile(infile, outfile, compression, compresswholefile, compressionlevel, checksumtype, extradata, formatspecs, verbose, returnfp)
4953 elif(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
4954 return PackArchiveFileFromRarFile(infile, outfile, compression, compresswholefile, compressionlevel, checksumtype, extradata, formatspecs, verbose, returnfp)
4955 elif(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
4956 return PackArchiveFileFromSevenZipFile(infile, outfile, compression, compresswholefile, compressionlevel, checksumtype, extradata, formatspecs, verbose, returnfp)
4957 elif(checkcompressfile == "catfile"):
4958 return RePackArchiveFile(infile, outfile, compression, compresswholefile, compressionlevel, False, 0, 0, checksumtype, False, extradata, formatspecs, verbose, returnfp)
4959 else:
4960 return False
4961 return False
4964 create_alias_function("Pack", __file_format_name__,
4965 "FromInFile", PackArchiveFileFromInFile)
4968 def ArchiveFileSeekToFileNum(infile, seekto=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
4969 formatspecs = FormatSpecsListToDict(formatspecs)
4970 if(hasattr(infile, "read") or hasattr(infile, "write")):
4971 catfp = infile
4972 catfp.seek(0, 0)
4973 catfp = UncompressArchiveFile(catfp, formatspecs)
4974 checkcompressfile = CheckCompressionSubType(catfp, formatspecs, True)
4975 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
4976 return TarFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
4977 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
4978 return ZipFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
4979 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
4980 return RarFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
4981 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
4982 return SevenZipFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
4983 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
4984 return False
4985 if(not catfp):
4986 return False
4987 catfp.seek(0, 0)
4988 elif(infile == "-"):
4989 catfp = BytesIO()
4990 if(hasattr(sys.stdin, "buffer")):
4991 shutil.copyfileobj(sys.stdin.buffer, catfp)
4992 else:
4993 shutil.copyfileobj(sys.stdin, catfp)
4994 catfp.seek(0, 0)
4995 catfp = UncompressArchiveFile(catfp, formatspecs)
4996 if(not catfp):
4997 return False
4998 catfp.seek(0, 0)
4999 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
5000 catfp = download_file_from_internet_file(infile)
5001 catfp.seek(0, 0)
5002 catfp = UncompressArchiveFile(catfp, formatspecs)
5003 if(not catfp):
5004 return False
5005 catfp.seek(0, 0)
5006 else:
5007 infile = RemoveWindowsPath(infile)
5008 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
5009 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
5010 return TarFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5011 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
5012 return ZipFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5013 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
5014 return RarFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5015 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
5016 return SevenZipFileToArray(infile, seekto, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5017 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
5018 return False
5019 compresscheck = CheckCompressionType(infile, formatspecs, True)
5020 if(not compresscheck):
5021 fextname = os.path.splitext(infile)[1]
5022 if(fextname == ".gz"):
5023 compresscheck = "gzip"
5024 elif(fextname == ".bz2"):
5025 compresscheck = "bzip2"
5026 elif(fextname == ".zst"):
5027 compresscheck = "zstd"
5028 elif(fextname == ".lz4" or fextname == ".clz4"):
5029 compresscheck = "lz4"
5030 elif(fextname == ".lzo" or fextname == ".lzop"):
5031 compresscheck = "lzo"
5032 elif(fextname == ".lzma"):
5033 compresscheck = "lzma"
5034 elif(fextname == ".xz"):
5035 compresscheck = "xz"
5036 elif(fextname == ".zz" or fextname == ".zl" or fextname == ".zlib"):
5037 compresscheck = "zlib"
5038 else:
5039 return False
5040 if(not compresscheck):
5041 return False
5042 catfp = UncompressFile(infile, formatspecs, "rb")
5044 try:
5045 catfp.seek(0, 2);
5046 except OSError:
5047 SeekToEndOfFile(catfp);
5048 except ValueError:
5049 SeekToEndOfFile(catfp);
5050 CatSize = catfp.tell();
5051 CatSizeEnd = CatSize;
5053 try:
5054 catfp.seek(0, 0)
5055 except OSError:
5056 return False
5057 except ValueError:
5058 return False
5059 curloc = catfp.tell()
5060 if(curloc > 0):
5061 catfp.seek(0, 0)
5062 catheaderver = str(int(formatspecs['format_ver'].replace(".", "")))
5063 catstring = catfp.read(len(formatspecs['format_magic']+catheaderver)).decode("UTF-8")
5064 catdel = catfp.read(1).decode("UTF-8")
5065 if(catstring != formatspecs['format_magic']+catheaderver):
5066 return False
5067 if(catdel != formatspecs['format_delimiter']):
5068 return False
5069 catheader = ReadFileHeaderData(catfp, 3, formatspecs['format_delimiter'])
5070 if(curloc > 0):
5071 catfp.seek(curloc, 0)
5072 catversion = re.findall("([\\d]+)", catstring)
5073 fprenumfiles = catheader[0]
5074 fnumfiles = int(fprenumfiles, 16)
5075 fprechecksumtype = catheader[1]
5076 fprechecksum = catheader[2]
5077 fileheader = AppendNullByte(catstring, formatspecs['format_delimiter'])
5078 fnumfileshex = format(int(fnumfiles), 'x').lower()
5079 fileheader = fileheader + \
5080 AppendNullBytes([fnumfileshex, fprechecksumtype],
5081 formatspecs['format_delimiter'])
5082 catfileheadercshex = GetFileChecksum(
5083 fileheader, fprechecksumtype, True, formatspecs)
5084 fileheader = fileheader + \
5085 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
5086 fheadtell = len(fileheader)
5087 if(fprechecksum != catfileheadercshex and not skipchecksum):
5088 VerbosePrintOut("File Header Checksum Error with file " +
5089 infile + " at offset " + str(0))
5090 VerbosePrintOut("'" + str(fprechecksum) + "' != " +
5091 "'" + str(catfileheadercshex) + "'")
5092 return False
5093 catversions = re.search('(.*?)(\\d+)', catstring).groups()
5094 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
5095 'fformatspecs': formatspecs, 'fchecksumtype': fprechecksumtype, 'fheaderchecksum': fprechecksum, 'ffilelist': {}}
5096 if(seekto >= fnumfiles):
5097 seekto = fnumfiles - 1
5098 if(seekto < 0):
5099 seekto = 0
5100 if(seekto >= 0):
5101 il = -1
5102 while(il < seekto):
5103 prefhstart = catfp.tell()
5104 if(formatspecs['new_style']):
5105 preheaderdata = ReadFileHeaderDataBySize(
5106 catfp, formatspecs['format_delimiter'])
5107 else:
5108 preheaderdata = ReadFileHeaderDataWoSize(
5109 catfp, formatspecs['format_delimiter'])
5110 if(len(preheaderdata) == 0):
5111 break
5112 prefheadsize = int(preheaderdata[0], 16)
5113 prefnumfields = int(preheaderdata[1], 16)
5114 preftype = int(preheaderdata[2], 16)
5115 if(re.findall("^[.|/]", preheaderdata[3])):
5116 prefname = preheaderdata[3]
5117 else:
5118 prefname = "./"+preheaderdata[3]
5119 prefbasedir = os.path.dirname(prefname)
5120 preflinkname = preheaderdata[4]
5121 prefsize = int(preheaderdata[5], 16)
5122 prefatime = int(preheaderdata[6], 16)
5123 prefmtime = int(preheaderdata[7], 16)
5124 prefctime = int(preheaderdata[8], 16)
5125 prefbtime = int(preheaderdata[9], 16)
5126 prefmode = int(preheaderdata[10], 16)
5127 prefchmode = stat.S_IMODE(prefmode)
5128 preftypemod = stat.S_IFMT(prefmode)
5129 prefwinattributes = int(preheaderdata[11], 16)
5130 prefcompression = preheaderdata[12]
5131 prefcsize = int(preheaderdata[13], 16)
5132 prefuid = int(preheaderdata[14], 16)
5133 prefuname = preheaderdata[15]
5134 prefgid = int(preheaderdata[16], 16)
5135 prefgname = preheaderdata[17]
5136 fid = int(preheaderdata[18], 16)
5137 finode = int(preheaderdata[19], 16)
5138 flinkcount = int(preheaderdata[20], 16)
5139 prefdev_minor = int(preheaderdata[21], 16)
5140 prefdev_major = int(preheaderdata[22], 16)
5141 prefrdev_minor = int(preheaderdata[23], 16)
5142 prefrdev_major = int(preheaderdata[24], 16)
5143 prefseeknextfile = preheaderdata[25]
5144 prefextrasize = int(preheaderdata[26], 16)
5145 prefextrafields = int(preheaderdata[27], 16)
5146 extrafieldslist = []
5147 extrastart = 28
5148 extraend = extrastart + prefextrafields
5149 extrafieldslist = []
5150 if(extrastart < extraend):
5151 extrafieldslist.append(preheaderdata[extrastart])
5152 extrastart = extrastart + 1
5153 prefcs = preheaderdata[-2].lower()
5154 prenewfcs = preheaderdata[-1].lower()
5155 prenewfcs = GetHeaderChecksum(
5156 preheaderdata[:-2], preheaderdata[-4].lower(), True, formatspecs)
5157 if(prefcs != prenewfcs and not skipchecksum):
5158 VerbosePrintOut("File Header Checksum Error with file " +
5159 prefname + " at offset " + str(prefhstart))
5160 VerbosePrintOut("'" + str(prefcs) + "' != " +
5161 "'" + str(prenewfcs) + "'")
5162 return False
5163 valid_archive = False
5164 invalid_archive = True
5165 prefhend = catfp.tell() - 1
5166 prefcontentstart = catfp.tell()
5167 prefcontents = ""
5168 pyhascontents = False
5169 if(prefsize > 0):
5170 if(prefcompression):
5171 prefcontents = catfp.read(prefsize)
5172 else:
5173 prefcontents = catfp.read(prefcsize)
5174 prenewfccs = GetFileChecksum(
5175 prefcontents, preheaderdata[-3].lower(), False, formatspecs)
5176 pyhascontents = True
5177 if(prefccs != prenewfccs and not skipchecksum):
5178 VerbosePrintOut("File Content Checksum Error with file " +
5179 prefname + " at offset " + str(prefcontentstart))
5180 VerbosePrintOut("'" + str(prefccs) +
5181 "' != " + "'" + str(prenewfccs) + "'")
5182 return False
5183 if(re.findall("^\\+([0-9]+)", prefseeknextfile)):
5184 fseeknextasnum = int(prefseeknextfile.replace("+", ""))
5185 if(abs(fseeknextasnum) == 0):
5186 pass
5187 catfp.seek(fseeknextasnum, 1)
5188 elif(re.findall("^\\-([0-9]+)", prefseeknextfile)):
5189 fseeknextasnum = int(prefseeknextfile)
5190 if(abs(fseeknextasnum) == 0):
5191 pass
5192 catfp.seek(fseeknextasnum, 1)
5193 elif(re.findall("^([0-9]+)", prefseeknextfile)):
5194 fseeknextasnum = int(prefseeknextfile)
5195 if(abs(fseeknextasnum) == 0):
5196 pass
5197 catfp.seek(fseeknextasnum, 0)
5198 else:
5199 return False
5200 il = il + 1
5201 catfp.seek(seekstart, 0)
5202 fileidnum = il
5203 catfheadsize = int(preheaderdata[0], 16)
5204 catfnumfields = int(preheaderdata[1], 16)
5205 catftype = int(preheaderdata[2], 16)
5206 if(re.findall("^[.|/]", preheaderdata[3])):
5207 catfname = preheaderdata[3]
5208 else:
5209 catfname = "./"+preheaderdata[3]
5210 catflinkname = preheaderdata[4]
5211 catfsize = int(preheaderdata[5], 16)
5212 catfbasedir = os.path.dirname(catfname)
5213 catlist = {'fid': fileidnum, 'foffset': catfp.tell(), 'ftype': catftype, 'fname': catfname,
5214 'fbasedir': catfbasedir, 'flinkname': catflinkname, 'fsize': catfsize}
5215 if(returnfp):
5216 catlist.update({'catfp': catfp})
5217 else:
5218 catfp.close()
5219 return catlist
5222 create_alias_function("", __file_format_name__,
5223 "SeekToFileNum", ArchiveFileSeekToFileNum)
5226 def ArchiveFileSeekToFileName(infile, seekfile=None, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
5227 formatspecs = FormatSpecsListToDict(formatspecs)
5228 if(hasattr(infile, "read") or hasattr(infile, "write")):
5229 catfp = infile
5230 catfp.seek(0, 0)
5231 catfp = UncompressArchiveFile(catfp, formatspecs)
5232 checkcompressfile = CheckCompressionSubType(catfp, formatspecs, True)
5233 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
5234 return TarFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5235 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
5236 return ZipFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5237 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
5238 return RarFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5239 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
5240 return SevenZipFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5241 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
5242 return False
5243 if(not catfp):
5244 return False
5245 catfp.seek(0, 0)
5246 elif(infile == "-"):
5247 catfp = BytesIO()
5248 if(hasattr(sys.stdin, "buffer")):
5249 shutil.copyfileobj(sys.stdin.buffer, catfp)
5250 else:
5251 shutil.copyfileobj(sys.stdin, catfp)
5252 catfp.seek(0, 0)
5253 catfp = UncompressArchiveFile(catfp, formatspecs)
5254 if(not catfp):
5255 return False
5256 catfp.seek(0, 0)
5257 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
5258 catfp = download_file_from_internet_file(infile)
5259 catfp = UncompressArchiveFile(catfp, formatspecs)
5260 catfp.seek(0, 0)
5261 if(not catfp):
5262 return False
5263 catfp.seek(0, 0)
5264 else:
5265 infile = RemoveWindowsPath(infile)
5266 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
5267 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
5268 return TarFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5269 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
5270 return ZipFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5271 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
5272 return RarFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5273 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
5274 return SevenZipFileToArray(infile, 0, 0, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5275 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
5276 return False
5277 compresscheck = CheckCompressionType(infile, formatspecs, True)
5278 if(not compresscheck):
5279 fextname = os.path.splitext(infile)[1]
5280 if(fextname == ".gz"):
5281 compresscheck = "gzip"
5282 elif(fextname == ".bz2"):
5283 compresscheck = "bzip2"
5284 elif(fextname == ".zst"):
5285 compresscheck = "zstd"
5286 elif(fextname == ".lz4" or fextname == ".clz4"):
5287 compresscheck = "lz4"
5288 elif(fextname == ".lzo" or fextname == ".lzop"):
5289 compresscheck = "lzo"
5290 elif(fextname == ".lzma"):
5291 compresscheck = "lzma"
5292 elif(fextname == ".xz"):
5293 compresscheck = "xz"
5294 elif(fextname == ".zz" or fextname == ".zl" or fextname == ".zlib"):
5295 compresscheck = "zlib"
5296 else:
5297 return False
5298 if(not compresscheck):
5299 return False
5300 catfp = UncompressFile(infile, formatspecs, "rb")
5302 try:
5303 catfp.seek(0, 2);
5304 except OSError:
5305 SeekToEndOfFile(catfp);
5306 except ValueError:
5307 SeekToEndOfFile(catfp);
5308 CatSize = catfp.tell();
5309 CatSizeEnd = CatSize;
5311 try:
5312 catfp.seek(0, 0)
5313 except OSError:
5314 return False
5315 except ValueError:
5316 return False
5317 curloc = catfp.tell()
5318 if(curloc > 0):
5319 catfp.seek(0, 0)
5320 catheaderver = str(int(formatspecs['format_ver'].replace(".", "")))
5321 catstring = catfp.read(len(formatspecs['format_magic']+catheaderver)).decode("UTF-8")
5322 catdel = catfp.read(1).decode("UTF-8")
5323 if(catstring != formatspecs['format_magic']+catheaderver):
5324 return False
5325 if(catdel != formatspecs['format_delimiter']):
5326 return False
5327 catheader = ReadFileHeaderData(catfp, 3, formatspecs['format_delimiter'])
5328 if(curloc > 0):
5329 catfp.seek(curloc, 0)
5330 catversion = re.findall("([\\d]+)", catstring)
5331 fprenumfiles = catheader[0]
5332 fnumfiles = int(fprenumfiles, 16)
5333 fprechecksumtype = catheader[1]
5334 fprechecksum = catheader[2]
5335 fileheader = AppendNullByte(catstring, formatspecs['format_delimiter'])
5336 fnumfileshex = format(int(fnumfiles), 'x').lower()
5337 fileheader = fileheader + \
5338 AppendNullBytes([fnumfileshex, fprechecksumtype],
5339 formatspecs['format_delimiter'])
5340 catfileheadercshex = GetFileChecksum(
5341 fileheader, fprechecksumtype, True, formatspecs)
5342 fileheader = fileheader + \
5343 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
5344 fheadtell = len(fileheader)
5345 if(fprechecksum != catfileheadercshex and not skipchecksum):
5346 VerbosePrintOut("File Header Checksum Error with file " +
5347 infile + " at offset " + str(0))
5348 VerbosePrintOut("'" + str(fprechecksum) + "' != " +
5349 "'" + str(catfileheadercshex) + "'")
5350 return False
5351 catversions = re.search('(.*?)(\\d+)', catstring).groups()
5352 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
5353 'fformatspecs': formatspecs, 'fchecksumtype': fprechecksumtype, 'fheaderchecksum': fprechecksum, 'ffilelist': {}}
5354 seekto = fnumfiles - 1
5355 filefound = False
5356 if(seekto >= 0):
5357 il = -1
5358 while(il < seekto):
5359 prefhstart = catfp.tell()
5360 if(formatspecs['new_style']):
5361 preheaderdata = ReadFileHeaderDataBySize(
5362 catfp, formatspecs['format_delimiter'])
5363 else:
5364 preheaderdata = ReadFileHeaderDataWoSize(
5365 catfp, formatspecs['format_delimiter'])
5366 if(len(preheaderdata) == 0):
5367 break
5368 prefheadsize = int(preheaderdata[0], 16)
5369 prefnumfields = int(preheaderdata[1], 16)
5370 preftype = int(preheaderdata[2], 16)
5371 if(re.findall("^[.|/]", preheaderdata[3])):
5372 prefname = preheaderdata[3]
5373 else:
5374 prefname = "./"+preheaderdata[3]
5375 prefbasedir = os.path.dirname(prefname)
5376 preflinkname = preheaderdata[4]
5377 prefsize = int(preheaderdata[5], 16)
5378 prefatime = int(preheaderdata[6], 16)
5379 prefmtime = int(preheaderdata[7], 16)
5380 prefctime = int(preheaderdata[8], 16)
5381 prefbtime = int(preheaderdata[9], 16)
5382 prefmode = int(preheaderdata[10], 16)
5383 prefchmode = stat.S_IMODE(prefmode)
5384 preftypemod = stat.S_IFMT(prefmode)
5385 prefwinattributes = int(preheaderdata[11], 16)
5386 prefcompression = preheaderdata[12]
5387 prefcsize = int(preheaderdata[13], 16)
5388 prefuid = int(preheaderdata[14], 16)
5389 prefuname = preheaderdata[15]
5390 prefgid = int(preheaderdata[16], 16)
5391 prefgname = preheaderdata[17]
5392 fid = int(preheaderdata[18], 16)
5393 finode = int(preheaderdata[19], 16)
5394 flinkcount = int(preheaderdata[20], 16)
5395 prefdev_minor = int(preheaderdata[21], 16)
5396 prefdev_major = int(preheaderdata[22], 16)
5397 prefrdev_minor = int(preheaderdata[23], 16)
5398 prefrdev_major = int(preheaderdata[24], 16)
5399 prefseeknextfile = preheaderdata[25]
5400 prefextrasize = int(preheaderdata[26], 16)
5401 prefextrafields = int(preheaderdata[27], 16)
5402 extrafieldslist = []
5403 extrastart = 28
5404 extraend = extrastart + prefextrafields
5405 extrafieldslist = []
5406 if(extrastart < extraend):
5407 extrafieldslist.append(preheaderdata[extrastart])
5408 extrastart = extrastart + 1
5409 prefcs = preheaderdata[-2].lower()
5410 prenewfcs = preheaderdata[-1].lower()
5411 prenewfcs = GetHeaderChecksum(
5412 preheaderdata[:-2], preheaderdata[-4].lower(), True, formatspecs)
5413 if(prefcs != prenewfcs and not skipchecksum):
5414 VerbosePrintOut("File Header Checksum Error with file " +
5415 prefname + " at offset " + str(prefhstart))
5416 VerbosePrintOut("'" + str(prefcs) + "' != " +
5417 "'" + str(prenewfcs) + "'")
5418 return False
5419 valid_archive = False
5420 invalid_archive = True
5421 prefhend = catfp.tell() - 1
5422 prefcontentstart = catfp.tell()
5423 prefcontents = ""
5424 pyhascontents = False
5425 if(prefsize > 0):
5426 if(prefcompression):
5427 prefcontents = catfp.read(prefsize)
5428 else:
5429 prefcontents = catfp.read(prefcsize)
5430 prenewfccs = GetFileChecksum(
5431 prefcontents, preheaderdata[-3].lower(), False, formatspecs)
5432 pyhascontents = True
5433 if(prefccs != prenewfccs and not skipchecksum):
5434 VerbosePrintOut("File Content Checksum Error with file " +
5435 prefname + " at offset " + str(prefcontentstart))
5436 VerbosePrintOut("'" + str(prefccs) +
5437 "' != " + "'" + str(prenewfccs) + "'")
5438 return False
5439 if(re.findall("^\\+([0-9]+)", prefseeknextfile)):
5440 fseeknextasnum = int(prefseeknextfile.replace("+", ""))
5441 if(abs(fseeknextasnum) == 0):
5442 pass
5443 catfp.seek(fseeknextasnum, 1)
5444 elif(re.findall("^\\-([0-9]+)", prefseeknextfile)):
5445 fseeknextasnum = int(prefseeknextfile)
5446 if(abs(fseeknextasnum) == 0):
5447 pass
5448 catfp.seek(fseeknextasnum, 1)
5449 elif(re.findall("^([0-9]+)", prefseeknextfile)):
5450 fseeknextasnum = int(prefseeknextfile)
5451 if(abs(fseeknextasnum) == 0):
5452 pass
5453 catfp.seek(fseeknextasnum, 0)
5454 else:
5455 return False
5456 il = il + 1
5457 filefound = False
5458 prefname = preheaderdata[2]
5459 if(re.findall("^[.|/]", preheaderdata[2])):
5460 prefname = preheaderdata[2]
5461 else:
5462 prefname = "./"+preheaderdata[2]
5463 if(prefname == seekfile):
5464 filefound = True
5465 break
5466 catfp.seek(seekstart, 0)
5467 fileidnum = il
5468 catfheadsize = int(preheaderdata[0], 16)
5469 catfnumfields = int(preheaderdata[1], 16)
5470 catftype = int(preheaderdata[2], 16)
5471 if(re.findall("^[.|/]", preheaderdata[3])):
5472 catfname = preheaderdata[3]
5473 else:
5474 catfname = "./"+preheaderdata[3]
5475 catflinkname = preheaderdata[4]
5476 catfsize = int(preheaderdata[5], 16)
5477 catfbasedir = os.path.dirname(catfname)
5478 if(filefound):
5479 catlist = {'fid': fileidnum, 'foffset': catfp.tell(), 'ftype': catftype, 'fname': catfname,
5480 'fbasedir': catfbasedir, 'flinkname': catflinkname, 'fsize': catfsize}
5481 else:
5482 return False
5483 if(returnfp):
5484 catlist.update({'catfp': catfp})
5485 else:
5486 catfp.close()
5487 return catlist
5490 create_alias_function("", __file_format_name__,
5491 "SeekToFileName", ArchiveFileSeekToFileName)
5494 def ArchiveFileValidate(infile, formatspecs=__file_format_dict__, verbose=False, returnfp=False):
5495 formatspecs = FormatSpecsListToDict(formatspecs)
5496 if(verbose):
5497 logging.basicConfig(format="%(message)s",
5498 stream=sys.stdout, level=logging.DEBUG)
5499 if(hasattr(infile, "read") or hasattr(infile, "write")):
5500 catfp = infile
5501 catfp.seek(0, 0)
5502 catfp = UncompressArchiveFile(catfp, formatspecs)
5503 checkcompressfile = CheckCompressionSubType(catfp, formatspecs, True)
5504 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
5505 return TarFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5506 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
5507 return ZipFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5508 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
5509 return RarFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5510 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
5511 return SevenZipFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5512 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
5513 return False
5514 if(not catfp):
5515 return False
5516 catfp.seek(0, 0)
5517 elif(infile == "-"):
5518 catfp = BytesIO()
5519 if(hasattr(sys.stdin, "buffer")):
5520 shutil.copyfileobj(sys.stdin.buffer, catfp)
5521 else:
5522 shutil.copyfileobj(sys.stdin, catfp)
5523 catfp.seek(0, 0)
5524 catfp = UncompressArchiveFile(catfp, formatspecs)
5525 if(not catfp):
5526 return False
5527 catfp.seek(0, 0)
5528 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
5529 catfp = download_file_from_internet_file(infile)
5530 catfp = UncompressArchiveFile(catfp, formatspecs)
5531 catfp.seek(0, 0)
5532 if(not catfp):
5533 return False
5534 catfp.seek(0, 0)
5535 else:
5536 infile = RemoveWindowsPath(infile)
5537 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
5538 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
5539 return TarFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5540 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
5541 return ZipFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5542 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
5543 return RarFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5544 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
5545 return SevenZipFileToArray(infile, 0, 0, False, True, False, formatspecs, returnfp)
5546 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
5547 return False
5548 compresscheck = CheckCompressionType(infile, formatspecs, True)
5549 if(not compresscheck):
5550 fextname = os.path.splitext(infile)[1]
5551 if(fextname == ".gz"):
5552 compresscheck = "gzip"
5553 elif(fextname == ".bz2"):
5554 compresscheck = "bzip2"
5555 elif(fextname == ".zst"):
5556 compresscheck = "zstd"
5557 elif(fextname == ".lz4" or fextname == ".clz4"):
5558 compresscheck = "lz4"
5559 elif(fextname == ".lzo" or fextname == ".lzop"):
5560 compresscheck = "lzo"
5561 elif(fextname == ".lzma"):
5562 compresscheck = "lzma"
5563 elif(fextname == ".xz"):
5564 compresscheck = "xz"
5565 elif(fextname == ".zz" or fextname == ".zl" or fextname == ".zlib"):
5566 compresscheck = "zlib"
5567 else:
5568 return False
5569 if(not compresscheck):
5570 return False
5571 catfp = UncompressFile(infile, formatspecs, "rb")
5573 try:
5574 catfp.seek(0, 2);
5575 except OSError:
5576 SeekToEndOfFile(catfp);
5577 except ValueError:
5578 SeekToEndOfFile(catfp);
5579 CatSize = catfp.tell();
5580 CatSizeEnd = CatSize;
5582 try:
5583 catfp.seek(0, 0)
5584 except OSError:
5585 return False
5586 except ValueError:
5587 return False
5588 curloc = catfp.tell()
5589 if(curloc > 0):
5590 catfp.seek(0, 0)
5591 catheaderver = str(int(formatspecs['format_ver'].replace(".", "")))
5592 catstring = catfp.read(len(formatspecs['format_magic']+catheaderver)).decode("UTF-8")
5593 catdel = catfp.read(1).decode("UTF-8")
5594 if(catstring != formatspecs['format_magic']+catheaderver):
5595 return False
5596 if(catdel != formatspecs['format_delimiter']):
5597 return False
5598 catheader = ReadFileHeaderData(catfp, 3, formatspecs['format_delimiter'])
5599 if(curloc > 0):
5600 catfp.seek(curloc, 0)
5601 catversion = re.findall("([\\d]+)", catstring)
5602 fprenumfiles = catheader[0]
5603 fnumfiles = int(fprenumfiles, 16)
5604 fprechecksumtype = catheader[1]
5605 fprechecksum = catheader[2]
5606 il = 0
5607 fileheader = AppendNullByte(catstring, formatspecs['format_delimiter'])
5608 fnumfileshex = format(int(fnumfiles), 'x').lower()
5609 fileheader = fileheader + \
5610 AppendNullBytes([fnumfileshex, fprechecksumtype],
5611 formatspecs['format_delimiter'])
5612 catfileheadercshex = GetFileChecksum(
5613 fileheader, fprechecksumtype, True, formatspecs)
5614 fileheader = fileheader + \
5615 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
5616 valid_archive = True
5617 invalid_archive = False
5618 if(verbose):
5619 if(hasattr(infile, "read") or hasattr(infile, "write")):
5620 try:
5621 VerbosePrintOut(infile.name)
5622 except AttributeError:
5623 VerbosePrintOut(infile)
5624 else:
5625 VerbosePrintOut(infile)
5626 VerbosePrintOut("Number of Records " + str(fnumfiles))
5627 if(fprechecksum == catfileheadercshex):
5628 if(verbose):
5629 VerbosePrintOut("File Header Checksum Passed at offset " + str(0))
5630 VerbosePrintOut("'" + str(fprechecksum) + "' == " +
5631 "'" + str(catfileheadercshex) + "'")
5632 else:
5633 if(verbose):
5634 VerbosePrintOut("File Header Checksum Failed at offset " + str(0))
5635 VerbosePrintOut("'" + str(fprechecksum) + "' != " +
5636 "'" + str(catfileheadercshex) + "'")
5637 valid_archive = False
5638 invalid_archive = True
5639 if(verbose):
5640 VerbosePrintOut("")
5641 while(il < fnumfiles):
5642 catfhstart = catfp.tell()
5643 if(formatspecs['new_style']):
5644 catheaderdata = ReadFileHeaderDataBySize(
5645 catfp, formatspecs['format_delimiter'])
5646 else:
5647 catheaderdata = ReadFileHeaderDataWoSize(
5648 catfp, formatspecs['format_delimiter'])
5649 if(len(catheaderdata) == 0):
5650 break
5651 catfheadsize = int(catheaderdata[0], 16)
5652 catfnumfields = int(catheaderdata[1], 16)
5653 catftype = int(catheaderdata[2], 16)
5654 if(re.findall("^[.|/]", catheaderdata[3])):
5655 catfname = catheaderdata[3]
5656 else:
5657 catfname = "./"+catheaderdata[3]
5658 catfbasedir = os.path.dirname(catfname)
5659 catflinkname = catheaderdata[4]
5660 catfsize = int(catheaderdata[5], 16)
5661 catfatime = int(catheaderdata[6], 16)
5662 catfmtime = int(catheaderdata[7], 16)
5663 catfctime = int(catheaderdata[8], 16)
5664 catfbtime = int(catheaderdata[9], 16)
5665 catfmode = int(catheaderdata[10], 16)
5666 catfchmode = stat.S_IMODE(catfmode)
5667 catftypemod = stat.S_IFMT(catfmode)
5668 catfwinattributes = int(catheaderdata[11], 16)
5669 catfcompression = catheaderdata[12]
5670 catfcsize = int(catheaderdata[13], 16)
5671 catfuid = int(catheaderdata[14], 16)
5672 catfuname = catheaderdata[15]
5673 catfgid = int(catheaderdata[16], 16)
5674 catfgname = catheaderdata[17]
5675 fid = int(catheaderdata[18], 16)
5676 finode = int(catheaderdata[19], 16)
5677 flinkcount = int(catheaderdata[20], 16)
5678 catfdev_minor = int(catheaderdata[21], 16)
5679 catfdev_major = int(catheaderdata[22], 16)
5680 catfrdev_minor = int(catheaderdata[23], 16)
5681 catfrdev_major = int(catheaderdata[24], 16)
5682 catfseeknextfile = catheaderdata[25]
5683 catfextrasize = int(catheaderdata[26], 16)
5684 catfextrafields = int(catheaderdata[27], 16)
5685 extrafieldslist = []
5686 extrastart = 28
5687 extraend = extrastart + catfextrafields
5688 extrafieldslist = []
5689 if(extrastart < extraend):
5690 extrafieldslist.append(catheaderdata[extrastart])
5691 extrastart = extrastart + 1
5692 catfcs = catheaderdata[-2].lower()
5693 catfccs = catheaderdata[-1].lower()
5694 catnewfcs = GetHeaderChecksum(
5695 catheaderdata[:-2], catheaderdata[-4].lower(), True, formatspecs)
5696 if(verbose):
5697 VerbosePrintOut(catfname)
5698 VerbosePrintOut("Record Number " + str(il) + "; File ID " +
5699 str(fid) + "; iNode Number " + str(finode))
5700 if(catfcs == catnewfcs):
5701 if(verbose):
5702 VerbosePrintOut(
5703 "File Header Checksum Passed at offset " + str(catfhstart))
5704 VerbosePrintOut("'" + str(catfcs) + "' == " +
5705 "'" + str(catnewfcs) + "'")
5706 else:
5707 if(verbose):
5708 VerbosePrintOut(
5709 "File Header Checksum Failed at offset " + str(catfhstart))
5710 VerbosePrintOut("'" + str(catfcs) + "' != " +
5711 "'" + str(catnewfcs) + "'")
5712 valid_archive = False
5713 invalid_archive = True
5714 catfhend = catfp.tell() - 1
5715 catfcontentstart = catfp.tell()
5716 catfcontents = ""
5717 pyhascontents = False
5718 if(catfsize > 0):
5719 if(catfcompression == "none" or catfcompression == "" or catfcompression == "auto"):
5720 catfcontents = catfp.read(catfsize)
5721 else:
5722 catfcontents = catfp.read(catfcsize)
5723 catnewfccs = GetFileChecksum(
5724 catfcontents, catheaderdata[-3].lower(), False, formatspecs)
5725 pyhascontents = True
5726 if(catfccs == catnewfccs):
5727 if(verbose):
5728 VerbosePrintOut(
5729 "File Content Checksum Passed at offset " + str(catfcontentstart))
5730 VerbosePrintOut("'" + str(catfccs) +
5731 "' == " + "'" + str(catnewfccs) + "'")
5732 else:
5733 if(verbose):
5734 VerbosePrintOut(
5735 "File Content Checksum Failed at offset " + str(catfcontentstart))
5736 VerbosePrintOut("'" + str(catfccs) +
5737 "' != " + "'" + str(catnewfccs) + "'")
5738 valid_archive = False
5739 invalid_archive = True
5740 if(verbose):
5741 VerbosePrintOut("")
5742 if(re.findall("^\\+([0-9]+)", catfseeknextfile)):
5743 fseeknextasnum = int(catfseeknextfile.replace("+", ""))
5744 if(abs(fseeknextasnum) == 0):
5745 pass
5746 catfp.seek(fseeknextasnum, 1)
5747 elif(re.findall("^\\-([0-9]+)", catfseeknextfile)):
5748 fseeknextasnum = int(catfseeknextfile)
5749 if(abs(fseeknextasnum) == 0):
5750 pass
5751 catfp.seek(fseeknextasnum, 1)
5752 elif(re.findall("^([0-9]+)", catfseeknextfile)):
5753 fseeknextasnum = int(catfseeknextfile)
5754 if(abs(fseeknextasnum) == 0):
5755 pass
5756 catfp.seek(fseeknextasnum, 0)
5757 else:
5758 return False
5759 il = il + 1
5760 if(valid_archive):
5761 if(returnfp):
5762 return catfp
5763 else:
5764 catfp.close()
5765 return True
5766 else:
5767 catfp.close()
5768 return False
5771 create_alias_function("", __file_format_name__,
5772 "Validate", ArchiveFileValidate)
5775 def ArchiveFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
5776 formatspecs = FormatSpecsListToDict(formatspecs)
5777 if(hasattr(infile, "read") or hasattr(infile, "write")):
5778 catfp = infile
5779 catfp.seek(0, 0)
5780 catfp = UncompressArchiveFile(catfp, formatspecs)
5781 checkcompressfile = CheckCompressionSubType(catfp, formatspecs, True)
5782 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
5783 return TarFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5784 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
5785 return ZipFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5786 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
5787 return RarFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5788 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
5789 return SevenZipFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
5790 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
5791 return False
5792 if(not catfp):
5793 return False
5794 catfp.seek(0, 0)
5795 elif(infile == "-"):
5796 catfp = BytesIO()
5797 if(hasattr(sys.stdin, "buffer")):
5798 shutil.copyfileobj(sys.stdin.buffer, catfp)
5799 else:
5800 shutil.copyfileobj(sys.stdin, catfp)
5801 catfp.seek(0, 0)
5802 catfp = UncompressArchiveFile(catfp, formatspecs)
5803 if(not catfp):
5804 return False
5805 catfp.seek(0, 0)
5806 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
5807 catfp = download_file_from_internet_file(infile)
5808 catfp = UncompressArchiveFile(catfp, formatspecs)
5809 catfp.seek(0, 0)
5810 if(not catfp):
5811 return False
5812 catfp.seek(0, 0)
5813 else:
5814 infile = RemoveWindowsPath(infile)
5815 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
5816 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
5817 return TarFileToArray(infile, seekstart, seekend, listonly, skipchecksum, formatspecs, returnfp)
5818 if(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
5819 return ZipFileToArray(infile, seekstart, seekend, listonly, skipchecksum, formatspecs, returnfp)
5820 if(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
5821 return RarFileToArray(infile, seekstart, seekend, listonly, skipchecksum, formatspecs, returnfp)
5822 if(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
5823 return SevenZipFileToArray(infile, seekstart, seekend, listonly, skipchecksum, formatspecs, returnfp)
5824 if(checkcompressfile != "catfile" and checkcompressfile != formatspecs['format_lower']):
5825 return False
5826 compresscheck = CheckCompressionType(infile, formatspecs, True)
5827 if(not compresscheck):
5828 fextname = os.path.splitext(infile)[1]
5829 if(fextname == ".gz"):
5830 compresscheck = "gzip"
5831 elif(fextname == ".bz2"):
5832 compresscheck = "bzip2"
5833 elif(fextname == ".zst"):
5834 compresscheck = "zstd"
5835 elif(fextname == ".lz4" or fextname == ".clz4"):
5836 compresscheck = "lz4"
5837 elif(fextname == ".lzo" or fextname == ".lzop"):
5838 compresscheck = "lzo"
5839 elif(fextname == ".lzma"):
5840 compresscheck = "lzma"
5841 elif(fextname == ".xz"):
5842 compresscheck = "xz"
5843 elif(fextname == ".zz" or fextname == ".zl" or fextname == ".zlib"):
5844 compresscheck = "zlib"
5845 else:
5846 return False
5847 if(not compresscheck):
5848 return False
5849 catfp = UncompressFile(infile, formatspecs, "rb")
5851 try:
5852 catfp.seek(0, 2);
5853 except OSError:
5854 SeekToEndOfFile(catfp);
5855 except ValueError:
5856 SeekToEndOfFile(catfp);
5857 CatSize = catfp.tell();
5858 CatSizeEnd = CatSize;
5860 try:
5861 catfp.seek(0, 0)
5862 except OSError:
5863 return False
5864 except ValueError:
5865 return False
5866 curloc = catfp.tell()
5867 if(curloc > 0):
5868 catfp.seek(0, 0)
5869 catheaderver = str(int(formatspecs['format_ver'].replace(".", "")))
5870 catstring = catfp.read(len(formatspecs['format_magic']+catheaderver)).decode("UTF-8")
5871 catdel = catfp.read(1).decode("UTF-8")
5872 if(catstring != formatspecs['format_magic']+catheaderver):
5873 return False
5874 if(catdel != formatspecs['format_delimiter']):
5875 return False
5876 catheader = ReadFileHeaderData(catfp, 3, formatspecs['format_delimiter'])
5877 if(curloc > 0):
5878 catfp.seek(curloc, 0)
5879 catversion = re.findall("([\\d]+)", catstring)
5880 fprenumfiles = catheader[0]
5881 fnumfiles = int(fprenumfiles, 16)
5882 fprechecksumtype = catheader[1]
5883 fprechecksum = catheader[2]
5884 fileheader = AppendNullByte(catstring, formatspecs['format_delimiter'])
5885 fnumfileshex = format(int(fnumfiles), 'x').lower()
5886 fileheader = fileheader + \
5887 AppendNullBytes([fnumfileshex, fprechecksumtype],
5888 formatspecs['format_delimiter'])
5889 catfileheadercshex = GetFileChecksum(
5890 fileheader, fprechecksumtype, True, formatspecs)
5891 fileheader = fileheader + \
5892 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
5893 fheadtell = len(fileheader)
5894 if(fprechecksum != catfileheadercshex and not skipchecksum):
5895 VerbosePrintOut(
5896 "File Header Checksum Error with file at offset " + str(0))
5897 VerbosePrintOut("'" + str(fprechecksum) + "' != " +
5898 "'" + str(catfileheadercshex) + "'")
5899 return False
5900 catversions = re.search('(.*?)(\\d+)', catstring).groups()
5901 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
5902 'fformatspecs': formatspecs, 'fchecksumtype': fprechecksumtype, 'fheaderchecksum': fprechecksum, 'ffilelist': []}
5903 if(seekstart < 0 and seekstart > fnumfiles):
5904 seekstart = 0
5905 if(seekend == 0 or seekend > fnumfiles and seekend < seekstart):
5906 seekend = fnumfiles
5907 elif(seekend < 0 and abs(seekend) <= fnumfiles and abs(seekend) >= seekstart):
5908 seekend = fnumfiles - abs(seekend)
5909 if(seekstart > 0):
5910 il = 0
5911 while(il < seekstart):
5912 prefhstart = catfp.tell()
5913 if(formatspecs['new_style']):
5914 preheaderdata = ReadFileHeaderDataBySize(
5915 catfp, formatspecs['format_delimiter'])
5916 else:
5917 preheaderdata = ReadFileHeaderDataWoSize(
5918 catfp, formatspecs['format_delimiter'])
5919 if(len(preheaderdata) == 0):
5920 break
5921 prefheadsize = int(preheaderdata[0], 16)
5922 prefnumfields = int(preheaderdata[1], 16)
5923 if(re.findall("^[.|/]", preheaderdata[3])):
5924 prefname = preheaderdata[3]
5925 else:
5926 prefname = "./"+preheaderdata[3]
5927 prefsize = int(preheaderdata[5], 16)
5928 prefcompression = preheaderdata[12]
5929 prefcsize = int(preheaderdata[13], 16)
5930 prefseeknextfile = preheaderdata[25]
5931 prefextrasize = int(preheaderdata[26], 16)
5932 prefextrafields = int(preheaderdata[27], 16)
5933 extrafieldslist = []
5934 extrastart = 28
5935 extraend = extrastart + prefextrafields
5936 extrafieldslist = []
5937 if(extrastart < extraend):
5938 extrafieldslist.append(preheaderdata[extrastart])
5939 extrastart = extrastart + 1
5940 prefcs = preheaderdata[-2].lower()
5941 prenewfcs = preheaderdata[-1].lower()
5942 prenewfcs = GetHeaderChecksum(
5943 preheaderdata[:-2], preheaderdata[-4].lower(), True, formatspecs)
5944 if(prefcs != prenewfcs and not skipchecksum):
5945 VerbosePrintOut("File Header Checksum Error with file " +
5946 prefname + " at offset " + str(prefhstart))
5947 VerbosePrintOut("'" + str(prefcs) + "' != " +
5948 "'" + str(prenewfcs) + "'")
5949 return False
5950 valid_archive = False
5951 invalid_archive = True
5952 prefhend = catfp.tell() - 1
5953 prefcontentstart = catfp.tell()
5954 prefcontents = ""
5955 pyhascontents = False
5956 if(prefsize > 0):
5957 if(prefcompression == "none" or prefcompression == "" or prefcompression == "auto"):
5958 prefcontents = catfp.read(prefsize)
5959 else:
5960 prefcontents = catfp.read(prefcsize)
5961 prenewfccs = GetFileChecksum(
5962 prefcontents, preheaderdata[-3].lower(), False, formatspecs)
5963 pyhascontents = True
5964 if(prefccs != prenewfccs and not skipchecksum):
5965 VerbosePrintOut("File Content Checksum Error with file " +
5966 prefname + " at offset " + str(prefcontentstart))
5967 VerbosePrintOut("'" + str(prefccs) +
5968 "' != " + "'" + str(prenewfccs) + "'")
5969 return False
5970 if(re.findall("^\\+([0-9]+)", prefseeknextfile)):
5971 fseeknextasnum = int(prefseeknextfile.replace("+", ""))
5972 if(abs(fseeknextasnum) == 0):
5973 pass
5974 catfp.seek(fseeknextasnum, 1)
5975 elif(re.findall("^\\-([0-9]+)", prefseeknextfile)):
5976 fseeknextasnum = int(prefseeknextfile)
5977 if(abs(fseeknextasnum) == 0):
5978 pass
5979 catfp.seek(fseeknextasnum, 1)
5980 elif(re.findall("^([0-9]+)", prefseeknextfile)):
5981 fseeknextasnum = int(prefseeknextfile)
5982 if(abs(fseeknextasnum) == 0):
5983 pass
5984 catfp.seek(fseeknextasnum, 0)
5985 else:
5986 return False
5987 il = il + 1
5988 fileidnum = seekstart
5989 realidnum = 0
5990 while(fileidnum < seekend):
5991 catfhstart = catfp.tell()
5992 if(formatspecs['new_style']):
5993 catheaderdata = ReadFileHeaderDataBySize(
5994 catfp, formatspecs['format_delimiter'])
5995 else:
5996 catheaderdata = ReadFileHeaderDataWoSize(
5997 catfp, formatspecs['format_delimiter'])
5998 if(len(catheaderdata) == 0):
5999 break
6000 catfheadsize = int(catheaderdata[0], 16)
6001 catfnumfields = int(catheaderdata[1], 16)
6002 catftype = int(catheaderdata[2], 16)
6003 if(re.findall("^[.|/]", catheaderdata[3])):
6004 catfname = catheaderdata[3]
6005 else:
6006 catfname = "./"+catheaderdata[3]
6007 catfbasedir = os.path.dirname(catfname)
6008 catflinkname = catheaderdata[4]
6009 catfsize = int(catheaderdata[5], 16)
6010 catfatime = int(catheaderdata[6], 16)
6011 catfmtime = int(catheaderdata[7], 16)
6012 catfctime = int(catheaderdata[8], 16)
6013 catfbtime = int(catheaderdata[9], 16)
6014 catfmode = int(catheaderdata[10], 16)
6015 catfchmode = stat.S_IMODE(catfmode)
6016 catftypemod = stat.S_IFMT(catfmode)
6017 catfwinattributes = int(catheaderdata[11], 16)
6018 catfcompression = catheaderdata[12]
6019 catfcsize = int(catheaderdata[13], 16)
6020 catfuid = int(catheaderdata[14], 16)
6021 catfuname = catheaderdata[15]
6022 catfgid = int(catheaderdata[16], 16)
6023 catfgname = catheaderdata[17]
6024 catfid = int(catheaderdata[18], 16)
6025 catfinode = int(catheaderdata[19], 16)
6026 catflinkcount = int(catheaderdata[20], 16)
6027 catfdev_minor = int(catheaderdata[21], 16)
6028 catfdev_major = int(catheaderdata[22], 16)
6029 catfrdev_minor = int(catheaderdata[23], 16)
6030 catfrdev_major = int(catheaderdata[24], 16)
6031 catfseeknextfile = catheaderdata[25]
6032 catfextrasize = int(catheaderdata[26], 16)
6033 catfextrafields = int(catheaderdata[27], 16)
6034 extrafieldslist = []
6035 extrastart = 28
6036 extraend = extrastart + catfextrafields
6037 extrafieldslist = []
6038 if(extrastart < extraend):
6039 extrafieldslist.append(catheaderdata[extrastart])
6040 extrastart = extrastart + 1
6041 catfcs = catheaderdata[-2].lower()
6042 catfccs = catheaderdata[-1].lower()
6043 catnewfcs = GetHeaderChecksum(
6044 catheaderdata[:-2], catheaderdata[-4].lower(), True, formatspecs)
6045 if(catfcs != catnewfcs and not skipchecksum):
6046 VerbosePrintOut("File Header Checksum Error with file " +
6047 catfname + " at offset " + str(catfhstart))
6048 VerbosePrintOut("'" + str(catfcs) + "' != " +
6049 "'" + str(catnewfcs) + "'")
6050 return False
6051 catfhend = catfp.tell() - 1
6052 catfcontentstart = catfp.tell()
6053 catfcontents = BytesIO()
6054 pyhascontents = False
6055 if(catfsize > 0 and not listonly):
6056 if(catfcompression == "none" or catfcompression == "" or catfcompression == "auto"):
6057 catfcontents.write(catfp.read(catfsize))
6058 else:
6059 catfcontents.write(catfp.read(catfcsize))
6060 catfcontents.seek(0, 0)
6061 catnewfccs = GetFileChecksum(
6062 catfcontents.read(), catheaderdata[-3].lower(), False, formatspecs)
6063 pyhascontents = True
6064 if(catfccs != catnewfccs and skipchecksum):
6065 VerbosePrintOut("File Content Checksum Error with file " +
6066 catfname + " at offset " + str(catfcontentstart))
6067 VerbosePrintOut("'" + str(catfccs) + "' != " +
6068 "'" + str(catnewfccs) + "'")
6069 return False
6070 if(catfcompression == "none" or catfcompression == "" or catfcompression == "auto"):
6071 pass
6072 else:
6073 catfcontents.seek(0, 0)
6074 if(uncompress):
6075 catfcontents = UncompressArchiveFile(
6076 catfcontents, formatspecs)
6077 catfcontents.seek(0, 0)
6078 catfccs = GetFileChecksum(
6079 catfcontents.read(), catheaderdata[-3].lower(), False, formatspecs)
6080 if(catfsize > 0 and listonly):
6081 if(catfcompression == "none" or catfcompression == "" or catfcompression == "auto"):
6082 catfp.seek(catfsize, 1)
6083 else:
6084 catfp.seek(catfcsize, 1)
6085 pyhascontents = False
6086 catfcontentend = catfp.tell()
6087 if(re.findall("^\\+([0-9]+)", catfseeknextfile)):
6088 fseeknextasnum = int(catfseeknextfile.replace("+", ""))
6089 if(abs(fseeknextasnum) == 0):
6090 pass
6091 catfp.seek(fseeknextasnum, 1)
6092 elif(re.findall("^\\-([0-9]+)", catfseeknextfile)):
6093 fseeknextasnum = int(catfseeknextfile)
6094 if(abs(fseeknextasnum) == 0):
6095 pass
6096 catfp.seek(fseeknextasnum, 1)
6097 elif(re.findall("^([0-9]+)", catfseeknextfile)):
6098 fseeknextasnum = int(catfseeknextfile)
6099 if(abs(fseeknextasnum) == 0):
6100 pass
6101 catfp.seek(fseeknextasnum, 0)
6102 else:
6103 return False
6104 catfcontents.seek(0, 0)
6105 if(not contentasfile):
6106 catfcontents = catfcontents.read()
6107 catlist['ffilelist'].append({'fid': realidnum, 'fidalt': fileidnum, 'fheadersize': catfheadsize, 'fhstart': catfhstart, 'fhend': catfhend, 'ftype': catftype, 'fname': catfname, 'fbasedir': catfbasedir, 'flinkname': catflinkname, 'fsize': catfsize, 'fatime': catfatime, 'fmtime': catfmtime, 'fctime': catfctime, 'fbtime': catfbtime, 'fmode': catfmode, 'fchmode': catfchmode, 'ftypemod': catftypemod, 'fwinattributes': catfwinattributes, 'fcompression': catfcompression, 'fcsize': catfcsize, 'fuid': catfuid, 'funame': catfuname, 'fgid': catfgid, 'fgname': catfgname, 'finode': catfinode, 'flinkcount': catflinkcount,
6108 'fminor': catfdev_minor, 'fmajor': catfdev_major, 'frminor': catfrdev_minor, 'frmajor': catfrdev_major, 'fseeknextfile': catfseeknextfile, 'fheaderchecksumtype': catheaderdata[-4], 'fcontentchecksumtype': catheaderdata[-3], 'fnumfields': catfnumfields + 2, 'frawheader': catheaderdata, 'fextrafields': catfextrafields, 'fextrafieldsize': catfextrasize, 'fextralist': extrafieldslist, 'fheaderchecksum': catfcs, 'fcontentchecksum': catfccs, 'fhascontents': pyhascontents, 'fcontentstart': catfcontentstart, 'fcontentend': catfcontentend, 'fcontentasfile': contentasfile, 'fcontents': catfcontents})
6109 fileidnum = fileidnum + 1
6110 realidnum = realidnum + 1
6111 if(returnfp):
6112 catlist.update({'catfp': catfp})
6113 else:
6114 catfp.close()
6115 return catlist
6118 create_alias_function("", __file_format_name__, "ToArray", ArchiveFileToArray)
6121 def ArchiveFileStringToArray(catstr, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6122 formatspecs = FormatSpecsListToDict(formatspecs)
6123 catfp = BytesIO(catstr)
6124 listcatfiles = ArchiveFileToArray(
6125 catfp, seekstart, seekend, listonly, contentasfile, True, skipchecksum, formatspecs, returnfp)
6126 return listcatfiles
6129 create_alias_function("", __file_format_name__,
6130 "StringToArray", ArchiveFileStringToArray)
6133 def TarFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6134 formatspecs = FormatSpecsListToDict(formatspecs)
6135 catfp = BytesIO()
6136 catfp = PackArchiveFileFromTarFile(
6137 infile, catfp, "auto", True, None, "crc32", [], formatspecs, False, True)
6138 listcatfiles = ArchiveFileToArray(
6139 catfp, seekstart, seekend, listonly, contentasfile, True, skipchecksum, formatspecs, returnfp)
6140 return listcatfiles
6143 def ZipFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6144 formatspecs = FormatSpecsListToDict(formatspecs)
6145 catfp = BytesIO()
6146 catfp = PackArchiveFileFromZipFile(
6147 infile, catfp, "auto", True, None, "crc32", [], formatspecs, False, True)
6148 listcatfiles = ArchiveFileToArray(
6149 catfp, seekstart, seekend, listonly, contentasfile, True, skipchecksum, formatspecs, returnfp)
6150 return listcatfiles
6153 if(not rarfile_support):
6154 def RarFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6155 return False
6157 if(rarfile_support):
6158 def RarFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6159 formatspecs = FormatSpecsListToDict(formatspecs)
6160 catfp = BytesIO()
6161 catfp = PackArchiveFileFromSevenZipFile(
6162 infile, catfp, "auto", True, None, "crc32", [], formatspecs, False, True)
6163 listcatfiles = ArchiveFileToArray(
6164 catfp, seekstart, seekend, listonly, contentasfile, True, skipchecksum, formatspecs, returnfp)
6165 return listcatfiles
6167 if(not py7zr_support):
6168 def SevenZipFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6169 return False
6171 if(py7zr_support):
6172 def SevenZipFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6173 formatspecs = FormatSpecsListToDict(formatspecs)
6174 catfp = BytesIO()
6175 catfp = PackArchiveFileFromSevenZipFile(
6176 infile, catfp, "auto", True, None, "crc32", [], formatspecs, False, True)
6177 listcatfiles = ArchiveFileToArray(
6178 catfp, seekstart, seekend, listonly, contentasfile, True, skipchecksum, formatspecs, returnfp)
6179 return listcatfiles
6182 def InFileToArray(infile, seekstart=0, seekend=0, listonly=False, contentasfile=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
6183 formatspecs = FormatSpecsListToDict(formatspecs)
6184 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
6185 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
6186 return TarFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
6187 elif(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
6188 return ZipFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
6189 elif(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
6190 return RarFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
6191 elif(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
6192 return SevenZipFileToArray(infile, seekstart, seekend, listonly, contentasfile, skipchecksum, formatspecs, returnfp)
6193 elif(checkcompressfile == "catfile"):
6194 return ArchiveFileToArray(infile, seekstart, seekend, listonly, contentasfile, True, skipchecksum, formatspecs, returnfp)
6195 else:
6196 return False
6197 return False
6200 def ListDirToArrayAlt(infiles, dirlistfromtxt=False, followlink=False, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
6201 formatspecs = FormatSpecsListToDict(formatspecs)
6202 catver = formatspecs['format_ver']
6203 fileheaderver = str(int(catver.replace(".", "")))
6204 fileheader = AppendNullByte(
6205 formatspecs['format_magic'] + fileheaderver, formatspecs['format_delimiter'])
6206 advancedlist = formatspecs['use_advanced_list']
6207 altinode = formatspecs['use_alt_inode']
6208 infilelist = []
6209 if(infiles == "-"):
6210 for line in sys.stdin:
6211 infilelist.append(line.strip())
6212 infilelist = list(filter(None, infilelist))
6213 elif(infiles != "-" and dirlistfromtxt and os.path.exists(infiles) and (os.path.isfile(infiles) or infiles == "/dev/null" or infiles == "NUL")):
6214 if(not os.path.exists(infiles) or not os.path.isfile(infiles)):
6215 return False
6216 with UncompressFile(infiles, formatspecs, "r") as finfile:
6217 for line in finfile:
6218 infilelist.append(line.strip())
6219 infilelist = list(filter(None, infilelist))
6220 else:
6221 if(isinstance(infiles, (list, tuple, ))):
6222 infilelist = list(filter(None, infiles))
6223 elif(isinstance(infiles, (str, ))):
6224 infilelist = list(filter(None, [infiles]))
6225 if(advancedlist):
6226 GetDirList = ListDirAdvanced(infilelist, followlink, False)
6227 else:
6228 GetDirList = ListDir(infilelist, followlink, False)
6229 if(not GetDirList):
6230 return False
6231 curinode = 0
6232 curfid = 0
6233 inodelist = []
6234 inodetofile = {}
6235 filetoinode = {}
6236 inodetocatinode = {}
6237 fileidnum = 0
6238 fnumfiles = int(len(GetDirList))
6239 catver = formatspecs['format_ver']
6240 fileheaderver = str(int(catver.replace(".", "")))
6241 fileheader = AppendNullByte(
6242 formatspecs['format_magic'] + fileheaderver, formatspecs['format_delimiter'])
6243 fnumfileshex = format(int(fnumfiles), 'x').lower()
6244 fileheader = fileheader + \
6245 AppendNullBytes([fnumfileshex, checksumtype],
6246 formatspecs['format_delimiter'])
6247 catversion = re.findall("([\\d]+)", fileheader)
6248 catversions = re.search('(.*?)(\\d+)', fileheader).groups()
6249 catfileheadercshex = GetFileChecksum(
6250 fileheader, checksumtype, True, formatspecs)
6251 fileheader = fileheader + \
6252 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
6253 fheadtell = len(fileheader)
6254 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
6255 'fformatspecs': formatspecs, 'fchecksumtype': checksumtype, 'fheaderchecksum': catfileheadercshex, 'ffilelist': []}
6256 for curfname in GetDirList:
6257 catfhstart = fheadtell
6258 if(re.findall("^[.|/]", curfname)):
6259 fname = curfname
6260 else:
6261 fname = "./"+curfname
6262 if(verbose):
6263 VerbosePrintOut(fname)
6264 if(not followlink or followlink is None):
6265 fstatinfo = os.lstat(fname)
6266 else:
6267 fstatinfo = os.stat(fname)
6268 fpremode = fstatinfo.st_mode
6269 finode = fstatinfo.st_ino
6270 flinkcount = fstatinfo.st_nlink
6271 ftype = 0
6272 if(stat.S_ISREG(fpremode)):
6273 ftype = 0
6274 elif(stat.S_ISLNK(fpremode)):
6275 ftype = 2
6276 elif(stat.S_ISCHR(fpremode)):
6277 ftype = 3
6278 elif(stat.S_ISBLK(fpremode)):
6279 ftype = 4
6280 elif(stat.S_ISDIR(fpremode)):
6281 ftype = 5
6282 elif(stat.S_ISFIFO(fpremode)):
6283 ftype = 6
6284 elif(stat.S_ISSOCK(fpremode)):
6285 ftype = 8
6286 elif(hasattr(stat, "S_ISDOOR") and stat.S_ISDOOR(fpremode)):
6287 ftype = 9
6288 elif(hasattr(stat, "S_ISPORT") and stat.S_ISPORT(fpremode)):
6289 ftype = 10
6290 elif(hasattr(stat, "S_ISWHT") and stat.S_ISWHT(fpremode)):
6291 ftype = 11
6292 else:
6293 ftype = 0
6294 flinkname = ""
6295 fbasedir = os.path.dirname(fname)
6296 fcurfid = curfid
6297 if(not followlink and finode != 0):
6298 if(ftype != 1):
6299 if(finode in inodelist):
6300 ftype = 1
6301 flinkname = inodetofile[finode]
6302 if(altinode):
6303 fcurinode = finode
6304 else:
6305 fcurinode = inodetocatinode[finode]
6306 if(finode not in inodelist):
6307 inodelist.append(finode)
6308 inodetofile.update({finode: fname})
6309 inodetocatinode.update({finode: curinode})
6310 if(altinode):
6311 fcurinode = finode
6312 else:
6313 fcurinode = curinode
6314 curinode = curinode + 1
6315 else:
6316 fcurinode = curinode
6317 curinode = curinode + 1
6318 curfid = curfid + 1
6319 if(ftype == 2):
6320 flinkname = os.readlink(fname)
6321 fdev = fstatinfo.st_dev
6322 getfdev = GetDevMajorMinor(fdev)
6323 fdev_minor = getfdev[0]
6324 fdev_major = getfdev[1]
6325 frdev = fstatinfo.st_dev
6326 if(hasattr(fstatinfo, "st_rdev")):
6327 frdev = fstatinfo.st_rdev
6328 else:
6329 frdev = fstatinfo.st_dev
6330 getfrdev = GetDevMajorMinor(frdev)
6331 frdev_minor = getfrdev[0]
6332 frdev_major = getfrdev[1]
6333 if(ftype == 1 or ftype == 2 or ftype == 3 or ftype == 4 or ftype == 5 or ftype == 6):
6334 fsize = "0"
6335 if(ftype == 0 or ftype == 7):
6336 fsize = fstatinfo.st_size
6337 fatime = fstatinfo.st_atime
6338 fmtime = fstatinfo.st_mtime
6339 fctime = fstatinfo.st_ctime
6340 if(hasattr(fstatinfo, "st_birthtime")):
6341 fbtime = fstatinfo.st_birthtime
6342 else:
6343 fbtime = fstatinfo.st_ctime
6344 fmode = fstatinfo.st_mode
6345 fchmode = stat.S_IMODE(fstatinfo.st_mode)
6346 ftypemod = stat.S_IFMT(fstatinfo.st_mode)
6347 fuid = fstatinfo.st_uid
6348 fgid = fstatinfo.st_gid
6349 funame = ""
6350 try:
6351 import pwd
6352 try:
6353 userinfo = pwd.getpwuid(fstatinfo.st_uid)
6354 funame = userinfo.pw_name
6355 except KeyError:
6356 funame = ""
6357 except ImportError:
6358 funame = ""
6359 fgname = ""
6360 try:
6361 import grp
6362 try:
6363 groupinfo = grp.getgrgid(fstatinfo.st_gid)
6364 fgname = groupinfo.gr_name
6365 except KeyError:
6366 fgname = ""
6367 except ImportError:
6368 fgname = ""
6369 fdev_minor = fdev_minor
6370 fdev_major = fdev_major
6371 frdev_minor = frdev_minor
6372 frdev_major = frdev_major
6373 flinkcount = flinkcount
6374 if(hasattr(fstatinfo, "st_file_attributes")):
6375 fwinattributes = fstatinfo.st_file_attributes
6376 else:
6377 fwinattributes = 0
6378 fcompression = ""
6379 fcsize = 0
6380 fcontents = BytesIO()
6381 if(ftype == 0 or ftype == 7):
6382 with open(fname, "rb") as fpc:
6383 shutil.copyfileobj(fpc, fcontents)
6384 if(followlink and (ftype == 1 or ftype == 2)):
6385 flstatinfo = os.stat(flinkname)
6386 with open(flinkname, "rb") as fpc:
6387 shutil.copyfileobj(fpc, fcontents)
6388 fcontents.seek(0, 0)
6389 ftypehex = format(ftype, 'x').lower()
6390 extrafields = len(extradata)
6391 extrafieldslist = extradata
6392 catfextrafields = extrafields
6393 extrasizestr = AppendNullByte(
6394 extrafields, formatspecs['format_delimiter'])
6395 if(len(extradata) > 0):
6396 extrasizestr = extrasizestr + \
6397 AppendNullBytes(extradata, formatspecs['format_delimiter'])
6398 extrasizelen = len(extrasizestr)
6399 extrasizelenhex = format(extrasizelen, 'x').lower()
6400 catoutlist = [ftypehex, fname, flinkname, format(int(fsize), 'x').lower(), format(int(fatime), 'x').lower(), format(int(fmtime), 'x').lower(), format(int(fctime), 'x').lower(), format(int(fbtime), 'x').lower(), format(int(fmode), 'x').lower(), format(int(fwinattributes), 'x').lower(), fcompression, format(int(fcsize), 'x').lower(), format(int(fuid), 'x').lower(
6401 ), funame, format(int(fgid), 'x').lower(), fgname, format(int(fcurfid), 'x').lower(), format(int(fcurinode), 'x').lower(), format(int(flinkcount), 'x').lower(), format(int(fdev_minor), 'x').lower(), format(int(fdev_major), 'x').lower(), format(int(frdev_minor), 'x').lower(), format(int(frdev_major), 'x').lower(), "+1", extrasizelenhex, format(catfextrafields, 'x').lower()]
6402 catoutlen = len(catoutlist) + len(extradata) + 3
6403 catoutlenhex = format(catoutlen, 'x').lower()
6404 catoutlist.insert(0, catoutlenhex)
6405 catfileoutstr = AppendNullBytes(
6406 catoutlist, formatspecs['format_delimiter'])
6407 catheaderdata = catoutlist
6408 if(len(extradata) > 0):
6409 catfileoutstr = catfileoutstr + \
6410 AppendNullBytes(extradata, formatspecs['format_delimiter'])
6411 if(fsize == 0):
6412 checksumlist = [checksumtype, "none"]
6413 else:
6414 checksumlist = [checksumtype, checksumtype]
6415 catfileoutstr = catfileoutstr + \
6416 AppendNullBytes(checksumlist, formatspecs['format_delimiter'])
6417 catfnumfields = catoutlen
6418 catfileheadercshex = GetFileChecksum(
6419 catfileoutstr, checksumtype, True, formatspecs)
6420 fcontents.seek(0, 0)
6421 if(fsize == 0):
6422 catfilecontentcshex = GetFileChecksum(
6423 fcontents.read(), "none", False, formatspecs)
6424 else:
6425 catfilecontentcshex = GetFileChecksum(
6426 fcontents.read(), checksumtype, False, formatspecs)
6427 tmpfileoutstr = catfileoutstr + \
6428 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
6429 formatspecs['format_delimiter'])
6430 catheaersize = format(int(len(tmpfileoutstr) - 1), 'x').lower()
6431 catfileoutstr = AppendNullByte(
6432 catheaersize, formatspecs['format_delimiter']) + catfileoutstr
6433 catfileheadercshex = GetFileChecksum(
6434 catfileoutstr, checksumtype, True, formatspecs)
6435 catfileoutstr = catfileoutstr + \
6436 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
6437 formatspecs['format_delimiter'])
6438 catfileoutstrecd = catfileoutstr.encode('UTF-8')
6439 nullstrecd = formatspecs['format_delimiter'].encode('UTF-8')
6440 catfcontentstart = fheadtell
6441 fheadtell += len(catfileoutstr) + 1
6442 catfcontentend = fheadtell - 1
6443 catfhend = catfcontentend
6444 fcontents.seek(0, 0)
6445 catfileout = catfileoutstrecd + fcontents.read() + nullstrecd
6446 pyhascontents = False
6447 if(int(fsize) > 0 and not listonly):
6448 pyhascontents = True
6449 if(int(fsize) > 0 and listonly):
6450 fcontents = BytesIO()
6451 pyhascontents = False
6452 fcontents.seek(0, 0)
6453 if(not contentasfile):
6454 fcontents = fcontents.read()
6455 catlist['ffilelist'].append({'fid': fileidnum, 'fidalt': fileidnum, 'fheadersize': int(catheaersize, 16), 'fhstart': catfhstart, 'fhend': catfhend, 'ftype': ftype, 'fname': fname, 'fbasedir': fbasedir, 'flinkname': flinkname, 'fsize': fsize, 'fatime': fatime, 'fmtime': fmtime, 'fctime': fctime, 'fbtime': fbtime, 'fmode': fmode, 'fchmode': fchmode, 'ftypemod': ftypemod, 'fwinattributes': fwinattributes, 'fcompression': fcompression, 'fcsize': fcsize, 'fuid': fuid, 'funame': funame, 'fgid': fgid, 'fgname': fgname, 'finode': finode, 'flinkcount': flinkcount, 'fminor': fdev_minor,
6456 'fmajor': fdev_major, 'frminor': frdev_minor, 'frmajor': frdev_major, 'fseeknextfile': "+1", 'fheaderchecksumtype': checksumtype, 'fcontentchecksumtype': checksumtype, 'fnumfields': catfnumfields + 2, 'frawheader': catheaderdata, 'fextrafields': catfextrafields, 'fextrafieldsize': extrasizelen, 'fextralist': extrafieldslist, 'fheaderchecksum': int(catfileheadercshex, 16), 'fcontentchecksum': int(catfilecontentcshex, 16), 'fhascontents': pyhascontents, 'fcontentstart': catfcontentstart, 'fcontentend': catfcontentend, 'fcontentasfile': contentasfile, 'fcontents': fcontents})
6457 fileidnum = fileidnum + 1
6458 return catlist
6461 def TarFileToArrayAlt(infile, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
6462 formatspecs = FormatSpecsListToDict(formatspecs)
6463 curinode = 0
6464 curfid = 0
6465 inodelist = []
6466 inodetofile = {}
6467 filetoinode = {}
6468 inodetocatinode = {}
6469 fileidnum = 0
6470 if(infile == "-"):
6471 infile = BytesIO()
6472 if(hasattr(sys.stdin, "buffer")):
6473 shutil.copyfileobj(sys.stdin.buffer, infile)
6474 else:
6475 shutil.copyfileobj(sys.stdin, infile)
6476 infile.seek(0, 0)
6477 if(not infile):
6478 return False
6479 infile.seek(0, 0)
6480 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
6481 infile = download_file_from_internet_file(infile)
6482 infile.seek(0, 0)
6483 if(not infile):
6484 return False
6485 infile.seek(0, 0)
6486 elif(not os.path.exists(infile) or not os.path.isfile(infile)):
6487 return False
6488 elif(os.path.exists(infile) and os.path.isfile(infile)):
6489 try:
6490 if(not tarfile.TarFileCheck(infile)):
6491 return False
6492 except AttributeError:
6493 if(not TarFileCheck(infile)):
6494 return False
6495 try:
6496 if(hasattr(infile, "read") or hasattr(infile, "write")):
6497 tarfp = tarfile.open(fileobj=infile, mode="r")
6498 else:
6499 tarfp = tarfile.open(infile, "r")
6500 except FileNotFoundError:
6501 return False
6502 fnumfiles = int(len(tarfp.getmembers()))
6503 catver = formatspecs['format_ver']
6504 fileheaderver = str(int(catver.replace(".", "")))
6505 fileheader = AppendNullByte(
6506 formatspecs['format_magic'] + fileheaderver, formatspecs['format_delimiter'])
6507 fnumfileshex = format(int(fnumfiles), 'x').lower()
6508 fileheader = fileheader + \
6509 AppendNullBytes([fnumfileshex, checksumtype],
6510 formatspecs['format_delimiter'])
6511 catversion = re.findall("([\\d]+)", fileheader)
6512 catversions = re.search('(.*?)(\\d+)', fileheader).groups()
6513 catfileheadercshex = GetFileChecksum(
6514 fileheader, checksumtype, True, formatspecs)
6515 fileheader = fileheader + \
6516 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
6517 fheadtell = len(fileheader)
6518 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
6519 'fformatspecs': formatspecs, 'fchecksumtype': checksumtype, 'fheaderchecksum': catfileheadercshex, 'ffilelist': []}
6520 for member in sorted(tarfp.getmembers(), key=lambda x: x.name):
6521 catfhstart = fheadtell
6522 if(re.findall("^[.|/]", member.name)):
6523 fname = member.name
6524 else:
6525 fname = "./"+member.name
6526 if(verbose):
6527 VerbosePrintOut(fname)
6528 fpremode = member.mode
6529 ffullmode = member.mode
6530 flinkcount = 0
6531 ftype = 0
6532 if(member.isreg()):
6533 ffullmode = member.mode + stat.S_IFREG
6534 ftype = 0
6535 elif(member.isdev()):
6536 ffullmode = member.mode
6537 ftype = 7
6538 elif(member.islnk()):
6539 ffullmode = member.mode + stat.S_IFREG
6540 ftype = 1
6541 elif(member.issym()):
6542 ffullmode = member.mode + stat.S_IFLNK
6543 ftype = 2
6544 elif(member.ischr()):
6545 ffullmode = member.mode + stat.S_IFCHR
6546 ftype = 3
6547 elif(member.isblk()):
6548 ffullmode = member.mode + stat.S_IFBLK
6549 ftype = 4
6550 elif(member.isdir()):
6551 ffullmode = member.mode + stat.S_IFDIR
6552 ftype = 5
6553 elif(member.isfifo()):
6554 ffullmode = member.mode + stat.S_IFIFO
6555 ftype = 6
6556 elif(member.issparse()):
6557 ffullmode = member.mode
6558 ftype = 12
6559 else:
6560 ffullmode = member.mode
6561 ftype = 0
6562 flinkname = ""
6563 fbasedir = os.path.dirname(fname)
6564 fcurfid = curfid
6565 fcurinode = curfid
6566 finode = fcurinode
6567 curfid = curfid + 1
6568 if(ftype == 2):
6569 flinkname = member.linkname
6570 fdev_minor = member.devminor
6571 fdev_major = member.devmajor
6572 frdev_minor = member.devminor
6573 frdev_major = member.devmajor
6574 if(ftype == 1 or ftype == 2 or ftype == 3 or ftype == 4 or ftype == 5 or ftype == 6):
6575 fsize = "0"
6576 elif(ftype == 0 or ftype == 7):
6577 fsize = member.size
6578 else:
6579 fsize = member.size
6580 fatime = member.mtime
6581 fmtime = member.mtime
6582 fctime = member.mtime
6583 fbtime = member.mtime
6584 fmode = ffullmode
6585 fchmode = stat.S_IMODE(ffullmode)
6586 ftypemod = stat.S_IFMT(ffullmode)
6587 fuid = member.uid
6588 fgid = member.gid
6589 funame = member.uname
6590 fgname = member.gname
6591 flinkcount = flinkcount
6592 fwinattributes = int(0)
6593 fcompression = ""
6594 fcsize = 0
6595 fcontents = BytesIO()
6596 if(ftype == 0 or ftype == 7):
6597 with tarfp.extractfile(member) as fpc:
6598 shutil.copyfileobj(fpc, fcontents)
6599 fcontents.seek(0, 0)
6600 ftypehex = format(ftype, 'x').lower()
6601 extrafields = len(extradata)
6602 extrafieldslist = extradata
6603 catfextrafields = extrafields
6604 extrasizestr = AppendNullByte(
6605 extrafields, formatspecs['format_delimiter'])
6606 if(len(extradata) > 0):
6607 extrasizestr = extrasizestr + \
6608 AppendNullBytes(extradata, formatspecs['format_delimiter'])
6609 extrasizelen = len(extrasizestr)
6610 extrasizelenhex = format(extrasizelen, 'x').lower()
6611 catoutlist = [ftypehex, fname, flinkname, format(int(fsize), 'x').lower(), format(int(fatime), 'x').lower(), format(int(fmtime), 'x').lower(), format(int(fctime), 'x').lower(), format(int(fbtime), 'x').lower(), format(int(fmode), 'x').lower(), format(int(fwinattributes), 'x').lower(), fcompression, format(int(fcsize), 'x').lower(), format(int(fuid), 'x').lower(
6612 ), funame, format(int(fgid), 'x').lower(), fgname, format(int(fcurfid), 'x').lower(), format(int(fcurinode), 'x').lower(), format(int(flinkcount), 'x').lower(), format(int(fdev_minor), 'x').lower(), format(int(fdev_major), 'x').lower(), format(int(frdev_minor), 'x').lower(), format(int(frdev_major), 'x').lower(), "+1", extrasizelenhex, format(catfextrafields, 'x').lower()]
6613 catoutlen = len(catoutlist) + len(extradata) + 3
6614 catoutlenhex = format(catoutlen, 'x').lower()
6615 catoutlist.insert(0, catoutlenhex)
6616 catfileoutstr = AppendNullBytes(
6617 catoutlist, formatspecs['format_delimiter'])
6618 catheaderdata = catoutlist
6619 if(len(extradata) > 0):
6620 catfileoutstr = catfileoutstr + \
6621 AppendNullBytes(extradata, formatspecs['format_delimiter'])
6622 if(fsize == 0):
6623 checksumlist = [checksumtype, "none"]
6624 else:
6625 checksumlist = [checksumtype, checksumtype]
6626 catfileoutstr = catfileoutstr + \
6627 AppendNullBytes(checksumlist, formatspecs['format_delimiter'])
6628 catfnumfields = catoutlen
6629 catfileheadercshex = GetFileChecksum(
6630 catfileoutstr, checksumtype, True, formatspecs)
6631 fcontents.seek(0, 0)
6632 if(fsize == 0):
6633 catfilecontentcshex = GetFileChecksum(
6634 fcontents.read(), "none", False, formatspecs)
6635 else:
6636 catfilecontentcshex = GetFileChecksum(
6637 fcontents.read(), checksumtype, False, formatspecs)
6638 tmpfileoutstr = catfileoutstr + \
6639 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
6640 formatspecs['format_delimiter'])
6641 catheaersize = format(int(len(tmpfileoutstr) - 1), 'x').lower()
6642 catfileoutstr = AppendNullByte(
6643 catheaersize, formatspecs['format_delimiter']) + catfileoutstr
6644 catfileheadercshex = GetFileChecksum(
6645 catfileoutstr, checksumtype, True, formatspecs)
6646 catfileoutstr = catfileoutstr + \
6647 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
6648 formatspecs['format_delimiter'])
6649 catfileoutstrecd = catfileoutstr.encode('UTF-8')
6650 nullstrecd = formatspecs['format_delimiter'].encode('UTF-8')
6651 catfcontentstart = fheadtell
6652 fheadtell += len(catfileoutstr) + 1
6653 catfcontentend = fheadtell - 1
6654 catfhend = catfcontentend
6655 fcontents.seek(0, 0)
6656 catfileout = catfileoutstrecd + fcontents.read() + nullstrecd
6657 pyhascontents = False
6658 if(int(fsize) > 0 and not listonly):
6659 pyhascontents = True
6660 if(int(fsize) > 0 and listonly):
6661 fcontents = BytesIO()
6662 pyhascontents = False
6663 fcontents.seek(0, 0)
6664 if(not contentasfile):
6665 fcontents = fcontents.read()
6666 catlist['ffilelist'].append({'fid': fileidnum, 'fidalt': fileidnum, 'fheadersize': int(catheaersize, 16), 'fhstart': catfhstart, 'fhend': catfhend, 'ftype': ftype, 'fname': fname, 'fbasedir': fbasedir, 'flinkname': flinkname, 'fsize': fsize, 'fatime': fatime, 'fmtime': fmtime, 'fctime': fctime, 'fbtime': fbtime, 'fmode': fmode, 'fchmode': fchmode, 'ftypemod': ftypemod, 'fwinattributes': fwinattributes, 'fcompression': fcompression, 'fcsize': fcsize, 'fuid': fuid, 'funame': funame, 'fgid': fgid, 'fgname': fgname, 'finode': finode, 'flinkcount': flinkcount, 'fminor': fdev_minor,
6667 'fmajor': fdev_major, 'frminor': frdev_minor, 'frmajor': frdev_major, 'fseeknextfile': "+1", 'fheaderchecksumtype': checksumtype, 'fcontentchecksumtype': checksumtype, 'fnumfields': catfnumfields + 2, 'frawheader': catheaderdata, 'fextrafields': catfextrafields, 'fextrafieldsize': extrasizelen, 'fextralist': extrafieldslist, 'fheaderchecksum': int(catfileheadercshex, 16), 'fcontentchecksum': int(catfilecontentcshex, 16), 'fhascontents': pyhascontents, 'fcontentstart': catfcontentstart, 'fcontentend': catfcontentend, 'fcontentasfile': contentasfile, 'fcontents': fcontents})
6668 fileidnum = fileidnum + 1
6669 return catlist
6672 def ZipFileToArrayAlt(infile, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
6673 formatspecs = FormatSpecsListToDict(formatspecs)
6674 curinode = 0
6675 curfid = 0
6676 inodelist = []
6677 inodetofile = {}
6678 filetoinode = {}
6679 inodetocatinode = {}
6680 fileidnum = 0
6681 if(infile == "-"):
6682 infile = BytesIO()
6683 if(hasattr(sys.stdin, "buffer")):
6684 shutil.copyfileobj(sys.stdin.buffer, infile)
6685 else:
6686 shutil.copyfileobj(sys.stdin, infile)
6687 infile.seek(0, 0)
6688 if(not infile):
6689 return False
6690 infile.seek(0, 0)
6691 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
6692 infile = download_file_from_internet_file(infile)
6693 infile.seek(0, 0)
6694 if(not infile):
6695 return False
6696 infile.seek(0, 0)
6697 elif(not os.path.exists(infile) or not os.path.isfile(infile)):
6698 return False
6699 if(not zipfile.is_zipfile(infile)):
6700 return False
6701 try:
6702 zipfp = zipfile.ZipFile(infile, "r", allowZip64=True)
6703 except FileNotFoundError:
6704 return False
6705 ziptest = zipfp.testzip()
6706 if(ziptest):
6707 VerbosePrintOut("Bad file found!")
6708 fnumfiles = int(len(zipfp.infolist()))
6709 catver = formatspecs['format_ver']
6710 fileheaderver = str(int(catver.replace(".", "")))
6711 fileheader = AppendNullByte(
6712 formatspecs['format_magic'] + fileheaderver, formatspecs['format_delimiter'])
6713 catversion = re.findall("([\\d]+)", fileheader)
6714 catversions = re.search('(.*?)(\\d+)', fileheader).groups()
6715 fnumfileshex = format(int(fnumfiles), 'x').lower()
6716 fileheader = fileheader + \
6717 AppendNullBytes([fnumfileshex, checksumtype],
6718 formatspecs['format_delimiter'])
6719 catfileheadercshex = GetFileChecksum(
6720 fileheader, checksumtype, True, formatspecs)
6721 fileheader = fileheader + \
6722 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
6723 fheadtell = len(fileheader)
6724 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
6725 'fformatspecs': formatspecs, 'fchecksumtype': checksumtype, 'fheaderchecksum': catfileheadercshex, 'ffilelist': []}
6726 for member in sorted(zipfp.infolist(), key=lambda x: x.filename):
6727 catfhstart = fheadtell
6728 if(re.findall("^[.|/]", member.filename)):
6729 fname = member.filename
6730 else:
6731 fname = "./"+member.filename
6732 zipinfo = zipfp.getinfo(member.filename)
6733 if(verbose):
6734 VerbosePrintOut(fname)
6735 if(not member.is_dir()):
6736 fpremode = stat.S_IFREG + 438
6737 elif(member.is_dir()):
6738 fpremode = stat.S_IFDIR + 511
6739 flinkcount = 0
6740 ftype = 0
6741 if(not member.is_dir()):
6742 ftype = 0
6743 elif(member.is_dir()):
6744 ftype = 5
6745 flinkname = ""
6746 fbasedir = os.path.dirname(fname)
6747 fcurfid = curfid
6748 fcurinode = curfid
6749 finode = fcurinode
6750 curfid = curfid + 1
6751 fdev_minor = 0
6752 fdev_major = 0
6753 frdev_minor = 0
6754 frdev_major = 0
6755 if(ftype == 5):
6756 fsize = "0"
6757 elif(ftype == 0):
6758 fsize = member.file_size
6759 else:
6760 fsize = member.file_size
6761 fatime = time.mktime(member.date_time + (0, 0, -1))
6762 fmtime = time.mktime(member.date_time + (0, 0, -1))
6763 fctime = time.mktime(member.date_time + (0, 0, -1))
6764 fbtime = time.mktime(member.date_time + (0, 0, -1))
6765 if(zipinfo.create_system == 0 or zipinfo.create_system == 10):
6766 fwinattributes = int(zipinfo.external_attr)
6767 if(not member.is_dir()):
6768 fmode = int(stat.S_IFREG + 438)
6769 fchmode = int(stat.S_IMODE(int(stat.S_IFREG + 438)))
6770 ftypemod = int(stat.S_IFMT(int(stat.S_IFREG + 438)))
6771 elif(member.is_dir()):
6772 fmode = int(stat.S_IFDIR + 511)
6773 fchmode = int(stat.S_IMODE(int(stat.S_IFDIR + 511)))
6774 ftypemod = int(stat.S_IFMT(int(stat.S_IFDIR + 511)))
6775 elif(zipinfo.create_system == 3):
6776 fwinattributes = int(0)
6777 try:
6778 fmode = int(zipinfo.external_attr)
6779 fchmode = stat.S_IMODE(fmode)
6780 ftypemod = stat.S_IFMT(fmode)
6781 except OverflowError:
6782 fmode = int(zipinfo.external_attr >> 16)
6783 fchmode = stat.S_IMODE(fmode)
6784 ftypemod = stat.S_IFMT(fmode)
6785 else:
6786 fwinattributes = int(0)
6787 if(not member.is_dir()):
6788 fmode = int(stat.S_IFREG + 438)
6789 fchmode = int(stat.S_IMODE(int(stat.S_IFREG + 438)))
6790 ftypemod = int(stat.S_IFMT(int(stat.S_IFREG + 438)))
6791 elif(member.is_dir()):
6792 fmode = int(stat.S_IFDIR + 511)
6793 fchmode = int(stat.S_IMODE(int(stat.S_IFDIR + 511)))
6794 ftypemod = int(stat.S_IFMT(int(stat.S_IFDIR + 511)))
6795 fcompression = ""
6796 fcsize = 0
6797 try:
6798 fuid = os.getuid()
6799 except AttributeError:
6800 fuid = 0
6801 except KeyError:
6802 fuid = 0
6803 try:
6804 fgid = os.getgid()
6805 except AttributeError:
6806 fgid = 0
6807 except KeyError:
6808 fgid = 0
6809 try:
6810 import pwd
6811 try:
6812 userinfo = pwd.getpwuid(os.getuid())
6813 funame = userinfo.pw_name
6814 except KeyError:
6815 funame = ""
6816 except AttributeError:
6817 funame = ""
6818 except ImportError:
6819 funame = ""
6820 fgname = ""
6821 try:
6822 import grp
6823 try:
6824 groupinfo = grp.getgrgid(os.getgid())
6825 fgname = groupinfo.gr_name
6826 except KeyError:
6827 fgname = ""
6828 except AttributeError:
6829 fgname = ""
6830 except ImportError:
6831 fgname = ""
6832 fcontents = BytesIO()
6833 if(ftype == 0):
6834 fcontents.write(zipfp.read(member.filename))
6835 fcontents.seek(0, 0)
6836 ftypehex = format(ftype, 'x').lower()
6837 extrafields = len(extradata)
6838 extrafieldslist = extradata
6839 catfextrafields = extrafields
6840 extrasizestr = AppendNullByte(
6841 extrafields, formatspecs['format_delimiter'])
6842 if(len(extradata) > 0):
6843 extrasizestr = extrasizestr + \
6844 AppendNullBytes(extradata, formatspecs['format_delimiter'])
6845 extrasizelen = len(extrasizestr)
6846 extrasizelenhex = format(extrasizelen, 'x').lower()
6847 catoutlist = [ftypehex, fname, flinkname, format(int(fsize), 'x').lower(), format(int(fatime), 'x').lower(), format(int(fmtime), 'x').lower(), format(int(fctime), 'x').lower(), format(int(fbtime), 'x').lower(), format(int(fmode), 'x').lower(), format(int(fwinattributes), 'x').lower(), fcompression, format(int(fcsize), 'x').lower(), format(int(fuid), 'x').lower(
6848 ), funame, format(int(fgid), 'x').lower(), fgname, format(int(fcurfid), 'x').lower(), format(int(fcurinode), 'x').lower(), format(int(flinkcount), 'x').lower(), format(int(fdev_minor), 'x').lower(), format(int(fdev_major), 'x').lower(), format(int(frdev_minor), 'x').lower(), format(int(frdev_major), 'x').lower(), "+1", extrasizelenhex, format(catfextrafields, 'x').lower()]
6849 catoutlen = len(catoutlist) + len(extradata) + 3
6850 catoutlenhex = format(catoutlen, 'x').lower()
6851 catoutlist.insert(0, catoutlenhex)
6852 catfileoutstr = AppendNullBytes(
6853 catoutlist, formatspecs['format_delimiter'])
6854 catheaderdata = catoutlist
6855 if(len(extradata) > 0):
6856 catfileoutstr = catfileoutstr + \
6857 AppendNullBytes(extradata, formatspecs['format_delimiter'])
6858 if(fsize == 0):
6859 checksumlist = [checksumtype, "none"]
6860 else:
6861 checksumlist = [checksumtype, checksumtype]
6862 catfileoutstr = catfileoutstr + \
6863 AppendNullBytes(checksumlist, formatspecs['format_delimiter'])
6864 catfnumfields = catoutlen
6865 catfileheadercshex = GetFileChecksum(
6866 catfileoutstr, checksumtype, True, formatspecs)
6867 fcontents.seek(0, 0)
6868 if(fsize == 0):
6869 catfilecontentcshex = GetFileChecksum(
6870 fcontents.read(), "none", False, formatspecs)
6871 else:
6872 catfilecontentcshex = GetFileChecksum(
6873 fcontents.read(), checksumtype, False, formatspecs)
6874 tmpfileoutstr = catfileoutstr + \
6875 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
6876 formatspecs['format_delimiter'])
6877 catheaersize = format(int(len(tmpfileoutstr) - 1), 'x').lower()
6878 catfileoutstr = AppendNullByte(
6879 catheaersize, formatspecs['format_delimiter']) + catfileoutstr
6880 catfileheadercshex = GetFileChecksum(
6881 catfileoutstr, checksumtype, True, formatspecs)
6882 catfileoutstr = catfileoutstr + \
6883 AppendNullBytes([catfileheadercshex, catfilecontentcshex],
6884 formatspecs['format_delimiter'])
6885 catfileoutstrecd = catfileoutstr.encode('UTF-8')
6886 nullstrecd = formatspecs['format_delimiter'].encode('UTF-8')
6887 catfcontentstart = fheadtell
6888 fheadtell += len(catfileoutstr) + 1
6889 catfcontentend = fheadtell - 1
6890 catfhend = catfcontentend
6891 fcontents.seek(0, 0)
6892 catfileout = catfileoutstrecd + fcontents.read() + nullstrecd
6893 pyhascontents = False
6894 if(int(fsize) > 0 and not listonly):
6895 pyhascontents = True
6896 if(int(fsize) > 0 and listonly):
6897 fcontents = BytesIO()
6898 pyhascontents = False
6899 fcontents.seek(0, 0)
6900 if(not contentasfile):
6901 fcontents = fcontents.read()
6902 catlist['ffilelist'].append({'fid': fileidnum, 'fidalt': fileidnum, 'fheadersize': int(catheaersize, 16), 'fhstart': catfhstart, 'fhend': catfhend, 'ftype': ftype, 'fname': fname, 'fbasedir': fbasedir, 'flinkname': flinkname, 'fsize': fsize, 'fatime': fatime, 'fmtime': fmtime, 'fctime': fctime, 'fbtime': fbtime, 'fmode': fmode, 'fchmode': fchmode, 'ftypemod': ftypemod, 'fwinattributes': fwinattributes, 'fcompression': fcompression, 'fcsize': fcsize, 'fuid': fuid, 'funame': funame, 'fgid': fgid, 'fgname': fgname, 'finode': finode, 'flinkcount': flinkcount, 'fminor': fdev_minor,
6903 'fmajor': fdev_major, 'frminor': frdev_minor, 'frmajor': frdev_major, 'fseeknextfile': "+1", 'fheaderchecksumtype': checksumtype, 'fcontentchecksumtype': checksumtype, 'fnumfields': catfnumfields + 2, 'frawheader': catheaderdata, 'fextrafields': catfextrafields, 'fextrafieldsize': extrasizelen, 'fextralist': extrafieldslist, 'fheaderchecksum': int(catfileheadercshex, 16), 'fcontentchecksum': int(catfilecontentcshex, 16), 'fhascontents': pyhascontents, 'fcontentstart': catfcontentstart, 'fcontentend': catfcontentend, 'fcontentasfile': contentasfile, 'fcontents': fcontents})
6904 fileidnum = fileidnum + 1
6905 return catlist
6908 if(not rarfile_support):
6909 def RarFileToArrayAlt(infile, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
6910 return False
6912 if(rarfile_support):
6913 def RarFileToArrayAlt(infile, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
6914 formatspecs = FormatSpecsListToDict(formatspecs)
6915 curinode = 0
6916 curfid = 0
6917 inodelist = []
6918 inodetofile = {}
6919 filetoinode = {}
6920 inodetocatinode = {}
6921 fileidnum = 0
6922 if(not os.path.exists(infile,) or not os.path.isfile(infile,)):
6923 return False
6924 if(not rarfile.is_rarfile(infile) and not rarfile.is_rarfile_sfx(infile)):
6925 return False
6926 rarfp = rarfile.RarFile(infile, "r")
6927 rartest = rarfp.testrar()
6928 if(rartest):
6929 VerbosePrintOut("Bad file found!")
6930 fnumfiles = int(len(rarfp.infolist()))
6931 catver = formatspecs['format_ver']
6932 fileheaderver = str(int(catver.replace(".", "")))
6933 fileheader = AppendNullByte(
6934 formatspecs['format_magic'] + fileheaderver, formatspecs['format_delimiter'])
6935 catversion = re.findall("([\\d]+)", fileheader)
6936 catversions = re.search('(.*?)(\\d+)', fileheader).groups()
6937 fnumfileshex = format(int(fnumfiles), 'x').lower()
6938 fileheader = fileheader + \
6939 AppendNullBytes([fnumfileshex, checksumtype],
6940 formatspecs['format_delimiter'])
6941 catfileheadercshex = GetFileChecksum(
6942 fileheader, checksumtype, True, formatspecs)
6943 fileheader = fileheader + \
6944 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
6945 fheadtell = len(fileheader)
6946 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
6947 'fformatspecs': formatspecs, 'fchecksumtype': checksumtype, 'fheaderchecksum': catfileheadercshex, 'ffilelist': []}
6948 for member in sorted(rarfp.infolist(), key=lambda x: x.filename):
6949 catfhstart = fheadtell
6950 is_unix = False
6951 is_windows = False
6952 if(member.host_os == rarfile.RAR_OS_UNIX):
6953 is_windows = False
6954 try:
6955 member.external_attr
6956 is_unix = True
6957 except AttributeError:
6958 is_unix = False
6959 elif(member.host_os == rarfile.RAR_OS_WIN32):
6960 is_unix = False
6961 try:
6962 member.external_attr
6963 is_windows = True
6964 except AttributeError:
6965 is_windows = False
6966 else:
6967 is_unix = False
6968 is_windows = False
6969 if(re.findall("^[.|/]", member.filename)):
6970 fname = member.filename
6971 else:
6972 fname = "./"+member.filename
6973 rarinfo = rarfp.getinfo(member.filename)
6974 if(verbose):
6975 VerbosePrintOut(fname)
6976 if(is_unix and member.external_attr != 0):
6977 fpremode = int(member.external_attr)
6978 elif(member.is_file()):
6979 fpremode = stat.S_IFREG + 438
6980 elif(member.is_symlink()):
6981 fpremode = stat.S_IFLNK + 438
6982 elif(member.is_dir()):
6983 fpremode = stat.S_IFDIR + 511
6984 if(is_windows and member.external_attr != 0):
6985 fwinattributes = int(member.external_attr)
6986 else:
6987 fwinattributes = int(0)
6988 fcompression = ""
6989 fcsize = 0
6990 flinkcount = 0
6991 ftype = 0
6992 if(member.is_file()):
6993 ftype = 0
6994 elif(member.is_symlink()):
6995 ftype = 2
6996 elif(member.is_dir()):
6997 ftype = 5
6998 flinkname = ""
6999 if(ftype == 2):
7000 flinkname = rarfp.read(member.filename).decode("UTF-8")
7001 fbasedir = os.path.dirname(fname)
7002 fcurfid = curfid
7003 fcurinode = curfid
7004 finode = fcurinode
7005 curfid = curfid + 1
7006 fdev_minor = 0
7007 fdev_major = 0
7008 frdev_minor = 0
7009 frdev_major = 0
7010 if(ftype == 5):
7011 fsize = "0"
7012 if(ftype == 0):
7013 fsize = member.file_size
7014 try:
7015 if(member.atime):
7016 fatime = int(member.atime.timestamp())
7017 else:
7018 fatime = int(member.mtime.timestamp())
7019 except AttributeError:
7020 fatime = int(member.mtime.timestamp())
7021 fmtime = int(member.mtime.timestamp())
7022 try:
7023 if(member.ctime):
7024 fctime = int(member.ctime.timestamp())
7025 else:
7026 fctime = int(member.mtime.timestamp())
7027 except AttributeError:
7028 fctime = int(member.mtime.timestamp())
7029 fbtime = int(member.mtime.timestamp())
7030 if(is_unix and member.external_attr != 0):
7031 fmode = int(member.external_attr)
7032 fchmode = int(stat.S_IMODE(member.external_attr))
7033 ftypemod = int(stat.S_IFMT(member.external_attr))
7034 elif(member.is_file()):
7035 fmode = int(stat.S_IFREG + 438)
7036 fchmode = int(stat.S_IMODE(stat.S_IFREG + 438))
7037 ftypemod = int(stat.S_IFMT(stat.S_IFREG + 438))
7038 elif(member.is_symlink()):
7039 fmode = int(stat.S_IFLNK + 438)
7040 fchmode = int(stat.S_IMODE(stat.S_IFREG + 438))
7041 ftypemod = int(stat.S_IFMT(stat.S_IFREG + 438))
7042 elif(member.is_dir()):
7043 fmode = int(stat.S_IFDIR + 511)
7044 fchmode = int(stat.S_IMODE(stat.S_IFDIR + 511))
7045 ftypemod = int(stat.S_IFMT(stat.S_IFDIR + 511))
7046 try:
7047 fuid = os.getuid()
7048 except AttributeError:
7049 fuid = 0
7050 except KeyError:
7051 fuid = 0
7052 try:
7053 fgid = os.getgid()
7054 except AttributeError:
7055 fgid = 0
7056 except KeyError:
7057 fgid = 0
7058 try:
7059 import pwd
7060 try:
7061 userinfo = pwd.getpwuid(os.getuid())
7062 funame = userinfo.pw_name
7063 except KeyError:
7064 funame = ""
7065 except AttributeError:
7066 funame = ""
7067 except ImportError:
7068 funame = ""
7069 fgname = ""
7070 try:
7071 import grp
7072 try:
7073 groupinfo = grp.getgrgid(os.getgid())
7074 fgname = groupinfo.gr_name
7075 except KeyError:
7076 fgname = ""
7077 except AttributeError:
7078 fgname = ""
7079 except ImportError:
7080 fgname = ""
7081 fcontents = BytesIO()
7082 if(ftype == 0):
7083 fcontents.write(rarfp.read(member.filename))
7084 fcontents.seek(0, 0)
7085 ftypehex = format(ftype, 'x').lower()
7086 extrafields = len(extradata)
7087 extrafieldslist = extradata
7088 catfextrafields = extrafields
7089 extrasizestr = AppendNullByte(
7090 extrafields, formatspecs['format_delimiter'])
7091 if(len(extradata) > 0):
7092 extrasizestr = extrasizestr + \
7093 AppendNullBytes(extradata, formatspecs['format_delimiter'])
7094 extrasizelen = len(extrasizestr)
7095 extrasizelenhex = format(extrasizelen, 'x').lower()
7096 catoutlist = [ftypehex, fname, flinkname, format(int(fsize), 'x').lower(), format(int(fatime), 'x').lower(), format(int(fmtime), 'x').lower(), format(int(fctime), 'x').lower(), format(int(fbtime), 'x').lower(), format(int(fmode), 'x').lower(), format(int(fwinattributes), 'x').lower(), fcompression, format(int(fcsize), 'x').lower(), format(int(fuid), 'x').lower(
7097 ), funame, format(int(fgid), 'x').lower(), fgname, format(int(fcurfid), 'x').lower(), format(int(fcurinode), 'x').lower(), format(int(flinkcount), 'x').lower(), format(int(fdev_minor), 'x').lower(), format(int(fdev_major), 'x').lower(), format(int(frdev_minor), 'x').lower(), format(int(frdev_major), 'x').lower(), "+1", extrasizelenhex, format(catfextrafields, 'x').lower()]
7098 catoutlen = len(catoutlist) + len(extradata) + 3
7099 catoutlenhex = format(catoutlen, 'x').lower()
7100 catoutlist.insert(0, catoutlenhex)
7101 catfileoutstr = AppendNullBytes(
7102 catoutlist, formatspecs['format_delimiter'])
7103 if(len(extradata) > 0):
7104 catfileoutstr = catfileoutstr + \
7105 AppendNullBytes(extradata, formatspecs['format_delimiter'])
7106 if(fsize == 0):
7107 checksumlist = [checksumtype, "none"]
7108 else:
7109 checksumlist = [checksumtype, checksumtype]
7110 ccatfileoutstr = catfileoutstr + \
7111 AppendNullBytes(checksumlist, formatspecs['format_delimiter'])
7112 catfnumfields = 24 + catfextrafields
7113 catfileheadercshex = GetFileChecksum(
7114 catfileoutstr, checksumtype, True, formatspecs)
7115 fcontents.seek(0, 0)
7116 if(fsize == 0):
7117 catfilecontentcshex = GetFileChecksum(
7118 fcontents.read(), "none", False, formatspecs)
7119 else:
7120 catfilecontentcshex = GetFileChecksum(
7121 fcontents.read(), checksumtype, False, formatspecs)
7122 tmpfileoutstr = catfileoutstr + \
7123 AppendNullBytes(
7124 [catfileheadercshex, catfilecontentcshex], formatspecs['format_delimiter'])
7125 catheaersize = format(int(len(tmpfileoutstr) - 1), 'x').lower()
7126 catfileoutstr = AppendNullByte(
7127 catheaersize, formatspecs['format_delimiter']) + catfileoutstr
7128 catfileheadercshex = GetFileChecksum(
7129 catfileoutstr, checksumtype, True, formatspecs)
7130 catfileoutstr = catfileoutstr + \
7131 AppendNullBytes(
7132 [catfileheadercshex, catfilecontentcshex], formatspecs['format_delimiter'])
7133 catheaderdata = catoutlist
7134 catfileoutstrecd = catfileoutstr.encode('UTF-8')
7135 nullstrecd = formatspecs['format_delimiter'].encode('UTF-8')
7136 catfcontentstart = fheadtell
7137 fheadtell += len(catfileoutstr) + 1
7138 catfcontentend = fheadtell - 1
7139 catfhend = catfcontentend
7140 fcontents.seek(0, 0)
7141 catfileout = catfileoutstrecd + fcontents.read() + nullstrecd
7142 pyhascontents = False
7143 if(int(fsize) > 0 and not listonly):
7144 pyhascontents = True
7145 if(int(fsize) > 0 and listonly):
7146 fcontents = BytesIO()
7147 pyhascontents = False
7148 fcontents.seek(0, 0)
7149 if(not contentasfile):
7150 fcontents = fcontents.read()
7151 catlist['ffilelist'].append({'fid': fileidnum, 'fidalt': fileidnum, 'fheadersize': int(catheaersize, 16), 'fhstart': catfhstart, 'fhend': catfhend, 'ftype': ftype, 'fname': fname, 'fbasedir': fbasedir, 'flinkname': flinkname, 'fsize': fsize, 'fatime': fatime, 'fmtime': fmtime, 'fctime': fctime, 'fbtime': fbtime, 'fmode': fmode, 'fchmode': fchmode, 'ftypemod': ftypemod, 'fwinattributes': fwinattributes, 'fcompression': fcompression, 'fcsize': fcsize, 'fuid': fuid, 'funame': funame, 'fgid': fgid, 'fgname': fgname, 'finode': finode, 'flinkcount': flinkcount, 'fminor': fdev_minor,
7152 'fmajor': fdev_major, 'frminor': frdev_minor, 'frmajor': frdev_major, 'fseeknextfile': "+1", 'fheaderchecksumtype': checksumtype, 'fcontentchecksumtype': checksumtype, 'fnumfields': catfnumfields + 2, 'frawheader': catheaderdata, 'fextrafields': catfextrafields, 'fextrafieldsize': extrasizelen, 'fextralist': extrafieldslist, 'fheaderchecksum': int(catfileheadercshex, 16), 'fcontentchecksum': int(catfilecontentcshex, 16), 'fhascontents': pyhascontents, 'fcontentstart': catfcontentstart, 'fcontentend': catfcontentend, 'fcontentasfile': contentasfile, 'fcontents': fcontents})
7153 fileidnum = fileidnum + 1
7154 return catlist
7156 if(not py7zr_support):
7157 def SevenZipFileToArrayAlt(infile, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
7158 return False
7160 if(py7zr_support):
7161 def SevenZipFileToArrayAlt(infile, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
7162 formatspecs = FormatSpecsListToDict(formatspecs)
7163 curinode = 0
7164 curfid = 0
7165 inodelist = []
7166 inodetofile = {}
7167 filetoinode = {}
7168 inodetocatinode = {}
7169 fileidnum = 0
7170 szpfp = py7zr.SevenZipFile(infile, mode="r")
7171 file_content = szpfp.readall()
7172 #sztest = szpfp.testzip();
7173 sztestalt = szpfp.test()
7174 if(sztestalt):
7175 VerbosePrintOut("Bad file found!")
7176 numfiles = int(len(szpfp.list()))
7177 catver = formatspecs['format_ver']
7178 fileheaderver = str(int(catver.replace(".", "")))
7179 fileheader = AppendNullByte(
7180 formatspecs['format_magic'] + fileheaderver, formatspecs['format_delimiter'])
7181 catversion = re.findall("([\\d]+)", fileheader)
7182 catversions = re.search('(.*?)(\\d+)', fileheader).groups()
7183 fnumfileshex = format(int(fnumfiles), 'x').lower()
7184 fileheader = fileheader + \
7185 AppendNullBytes([fnumfileshex, checksumtype],
7186 formatspecs['format_delimiter'])
7187 catfileheadercshex = GetFileChecksum(
7188 fileheader, checksumtype, True, formatspecs)
7189 fileheader = fileheader + \
7190 AppendNullByte(catfileheadercshex, formatspecs['format_delimiter'])
7191 fheadtell = len(fileheader)
7192 catlist = {'fnumfiles': fnumfiles, 'fformat': catversions[0], 'fversion': catversions[1],
7193 'fformatspecs': formatspecs, 'fchecksumtype': checksumtype, 'fheaderchecksum': catfileheadercshex, 'ffilelist': []}
7194 for member in sorted(szpfp.list(), key=lambda x: x.filename):
7195 catfhstart = fheadtell
7196 if(re.findall("^[.|/]", member.filename)):
7197 fname = member.filename
7198 else:
7199 fname = "./"+member.filename
7200 if(not member.is_directory):
7201 fpremode = int(stat.S_IFREG + 438)
7202 elif(member.is_directory):
7203 fpremode = int(stat.S_IFDIR + 511)
7204 fwinattributes = int(0)
7205 fcompression = ""
7206 fcsize = 0
7207 flinkcount = 0
7208 ftype = 0
7209 if(member.is_directory):
7210 ftype = 5
7211 else:
7212 ftype = 0
7213 flinkname = ""
7214 fbasedir = os.path.dirname(fname)
7215 fcurfid = curfid
7216 fcurinode = curfid
7217 finode = fcurinode
7218 curfid = curfid + 1
7219 fdev_minor = 0
7220 fdev_major = 0
7221 frdev_minor = 0
7222 frdev_major = 0
7223 if(ftype == 5):
7224 fsize = "0"
7225 fatime = int(member.creationtime.timestamp())
7226 fmtime = int(member.creationtime.timestamp())
7227 fctime = int(member.creationtime.timestamp())
7228 fbtime = int(member.creationtime.timestamp())
7229 if(member.is_directory):
7230 fmode = int(stat.S_IFDIR + 511)
7231 fchmode = int(stat.S_IMODE(stat.S_IFDIR + 511))
7232 ftypemod = int(stat.S_IFMT(stat.S_IFDIR + 511))
7233 else:
7234 fmode = int(stat.S_IFLNK + 438)
7235 fchmode = int(stat.S_IMODE(stat.S_IFREG + 438))
7236 ftypemod = int(stat.S_IFMT(stat.S_IFREG + 438))
7237 try:
7238 fuid = os.getuid()
7239 except AttributeError:
7240 fuid = 0
7241 except KeyError:
7242 fuid = 0
7243 try:
7244 fgid = os.getgid()
7245 except AttributeError:
7246 fgid = 0
7247 except KeyError:
7248 fgid = 0
7249 try:
7250 import pwd
7251 try:
7252 userinfo = pwd.getpwuid(os.getuid())
7253 funame = userinfo.pw_name
7254 except KeyError:
7255 funame = ""
7256 except AttributeError:
7257 funame = ""
7258 except ImportError:
7259 funame = ""
7260 fgname = ""
7261 try:
7262 import grp
7263 try:
7264 groupinfo = grp.getgrgid(os.getgid())
7265 fgname = groupinfo.gr_name
7266 except KeyError:
7267 fgname = ""
7268 except AttributeError:
7269 fgname = ""
7270 except ImportError:
7271 fgname = ""
7272 fcontents = BytesIO()
7273 if(ftype == 0):
7274 fcontents.write(file_content[member.filename].read())
7275 fsize = format(fcontents.tell(), 'x').lower()
7276 fileop.close()
7277 fcontents.seek(0, 0)
7278 ftypehex = format(ftype, 'x').lower()
7279 extrafields = len(extradata)
7280 extrafieldslist = extradata
7281 catfextrafields = extrafields
7282 extrasizestr = AppendNullByte(
7283 extrafields, formatspecs['format_delimiter'])
7284 if(len(extradata) > 0):
7285 extrasizestr = extrasizestr + \
7286 AppendNullBytes(extradata, formatspecs['format_delimiter'])
7287 extrasizelen = len(extrasizestr)
7288 extrasizelenhex = format(extrasizelen, 'x').lower()
7289 catoutlist = [ftypehex, fname, flinkname, format(int(fsize), 'x').lower(), format(int(fatime), 'x').lower(), format(int(fmtime), 'x').lower(), format(int(fctime), 'x').lower(), format(int(fbtime), 'x').lower(), format(int(fmode), 'x').lower(), format(int(fwinattributes), 'x').lower(), fcompression, format(int(fcsize), 'x').lower(), format(int(fuid), 'x').lower(
7290 ), funame, format(int(fgid), 'x').lower(), fgname, format(int(fcurfid), 'x').lower(), format(int(fcurinode), 'x').lower(), format(int(flinkcount), 'x').lower(), format(int(fdev_minor), 'x').lower(), format(int(fdev_major), 'x').lower(), format(int(frdev_minor), 'x').lower(), format(int(frdev_major), 'x').lower(), "+1", extrasizelenhex, format(catfextrafields, 'x').lower()]
7291 catoutlen = len(catoutlist) + len(extradata) + 3
7292 catoutlenhex = format(catoutlen, 'x').lower()
7293 catoutlist.insert(0, catoutlenhex)
7294 catfileoutstr = AppendNullBytes(
7295 catoutlist, formatspecs['format_delimiter'])
7296 catheaderdata = catoutlist
7297 if(len(extradata) > 0):
7298 catfileoutstr = catfileoutstr + \
7299 AppendNullBytes(extradata, formatspecs['format_delimiter'])
7300 if(fsize == 0):
7301 checksumlist = [checksumtype, "none"]
7302 else:
7303 checksumlist = [checksumtype, checksumtype]
7304 catfileoutstr = catfileoutstr + \
7305 AppendNullBytes(checksumlist, formatspecs['format_delimiter'])
7306 catfnumfields = 24 + catfextrafields
7307 catfileheadercshex = GetFileChecksum(
7308 catfileoutstr, checksumtype, True, formatspecs)
7309 fcontents.seek(0, 0)
7310 if(fsize == 0):
7311 catfilecontentcshex = GetFileChecksum(
7312 fcontents.read(), "none", False, formatspecs)
7313 else:
7314 catfilecontentcshex = GetFileChecksum(
7315 fcontents.read(), checksumtype, False, formatspecs)
7316 tmpfileoutstr = catfileoutstr + \
7317 AppendNullBytes(
7318 [catfileheadercshex, catfilecontentcshex], formatspecs['format_delimiter'])
7319 catheaersize = format(int(len(tmpfileoutstr) - 1), 'x').lower()
7320 catfileoutstr = AppendNullByte(
7321 catheaersize, formatspecs['format_delimiter']) + catfileoutstr
7322 catfileheadercshex = GetFileChecksum(
7323 catfileoutstr, checksumtype, True, formatspecs)
7324 catfileoutstr = catfileoutstr + \
7325 AppendNullBytes(
7326 [catfileheadercshex, catfilecontentcshex], formatspecs['format_delimiter'])
7327 catfileoutstrecd = catfileoutstr.encode('UTF-8')
7328 nullstrecd = formatspecs['format_delimiter'].encode('UTF-8')
7329 catfcontentstart = fheadtell
7330 fheadtell += len(catfileoutstr) + 1
7331 catfcontentend = fheadtell - 1
7332 catfhend = catfcontentend
7333 fcontents.seek(0, 0)
7334 catfileout = catfileoutstrecd + fcontents.read() + nullstrecd
7335 pyhascontents = False
7336 if(int(fsize) > 0 and not listonly):
7337 pyhascontents = True
7338 if(int(fsize) > 0 and listonly):
7339 fcontents = BytesIO()
7340 pyhascontents = False
7341 fcontents.seek(0, 0)
7342 if(not contentasfile):
7343 fcontents = fcontents.read()
7344 catlist['ffilelist'].append({'fid': fileidnum, 'fidalt': fileidnum, 'fheadersize': int(catheaersize, 16), 'fhstart': catfhstart, 'fhend': catfhend, 'ftype': ftype, 'fname': fname, 'fbasedir': fbasedir, 'flinkname': flinkname, 'fsize': fsize, 'fatime': fatime, 'fmtime': fmtime, 'fctime': fctime, 'fbtime': fbtime, 'fmode': fmode, 'fchmode': fchmode, 'ftypemod': ftypemod, 'fwinattributes': fwinattributes, 'fcompression': fcompression, 'fcsize': fcsize, 'fuid': fuid, 'funame': funame, 'fgid': fgid, 'fgname': fgname, 'finode': finode, 'flinkcount': flinkcount, 'fminor': fdev_minor,
7345 'fmajor': fdev_major, 'frminor': frdev_minor, 'frmajor': frdev_major, 'fseeknextfile': "+1", 'fheaderchecksumtype': checksumtype, 'fcontentchecksumtype': checksumtype, 'fnumfields': catfnumfields + 2, 'frawheader': catheaderdata, 'fextrafields': catfextrafields, 'fextrafieldsize': extrasizelen, 'fextralist': extrafieldslist, 'fheaderchecksum': int(catfileheadercshex, 16), 'fcontentchecksum': int(catfilecontentcshex, 16), 'fhascontents': pyhascontents, 'fcontentstart': catfcontentstart, 'fcontentend': catfcontentend, 'fcontentasfile': contentasfile, 'fcontents': fcontents})
7346 fileidnum = fileidnum + 1
7347 return catlist
7350 def InFileToArrayAlt(infile, listonly=False, contentasfile=True, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False):
7351 formatspecs = FormatSpecsListToDict(formatspecs)
7352 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
7353 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
7354 return TarFileToArrayAlt(infile, listonly, contentasfile, checksumtype, extradata, formatspecs, verbose)
7355 elif(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
7356 return ZipFileToArrayAlt(infile, listonly, contentasfile, checksumtype, extradata, formatspecs, verbose)
7357 elif(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
7358 return RarFileToArrayAlt(infile, listonly, contentasfile, checksumtype, extradata, formatspecs, verbose)
7359 elif(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
7360 return SevenZipFileToArrayAlt(infile, listonly, contentasfile, checksumtype, extradata, formatspecs, verbose)
7361 elif(checkcompressfile == "catfile"):
7362 return ArchiveFileToArray(infile, 0, 0, listonly, contentasfile, True, False, formatspecs, False)
7363 else:
7364 return False
7365 return False
7368 def ListDirToArray(infiles, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, seekstart=0, seekend=0, listonly=False, skipchecksum=False, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
7369 formatspecs = FormatSpecsListToDict(formatspecs)
7370 outarray = BytesIO()
7371 packcat = PackArchiveFile(infiles, outarray, dirlistfromtxt, compression, compresswholefile,
7372 compressionlevel, followlink, checksumtype, extradata, formatspecs, verbose, True)
7373 listcatfiles = ArchiveFileToArray(
7374 outarray, seekstart, seekend, listonly, True, skipchecksum, formatspecs, returnfp)
7375 return listcatfiles
7378 def ArchiveFileArrayToArrayIndex(inarray, seekstart=0, seekend=0, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__, returnfp=False):
7379 formatspecs = FormatSpecsListToDict(formatspecs)
7380 if(isinstance(inarray, dict)):
7381 listcatfiles = inarray
7382 else:
7383 return False
7384 if(not listcatfiles):
7385 return False
7386 catarray = {'list': listcatfiles, 'filetoid': {}, 'idtofile': {}, 'filetypes': {'directories': {'filetoid': {}, 'idtofile': {}}, 'files': {'filetoid': {}, 'idtofile': {}}, 'links': {'filetoid': {}, 'idtofile': {}}, 'symlinks': {'filetoid': {
7387 }, 'idtofile': {}}, 'hardlinks': {'filetoid': {}, 'idtofile': {}}, 'character': {'filetoid': {}, 'idtofile': {}}, 'block': {'filetoid': {}, 'idtofile': {}}, 'fifo': {'filetoid': {}, 'idtofile': {}}, 'devices': {'filetoid': {}, 'idtofile': {}}}}
7388 if(returnfp):
7389 catarray.update({'catfp': listcatfiles['catfp']})
7390 lenlist = len(listcatfiles['ffilelist'])
7391 lcfi = 0
7392 lcfx = int(listcatfiles['fnumfiles'])
7393 if(lenlist > listcatfiles['fnumfiles'] or lenlist < listcatfiles['fnumfiles']):
7394 lcfx = int(lenlist)
7395 else:
7396 lcfx = int(listcatfiles['fnumfiles'])
7397 while(lcfi < lcfx):
7398 filetoidarray = {listcatfiles['ffilelist'][lcfi]
7399 ['fname']: listcatfiles['ffilelist'][lcfi]['fid']}
7400 idtofilearray = {listcatfiles['ffilelist'][lcfi]
7401 ['fid']: listcatfiles['ffilelist'][lcfi]['fname']}
7402 catarray['filetoid'].update(filetoidarray)
7403 catarray['idtofile'].update(idtofilearray)
7404 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 0 or listcatfiles['ffilelist'][lcfi]['ftype'] == 7):
7405 catarray['filetypes']['files']['filetoid'].update(filetoidarray)
7406 catarray['filetypes']['files']['idtofile'].update(idtofilearray)
7407 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 1):
7408 catarray['filetypes']['hardlinks']['filetoid'].update(
7409 filetoidarray)
7410 catarray['filetypes']['hardlinks']['idtofile'].update(
7411 idtofilearray)
7412 catarray['filetypes']['links']['filetoid'].update(filetoidarray)
7413 catarray['filetypes']['links']['idtofile'].update(idtofilearray)
7414 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 2):
7415 catarray['filetypes']['symlinks']['filetoid'].update(filetoidarray)
7416 catarray['filetypes']['symlinks']['idtofile'].update(idtofilearray)
7417 catarray['filetypes']['links']['filetoid'].update(filetoidarray)
7418 catarray['filetypes']['links']['idtofile'].update(idtofilearray)
7419 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 3):
7420 catarray['filetypes']['character']['filetoid'].update(
7421 filetoidarray)
7422 catarray['filetypes']['character']['idtofile'].update(
7423 idtofilearray)
7424 catarray['filetypes']['devices']['filetoid'].update(filetoidarray)
7425 catarray['filetypes']['devices']['idtofile'].update(idtofilearray)
7426 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 4):
7427 catarray['filetypes']['block']['filetoid'].update(filetoidarray)
7428 catarray['filetypes']['block']['idtofile'].update(idtofilearray)
7429 catarray['filetypes']['devices']['filetoid'].update(filetoidarray)
7430 catarray['filetypes']['devices']['idtofile'].update(idtofilearray)
7431 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 5):
7432 catarray['filetypes']['directories']['filetoid'].update(
7433 filetoidarray)
7434 catarray['filetypes']['directories']['idtofile'].update(
7435 idtofilearray)
7436 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 6):
7437 catarray['filetypes']['symlinks']['filetoid'].update(filetoidarray)
7438 catarray['filetypes']['symlinks']['idtofile'].update(idtofilearray)
7439 catarray['filetypes']['devices']['filetoid'].update(filetoidarray)
7440 catarray['filetypes']['devices']['idtofile'].update(idtofilearray)
7441 lcfi = lcfi + 1
7442 return catarray
7445 create_alias_function("", __file_format_name__,
7446 "ArrayToArrayIndex", ArchiveFileArrayToArrayIndex)
7449 def RePackArchiveFile(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, seekstart=0, seekend=0, checksumtype="crc32", skipchecksum=False, extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
7450 formatspecs = FormatSpecsListToDict(formatspecs)
7451 if(isinstance(infile, dict)):
7452 listcatfiles = infile
7453 else:
7454 if(infile != "-" and not hasattr(infile, "read") and not hasattr(infile, "write")):
7455 infile = RemoveWindowsPath(infile)
7456 listcatfiles = ArchiveFileToArray(
7457 infile, seekstart, seekend, False, True, skipchecksum, formatspecs, returnfp)
7458 if(outfile != "-" and not hasattr(infile, "read") and not hasattr(outfile, "write")):
7459 outfile = RemoveWindowsPath(outfile)
7460 checksumtype = checksumtype.lower()
7461 if(not CheckSumSupport(checksumtype, hashlib_guaranteed)):
7462 checksumtype = "crc32"
7463 if(checksumtype == "none"):
7464 checksumtype = ""
7465 if(not compression or compression == "catfile" or compression == formatspecs['format_lower']):
7466 compression = "auto"
7467 if(compression not in compressionlist and compression is None):
7468 compression = "auto"
7469 if(verbose):
7470 logging.basicConfig(format="%(message)s",
7471 stream=sys.stdout, level=logging.DEBUG)
7472 if(outfile != "-" and not hasattr(outfile, "read") and not hasattr(outfile, "write")):
7473 if(os.path.exists(outfile)):
7474 try:
7475 os.unlink(outfile)
7476 except OSError as e:
7477 pass
7478 if(not listcatfiles):
7479 return False
7480 if(outfile == "-"):
7481 verbose = False
7482 catfp = BytesIO()
7483 elif(hasattr(outfile, "read") or hasattr(outfile, "write")):
7484 catfp = outfile
7485 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
7486 catfp = BytesIO()
7487 else:
7488 fbasename = os.path.splitext(outfile)[0]
7489 fextname = os.path.splitext(outfile)[1]
7490 if(not compresswholefile and fextname in outextlistwd):
7491 compresswholefile = True
7492 catfp = CompressOpenFile(outfile, compresswholefile, compressionlevel)
7493 catver = formatspecs['format_ver']
7494 fileheaderver = str(int(catver.replace(".", "")))
7495 lenlist = len(listcatfiles['ffilelist'])
7496 fnumfiles = int(listcatfiles['fnumfiles'])
7497 if(lenlist > fnumfiles or lenlist < fnumfiles):
7498 fnumfiles = lenlist
7499 AppendFileHeader(catfp, fnumfiles, checksumtype, formatspecs)
7500 lenlist = len(listcatfiles['ffilelist'])
7501 fnumfiles = int(listcatfiles['fnumfiles'])
7502 lcfi = 0
7503 lcfx = int(listcatfiles['fnumfiles'])
7504 if(lenlist > listcatfiles['fnumfiles'] or lenlist < listcatfiles['fnumfiles']):
7505 lcfx = int(lenlist)
7506 else:
7507 lcfx = int(listcatfiles['fnumfiles'])
7508 curinode = 0
7509 curfid = 0
7510 inodelist = []
7511 inodetofile = {}
7512 filetoinode = {}
7513 reallcfi = 0
7514 while(lcfi < lcfx):
7515 if(re.findall("^[.|/]", listcatfiles['ffilelist'][reallcfi]['fname'])):
7516 fname = listcatfiles['ffilelist'][reallcfi]['fname']
7517 else:
7518 fname = "./"+listcatfiles['ffilelist'][reallcfi]['fname']
7519 if(verbose):
7520 VerbosePrintOut(fname)
7521 fheadersize = format(
7522 int(listcatfiles['ffilelist'][reallcfi]['fheadersize']), 'x').lower()
7523 fsize = format(
7524 int(listcatfiles['ffilelist'][reallcfi]['fsize']), 'x').lower()
7525 flinkname = listcatfiles['ffilelist'][reallcfi]['flinkname']
7526 fatime = format(
7527 int(listcatfiles['ffilelist'][reallcfi]['fatime']), 'x').lower()
7528 fmtime = format(
7529 int(listcatfiles['ffilelist'][reallcfi]['fmtime']), 'x').lower()
7530 fctime = format(
7531 int(listcatfiles['ffilelist'][reallcfi]['fctime']), 'x').lower()
7532 fbtime = format(
7533 int(listcatfiles['ffilelist'][reallcfi]['fbtime']), 'x').lower()
7534 fmode = format(
7535 int(listcatfiles['ffilelist'][reallcfi]['fmode']), 'x').lower()
7536 fchmode = format(
7537 int(listcatfiles['ffilelist'][reallcfi]['fchmode']), 'x').lower()
7538 fuid = format(
7539 int(listcatfiles['ffilelist'][reallcfi]['fuid']), 'x').lower()
7540 funame = listcatfiles['ffilelist'][reallcfi]['funame']
7541 fgid = format(
7542 int(listcatfiles['ffilelist'][reallcfi]['fgid']), 'x').lower()
7543 fgname = listcatfiles['ffilelist'][reallcfi]['fgname']
7544 finode = format(
7545 int(listcatfiles['ffilelist'][reallcfi]['finode']), 'x').lower()
7546 flinkcount = format(
7547 int(listcatfiles['ffilelist'][reallcfi]['flinkcount']), 'x').lower()
7548 fwinattributes = format(
7549 int(listcatfiles['ffilelist'][reallcfi]['fwinattributes']), 'x').lower()
7550 fcompression = listcatfiles['ffilelist'][reallcfi]['fcompression']
7551 fcsize = format(
7552 int(listcatfiles['ffilelist'][reallcfi]['fcsize']), 'x').lower()
7553 fdev_minor = format(
7554 int(listcatfiles['ffilelist'][reallcfi]['fminor']), 'x').lower()
7555 fdev_major = format(
7556 int(listcatfiles['ffilelist'][reallcfi]['fmajor']), 'x').lower()
7557 frdev_minor = format(
7558 int(listcatfiles['ffilelist'][reallcfi]['frminor']), 'x').lower()
7559 frdev_major = format(
7560 int(listcatfiles['ffilelist'][reallcfi]['frmajor']), 'x').lower()
7561 fseeknextfile = listcatfiles['ffilelist'][reallcfi]['fseeknextfile']
7562 if(len(listcatfiles['ffilelist'][reallcfi]['fextralist']) > listcatfiles['ffilelist'][reallcfi]['fextrafields'] and len(listcatfiles['ffilelist'][reallcfi]['fextralist']) > 0):
7563 listcatfiles['ffilelist'][reallcfi]['fextrafields'] = len(
7564 listcatfiles['ffilelist'][reallcfi]['fextralist'])
7565 if(not followlink and len(extradata) < 0):
7566 extradata = listcatfiles['ffilelist'][reallcfi]['fextralist']
7567 fcontents = listcatfiles['ffilelist'][reallcfi]['fcontents']
7568 if(not listcatfiles['ffilelist'][reallcfi]['fcontentasfile']):
7569 fcontents = BytesIO(fcontents)
7570 fcompression = ""
7571 fcsize = format(int(0), 'x').lower()
7572 if(not compresswholefile):
7573 fcontents.seek(0, 2)
7574 ucfsize = fcontents.tell()
7575 fcontents.seek(0, 0)
7576 if(compression == "auto"):
7577 ilsize = len(compressionlistalt)
7578 ilmin = 0
7579 ilcsize = []
7580 while(ilmin < ilsize):
7581 cfcontents = BytesIO()
7582 shutil.copyfileobj(fcontents, cfcontents)
7583 fcontents.seek(0, 0)
7584 cfcontents.seek(0, 0)
7585 cfcontents = CompressArchiveFile(
7586 cfcontents, compressionlistalt[ilmin], compressionlevel, formatspecs)
7587 if(cfcontents):
7588 cfcontents.seek(0, 2)
7589 ilcsize.append(cfcontents.tell())
7590 cfcontents.close()
7591 else:
7592 try:
7593 ilcsize.append(sys.maxint)
7594 except AttributeError:
7595 ilcsize.append(sys.maxsize)
7596 ilmin = ilmin + 1
7597 ilcmin = ilcsize.index(min(ilcsize))
7598 compression = compressionlistalt[ilcmin]
7599 fcontents.seek(0, 0)
7600 cfcontents = BytesIO()
7601 shutil.copyfileobj(fcontents, cfcontents)
7602 cfcontents.seek(0, 0)
7603 cfcontents = CompressArchiveFile(
7604 cfcontents, compression, compressionlevel, formatspecs)
7605 cfcontents.seek(0, 2)
7606 cfsize = cfcontents.tell()
7607 if(ucfsize > cfsize):
7608 fcsize = format(int(cfsize), 'x').lower()
7609 fcompression = compression
7610 fcontents.close()
7611 fcontents = cfcontents
7612 if(followlink):
7613 if(listcatfiles['ffilelist'][reallcfi]['ftype'] == 1 or listcatfiles['ffilelist'][reallcfi]['ftype'] == 2):
7614 getflinkpath = listcatfiles['ffilelist'][reallcfi]['flinkname']
7615 flinkid = prelistcatfiles['filetoid'][getflinkpath]
7616 flinkinfo = listcatfiles['ffilelist'][flinkid]
7617 fheadersize = format(
7618 int(flinkinfo['fheadersize']), 'x').lower()
7619 fsize = format(int(flinkinfo['fsize']), 'x').lower()
7620 flinkname = flinkinfo['flinkname']
7621 fatime = format(int(flinkinfo['fatime']), 'x').lower()
7622 fmtime = format(int(flinkinfo['fmtime']), 'x').lower()
7623 fctime = format(int(flinkinfo['fctime']), 'x').lower()
7624 fbtime = format(int(flinkinfo['fbtime']), 'x').lower()
7625 fmode = format(int(flinkinfo['fmode']), 'x').lower()
7626 fchmode = format(int(flinkinfo['fchmode']), 'x').lower()
7627 fuid = format(int(flinkinfo['fuid']), 'x').lower()
7628 funame = flinkinfo['funame']
7629 fgid = format(int(flinkinfo['fgid']), 'x').lower()
7630 fgname = flinkinfo['fgname']
7631 finode = format(int(flinkinfo['finode']), 'x').lower()
7632 flinkcount = format(int(flinkinfo['flinkcount']), 'x').lower()
7633 fwinattributes = format(
7634 int(flinkinfo['fwinattributes']), 'x').lower()
7635 fcompression = flinkinfo['fcompression']
7636 fcsize = format(int(flinkinfo['fcsize']), 'x').lower()
7637 fdev_minor = format(int(flinkinfo['fminor']), 'x').lower()
7638 fdev_major = format(int(flinkinfo['fmajor']), 'x').lower()
7639 frdev_minor = format(int(flinkinfo['frminor']), 'x').lower()
7640 frdev_major = format(int(flinkinfo['frmajor']), 'x').lower()
7641 fseeknextfile = flinkinfo['fseeknextfile']
7642 if(len(flinkinfo['fextralist']) > flinkinfo['fextrafields'] and len(flinkinfo['fextralist']) > 0):
7643 flinkinfo['fextrafields'] = len(flinkinfo['fextralist'])
7644 if(len(extradata) < 0):
7645 extradata = flinkinfo['fextralist']
7646 fcontents = flinkinfo['fcontents']
7647 if(not flinkinfo['fcontentasfile']):
7648 fcontents = BytesIO(fcontents)
7649 ftypehex = format(flinkinfo['ftype'], 'x').lower()
7650 else:
7651 ftypehex = format(
7652 listcatfiles['ffilelist'][reallcfi]['ftype'], 'x').lower()
7653 fcurfid = format(curfid, 'x').lower()
7654 if(not followlink and finode != 0):
7655 if(listcatfiles['ffilelist'][reallcfi]['ftype'] != 1):
7656 fcurinode = format(int(curinode), 'x').lower()
7657 inodetofile.update({curinode: fname})
7658 filetoinode.update({fname: curinode})
7659 curinode = curinode + 1
7660 else:
7661 fcurinode = format(int(filetoinode[flinkname]), 'x').lower()
7662 else:
7663 fcurinode = format(int(curinode), 'x').lower()
7664 curinode = curinode + 1
7665 curfid = curfid + 1
7666 if(fcompression == "none"):
7667 fcompression = ""
7668 catoutlist = [ftypehex, fname, flinkname, fsize, fatime, fmtime, fctime, fbtime, fmode, fwinattributes, fcompression, fcsize,
7669 fuid, funame, fgid, fgname, fcurfid, fcurinode, flinkcount, fdev_minor, fdev_major, frdev_minor, frdev_major, fseeknextfile]
7670 catfp = AppendFileHeaderWithContent(
7671 catfp, catoutlist, extradata, fcontents.read(), checksumtype, formatspecs)
7672 fcontents.close()
7673 lcfi = lcfi + 1
7674 reallcfi = reallcfi + 1
7675 if(lcfx > 0):
7676 catfp.write(AppendNullBytes(
7677 [0, 0], formatspecs['format_delimiter']).encode("UTF-8"))
7678 if(outfile == "-" or hasattr(outfile, "read") or hasattr(outfile, "write")):
7679 catfp = CompressArchiveFile(
7680 catfp, compression, compressionlevel, formatspecs)
7681 try:
7682 catfp.flush()
7683 os.fsync(catfp.fileno())
7684 except io.UnsupportedOperation:
7685 pass
7686 except AttributeError:
7687 pass
7688 except OSError as e:
7689 pass
7690 if(outfile == "-"):
7691 catfp.seek(0, 0)
7692 if(hasattr(sys.stdout, "buffer")):
7693 shutil.copyfileobj(catfp, sys.stdout.buffer)
7694 else:
7695 shutil.copyfileobj(catfp, sys.stdout)
7696 elif(re.findall("^(ftp|ftps|sftp):\\/\\/", str(outfile))):
7697 catfp = CompressArchiveFile(
7698 catfp, compression, compressionlevel, formatspecs)
7699 catfp.seek(0, 0)
7700 upload_file_to_internet_file(catfp, outfile)
7701 if(returnfp):
7702 catfp.seek(0, 0)
7703 return catfp
7704 else:
7705 catfp.close()
7706 return True
7709 create_alias_function("RePack", __file_format_name__, "", RePackArchiveFile)
7712 def RePackArchiveFileFromString(catstr, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", skipchecksum=False, extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
7713 formatspecs = FormatSpecsListToDict(formatspecs)
7714 catfp = BytesIO(catstr)
7715 listcatfiles = RePackArchiveFile(catfp, compression, compresswholefile, compressionlevel,
7716 checksumtype, skipchecksum, extradata, formatspecs, verbose, returnfp)
7717 return listcatfiles
7720 create_alias_function("RePack", __file_format_name__,
7721 "FromString", RePackArchiveFileFromString)
7724 def PackArchiveFileFromListDir(infiles, outfile, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, skipchecksum=False, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
7725 formatspecs = FormatSpecsListToDict(formatspecs)
7726 outarray = BytesIO()
7727 packcat = PackArchiveFile(infiles, outarray, dirlistfromtxt, compression, compresswholefile,
7728 compressionlevel, followlink, checksumtype, extradata, formatspecs, verbose, True)
7729 listcatfiles = RePackArchiveFile(outarray, outfile, compression, compresswholefile,
7730 compressionlevel, checksumtype, skipchecksum, extradata, formatspecs, verbose, returnfp)
7731 return listcatfiles
7734 create_alias_function("Pack", __file_format_name__,
7735 "FromListDir", PackArchiveFileFromListDir)
7738 def UnPackArchiveFile(infile, outdir=None, followlink=False, seekstart=0, seekend=0, skipchecksum=False, formatspecs=__file_format_dict__, preservepermissions=True, preservetime=True, verbose=False, returnfp=False):
7739 formatspecs = FormatSpecsListToDict(formatspecs)
7740 if(outdir is not None):
7741 outdir = RemoveWindowsPath(outdir)
7742 if(verbose):
7743 logging.basicConfig(format="%(message)s",
7744 stream=sys.stdout, level=logging.DEBUG)
7745 if(isinstance(infile, dict)):
7746 listcatfiles = infile
7747 else:
7748 if(infile != "-" and not hasattr(infile, "read") and not hasattr(infile, "write")):
7749 infile = RemoveWindowsPath(infile)
7750 listcatfiles = ArchiveFileToArray(
7751 infile, seekstart, seekend, False, True, skipchecksum, formatspecs, returnfp)
7752 if(not listcatfiles):
7753 return False
7754 lenlist = len(listcatfiles['ffilelist'])
7755 fnumfiles = int(listcatfiles['fnumfiles'])
7756 lcfi = 0
7757 lcfx = int(listcatfiles['fnumfiles'])
7758 if(lenlist > listcatfiles['fnumfiles'] or lenlist < listcatfiles['fnumfiles']):
7759 lcfx = int(lenlist)
7760 else:
7761 lcfx = int(listcatfiles['fnumfiles'])
7762 while(lcfi < lcfx):
7763 funame = ""
7764 try:
7765 import pwd
7766 try:
7767 userinfo = pwd.getpwuid(
7768 listcatfiles['ffilelist'][lcfi]['fuid'])
7769 funame = userinfo.pw_name
7770 except KeyError:
7771 funame = ""
7772 except ImportError:
7773 funame = ""
7774 fgname = ""
7775 try:
7776 import grp
7777 try:
7778 groupinfo = grp.getgrgid(
7779 listcatfiles['ffilelist'][lcfi]['fgid'])
7780 fgname = groupinfo.gr_name
7781 except KeyError:
7782 fgname = ""
7783 except ImportError:
7784 fgname = ""
7785 if(verbose):
7786 VerbosePrintOut(PrependPath(
7787 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7788 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 0 or listcatfiles['ffilelist'][lcfi]['ftype'] == 7):
7789 with open(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), "wb") as fpc:
7790 if(not listcatfiles['ffilelist'][lcfi]['fcontentasfile']):
7791 listcatfiles['ffilelist'][lcfi]['fcontents'] = BytesIO(
7792 listcatfiles['ffilelist'][lcfi]['fcontents'])
7793 listcatfiles['ffilelist'][lcfi]['fcontents'].seek(0, 0)
7794 shutil.copyfileobj(
7795 listcatfiles['ffilelist'][lcfi]['fcontents'], fpc)
7796 try:
7797 fpc.flush()
7798 os.fsync(fpc.fileno())
7799 except io.UnsupportedOperation:
7800 pass
7801 except AttributeError:
7802 pass
7803 except OSError as e:
7804 pass
7805 if(hasattr(os, "chown") and funame == listcatfiles['ffilelist'][lcfi]['funame'] and fgname == listcatfiles['ffilelist'][lcfi]['fgname'] and preservepermissions):
7806 os.chown(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']),
7807 listcatfiles['ffilelist'][lcfi]['fuid'], listcatfiles['ffilelist'][lcfi]['fgid'])
7808 if(preservepermissions):
7809 os.chmod(PrependPath(
7810 outdir, listcatfiles['ffilelist'][lcfi]['fname']), listcatfiles['ffilelist'][lcfi]['fchmode'])
7811 if(preservetime):
7812 os.utime(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), (
7813 listcatfiles['ffilelist'][lcfi]['fatime'], listcatfiles['ffilelist'][lcfi]['fmtime']))
7814 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 1):
7815 if(followlink):
7816 getflinkpath = listcatfiles['ffilelist'][lcfi]['flinkname']
7817 flinkid = prelistcatfiles['filetoid'][getflinkpath]
7818 flinkinfo = listcatfiles['ffilelist'][flinkid]
7819 funame = ""
7820 try:
7821 import pwd
7822 try:
7823 userinfo = pwd.getpwuid(flinkinfo['fuid'])
7824 funame = userinfo.pw_name
7825 except KeyError:
7826 funame = ""
7827 except ImportError:
7828 funame = ""
7829 fgname = ""
7830 try:
7831 import grp
7832 try:
7833 groupinfo = grp.getgrgid(flinkinfo['fgid'])
7834 fgname = groupinfo.gr_name
7835 except KeyError:
7836 fgname = ""
7837 except ImportError:
7838 fgname = ""
7839 if(flinkinfo['ftype'] == 0 or flinkinfo['ftype'] == 7):
7840 with open(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), "wb") as fpc:
7841 if(not flinkinfo['fcontentasfile']):
7842 flinkinfo['fcontents'] = BytesIO(
7843 flinkinfo['fcontents'])
7844 flinkinfo['fcontents'].seek(0, 0)
7845 shutil.copyfileobj(flinkinfo['fcontents'], fpc)
7846 try:
7847 fpc.flush()
7848 os.fsync(fpc.fileno())
7849 except io.UnsupportedOperation:
7850 pass
7851 except AttributeError:
7852 pass
7853 except OSError as e:
7854 pass
7855 if(hasattr(os, "chown") and funame == flinkinfo['funame'] and fgname == flinkinfo['fgname'] and preservepermissions):
7856 os.chown(PrependPath(
7857 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fuid'], flinkinfo['fgid'])
7858 if(preservepermissions):
7859 os.chmod(PrependPath(
7860 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7861 if(preservetime):
7862 os.utime(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), (
7863 flinkinfo['fatime'], flinkinfo['fmtime']))
7864 if(flinkinfo['ftype'] == 1):
7865 os.link(flinkinfo['flinkname'], PrependPath(
7866 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7867 if(flinkinfo['ftype'] == 2):
7868 os.symlink(flinkinfo['flinkname'], PrependPath(
7869 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7870 if(flinkinfo['ftype'] == 5):
7871 if(preservepermissions):
7872 os.mkdir(PrependPath(
7873 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7874 else:
7875 os.mkdir(PrependPath(
7876 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7877 if(hasattr(os, "chown") and funame == flinkinfo['funame'] and fgname == flinkinfo['fgname'] and preservepermissions):
7878 os.chown(PrependPath(
7879 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fuid'], flinkinfo['fgid'])
7880 if(preservepermissions):
7881 os.chmod(PrependPath(
7882 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7883 if(preservetime):
7884 os.utime(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), (
7885 flinkinfo['fatime'], flinkinfo['fmtime']))
7886 if(flinkinfo['ftype'] == 6 and hasattr(os, "mkfifo")):
7887 os.mkfifo(PrependPath(
7888 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7889 else:
7890 os.link(listcatfiles['ffilelist'][lcfi]['flinkname'], PrependPath(
7891 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7892 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 2):
7893 if(followlink):
7894 getflinkpath = listcatfiles['ffilelist'][lcfi]['flinkname']
7895 flinkid = prelistcatfiles['filetoid'][getflinkpath]
7896 flinkinfo = listcatfiles['ffilelist'][flinkid]
7897 funame = ""
7898 try:
7899 import pwd
7900 try:
7901 userinfo = pwd.getpwuid(flinkinfo['fuid'])
7902 funame = userinfo.pw_name
7903 except KeyError:
7904 funame = ""
7905 except ImportError:
7906 funame = ""
7907 fgname = ""
7908 try:
7909 import grp
7910 try:
7911 groupinfo = grp.getgrgid(flinkinfo['fgid'])
7912 fgname = groupinfo.gr_name
7913 except KeyError:
7914 fgname = ""
7915 except ImportError:
7916 fgname = ""
7917 if(flinkinfo['ftype'] == 0 or flinkinfo['ftype'] == 7):
7918 with open(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), "wb") as fpc:
7919 if(not flinkinfo['fcontentasfile']):
7920 flinkinfo['fcontents'] = BytesIO(
7921 flinkinfo['fcontents'])
7922 flinkinfo['fcontents'].seek(0, 0)
7923 shutil.copyfileobj(flinkinfo['fcontents'], fpc)
7924 try:
7925 fpc.flush()
7926 os.fsync(fpc.fileno())
7927 except io.UnsupportedOperation:
7928 pass
7929 except AttributeError:
7930 pass
7931 except OSError as e:
7932 pass
7933 if(hasattr(os, "chown") and funame == flinkinfo['funame'] and fgname == flinkinfo['fgname'] and preservepermissions):
7934 os.chown(PrependPath(
7935 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fuid'], flinkinfo['fgid'])
7936 if(preservepermissions):
7937 os.chmod(PrependPath(
7938 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7939 if(preservetime):
7940 os.utime(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), (
7941 flinkinfo['fatime'], flinkinfo['fmtime']))
7942 if(flinkinfo['ftype'] == 1):
7943 os.link(flinkinfo['flinkname'], PrependPath(
7944 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7945 if(flinkinfo['ftype'] == 2):
7946 os.symlink(flinkinfo['flinkname'], PrependPath(
7947 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7948 if(flinkinfo['ftype'] == 5):
7949 if(preservepermissions):
7950 os.mkdir(PrependPath(
7951 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7952 else:
7953 os.mkdir(PrependPath(
7954 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7955 if(hasattr(os, "chown") and funame == flinkinfo['funame'] and fgname == flinkinfo['fgname'] and preservepermissions):
7956 os.chown(PrependPath(
7957 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fuid'], flinkinfo['fgid'])
7958 if(preservepermissions):
7959 os.chmod(PrependPath(
7960 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7961 if(preservetime):
7962 os.utime(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), (
7963 flinkinfo['fatime'], flinkinfo['fmtime']))
7964 if(flinkinfo['ftype'] == 6 and hasattr(os, "mkfifo")):
7965 os.mkfifo(PrependPath(
7966 outdir, listcatfiles['ffilelist'][lcfi]['fname']), flinkinfo['fchmode'])
7967 else:
7968 os.symlink(listcatfiles['ffilelist'][lcfi]['flinkname'], PrependPath(
7969 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7970 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 5):
7971 if(preservepermissions):
7972 os.mkdir(PrependPath(
7973 outdir, listcatfiles['ffilelist'][lcfi]['fname']), listcatfiles['ffilelist'][lcfi]['fchmode'])
7974 else:
7975 os.mkdir(PrependPath(
7976 outdir, listcatfiles['ffilelist'][lcfi]['fname']))
7977 if(hasattr(os, "chown") and funame == listcatfiles['ffilelist'][lcfi]['funame'] and fgname == listcatfiles['ffilelist'][lcfi]['fgname'] and preservepermissions):
7978 os.chown(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']),
7979 listcatfiles['ffilelist'][lcfi]['fuid'], listcatfiles['ffilelist'][lcfi]['fgid'])
7980 if(preservepermissions):
7981 os.chmod(PrependPath(
7982 outdir, listcatfiles['ffilelist'][lcfi]['fname']), listcatfiles['ffilelist'][lcfi]['fchmode'])
7983 if(preservetime):
7984 os.utime(PrependPath(outdir, listcatfiles['ffilelist'][lcfi]['fname']), (
7985 listcatfiles['ffilelist'][lcfi]['fatime'], listcatfiles['ffilelist'][lcfi]['fmtime']))
7986 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 6 and hasattr(os, "mkfifo")):
7987 os.mkfifo(PrependPath(
7988 outdir, listcatfiles['ffilelist'][lcfi]['fname']), listcatfiles['ffilelist'][lcfi]['fchmode'])
7989 lcfi = lcfi + 1
7990 if(returnfp):
7991 return listcatfiles['ffilelist']['catfp']
7992 else:
7993 return True
7996 create_alias_function("UnPack", __file_format_name__, "", UnPackArchiveFile)
7998 if(hasattr(shutil, "register_unpack_format")):
7999 def UnPackArchiveFileFunc(archive_name, extract_dir=None, **kwargs):
8000 return UnPackArchiveFile(archive_name, extract_dir, False, 0, 0, False, __file_format_dict__['format_delimiter'], False, False)
8001 create_alias_function("UnPack", __file_format_name__,
8002 "Func", UnPackArchiveFileFunc)
8005 def UnPackArchiveFileString(catstr, outdir=None, followlink=False, seekstart=0, seekend=0, skipchecksum=False, formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8006 formatspecs = FormatSpecsListToDict(formatspecs)
8007 catfp = BytesIO(catstr)
8008 listcatfiles = UnPackArchiveFile(
8009 catfp, outdir, followlink, seekstart, seekend, skipchecksum, formatspecs, verbose, returnfp)
8010 return listcatfiles
8013 create_alias_function("UnPack", __file_format_name__,
8014 "String", UnPackArchiveFileString)
8017 def ArchiveFileListFiles(infile, seekstart=0, seekend=0, skipchecksum=False, formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8018 formatspecs = FormatSpecsListToDict(formatspecs)
8019 logging.basicConfig(format="%(message)s",
8020 stream=sys.stdout, level=logging.DEBUG)
8021 if(isinstance(infile, dict)):
8022 listcatfiles = infile
8023 else:
8024 if(infile != "-" and not hasattr(infile, "read") and not hasattr(infile, "write")):
8025 infile = RemoveWindowsPath(infile)
8026 listcatfiles = ArchiveFileToArray(
8027 infile, seekstart, seekend, True, False, skipchecksum, formatspecs, returnfp)
8028 if(not listcatfiles):
8029 return False
8030 lenlist = len(listcatfiles['ffilelist'])
8031 fnumfiles = int(listcatfiles['fnumfiles'])
8032 lcfi = 0
8033 lcfx = int(listcatfiles['fnumfiles'])
8034 if(lenlist > listcatfiles['fnumfiles'] or lenlist < listcatfiles['fnumfiles']):
8035 lcfx = int(lenlist)
8036 else:
8037 lcfx = int(listcatfiles['fnumfiles'])
8038 returnval = {}
8039 while(lcfi < lcfx):
8040 returnval.update({lcfi: listcatfiles['ffilelist'][lcfi]['fname']})
8041 if(not verbose):
8042 VerbosePrintOut(listcatfiles['ffilelist'][lcfi]['fname'])
8043 if(verbose):
8044 permissions = {'access': {'0': ('---'), '1': ('--x'), '2': ('-w-'), '3': ('-wx'), '4': (
8045 'r--'), '5': ('r-x'), '6': ('rw-'), '7': ('rwx')}, 'roles': {0: 'owner', 1: 'group', 2: 'other'}}
8046 printfname = listcatfiles['ffilelist'][lcfi]['fname']
8047 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 1):
8048 printfname = listcatfiles['ffilelist'][lcfi]['fname'] + \
8049 " link to " + listcatfiles['ffilelist'][lcfi]['flinkname']
8050 if(listcatfiles['ffilelist'][lcfi]['ftype'] == 2):
8051 printfname = listcatfiles['ffilelist'][lcfi]['fname'] + \
8052 " -> " + listcatfiles['ffilelist'][lcfi]['flinkname']
8053 fuprint = listcatfiles['ffilelist'][lcfi]['funame']
8054 if(len(fuprint) <= 0):
8055 fuprint = listcatfiles['ffilelist'][lcfi]['fuid']
8056 fgprint = listcatfiles['ffilelist'][lcfi]['fgname']
8057 if(len(fgprint) <= 0):
8058 fgprint = listcatfiles['ffilelist'][lcfi]['fgid']
8059 VerbosePrintOut(PrintPermissionString(listcatfiles['ffilelist'][lcfi]['fmode'], listcatfiles['ffilelist'][lcfi]['ftype']) + " " + str(str(fuprint) + "/" + str(fgprint) + " " + str(
8060 listcatfiles['ffilelist'][lcfi]['fsize']).rjust(15) + " " + datetime.datetime.utcfromtimestamp(listcatfiles['ffilelist'][lcfi]['fmtime']).strftime('%Y-%m-%d %H:%M') + " " + printfname))
8061 lcfi = lcfi + 1
8062 if(returnfp):
8063 return listcatfiles['catfp']
8064 else:
8065 return True
8068 create_alias_function("", __file_format_name__,
8069 "ListFiles", ArchiveFileListFiles)
8072 def ArchiveFileStringListFiles(catstr, seekstart=0, seekend=0, skipchecksum=False, formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8073 formatspecs = FormatSpecsListToDict(formatspecs)
8074 catfp = BytesIO(catstr)
8075 listcatfiles = ArchiveFileListFiles(
8076 catstr, seekstart, seekend, skipchecksum, formatspecs, verbose, returnfp)
8077 return listcatfiles
8080 create_alias_function("", __file_format_name__,
8081 "StringListFiles", ArchiveFileStringListFiles)
8084 def TarFileListFiles(infile, verbose=False, returnfp=False):
8085 logging.basicConfig(format="%(message)s",
8086 stream=sys.stdout, level=logging.DEBUG)
8087 if(infile == "-"):
8088 infile = BytesIO()
8089 if(hasattr(sys.stdin, "buffer")):
8090 shutil.copyfileobj(sys.stdin.buffer, infile)
8091 else:
8092 shutil.copyfileobj(sys.stdin, infile)
8093 infile.seek(0, 0)
8094 if(not infile):
8095 return False
8096 infile.seek(0, 0)
8097 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
8098 infile = download_file_from_internet_file(infile)
8099 infile.seek(0, 0)
8100 if(not infile):
8101 return False
8102 infile.seek(0, 0)
8103 elif(not os.path.exists(infile) or not os.path.isfile(infile)):
8104 return False
8105 elif(os.path.exists(infile) and os.path.isfile(infile)):
8106 try:
8107 if(not tarfile.TarFileCheck(infile)):
8108 return False
8109 except AttributeError:
8110 if(not TarFileCheck(infile)):
8111 return False
8112 try:
8113 if(hasattr(infile, "read") or hasattr(infile, "write")):
8114 tarfp = tarfile.open(fileobj=infile, mode="r")
8115 else:
8116 tarfp = tarfile.open(infile, "r")
8117 except FileNotFoundError:
8118 return False
8119 lcfi = 0
8120 returnval = {}
8121 for member in sorted(tarfp.getmembers(), key=lambda x: x.name):
8122 returnval.update({lcfi: member.name})
8123 fpremode = member.mode
8124 ffullmode = member.mode
8125 flinkcount = 0
8126 ftype = 0
8127 if(member.isreg()):
8128 ffullmode = member.mode + stat.S_IFREG
8129 ftype = 0
8130 elif(member.isdev()):
8131 ffullmode = member.mode
8132 ftype = 7
8133 elif(member.islnk()):
8134 ffullmode = member.mode + stat.S_IFREG
8135 ftype = 1
8136 elif(member.issym()):
8137 ffullmode = member.mode + stat.S_IFLNK
8138 ftype = 2
8139 elif(member.ischr()):
8140 ffullmode = member.mode + stat.S_IFCHR
8141 ftype = 3
8142 elif(member.isblk()):
8143 ffullmode = member.mode + stat.S_IFBLK
8144 ftype = 4
8145 elif(member.isdir()):
8146 ffullmode = member.mode + stat.S_IFDIR
8147 ftype = 5
8148 elif(member.isfifo()):
8149 ffullmode = member.mode + stat.S_IFIFO
8150 ftype = 6
8151 elif(member.issparse()):
8152 ffullmode = member.mode
8153 ftype = 12
8154 if(not verbose):
8155 VerbosePrintOut(member.name)
8156 elif(verbose):
8157 permissions = {'access': {'0': ('---'), '1': ('--x'), '2': ('-w-'), '3': ('-wx'), '4': (
8158 'r--'), '5': ('r-x'), '6': ('rw-'), '7': ('rwx')}, 'roles': {0: 'owner', 1: 'group', 2: 'other'}}
8159 printfname = member.name
8160 if(member.islnk()):
8161 printfname = member.name + " link to " + member.linkname
8162 elif(member.issym()):
8163 printfname = member.name + " -> " + member.linkname
8164 fuprint = member.uname
8165 if(len(fuprint) <= 0):
8166 fuprint = member.uid
8167 fgprint = member.gname
8168 if(len(fgprint) <= 0):
8169 fgprint = member.gid
8170 VerbosePrintOut(PrintPermissionString(ffullmode, ftype) + " " + str(str(fuprint) + "/" + str(fgprint) + " " + str(
8171 member.size).rjust(15) + " " + datetime.datetime.utcfromtimestamp(member.mtime).strftime('%Y-%m-%d %H:%M') + " " + printfname))
8172 lcfi = lcfi + 1
8173 if(returnfp):
8174 return listcatfiles['catfp']
8175 else:
8176 return True
8179 def ZipFileListFiles(infile, verbose=False, returnfp=False):
8180 logging.basicConfig(format="%(message)s",
8181 stream=sys.stdout, level=logging.DEBUG)
8182 if(infile == "-"):
8183 infile = BytesIO()
8184 if(hasattr(sys.stdin, "buffer")):
8185 shutil.copyfileobj(sys.stdin.buffer, infile)
8186 else:
8187 shutil.copyfileobj(sys.stdin, infile)
8188 infile.seek(0, 0)
8189 if(not infile):
8190 return False
8191 infile.seek(0, 0)
8192 elif(re.findall("^(http|https|ftp|ftps|sftp):\\/\\/", str(infile))):
8193 infile = download_file_from_internet_file(infile)
8194 infile.seek(0, 0)
8195 if(not infile):
8196 return False
8197 infile.seek(0, 0)
8198 elif(not os.path.exists(infile) or not os.path.isfile(infile)):
8199 return False
8200 if(not zipfile.is_zipfile(infile)):
8201 return False
8202 try:
8203 zipfp = zipfile.ZipFile(infile, "r", allowZip64=True)
8204 except FileNotFoundError:
8205 print(6)
8206 return False
8207 lcfi = 0
8208 returnval = {}
8209 ziptest = zipfp.testzip()
8210 if(ziptest):
8211 VerbosePrintOut("Bad file found!")
8212 for member in sorted(zipfp.infolist(), key=lambda x: x.filename):
8213 if(zipinfo.create_system == 0 or zipinfo.create_system == 10):
8214 fwinattributes = int(zipinfo.external_attr)
8215 if(not member.is_dir()):
8216 fmode = int(stat.S_IFREG + 438)
8217 fchmode = int(stat.S_IMODE(fmode))
8218 ftypemod = int(stat.S_IFMT(fmode))
8219 elif(member.is_dir()):
8220 fmode = int(stat.S_IFDIR + 511)
8221 fchmode = int(stat.S_IMODE(int(stat.S_IFDIR + 511)))
8222 ftypemod = int(stat.S_IFMT(int(stat.S_IFDIR + 511)))
8223 elif(zipinfo.create_system == 3):
8224 fwinattributes = int(0)
8225 try:
8226 fmode = int(zipinfo.external_attr)
8227 fchmode = stat.S_IMODE(fmode)
8228 ftypemod = stat.S_IFMT(fmode)
8229 except OverflowError:
8230 fmode = int(zipinfo.external_attr >> 16)
8231 fchmode = stat.S_IMODE(fmode)
8232 ftypemod = stat.S_IFMT(fmode)
8233 else:
8234 fwinattributes = int(0)
8235 if(not member.is_dir()):
8236 fmode = int(stat.S_IFREG + 438)
8237 fchmode = int(stat.S_IMODE(fmode))
8238 ftypemod = int(stat.S_IFMT(fmode))
8239 elif(member.is_dir()):
8240 fmode = int(stat.S_IFDIR + 511)
8241 fchmode = int(stat.S_IMODE(int(stat.S_IFDIR + 511)))
8242 ftypemod = int(stat.S_IFMT(int(stat.S_IFDIR + 511)))
8243 returnval.update({lcfi: member.filename})
8244 if(not verbose):
8245 VerbosePrintOut(member.filename)
8246 if(verbose):
8247 permissions = {'access': {'0': ('---'), '1': ('--x'), '2': ('-w-'), '3': ('-wx'), '4': (
8248 'r--'), '5': ('r-x'), '6': ('rw-'), '7': ('rwx')}, 'roles': {0: 'owner', 1: 'group', 2: 'other'}}
8249 permissionstr = ""
8250 for fmodval in str(oct(fmode))[-3:]:
8251 permissionstr = permissionstr + \
8252 permissions['access'].get(fmodval, '---')
8253 if(not member.is_dir()):
8254 ftype = 0
8255 permissionstr = "-" + permissionstr
8256 elif(member.is_dir()):
8257 ftype = 5
8258 permissionstr = "d" + permissionstr
8259 printfname = member.filename
8260 try:
8261 fuid = int(os.getuid())
8262 except AttributeError:
8263 fuid = int(0)
8264 except KeyError:
8265 fuid = int(0)
8266 try:
8267 fgid = int(os.getgid())
8268 except AttributeError:
8269 fgid = int(0)
8270 except KeyError:
8271 fgid = int(0)
8272 try:
8273 import pwd
8274 try:
8275 userinfo = pwd.getpwuid(os.getuid())
8276 funame = userinfo.pw_name
8277 except KeyError:
8278 funame = ""
8279 except AttributeError:
8280 funame = ""
8281 except ImportError:
8282 funame = ""
8283 fgname = ""
8284 try:
8285 import grp
8286 try:
8287 groupinfo = grp.getgrgid(os.getgid())
8288 fgname = groupinfo.gr_name
8289 except KeyError:
8290 fgname = ""
8291 except AttributeError:
8292 fgname = ""
8293 except ImportError:
8294 fgname = ""
8295 fuprint = funame
8296 if(len(fuprint) <= 0):
8297 fuprint = str(fuid)
8298 fgprint = fgname
8299 if(len(fgprint) <= 0):
8300 fgprint = str(fgid)
8301 VerbosePrintOut(PrintPermissionString(fmode, ftype) + " " + str(str(fuprint) + "/" + str(fgprint) + " " + str(member.file_size).rjust(
8302 15) + " " + datetime.datetime.utcfromtimestamp(int(time.mktime(member.date_time + (0, 0, -1)))).strftime('%Y-%m-%d %H:%M') + " " + printfname))
8303 lcfi = lcfi + 1
8304 if(returnfp):
8305 return listcatfiles['catfp']
8306 else:
8307 return True
8310 if(not rarfile_support):
8311 def RarFileListFiles(infile, verbose=False, returnfp=False):
8312 return False
8314 if(rarfile_support):
8315 def RarFileListFiles(infile, verbose=False, returnfp=False):
8316 logging.basicConfig(format="%(message)s",
8317 stream=sys.stdout, level=logging.DEBUG)
8318 if(not os.path.exists(infile) or not os.path.isfile(infile)):
8319 return False
8320 if(not rarfile.is_rarfile(infile) and not rarfile.is_rarfile_sfx(infile)):
8321 return False
8322 lcfi = 0
8323 returnval = {}
8324 rarfp = rarfile.RarFile(infile, "r")
8325 rartest = rarfp.testrar()
8326 if(rartest):
8327 VerbosePrintOut("Bad file found!")
8328 for member in sorted(rarfp.infolist(), key=lambda x: x.filename):
8329 is_unix = False
8330 is_windows = False
8331 if(member.host_os == rarfile.RAR_OS_UNIX):
8332 is_windows = False
8333 try:
8334 member.external_attr
8335 is_unix = True
8336 except AttributeError:
8337 is_unix = False
8338 elif(member.host_os == rarfile.RAR_OS_WIN32):
8339 is_unix = False
8340 try:
8341 member.external_attr
8342 is_windows = True
8343 except AttributeError:
8344 is_windows = False
8345 else:
8346 is_unix = False
8347 is_windows = False
8348 if(is_unix and member.external_attr != 0):
8349 fpremode = int(member.external_attr)
8350 elif(member.is_file()):
8351 fpremode = int(stat.S_IFREG + 438)
8352 elif(member.is_symlink()):
8353 fpremode = int(stat.S_IFLNK + 438)
8354 elif(member.is_dir()):
8355 fpremode = int(stat.S_IFDIR + 511)
8356 if(is_windows and member.external_attr != 0):
8357 fwinattributes = int(member.external_attr)
8358 else:
8359 fwinattributes = int(0)
8360 if(is_unix and member.external_attr != 0):
8361 fmode = int(member.external_attr)
8362 fchmode = int(stat.S_IMODE(member.external_attr))
8363 ftypemod = int(stat.S_IFMT(member.external_attr))
8364 elif(member.is_file()):
8365 fmode = int(stat.S_IFREG + 438)
8366 fchmode = int(stat.S_IMODE(int(stat.S_IFREG + 438)))
8367 ftypemod = int(stat.S_IFMT(int(stat.S_IFREG + 438)))
8368 elif(member.is_symlink()):
8369 fmode = int(stat.S_IFLNK + 438)
8370 fchmode = int(stat.S_IMODE(int(stat.S_IFLNK + 438)))
8371 ftypemod = int(stat.S_IFMT(int(stat.S_IFLNK + 438)))
8372 elif(member.is_dir()):
8373 fmode = int(stat.S_IFDIR + 511)
8374 fchmode = int(stat.S_IMODE(int(stat.S_IFDIR + 511)))
8375 ftypemod = int(stat.S_IFMT(int(stat.S_IFDIR + 511)))
8376 returnval.update({lcfi: member.filename})
8377 if(not verbose):
8378 VerbosePrintOut(member.filename)
8379 if(verbose):
8380 permissions = {'access': {'0': ('---'), '1': ('--x'), '2': ('-w-'), '3': ('-wx'), '4': (
8381 'r--'), '5': ('r-x'), '6': ('rw-'), '7': ('rwx')}, 'roles': {0: 'owner', 1: 'group', 2: 'other'}}
8382 permissionstr = ""
8383 for fmodval in str(oct(fmode))[-3:]:
8384 permissionstr = permissionstr + \
8385 permissions['access'].get(fmodval, '---')
8386 if(member.is_file()):
8387 ftype = 0
8388 permissionstr = "-" + permissionstr
8389 printfname = member.filename
8390 elif(member.is_symlink()):
8391 ftype = 2
8392 permissionstr = "l" + permissionstr
8393 printfname = member.name + " -> " + member.read().decode("UTF-8")
8394 elif(member.is_dir()):
8395 ftype = 5
8396 permissionstr = "d" + permissionstr
8397 printfname = member.filename
8398 try:
8399 fuid = int(os.getuid())
8400 except AttributeError:
8401 fuid = int(0)
8402 except KeyError:
8403 fuid = int(0)
8404 try:
8405 fgid = int(os.getgid())
8406 except AttributeError:
8407 fgid = int(0)
8408 except KeyError:
8409 fgid = int(0)
8410 try:
8411 import pwd
8412 try:
8413 userinfo = pwd.getpwuid(os.getuid())
8414 funame = userinfo.pw_name
8415 except KeyError:
8416 funame = ""
8417 except AttributeError:
8418 funame = ""
8419 except ImportError:
8420 funame = ""
8421 fgname = ""
8422 try:
8423 import grp
8424 try:
8425 groupinfo = grp.getgrgid(os.getgid())
8426 fgname = groupinfo.gr_name
8427 except KeyError:
8428 fgname = ""
8429 except AttributeError:
8430 fgname = ""
8431 except ImportError:
8432 fgname = ""
8433 fuprint = funame
8434 if(len(fuprint) <= 0):
8435 fuprint = str(fuid)
8436 fgprint = fgname
8437 if(len(fgprint) <= 0):
8438 fgprint = str(fgid)
8439 VerbosePrintOut(PrintPermissionString(fmode, ftype) + " " + str(str(fuprint) + "/" + str(fgprint) + " " + str(
8440 member.file_size).rjust(15) + " " + member.mtime.strftime('%Y-%m-%d %H:%M') + " " + printfname))
8441 lcfi = lcfi + 1
8442 if(returnfp):
8443 return listcatfiles['catfp']
8444 else:
8445 return True
8447 if(not py7zr_support):
8448 def SevenZipFileListFiles(infile, verbose=False, returnfp=False):
8449 return False
8451 if(py7zr_support):
8452 def SevenZipFileListFiles(infile, verbose=False, returnfp=False):
8453 logging.basicConfig(format="%(message)s",
8454 stream=sys.stdout, level=logging.DEBUG)
8455 if(not os.path.exists(infile) or not os.path.isfile(infile)):
8456 return False
8457 lcfi = 0
8458 returnval = {}
8459 szpfp = py7zr.SevenZipFile(infile, mode="r")
8460 file_content = szpfp.readall()
8461 #sztest = szpfp.testzip();
8462 sztestalt = szpfp.test()
8463 if(sztestalt):
8464 VerbosePrintOut("Bad file found!")
8465 for member in sorted(szpfp.list(), key=lambda x: x.filename):
8466 if(re.findall("^[.|/]", member.filename)):
8467 fname = member.filename
8468 else:
8469 fname = "./"+member.filename
8470 if(not member.is_directory):
8471 fpremode = int(stat.S_IFREG + 438)
8472 elif(member.is_directory):
8473 fpremode = int(stat.S_IFDIR + 511)
8474 fwinattributes = int(0)
8475 if(member.is_directory):
8476 fmode = int(stat.S_IFDIR + 511)
8477 fchmode = int(stat.S_IMODE(int(stat.S_IFDIR + 511)))
8478 ftypemod = int(stat.S_IFMT(int(stat.S_IFDIR + 511)))
8479 else:
8480 fmode = int(stat.S_IFLNK + 438)
8481 fchmode = int(stat.S_IMODE(int(stat.S_IFLNK + 438)))
8482 ftypemod = int(stat.S_IFMT(int(stat.S_IFLNK + 438)))
8483 returnval.update({lcfi: member.filename})
8484 if(not verbose):
8485 VerbosePrintOut(member.filename)
8486 if(verbose):
8487 permissions = {'access': {'0': ('---'), '1': ('--x'), '2': ('-w-'), '3': ('-wx'), '4': (
8488 'r--'), '5': ('r-x'), '6': ('rw-'), '7': ('rwx')}, 'roles': {0: 'owner', 1: 'group', 2: 'other'}}
8489 permissionstr = ""
8490 for fmodval in str(oct(fmode))[-3:]:
8491 permissionstr = permissionstr + \
8492 permissions['access'].get(fmodval, '---')
8493 fsize = int("0")
8494 if(not member.is_directory):
8495 ftype = 0
8496 permissionstr = "-" + permissionstr
8497 printfname = member.filename
8498 elif(member.is_directory):
8499 ftype = 5
8500 permissionstr = "d" + permissionstr
8501 printfname = member.filename
8502 if(ftype == 0):
8503 fsize = len(file_content[member.filename].read())
8504 file_content[member.filename].close()
8505 try:
8506 fuid = int(os.getuid())
8507 except AttributeError:
8508 fuid = int(0)
8509 except KeyError:
8510 fuid = int(0)
8511 try:
8512 fgid = int(os.getgid())
8513 except AttributeError:
8514 fgid = int(0)
8515 except KeyError:
8516 fgid = int(0)
8517 try:
8518 import pwd
8519 try:
8520 userinfo = pwd.getpwuid(os.getuid())
8521 funame = userinfo.pw_name
8522 except KeyError:
8523 funame = ""
8524 except AttributeError:
8525 funame = ""
8526 except ImportError:
8527 funame = ""
8528 fgname = ""
8529 try:
8530 import grp
8531 try:
8532 groupinfo = grp.getgrgid(os.getgid())
8533 fgname = groupinfo.gr_name
8534 except KeyError:
8535 fgname = ""
8536 except AttributeError:
8537 fgname = ""
8538 except ImportError:
8539 fgname = ""
8540 fuprint = funame
8541 if(len(fuprint) <= 0):
8542 fuprint = str(fuid)
8543 fgprint = fgname
8544 if(len(fgprint) <= 0):
8545 fgprint = str(fgid)
8546 VerbosePrintOut(PrintPermissionString(fmode, ftype) + " " + str(str(fuprint) + "/" + str(fgprint) + " " + str(
8547 fsize).rjust(15) + " " + member.creationtime.strftime('%Y-%m-%d %H:%M') + " " + printfname))
8548 lcfi = lcfi + 1
8549 if(returnfp):
8550 return listcatfiles['catfp']
8551 else:
8552 return True
8555 def InFileListFiles(infile, verbose=False, formatspecs=__file_format_dict__, returnfp=False):
8556 formatspecs = FormatSpecsListToDict(formatspecs)
8557 logging.basicConfig(format="%(message)s",
8558 stream=sys.stdout, level=logging.DEBUG)
8559 checkcompressfile = CheckCompressionSubType(infile, formatspecs, True)
8560 if(checkcompressfile == "tarfile" and TarFileCheck(infile)):
8561 return TarFileListFiles(infile, verbose, returnfp)
8562 elif(checkcompressfile == "zipfile" and zipfile.is_zipfile(infile)):
8563 return ZipFileListFiles(infile, verbose, returnfp)
8564 elif(rarfile_support and checkcompressfile == "rarfile" and (rarfile.is_rarfile(infile) or rarfile.is_rarfile_sfx(infile))):
8565 return RarFileListFiles(infile, verbose, returnfp)
8566 elif(py7zr_support and checkcompressfile == "7zipfile" and py7zr.is_7zfile(infile)):
8567 return SevenZipFileListFiles(infile, verbose, returnfp)
8568 elif(checkcompressfile == "catfile"):
8569 return ArchiveFileListFiles(infile, 0, 0, False, formatspecs, verbose, returnfp)
8570 else:
8571 return False
8572 return False
8575 def ListDirListFiles(infiles, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, seekstart=0, seekend=0, skipchecksum=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8576 formatspecs = FormatSpecsListToDict(formatspecs)
8577 outarray = BytesIO()
8578 packcat = PackArchiveFile(infiles, outarray, dirlistfromtxt, compression, compresswholefile,
8579 compressionlevel, followlink, checksumtype, formatspecs, False, True)
8580 listcatfiles = ArchiveFileListFiles(
8581 outarray, seekstart, seekend, skipchecksum, formatspecs, verbose, returnfp)
8582 return listcatfiles
8585 def ListDirListFilesAlt(infiles, dirlistfromtxt=False, followlink=False, listonly=False, contentasfile=True, seekstart=0, seekend=0, skipchecksum=False, checksumtype="crc32", formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8586 formatspecs = FormatSpecsListToDict(formatspecs)
8587 outarray = ListDirToArrayAlt(infiles, dirlistfromtxt, followlink,
8588 listonly, contentasfile, checksumtype, formatspecs, verbose)
8589 listcatfiles = ArchiveFileListFiles(
8590 outarray, seekstart, seekend, skipchecksum, formatspecs, verbose, returnfp)
8591 return listcatfiles
8594 def PackArchiveFileFromListDirAlt(infiles, outfile, dirlistfromtxt=False, compression="auto", compresswholefile=True, compressionlevel=None, followlink=False, skipchecksum=False, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8595 formatspecs = FormatSpecsListToDict(formatspecs)
8596 outarray = ListDirToArrayAlt(infiles, dirlistfromtxt, followlink,
8597 False, True, checksumtype, extradata, formatspecs, False)
8598 listcatfiles = RePackArchiveFile(outarray, outfile, compression, compresswholefile, compressionlevel,
8599 followlink, checksumtype, skipchecksum, extradata, formatspecs, verbose, returnfp)
8600 return listcatfiles
8603 create_alias_function("Pack", __file_format_name__,
8604 "FromListDirAlt", PackArchiveFileFromListDirAlt)
8607 def PackArchiveFileFromTarFileAlt(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8608 formatspecs = FormatSpecsListToDict(formatspecs)
8609 outarray = TarFileToArrayAlt(
8610 infile, False, True, checksumtype, extradata, formatspecs, False)
8611 listcatfiles = RePackArchiveFile(outarray, outfile, compression, compresswholefile,
8612 compressionlevel, False, checksumtype, False, extradata, formatspecs, verbose, returnfp)
8613 return listcatfiles
8616 create_alias_function("Pack", __file_format_name__,
8617 "FromTarFileAlt", PackArchiveFileFromTarFileAlt)
8620 def PackArchiveFileFromZipFileAlt(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8621 formatspecs = FormatSpecsListToDict(formatspecs)
8622 outarray = ZipFileToArrayAlt(
8623 infile, False, True, checksumtype, extradata, formatspecs, False)
8624 listcatfiles = RePackArchiveFile(outarray, outfile, compression, compresswholefile,
8625 compressionlevel, False, checksumtype, False, extradata, formatspecs, verbose, returnfp)
8626 return listcatfiles
8629 create_alias_function("Pack", __file_format_name__,
8630 "FromZipFileAlt", PackArchiveFileFromZipFileAlt)
8632 if(not rarfile_support):
8633 def PackArchiveFileFromRarFileAlt(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8634 return False
8636 if(rarfile_support):
8637 def PackArchiveFileFromRarFileAlt(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8638 formatspecs = FormatSpecsListToDict(formatspecs)
8639 outarray = RarFileToArrayAlt(
8640 infile, False, True, checksumtype, extradata, formatspecs, False)
8641 listcatfiles = RePackArchiveFile(outarray, outfile, compression, compresswholefile,
8642 compressionlevel, False, checksumtype, False, extradata, formatspecs, verbose, returnfp)
8643 return listcatfiles
8645 create_alias_function("Pack", __file_format_name__,
8646 "FromRarFileAlt", PackArchiveFileFromRarFileAlt)
8648 if(not py7zr_support):
8649 def PackArchiveFileFromSevenZipFileAlt(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8650 return False
8652 if(py7zr_support):
8653 def PackArchiveFileFromSevenZipFileAlt(infile, outfile, compression="auto", compresswholefile=True, compressionlevel=None, checksumtype="crc32", extradata=[], formatspecs=__file_format_dict__, verbose=False, returnfp=False):
8654 formatspecs = FormatSpecsListToDict(formatspecs)
8655 outarray = SevenZipFileToArrayAlt(
8656 infile, False, True, checksumtype, extradata, formatspecs, False)
8657 listcatfiles = RePackArchiveFile(outarray, outfile, compression, compresswholefile,
8658 compressionlevel, False, checksumtype, False, extradata, formatspecs, verbose, returnfp)
8659 return listcatfiles
8661 create_alias_function("Pack", __file_format_name__,
8662 "FromSevenZipFileAlt", PackArchiveFileFromSevenZipFileAlt)
8665 def download_file_from_ftp_file(url):
8666 urlparts = urlparse(url)
8667 file_name = os.path.basename(urlparts.path)
8668 file_dir = os.path.dirname(urlparts.path)
8669 if(urlparts.username is not None):
8670 ftp_username = urlparts.username
8671 else:
8672 ftp_username = "anonymous"
8673 if(urlparts.password is not None):
8674 ftp_password = urlparts.password
8675 elif(urlparts.password is None and urlparts.username == "anonymous"):
8676 ftp_password = "anonymous"
8677 else:
8678 ftp_password = ""
8679 if(urlparts.scheme == "ftp"):
8680 ftp = FTP()
8681 elif(urlparts.scheme == "ftps" and ftpssl):
8682 ftp = FTP_TLS()
8683 else:
8684 return False
8685 if(urlparts.scheme == "sftp"):
8686 if(__use_pysftp__):
8687 return download_file_from_pysftp_file(url)
8688 else:
8689 return download_file_from_sftp_file(url)
8690 elif(urlparts.scheme == "http" or urlparts.scheme == "https"):
8691 return download_file_from_http_file(url)
8692 ftp_port = urlparts.port
8693 if(urlparts.port is None):
8694 ftp_port = 21
8695 try:
8696 ftp.connect(urlparts.hostname, ftp_port)
8697 except socket.gaierror:
8698 log.info("Error With URL "+url)
8699 return False
8700 except socket.timeout:
8701 log.info("Error With URL "+url)
8702 return False
8703 ftp.login(urlparts.username, urlparts.password)
8704 if(urlparts.scheme == "ftps"):
8705 ftp.prot_p()
8706 ftpfile = BytesIO()
8707 ftp.retrbinary("RETR "+urlparts.path, ftpfile.write)
8708 #ftp.storbinary("STOR "+urlparts.path, ftpfile.write);
8709 ftp.close()
8710 ftpfile.seek(0, 0)
8711 return ftpfile
8714 def download_file_from_ftp_string(url):
8715 ftpfile = download_file_from_ftp_file(url)
8716 return ftpfile.read()
8719 def upload_file_to_ftp_file(ftpfile, url):
8720 urlparts = urlparse(url)
8721 file_name = os.path.basename(urlparts.path)
8722 file_dir = os.path.dirname(urlparts.path)
8723 if(urlparts.username is not None):
8724 ftp_username = urlparts.username
8725 else:
8726 ftp_username = "anonymous"
8727 if(urlparts.password is not None):
8728 ftp_password = urlparts.password
8729 elif(urlparts.password is None and urlparts.username == "anonymous"):
8730 ftp_password = "anonymous"
8731 else:
8732 ftp_password = ""
8733 if(urlparts.scheme == "ftp"):
8734 ftp = FTP()
8735 elif(urlparts.scheme == "ftps" and ftpssl):
8736 ftp = FTP_TLS()
8737 else:
8738 return False
8739 if(urlparts.scheme == "sftp"):
8740 if(__use_pysftp__):
8741 return upload_file_to_pysftp_file(url)
8742 else:
8743 return upload_file_to_sftp_file(url)
8744 elif(urlparts.scheme == "http" or urlparts.scheme == "https"):
8745 return False
8746 ftp_port = urlparts.port
8747 if(urlparts.port is None):
8748 ftp_port = 21
8749 try:
8750 ftp.connect(urlparts.hostname, ftp_port)
8751 except socket.gaierror:
8752 log.info("Error With URL "+url)
8753 return False
8754 except socket.timeout:
8755 log.info("Error With URL "+url)
8756 return False
8757 ftp.login(urlparts.username, urlparts.password)
8758 if(urlparts.scheme == "ftps"):
8759 ftp.prot_p()
8760 ftp.storbinary("STOR "+urlparts.path, ftpfile)
8761 ftp.close()
8762 ftpfile.seek(0, 0)
8763 return ftpfile
8766 def upload_file_to_ftp_string(ftpstring, url):
8767 ftpfileo = BytesIO(ftpstring)
8768 ftpfile = upload_file_to_ftp_file(ftpfileo, url)
8769 ftpfileo.close()
8770 return ftpfile
8773 class RawIteratorWrapper:
8774 def __init__(self, iterator):
8775 self.iterator = iterator
8776 self.buffer = b""
8777 self._iterator_exhausted = False
8779 def read(self, size=-1):
8780 if self._iterator_exhausted:
8781 return b''
8782 while size < 0 or len(self.buffer) < size:
8783 try:
8784 chunk = next(self.iterator)
8785 self.buffer += chunk
8786 except StopIteration:
8787 self._iterator_exhausted = True
8788 break
8789 if size < 0:
8790 size = len(self.buffer)
8791 result, self.buffer = self.buffer[:size], self.buffer[size:]
8792 return result
8795 def download_file_from_http_file(url, headers=None, usehttp=__use_http_lib__):
8796 if headers is None:
8797 headers = {}
8798 # Parse the URL to extract username and password if present
8799 urlparts = urlparse(url)
8800 username = urlparts.username
8801 password = urlparts.password
8802 # Rebuild the URL without the username and password
8803 netloc = urlparts.hostname
8804 if urlparts.scheme == "sftp":
8805 if __use_pysftp__:
8806 return download_file_from_pysftp_file(url)
8807 else:
8808 return download_file_from_sftp_file(url)
8809 elif urlparts.scheme == "ftp" or urlparts.scheme == "ftps":
8810 return download_file_from_ftp_file(url)
8811 if urlparts.port:
8812 netloc += ':' + str(urlparts.port)
8813 rebuilt_url = urlunparse((urlparts.scheme, netloc, urlparts.path,
8814 urlparts.params, urlparts.query, urlparts.fragment))
8815 # Create a temporary file object
8816 httpfile = BytesIO()
8817 if usehttp == 'requests' and haverequests:
8818 # Use the requests library if selected and available
8819 if username and password:
8820 response = requests.get(rebuilt_url, headers=headers, auth=(
8821 username, password), stream=True)
8822 else:
8823 response = requests.get(rebuilt_url, headers=headers, stream=True)
8824 response.raw.decode_content = True
8825 shutil.copyfileobj(response.raw, httpfile)
8826 elif usehttp == 'httpx' and havehttpx:
8827 # Use httpx if selected and available
8828 with httpx.Client(follow_redirects=True) as client:
8829 if username and password:
8830 response = client.get(
8831 rebuilt_url, headers=headers, auth=(username, password))
8832 else:
8833 response = client.get(rebuilt_url, headers=headers)
8834 raw_wrapper = RawIteratorWrapper(response.iter_bytes())
8835 shutil.copyfileobj(raw_wrapper, httpfile)
8836 else:
8837 # Use urllib as a fallback
8838 # Build a Request object for urllib
8839 request = Request(rebuilt_url, headers=headers)
8840 # Create an opener object for handling URLs
8841 if username and password:
8842 # Create a password manager
8843 password_mgr = HTTPPasswordMgrWithDefaultRealm()
8844 # Add the username and password
8845 password_mgr.add_password(None, rebuilt_url, username, password)
8846 # Create an authentication handler using the password manager
8847 auth_handler = HTTPBasicAuthHandler(password_mgr)
8848 # Build the opener with the authentication handler
8849 opener = build_opener(auth_handler)
8850 else:
8851 opener = build_opener()
8852 response = opener.open(request)
8853 shutil.copyfileobj(response, httpfile)
8854 # Reset file pointer to the start
8855 httpfile.seek(0, 0)
8856 # Return the temporary file object
8857 return httpfile
8860 def download_file_from_http_string(url, headers=geturls_headers_pycatfile_python_alt, usehttp=__use_http_lib__):
8861 httpfile = download_file_from_http_file(url, headers, usehttp)
8862 return httpfile.read()
8865 if(haveparamiko):
8866 def download_file_from_sftp_file(url):
8867 urlparts = urlparse(url)
8868 file_name = os.path.basename(urlparts.path)
8869 file_dir = os.path.dirname(urlparts.path)
8870 sftp_port = urlparts.port
8871 if(urlparts.port is None):
8872 sftp_port = 22
8873 else:
8874 sftp_port = urlparts.port
8875 if(urlparts.username is not None):
8876 sftp_username = urlparts.username
8877 else:
8878 sftp_username = "anonymous"
8879 if(urlparts.password is not None):
8880 sftp_password = urlparts.password
8881 elif(urlparts.password is None and urlparts.username == "anonymous"):
8882 sftp_password = "anonymous"
8883 else:
8884 sftp_password = ""
8885 if(urlparts.scheme == "ftp"):
8886 return download_file_from_ftp_file(url)
8887 elif(urlparts.scheme == "http" or urlparts.scheme == "https"):
8888 return download_file_from_http_file(url)
8889 if(urlparts.scheme != "sftp"):
8890 return False
8891 ssh = paramiko.SSHClient()
8892 ssh.load_system_host_keys()
8893 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
8894 try:
8895 ssh.connect(urlparts.hostname, port=sftp_port,
8896 username=urlparts.username, password=urlparts.password)
8897 except paramiko.ssh_exception.SSHException:
8898 return False
8899 except socket.gaierror:
8900 log.info("Error With URL "+url)
8901 return False
8902 except socket.timeout:
8903 log.info("Error With URL "+url)
8904 return False
8905 sftp = ssh.open_sftp()
8906 sftpfile = BytesIO()
8907 sftp.getfo(urlparts.path, sftpfile)
8908 sftp.close()
8909 ssh.close()
8910 sftpfile.seek(0, 0)
8911 return sftpfile
8912 else:
8913 def download_file_from_sftp_file(url):
8914 return False
8916 if(haveparamiko):
8917 def download_file_from_sftp_string(url):
8918 sftpfile = download_file_from_sftp_file(url)
8919 return sftpfile.read()
8920 else:
8921 def download_file_from_sftp_string(url):
8922 return False
8924 if(haveparamiko):
8925 def upload_file_to_sftp_file(sftpfile, url):
8926 urlparts = urlparse(url)
8927 file_name = os.path.basename(urlparts.path)
8928 file_dir = os.path.dirname(urlparts.path)
8929 sftp_port = urlparts.port
8930 if(urlparts.port is None):
8931 sftp_port = 22
8932 else:
8933 sftp_port = urlparts.port
8934 if(urlparts.username is not None):
8935 sftp_username = urlparts.username
8936 else:
8937 sftp_username = "anonymous"
8938 if(urlparts.password is not None):
8939 sftp_password = urlparts.password
8940 elif(urlparts.password is None and urlparts.username == "anonymous"):
8941 sftp_password = "anonymous"
8942 else:
8943 sftp_password = ""
8944 if(urlparts.scheme == "ftp"):
8945 return upload_file_to_ftp_file(url)
8946 elif(urlparts.scheme == "http" or urlparts.scheme == "https"):
8947 return False
8948 if(urlparts.scheme != "sftp"):
8949 return False
8950 ssh = paramiko.SSHClient()
8951 ssh.load_system_host_keys()
8952 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
8953 try:
8954 ssh.connect(urlparts.hostname, port=sftp_port,
8955 username=urlparts.username, password=urlparts.password)
8956 except paramiko.ssh_exception.SSHException:
8957 return False
8958 except socket.gaierror:
8959 log.info("Error With URL "+url)
8960 return False
8961 except socket.timeout:
8962 log.info("Error With URL "+url)
8963 return False
8964 sftp = ssh.open_sftp()
8965 sftp.putfo(sftpfile, urlparts.path)
8966 sftp.close()
8967 ssh.close()
8968 sftpfile.seek(0, 0)
8969 return sftpfile
8970 else:
8971 def upload_file_to_sftp_file(sftpfile, url):
8972 return False
8974 if(haveparamiko):
8975 def upload_file_to_sftp_string(sftpstring, url):
8976 sftpfileo = BytesIO(sftpstring)
8977 sftpfile = upload_file_to_sftp_files(ftpfileo, url)
8978 sftpfileo.close()
8979 return sftpfile
8980 else:
8981 def upload_file_to_sftp_string(url):
8982 return False
8984 if(havepysftp):
8985 def download_file_from_pysftp_file(url):
8986 urlparts = urlparse(url)
8987 file_name = os.path.basename(urlparts.path)
8988 file_dir = os.path.dirname(urlparts.path)
8989 sftp_port = urlparts.port
8990 if(urlparts.port is None):
8991 sftp_port = 22
8992 else:
8993 sftp_port = urlparts.port
8994 if(urlparts.username is not None):
8995 sftp_username = urlparts.username
8996 else:
8997 sftp_username = "anonymous"
8998 if(urlparts.password is not None):
8999 sftp_password = urlparts.password
9000 elif(urlparts.password is None and urlparts.username == "anonymous"):
9001 sftp_password = "anonymous"
9002 else:
9003 sftp_password = ""
9004 if(urlparts.scheme == "ftp"):
9005 return download_file_from_ftp_file(url)
9006 elif(urlparts.scheme == "http" or urlparts.scheme == "https"):
9007 return download_file_from_http_file(url)
9008 if(urlparts.scheme != "sftp"):
9009 return False
9010 try:
9011 pysftp.Connection(urlparts.hostname, port=sftp_port,
9012 username=urlparts.username, password=urlparts.password)
9013 except paramiko.ssh_exception.SSHException:
9014 return False
9015 except socket.gaierror:
9016 log.info("Error With URL "+url)
9017 return False
9018 except socket.timeout:
9019 log.info("Error With URL "+url)
9020 return False
9021 sftp = ssh.open_sftp()
9022 sftpfile = BytesIO()
9023 sftp.getfo(urlparts.path, sftpfile)
9024 sftp.close()
9025 ssh.close()
9026 sftpfile.seek(0, 0)
9027 return sftpfile
9028 else:
9029 def download_file_from_pysftp_file(url):
9030 return False
9032 if(havepysftp):
9033 def download_file_from_pysftp_string(url):
9034 sftpfile = download_file_from_pysftp_file(url)
9035 return sftpfile.read()
9036 else:
9037 def download_file_from_pyftp_string(url):
9038 return False
9040 if(havepysftp):
9041 def upload_file_to_pysftp_file(sftpfile, url):
9042 urlparts = urlparse(url)
9043 file_name = os.path.basename(urlparts.path)
9044 file_dir = os.path.dirname(urlparts.path)
9045 sftp_port = urlparts.port
9046 if(urlparts.port is None):
9047 sftp_port = 22
9048 else:
9049 sftp_port = urlparts.port
9050 if(urlparts.username is not None):
9051 sftp_username = urlparts.username
9052 else:
9053 sftp_username = "anonymous"
9054 if(urlparts.password is not None):
9055 sftp_password = urlparts.password
9056 elif(urlparts.password is None and urlparts.username == "anonymous"):
9057 sftp_password = "anonymous"
9058 else:
9059 sftp_password = ""
9060 if(urlparts.scheme == "ftp"):
9061 return upload_file_to_ftp_file(url)
9062 elif(urlparts.scheme == "http" or urlparts.scheme == "https"):
9063 return False
9064 if(urlparts.scheme != "sftp"):
9065 return False
9066 try:
9067 pysftp.Connection(urlparts.hostname, port=sftp_port,
9068 username=urlparts.username, password=urlparts.password)
9069 except paramiko.ssh_exception.SSHException:
9070 return False
9071 except socket.gaierror:
9072 log.info("Error With URL "+url)
9073 return False
9074 except socket.timeout:
9075 log.info("Error With URL "+url)
9076 return False
9077 sftp = ssh.open_sftp()
9078 sftp.putfo(sftpfile, urlparts.path)
9079 sftp.close()
9080 ssh.close()
9081 sftpfile.seek(0, 0)
9082 return sftpfile
9083 else:
9084 def upload_file_to_pysftp_file(sftpfile, url):
9085 return False
9087 if(havepysftp):
9088 def upload_file_to_pysftp_string(sftpstring, url):
9089 sftpfileo = BytesIO(sftpstring)
9090 sftpfile = upload_file_to_pysftp_files(ftpfileo, url)
9091 sftpfileo.close()
9092 return sftpfile
9093 else:
9094 def upload_file_to_pysftp_string(url):
9095 return False
9098 def download_file_from_internet_file(url, headers=geturls_headers_pycatfile_python_alt, usehttp=__use_http_lib__):
9099 urlparts = urlparse(url)
9100 if(urlparts.scheme == "http" or urlparts.scheme == "https"):
9101 return download_file_from_http_file(url, headers, usehttp)
9102 elif(urlparts.scheme == "ftp" or urlparts.scheme == "ftps"):
9103 return download_file_from_ftp_file(url)
9104 elif(urlparts.scheme == "sftp"):
9105 if(__use_pysftp__ and havepysftp):
9106 return download_file_from_pysftp_file(url)
9107 else:
9108 return download_file_from_sftp_file(url)
9109 else:
9110 return False
9111 return False
9114 def download_file_from_internet_uncompress_file(url, headers=geturls_headers_pycatfile_python_alt, formatspecs=__file_format_dict__):
9115 formatspecs = FormatSpecsListToDict(formatspecs)
9116 fp = download_file_from_internet_file(url)
9117 fp = UncompressArchiveFile(fp, formatspecs)
9118 fp.seek(0, 0)
9119 if(not fp):
9120 return False
9121 return fp
9124 def download_file_from_internet_string(url, headers=geturls_headers_pycatfile_python_alt):
9125 urlparts = urlparse(url)
9126 if(urlparts.scheme == "http" or urlparts.scheme == "https"):
9127 return download_file_from_http_string(url, headers)
9128 elif(urlparts.scheme == "ftp" or urlparts.scheme == "ftps"):
9129 return download_file_from_ftp_string(url)
9130 elif(urlparts.scheme == "sftp"):
9131 if(__use_pysftp__ and havepysftp):
9132 return download_file_from_pysftp_string(url)
9133 else:
9134 return download_file_from_sftp_string(url)
9135 else:
9136 return False
9137 return False
9140 def download_file_from_internet_uncompress_string(url, headers=geturls_headers_pycatfile_python_alt, formatspecs=__file_format_dict__):
9141 formatspecs = FormatSpecsListToDict(formatspecs)
9142 fp = download_file_from_internet_string(url)
9143 fp = UncompressArchiveFile(fp, formatspecs)
9144 fp.seek(0, 0)
9145 if(not fp):
9146 return False
9147 return fp
9150 def upload_file_to_internet_file(ifp, url):
9151 urlparts = urlparse(url)
9152 if(urlparts.scheme == "http" or urlparts.scheme == "https"):
9153 return False
9154 elif(urlparts.scheme == "ftp" or urlparts.scheme == "ftps"):
9155 return upload_file_to_ftp_file(ifp, url)
9156 elif(urlparts.scheme == "sftp"):
9157 if(__use_pysftp__ and havepysftp):
9158 return upload_file_to_pysftp_file(ifp, url)
9159 else:
9160 return upload_file_to_sftp_file(ifp, url)
9161 else:
9162 return False
9163 return False
9166 def upload_file_to_internet_compress_file(ifp, url, compression="auto", compressionlevel=None, formatspecs=__file_format_dict__):
9167 formatspecs = FormatSpecsListToDict(formatspecs)
9168 catfp = CompressArchiveFile(
9169 catfp, compression, compressionlevel, formatspecs)
9170 if(not catfileout):
9171 return False
9172 catfp.seek(0, 0)
9173 upload_file_to_internet_file(catfp, outfile)
9174 return True
9177 def upload_file_to_internet_string(ifp, url):
9178 urlparts = urlparse(url)
9179 if(urlparts.scheme == "http" or urlparts.scheme == "https"):
9180 return False
9181 elif(urlparts.scheme == "ftp" or urlparts.scheme == "ftps"):
9182 return upload_file_to_ftp_string(ifp, url)
9183 elif(urlparts.scheme == "sftp"):
9184 if(__use_pysftp__ and havepysftp):
9185 return upload_file_to_pysftp_string(ifp, url)
9186 else:
9187 return upload_file_to_sftp_string(ifp, url)
9188 else:
9189 return False
9190 return False
9193 def upload_file_to_internet_compress_string(ifp, url, compression="auto", compressionlevel=None, formatspecs=__file_format_dict__):
9194 formatspecs = FormatSpecsListToDict(formatspecs)
9195 catfp = CompressArchiveFile(
9196 BytesIO(ifp), compression, compressionlevel, formatspecs)
9197 if(not catfileout):
9198 return False
9199 catfp.seek(0, 0)
9200 upload_file_to_internet_file(catfp, outfile)
9201 return True
9204 try:
9205 if(hasattr(shutil, "register_archive_format")):
9206 # Register the packing format
9207 shutil.register_archive_format(
9208 __file_format_name__, PackArchiveFileFunc, description='Pack concatenated files')
9209 except shutil.RegistryError:
9210 pass
9212 try:
9213 if(hasattr(shutil, "register_unpack_format")):
9214 # Register the unpacking format
9215 shutil.register_unpack_format(__file_format_name__, archivefile_extensions,
9216 UnPackArchiveFileFunc, description='UnPack concatenated files')
9217 except shutil.RegistryError:
9218 pass