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