Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ubi_reader for openSUSE:Factory 
checked in at 2022-01-04 19:37:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ubi_reader (Old)
 and      /work/SRC/openSUSE:Factory/.ubi_reader.new.1896 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ubi_reader"

Tue Jan  4 19:37:59 2022 rev:3 rq:943725 version:0.7.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/ubi_reader/ubi_reader.changes    2021-04-08 
22:13:08.085536490 +0200
+++ /work/SRC/openSUSE:Factory/.ubi_reader.new.1896/ubi_reader.changes  
2022-01-04 19:38:24.274001880 +0100
@@ -1,0 +2,6 @@
+Mon Jan  3 22:11:10 UTC 2022 - Martin Hauke <[email protected]>
+
+- Update to version 0.7.1
+  * Bug fixes and minor updates.
+
+-------------------------------------------------------------------

Old:
----
  ubi_reader-0.6.3.tar.gz

New:
----
  ubi_reader-0.7.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ubi_reader.spec ++++++
--- /var/tmp/diff_new_pack.fxcUgx/_old  2022-01-04 19:38:24.734002481 +0100
+++ /var/tmp/diff_new_pack.fxcUgx/_new  2022-01-04 19:38:24.738002487 +0100
@@ -1,8 +1,8 @@
 #
 # spec file for package ubi_reader
 #
-# Copyright (c) 2021 SUSE LLC
-# Copyright (c) 2018-2021, Martin Hauke <[email protected]>
+# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2018-2022, Martin Hauke <[email protected]>
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 
 Name:           ubi_reader
-Version:        0.6.3
+Version:        0.7.1
 Release:        0
 Summary:        Extract files from UBI and UBIFS images
 License:        LGPL-3.0-or-later
@@ -62,6 +62,7 @@
 %files
 %license LICENSE
 %doc README.md
+%{_bindir}/ubireader_display_blocks
 %{_bindir}/ubireader_display_info
 %{_bindir}/ubireader_extract_files
 %{_bindir}/ubireader_extract_images

++++++ ubi_reader-0.6.3.tar.gz -> ubi_reader-0.7.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/.github/FUNDING.yml 
new/ubi_reader-0.7.1-master/.github/FUNDING.yml
--- old/ubi_reader-0.6.3-master/.github/FUNDING.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/ubi_reader-0.7.1-master/.github/FUNDING.yml     2021-05-22 
12:29:19.000000000 +0200
@@ -0,0 +1,2 @@
+github: jrspruitt
+patreon: jrspruitt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/README.md 
new/ubi_reader-0.7.1-master/README.md
--- old/ubi_reader-0.6.3-master/README.md       2019-04-16 20:26:50.000000000 
+0200
+++ new/ubi_reader-0.7.1-master/README.md       2021-05-22 12:29:19.000000000 
+0200
@@ -3,6 +3,17 @@
 the contents of UBI and UBIFS images, along with analyzing these images to
 determine the parameter settings to recreate them using the mtd-utils tools.
 
+
+### Known Issues
+These are some known issues, that prevent an exact data dump from occuring.
+
+* This does not replay the journal, so uncommited data will not be retrieved. 
Data can be in the journal with both clean and unclean shutdowns.
+
+* Depending on how the NAND was dumped, the data bits may not be error 
corrected.
+
+* Socket files will be ignored, you can change ubireader/settings.py to have 
it create dummy files in their place.
+
+
 ## Testing Branch
 The testing branch includes a tools/ directory, that has scripts to help when 
trying to extract data from broken images. These also serve as examples of how 
to use parts of ubi_reader in custom scripts.
 
@@ -10,6 +21,7 @@
 
 This branch will probably remain seperate, as it is meant to be customized to 
aid in extracting data from problematic images. You can install it with 'python 
setup.py develop' to make it easier to modify ubi_reader as needed.
 
+
 ## Dependencies:
 
 Python 2.7 or 3.
@@ -81,6 +93,15 @@
 image, the Super Node, and both Master Nodes are displayed. Using the (-u, 
--ubifs-info)
 option, it will get the UBIFS info from inside a UBI file instead.
 
+## Display Block Information:
+    ubireader_display_blocks [options] "{'block.attr':?, ...}" path/to/file
+
+Search for and display block information. This can be used for debugging 
failed image
+and file extractions. The blocks are searched for using a double quoted Python 
Dict of
+search paramaters, example. "{'peb_num':[0, 1] + range(100, 102), 'ec_hdr.ec': 
1, 'is_valid': True}"
+This will find PEBs 0, 1, 100, 101, 102, with an erase count of 1 that is a 
valid block.
+Can use any of the parameters in ubireader.ubi.block.description.
+
 ## Options:
 Some general option flags are
 * -l, --log: This prints to screen actions being taken while running.
@@ -92,20 +113,5 @@
 * -g, --guess-offset: Specify offset to start guessing where UBI data is in 
file. Useful for NAND dumps with false positives before image.
 * -w, --warn-only-block-read-errors: Attempts to continue extracting files 
even with bad block reads. Some data will be missing or corrupted!
 * -i, --ignore-block-header-errors: Forces unused and error containing blocks 
to be included and also displayed with log/verbose.
+* -f, --u-boot-fix: Assume blocks with image_seq 0 are because of older U-boot 
implementations and include them. *This may cause issues with multiple UBI 
image files.
 * -o, --output-dir path: Specify where files should be written to, instead of 
ubi_reader/output
-
-### Known Issues
-
-* Socket files will be ignored, you can change modules/settings.py to have it 
create dummy files in their place.
-
-* For NAND dumps and the like, this will not fix anything ECC would take care 
of, so some bad data
-may be extracted, this can also cause erratic behavior.
-
-* This does not replay the journal, so uncommited data will not be retrieved.
-
-* Assumes things are in good condition and where it thinks they should be...
-
-### TODO
-
-* Arbitrary block analyzer script.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ubi_reader-0.6.3-master/scripts/ubireader_display_blocks 
new/ubi_reader-0.7.1-master/scripts/ubireader_display_blocks
--- old/ubi_reader-0.6.3-master/scripts/ubireader_display_blocks        
1970-01-01 01:00:00.000000000 +0100
+++ new/ubi_reader-0.7.1-master/scripts/ubireader_display_blocks        
2021-05-22 12:29:19.000000000 +0200
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+#############################################################
+# ubi_reader/scripts/ubireader_display_blocks
+# (c) 2019 Jason Pruitt ([email protected])
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#############################################################
+
+#############################################################
+# Search by block parameters and display information about
+# matching blocks.
+#############################################################
+
+import os
+import sys
+import argparse
+from ubireader.ubi import ubi_base
+from ubireader.ubi_io import ubi_file
+from ubireader import settings
+from ubireader.ubi.defines import UBI_EC_HDR_MAGIC
+from ubireader.ubifs.defines import UBIFS_NODE_MAGIC
+from ubireader.utils import guess_filetype, guess_start_offset, 
guess_leb_size, guess_peb_size
+
+if __name__=='__main__':
+
+    description = 'Search for specified blocks and display information.'
+    usage = """
+    ubireader_display_blocks "{'block.attr': value,...}" path/to/image
+        Search for blocks by given parameters and display information about 
them.
+        This is block only, no volume or image information is created, which 
can
+        be used to debug file and image extraction.
+    Example:
+        "{'peb_num':[0, 1] + range(100, 102), 'ec_hdr.ec': 1, 'is_valid': 
True}"
+        This matches block.peb_num 0, 1, 100, 101, and 102 
+        with a block.ec_hdr.ec (erase count) of 1, that are valid PEB blocks.
+        For a full list of parameters check ubireader.ubi.block.description.
+    """
+    parser = argparse.ArgumentParser(usage=usage, description=description)
+
+    parser.add_argument('-l', '--log', action='store_true', dest='log',
+                      help='Print extraction information to screen.')
+
+    parser.add_argument('-v', '--verbose-log', action='store_true', 
dest='verbose',
+                      help='Prints nearly everything about anything to 
screen.')
+    
+    parser.add_argument('-p', '--peb-size', type=int, dest='block_size',
+                        help='Specify PEB size. (UBI Only)')
+    
+    parser.add_argument('-e', '--leb-size', type=int, dest='block_size',
+                        help='Specify LEB size. (UBIFS Only)')
+
+    parser.add_argument('-s', '--start-offset', type=int, dest='start_offset',
+                        help='Specify offset of UBI/UBIFS data in file. 
(default: 0)')
+
+    parser.add_argument('-n', '--end-offset', type=int, dest='end_offset',
+                        help='Specify end offset of UBI/UBIFS data in file.')
+
+    parser.add_argument('-g', '--guess-offset', type=int, dest='guess_offset',
+                        help='Specify offset to start guessing where UBI data 
is in file. (default: 0)')
+
+    parser.add_argument('-w', '--warn-only-block-read-errors', 
action='store_true', dest='warn_only_block_read_errors',
+                      help='Attempts to continue extracting files even with 
bad block reads. Some data will be missing or corrupted! (default: False)')
+
+    parser.add_argument('-i', '--ignore-block-header-errors', 
action='store_true', dest='ignore_block_header_errors',
+                      help='Forces unused and error containing blocks to be 
included and also displayed with log/verbose. (default: False)')
+
+    parser.add_argument('-f', '--u-boot-fix', action='store_true', 
dest='uboot_fix',
+                      help='Assume blocks with image_seq 0 are because of 
older U-boot implementations and include them. (default: False)')
+
+    parser.add_argument('block_search_params',
+                      help="""
+                      Double quoted Dict of ubi.block.description attributes, 
which is run through eval().
+                      Ex. "{\'peb_num\':[0, 1], \'ec_hdr.ec\': 1, 
\'is_valid\': True}"
+                      """)
+
+    parser.add_argument('filepath', help='File with blocks of interest.')
+
+    if len(sys.argv) == 1:
+        parser.print_help()
+
+    args = parser.parse_args()
+
+    settings.logging_on = args.log
+
+    settings.logging_on_verbose = args.verbose
+
+    settings.warn_only_block_read_errors = args.warn_only_block_read_errors
+
+    settings.ignore_block_header_errors = args.ignore_block_header_errors
+
+    settings.uboot_fix = args.uboot_fix
+
+    if args.filepath:
+        path = args.filepath
+        if not os.path.exists(path):
+            parser.error("File path doesn't exist.")
+    else:
+        parser.error('File path must be provided.')
+        sys.exit(1)
+
+    if args.start_offset:
+        start_offset = args.start_offset
+    elif args.guess_offset:
+        start_offset = guess_start_offset(path, args.guess_offset)
+    else:
+        start_offset = guess_start_offset(path)
+
+    if args.end_offset:
+        end_offset = args.end_offset
+    else:
+        end_offset = None
+
+    filetype = guess_filetype(path, start_offset)
+    if not filetype:
+        parser.error('Could not determine file type.')
+
+    if args.block_size:
+        block_size = args.block_size
+    else:
+        if filetype == UBI_EC_HDR_MAGIC:
+            block_size = guess_peb_size(path)
+        elif filetype == UBIFS_NODE_MAGIC:
+            block_size = guess_leb_size(path)
+
+        if not block_size:
+            parser.error('Block size could not be determined.')
+
+    if args.block_search_params:
+        try:
+            search_params = eval(args.block_search_params)
+
+            if not isinstance(search_params, dict):
+                parser.error('Search Param Error: Params must be a Dict of 
block PEB object items:value pairs.')
+
+        except NameError as e:
+            parser.error('Search Param Error: Dict key block attrs must be 
single quoted.')
+
+        except Exception as e:
+            parser.error('Search Param Error: %s' % e)
+
+    else:
+        parser.error('No search parameters given, -b arg is required.')
+
+
+    ufile_obj = ubi_file(path, block_size, start_offset, end_offset)
+    ubi_obj = ubi_base(ufile_obj)
+    blocks = []
+
+    for block in ubi_obj.blocks:
+        match = True
+
+        for key in search_params:
+            b = ubi_obj.blocks[block]
+
+            for attr in key.split('.'):
+                if hasattr(b, attr):
+                    b = getattr(b, attr)
+
+            if isinstance(search_params[key], list):
+                if isinstance(b, list):
+                    for value in b:
+                        if value in search_params[key]:
+                            break
+                    else:
+                        match = False
+                elif b not in search_params[key]:
+                    match = False
+
+            elif b != search_params[key]:
+                match = False
+                break
+
+        if match:                
+            blocks.append(ubi_obj.blocks[block])
+
+    print('\nBlock matches: %s' % len(blocks))
+
+    for block in blocks:
+        print(block.display())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ubi_reader-0.6.3-master/scripts/ubireader_display_info 
new/ubi_reader-0.7.1-master/scripts/ubireader_display_info
--- old/ubi_reader-0.6.3-master/scripts/ubireader_display_info  2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/scripts/ubireader_display_info  2021-05-22 
12:29:19.000000000 +0200
@@ -68,6 +68,9 @@
     parser.add_argument('-i', '--ignore-block-header-errors', 
action='store_true', dest='ignore_block_header_errors',
                       help='Forces unused and error containing blocks to be 
included and also displayed with log/verbose. (default: False)')
 
+    parser.add_argument('-f', '--u-boot-fix', action='store_true', 
dest='uboot_fix',
+                      help='Assume blocks with image_seq 0 are because of 
older U-boot implementations and include them. (default: False)')
+
     parser.add_argument('filepath', help='File to extract contents of.')
 
     if len(sys.argv) == 1:
@@ -84,6 +87,8 @@
 
     settings.ignore_block_header_errors = args.ignore_block_header_errors
 
+    settings.uboot_fix = args.uboot_fix
+
     if args.filepath:
         path = args.filepath
         if not os.path.exists(path):
@@ -162,7 +167,10 @@
                     print(ubifs_obj.display())
                     print(ubifs_obj.superblock_node.display('\t'))
                     print(ubifs_obj.master_node.display('\t'))
-                    print(ubifs_obj.master_node2.display('\t'))
+                    try:
+                        print(ubifs_obj.master_node2.display('\t'))
+                    except:
+                        print('Master Node Error only one valid node.')
 
     elif filetype == UBIFS_NODE_MAGIC:
         # Create UBIFS object
@@ -170,7 +178,10 @@
         print(ubifs_obj.display())
         print(ubifs_obj.superblock_node.display('\t'))
         print(ubifs_obj.master_node.display('\t'))
-        print(ubifs_obj.master_node2.display('\t'))
+        try:
+            print(ubifs_obj.master_node2.display('\t'))
+        except:
+            print('Master Node Error only one valid node.')
 
     else:
         print('Something went wrong to get here.')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ubi_reader-0.6.3-master/scripts/ubireader_extract_files 
new/ubi_reader-0.7.1-master/scripts/ubireader_extract_files
--- old/ubi_reader-0.6.3-master/scripts/ubireader_extract_files 2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/scripts/ubireader_extract_files 2021-05-22 
12:29:19.000000000 +0200
@@ -81,6 +81,9 @@
     parser.add_argument('-i', '--ignore-block-header-errors', 
action='store_true', dest='ignore_block_header_errors',
                       help='Forces unused and error containing blocks to be 
included and also displayed with log/verbose. (default: False)')
 
+    parser.add_argument('-f', '--u-boot-fix', action='store_true', 
dest='uboot_fix',
+                      help='Assume blocks with image_seq 0 are because of 
older U-boot implementations and include them. (default: False)')
+
     parser.add_argument('-o', '--output-dir', dest='outpath',
                         help='Specify output directory path.')
 
@@ -100,6 +103,8 @@
 
     settings.ignore_block_header_errors = args.ignore_block_header_errors
 
+    settings.uboot_fix = args.uboot_fix
+
     if args.filepath:
         path = args.filepath
         if not os.path.exists(path):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ubi_reader-0.6.3-master/scripts/ubireader_extract_images 
new/ubi_reader-0.7.1-master/scripts/ubireader_extract_images
--- old/ubi_reader-0.6.3-master/scripts/ubireader_extract_images        
2019-04-16 20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/scripts/ubireader_extract_images        
2021-05-22 12:29:19.000000000 +0200
@@ -72,6 +72,9 @@
     parser.add_argument('-i', '--ignore-block-header-errors', 
action='store_true', dest='ignore_block_header_errors',
                       help='Forces unused and error containing blocks to be 
included and also displayed with log/verbose. (default: False)')
 
+    parser.add_argument('-f', '--u-boot-fix', action='store_true', 
dest='uboot_fix',
+                      help='Assume blocks with image_seq 0 are because of 
older U-boot implementations and include them. (default: False)')
+
     parser.add_argument('-o', '--output-dir', dest='outpath',
                         help='Specify output directory path.')
 
@@ -91,6 +94,8 @@
 
     settings.ignore_block_header_errors = args.ignore_block_header_errors
 
+    settings.uboot_fix = args.uboot_fix
+
     if args.filepath:
         path = args.filepath
         if not os.path.exists(path):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/scripts/ubireader_list_files 
new/ubi_reader-0.7.1-master/scripts/ubireader_list_files
--- old/ubi_reader-0.6.3-master/scripts/ubireader_list_files    2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/scripts/ubireader_list_files    2021-05-22 
12:29:19.000000000 +0200
@@ -66,6 +66,9 @@
     parser.add_argument('-i', '--ignore-block-header-errors', 
action='store_true', dest='ignore_block_header_errors',
                       help='Forces unused and error containing blocks to be 
included and also displayed with log/verbose. (default: False)')
 
+    parser.add_argument('-f', '--u-boot-fix', action='store_true', 
dest='uboot_fix',
+                      help='Assume blocks with image_seq 0 are because of 
older U-boot implementations and include them. (default: False)')
+
     parser.add_argument('-P', '--path', dest='listpath',
                         help='Path to list.')
 
@@ -91,6 +94,8 @@
 
     settings.ignore_block_header_errors = args.ignore_block_header_errors
 
+    settings.uboot_fix = args.uboot_fix
+
     if args.filepath:
         path = args.filepath
         if not os.path.exists(path):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/scripts/ubireader_utils_info 
new/ubi_reader-0.7.1-master/scripts/ubireader_utils_info
--- old/ubi_reader-0.6.3-master/scripts/ubireader_utils_info    2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/scripts/ubireader_utils_info    2021-05-22 
12:29:19.000000000 +0200
@@ -270,6 +270,9 @@
     parser.add_argument('-i', '--ignore-block-header-errors', 
action='store_true', dest='ignore_block_header_errors',
                       help='Forces unused and error containing blocks to be 
included and also displayed with log/verbose. (default: False)')
 
+    parser.add_argument('-f', '--u-boot-fix', action='store_true', 
dest='uboot_fix',
+                      help='Assume blocks with image_seq 0 are because of 
older U-boot implementations and include them. (default: False)')
+
     parser.add_argument('-o', '--output-dir', dest='outpath',
                         help='Specify output directory path.')
 
@@ -289,6 +292,8 @@
 
     settings.ignore_block_header_errors = args.ignore_block_header_errors
 
+    settings.uboot_fix = args.uboot_fix
+
     if args.filepath:
         path = args.filepath
         if not os.path.exists(path):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/setup.py 
new/ubi_reader-0.7.1-master/setup.py
--- old/ubi_reader-0.6.3-master/setup.py        2019-04-16 20:26:50.000000000 
+0200
+++ new/ubi_reader-0.7.1-master/setup.py        2021-05-22 12:29:19.000000000 
+0200
@@ -2,7 +2,7 @@
 
 from setuptools import setup, find_packages
 
-version = '0.6.3'
+version = '0.7.1'
 
 setup(
     name='ubi_reader',
@@ -22,6 +22,7 @@
              'scripts/ubireader_extract_files',
              'scripts/ubireader_list_files',
              'scripts/ubireader_extract_images',
-             'scripts/ubireader_utils_info'
+             'scripts/ubireader_utils_info',
+             'scripts/ubireader_display_blocks',
             ],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/debug.py 
new/ubi_reader-0.7.1-master/ubireader/debug.py
--- old/ubi_reader-0.6.3-master/ubireader/debug.py      2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/debug.py      2021-05-22 
12:29:19.000000000 +0200
@@ -34,7 +34,7 @@
         print(displayable_obj.display('\t'))
 
 def error(obj, level, message):
-    if settings.error_action is 'exit':
+    if settings.error_action == 'exit':
         print('{} {}: {}'.format(obj.__name__, level, message))
         if settings.fatal_traceback:
             traceback.print_exc()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/settings.py 
new/ubi_reader-0.7.1-master/ubireader/settings.py
--- old/ubi_reader-0.6.3-master/ubireader/settings.py   2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/settings.py   2021-05-22 
12:29:19.000000000 +0200
@@ -30,4 +30,7 @@
 logging_on = False                      # Print debug info on.
 logging_on_verbose = False              # Print verbose debug info on.
 
-use_dummy_socket_file = False           # Create regular file place holder.
+use_dummy_socket_file = False           # Create regular file place holder for 
sockets.
+use_dummy_devices = False               # Create regular file place holder for 
devices.
+
+uboot_fix = False                       # Older u-boot sets image_seq to 0 on 
blocks it's written to.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/ubi/block/sort.py 
new/ubi_reader-0.7.1-master/ubireader/ubi/block/sort.py
--- old/ubi_reader-0.6.3-master/ubireader/ubi/block/sort.py     2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/ubi/block/sort.py     2021-05-22 
12:29:19.000000000 +0200
@@ -16,9 +16,11 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #############################################################
+from ubireader import settings
 
 def by_image_seq(blocks, image_seq):
     """Filter blocks to return only those associated with the provided 
image_seq number.
+       If uboot_fix is set, associate blocks with an image_seq of 0 also.
 
     Argument:
     List:blocks       -- List of block objects to sort.
@@ -27,7 +29,11 @@
     Returns:
     List        -- List of block indexes matching image_seq number.
     """
-    return list(filter(lambda block: blocks[block].ec_hdr.image_seq == 
image_seq, blocks))
+    if settings.uboot_fix:
+        return list(filter(lambda block: blocks[block].ec_hdr.image_seq == 
image_seq or image_seq == 0 or blocks[block].ec_hdr.image_seq == 0, blocks))
+
+    else:
+        return list(filter(lambda block: blocks[block].ec_hdr.image_seq == 
image_seq, blocks))
 
 def by_leb(blocks):
     """Sort blocks by Logical Erase Block number.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/ubi_io.py 
new/ubi_reader-0.7.1-master/ubireader/ubi_io.py
--- old/ubi_reader-0.6.3-master/ubireader/ubi_io.py     2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/ubi_io.py     2021-05-22 
12:29:19.000000000 +0200
@@ -17,6 +17,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #############################################################
 
+from ubireader import settings
 from ubireader.debug import error, log, verbose_log
 from ubireader.ubi.block import sort
 
@@ -66,10 +67,14 @@
         log(self, 'Start Offset: %s' % (self._start_offset))
 
         if end_offset:
+            tail = file_size - end_offset
             self._end_offset = end_offset
         else:
-            self._end_offset = file_size 
+            tail = (file_size - start_offset) % block_size
+            self._end_offset = file_size - tail
         log(self, 'End Offset: %s' % (self._end_offset))
+        if tail > 0:
+            log(self, 'File Tail Size: %s' % (tail))
 
         self._block_size = block_size
         log(self, 'Block Size: %s' % block_size)
@@ -80,6 +85,13 @@
         if ( not end_offset is None ) and ( end_offset > file_size ):
             error(self, 'Fatal', 'End offset larger than file size.')
 
+        remainder = (self._end_offset - start_offset) % block_size
+        if remainder != 0:
+            if settings.warn_only_block_read_errors:
+                error(self, 'Error', 'File read is not block aligned.')
+            else:
+                error(self, 'Fatal', 'File read is not block aligned.')
+
         self._fhandle.seek(self._start_offset)
         self._last_read_addr = self._fhandle.tell()
         self.is_valid = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/ubifs/__init__.py 
new/ubi_reader-0.7.1-master/ubireader/ubifs/__init__.py
--- old/ubi_reader-0.6.3-master/ubireader/ubifs/__init__.py     2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/ubifs/__init__.py     2021-05-22 
12:29:19.000000000 +0200
@@ -49,7 +49,7 @@
             if sb_chdr.node_type == UBIFS_SB_NODE:
                 self.file.seek(UBIFS_COMMON_HDR_SZ)
                 buf = self.file.read(UBIFS_SB_NODE_SZ)
-                self._sb_node = nodes.sb_node(buf)
+                self._sb_node = nodes.sb_node(buf, self.file.last_read_addr())
                 self._min_io_size = self._sb_node.min_io_size
                 self._leb_size = self._sb_node.leb_size       
                 log(self , '%s file addr: %s' % (self._sb_node, 
self.file.last_read_addr()))
@@ -71,16 +71,21 @@
                 if mst_chdr.node_type == UBIFS_MST_NODE:
                     self.file.seek(mst_offset + UBIFS_COMMON_HDR_SZ)
                     buf = self.file.read(UBIFS_MST_NODE_SZ)
-                    self._mst_nodes[i] = nodes.mst_node(buf)
+                    self._mst_nodes[i] = nodes.mst_node(buf, 
self.file.last_read_addr())
                     log(self , '%s%s file addr: %s' % (self._mst_nodes[i], i, 
self.file.last_read_addr()))
                     verbose_display(self._mst_nodes[i])
                 else:
                     raise Exception('Wrong node type.')
             except Exception as e:
-                error(self, 'Fatal', 'Master block %s error: %s' % (i, e))
+                error(self, 'Warn', 'Master block %s error: %s' % (i, e))
 
-        if not self._mst_nodes[0] or not self._mst_nodes[1]:
-            error(self, 'Fatal', 'Less than 2 Master blocks found.')
+        if self._mst_nodes[0] is None and self._mst_nodes[1] is None:
+            error(self, 'Fatal', 'No valid Master Node found.')
+
+        elif self._mst_nodes[0] is None and self._mst_nodes[1] is not None:
+            self._mst_nodes[0] = self._mst_nodes[1]
+            self._mst_nodes[1] = None
+            log(self , 'Swapping Master Nodes due to bad first node.')
 
 
     def _get_file(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/ubifs/defines.py 
new/ubi_reader-0.7.1-master/ubireader/ubifs/defines.py
--- old/ubi_reader-0.6.3-master/ubireader/ubifs/defines.py      2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/ubifs/defines.py      2021-05-22 
12:29:19.000000000 +0200
@@ -156,31 +156,38 @@
 UBIFS_FL_MASK = 0x0000001F
 
 # Compression alogrithms.
-UBIFS_COMPR_NONE        = 0 # No compression
-UBIFS_COMPR_LZO         = 1 # LZO compression
-UBIFS_COMPR_ZLIB        = 2 # ZLIB compression
-UBIFS_COMPR_TYPES_CNT   = 3 # Count of supported compression types
-PRINT_UBIFS_COMPR = ['none','lzo','zlib']
+UBIFS_COMPR_NONE            = 0 # No compression
+UBIFS_COMPR_LZO             = 1 # LZO compression
+UBIFS_COMPR_ZLIB            = 2 # ZLIB compression
+UBIFS_COMPR_ZSTD            = 3 # ZSTD compression
+UBIFS_COMPR_TYPES_CNT       = 4 # Count of supported compression types
+PRINT_UBIFS_COMPR = ['none','lzo','zlib', 'zstd']
 
 # UBIFS node types
-UBIFS_INO_NODE          = 0  # Inode node
-UBIFS_DATA_NODE         = 1  # Data node
-UBIFS_DENT_NODE         = 2  # Directory entry node
-UBIFS_XENT_NODE         = 3  # Extended attribute node
-UBIFS_TRUN_NODE         = 4  # Truncation node
-UBIFS_PAD_NODE          = 5  # Padding node
-UBIFS_SB_NODE           = 6  # Superblock node
-UBIFS_MST_NODE          = 7  # Master node
-UBIFS_REF_NODE          = 8  # LEB reference node
-UBIFS_IDX_NODE          = 9  # Index node
-UBIFS_CS_NODE           = 10 # Commit start node
-UBIFS_ORPH_NODE         = 11 # Orphan node
-UBIFS_NODE_TYPES_CNT    = 12 # Count of supported node types
+UBIFS_INO_NODE              = 0  # Inode node
+UBIFS_DATA_NODE             = 1  # Data node
+UBIFS_DENT_NODE             = 2  # Directory entry node
+UBIFS_XENT_NODE             = 3  # Extended attribute node
+UBIFS_TRUN_NODE             = 4  # Truncation node
+UBIFS_PAD_NODE              = 5  # Padding node
+UBIFS_SB_NODE               = 6  # Superblock node
+UBIFS_MST_NODE              = 7  # Master node
+UBIFS_REF_NODE              = 8  # LEB reference node
+UBIFS_IDX_NODE              = 9  # Index node
+UBIFS_CS_NODE               = 10 # Commit start node
+UBIFS_ORPH_NODE             = 11 # Orphan node
+UBIFS_AUTH_NODE             = 12 # Authentication node
+UBIFS_SIG_NODE              = 13 # Signature node
+UBIFS_NODE_TYPES_CNT        = 14 # Count of supported node types
 
 # Master node flags
-UBIFS_MST_DIRTY     = 1 # Rebooted uncleanly
-UBIFS_MST_NO_ORPHS  = 2 # No orphans present
-UBIFS_MST_RCVRY     = 4 # Written by recovery
+UBIFS_MST_DIRTY             = 1 # Rebooted uncleanly
+UBIFS_MST_NO_ORPHS          = 2 # No orphans present
+UBIFS_MST_RCVRY             = 4 # Written by recovery
+PRINT_UBIFS_MST = [[UBIFS_MST_DIRTY, 'Dirty'],
+                   [UBIFS_MST_NO_ORPHS, 'No orphans'],
+                   [UBIFS_MST_RCVRY, 'Recovery write'],
+                  ]
 
 # Node group type
 UBIFS_NO_NODE_GROUP         = 0 # This node is not part of a group
@@ -188,21 +195,30 @@
 UBIFS_LAST_OF_NODE_GROUP    = 2 # This node is the last in a group
 
 # Superblock flags
-UBIFS_FLG_BIGLPT        = 2 # if 'big' LPT model is used if set.
-UBIFS_FLG_SPACE_FIXUP   = 4 # first-mount 'fixup' of free space within
-
+UBIFS_FLG_BIGLPT            = 2     # If 'big' LPT model is used if set.
+UBIFS_FLG_SPACE_FIXUP       = 4     # First-mount 'fixup' of free space within.
+UBIFS_FLG_DOUBLE_HASH       = 8     # Store 32bit cookie for 64bit support.
+UBIFS_FLG_ENCRYPTION        = 16    # If filesystem contains encrypted files.
+UBIFS_FLG_AUTHENTICATION    = 32    # If contains hashes for authentication.
+PRINT_UBIFS_FLGS = [[UBIFS_FLG_BIGLPT,       'Big LPT'],
+                    [UBIFS_FLG_SPACE_FIXUP,   'Space fixup'],
+                    [UBIFS_FLG_DOUBLE_HASH,   'Double hash'],
+                    [UBIFS_FLG_ENCRYPTION,    'Encryption'],
+                    [UBIFS_FLG_AUTHENTICATION,'Authentication'],
+                   ]
 
 # Struct defines
 
 # Common header node
 UBIFS_COMMON_HDR_FORMAT = '<IIQIBB2s'
-UBIFS_COMMON_HDR_FIELDS = ['magic',     # UBIFS node magic number.
-                           'crc',       # CRC32 checksum of header.
-                           'sqnum',     # Sequence number.
-                           'len',       # Full node length.
-                           'node_type', # Node type.
-                           'group_type',# Node group type.
-                           'padding']   # Reserved for future, zeros.
+UBIFS_COMMON_HDR_FIELDS = ['magic',         # UBIFS node magic number.
+                           'crc',           # CRC32 checksum of header.
+                           'sqnum',         # Sequence number.
+                           'len',           # Full node length.
+                           'node_type',     # Node type.
+                           'group_type',    # Node group type.
+                           'padding',       # Reserved for future, zeros.
+                           ]
 UBIFS_COMMON_HDR_SZ = struct.calcsize(UBIFS_COMMON_HDR_FORMAT)
                             # LEBs needed.
 # Key offset in key nodes
@@ -212,12 +228,13 @@
 # Device node descriptor
 UBIFS_DEV_DESC_FORMAT = '<IQ'
 UBIFS_DEV_DESC_FIELDS = ['new',  # New type device descriptor.
-                         'huge'] # huge type device descriptor.
+                         'huge', # huge type device descriptor.
+                         ]
 UBIFS_DEV_DESC_SZ = struct.calcsize(UBIFS_DEV_DESC_FORMAT)
 
 # Inode node
 UBIFS_INO_NODE_FORMAT = '<%ssQQQQQIIIIIIIIIII4sIH26s' % (UBIFS_MAX_KEY_LEN)
-UBIFS_INO_NODE_FIELDS = ['key',         # Node key
+UBIFS_INO_NODE_FIELDS = ['key',         # Node key.
                          'creat_sqnum', # Sequence number at time of creation.
                          'size',        # Inode size in bytes (uncompressed).
                          'atime_sec',   # Access time in seconds.
@@ -232,46 +249,52 @@
                          'mode',        # Access flags.
                          'flags',       # Per-inode flags.
                          'data_len',    # Inode data length.
-                         'xattr_cnt',   # Count of extended attr this inode has
+                         'xattr_cnt',   # Count of extended attr this inode 
has.
                          'xattr_size',  # Summarized size of all extended
                                         # attributes in bytes.
                          'padding1',    # Reserved for future, zeros.
-                         'xattr_names', # Sum of lengths of all extended.
+                         'xattr_names', # Sum of lengths of all extended
                                         # attribute names belonging to this
                                         # inode.
                          'compr_type',  # Compression type used for this inode.
-                         'padding2']    # Reserved for future, zeros.
-                        # 'data' No size
+                         'padding2',    # Reserved for future, zeros.
+                         ]
+                                        # 'data', no size.
 UBIFS_INO_NODE_SZ = struct.calcsize(UBIFS_INO_NODE_FORMAT)
 
 
 # Directory entry node
-UBIFS_DENT_NODE_FORMAT = '<%ssQBBH4s' % (UBIFS_MAX_KEY_LEN)
-UBIFS_DENT_NODE_FIELDS = ['key',     # Node key.
-                          'inum',    # Target inode number.
-                          'padding1',# Reserved for future, zeros.
-                          'type',    # Type of target inode.
-                          'nlen',    # Name length.
-                          'padding2']# Reserved for future, zeros.
-                        # 'Name' No size
+UBIFS_DENT_NODE_FORMAT = '<%ssQBBHI' % (UBIFS_MAX_KEY_LEN)
+UBIFS_DENT_NODE_FIELDS = ['key',        # Node key.
+                          'inum',       # Target inode number.
+                          'padding1',   # Reserved for future, zeros.
+                          'type',       # Type of target inode.
+                          'nlen',       # Name length.
+                          'cookie',     # 32bit random number, used to
+                                        # construct a 64bit identifier.
+                          ]
+                                        # 'name', no size.
 UBIFS_DENT_NODE_SZ = struct.calcsize(UBIFS_DENT_NODE_FORMAT)
 
 
 # Data node
-UBIFS_DATA_NODE_FORMAT = '<%ssIH2s' % (UBIFS_MAX_KEY_LEN)
-UBIFS_DATA_NODE_FIELDS = ['key',        # Node key.
-                          'size',       # Uncompressed data size.
-                          'compr_type', # Compression type UBIFS_COMPR_*
-                          'padding']    # Reserved for future, zeros.
-                        # 'data' No size
+UBIFS_DATA_NODE_FORMAT = '<%ssIHH' % (UBIFS_MAX_KEY_LEN)
+UBIFS_DATA_NODE_FIELDS = ['key',            # Node key.
+                          'size',           # Uncompressed data size.
+                          'compr_type',     # Compression type UBIFS_COMPR_*.
+                          'compr_size',     # Compressed data size in bytes
+                                            # only valid when data is 
encrypted.
+                          ]
+                                            # 'data', no size.
 UBIFS_DATA_NODE_SZ = struct.calcsize(UBIFS_DATA_NODE_FORMAT)
 
 # Truncation node
 UBIFS_TRUN_NODE_FORMAT = '<I12sQQ'
-UBIFS_TRUN_NODE_FIELDS = ['inum',     # Truncated inode number.
-                          'padding',  # Reserved for future, zeros.
-                          'old_size', # size before truncation.
-                          'new_size'] # Size after truncation.
+UBIFS_TRUN_NODE_FIELDS = ['inum',           # Truncated inode number.
+                          'padding',        # Reserved for future, zeros.
+                          'old_size',       # size before truncation.
+                          'new_size',       # Size after truncation.
+                          ]
 UBIFS_TRUN_NODE_SZ = struct.calcsize(UBIFS_TRUN_NODE_FORMAT)
 
 # Padding node
@@ -279,8 +302,16 @@
 UBIFS_PAD_NODE_FIELDS = ['pad_len'] # Number of bytes after this inode unused.
 UBIFS_PAD_NODE_SZ = struct.calcsize(UBIFS_PAD_NODE_FORMAT)
 
+
+# The maxmimum size of a hash, enough for sha512
+UBIFS_MAX_HASH_LEN = 64
+
+# The maxmimum size of a hmac, enough for hmac(sha512)
+UBIFS_MAX_HMAC_LEN = 64
+
+
 # Superblock node
-UBIFS_SB_NODE_FORMAT = '<2sBBIIIIIQIIIIIIIH2sIIQI16sI3968s'
+UBIFS_SB_NODE_FORMAT = '<2sBBIIIIIQIIIIIIIH2sIIQI16sI%ss%ssH%ss3774s' % 
(UBIFS_MAX_HMAC_LEN, UBIFS_MAX_HMAC_LEN, UBIFS_MAX_HASH_LEN)
 UBIFS_SB_NODE_FIELDS = ['padding',          # Reserved for future, zeros.
                         'key_hash',         # Type of hash func used in keys.
                         'key_fmt',          # Format of the key.
@@ -295,7 +326,7 @@
                                             # table.
                         'orph_lebs',        # Number of LEBS used for
                                             # recording orphans.
-                        'jhead_cnt',        # Count of journal heads
+                        'jhead_cnt',        # Count of journal heads.
                         'fanout',           # Tree fanout, max number of links
                                             # per indexing node.
                         'lsave_cnt',        # Number of LEB numbers in LPT's
@@ -303,72 +334,99 @@
                         'fmt_version',      # UBIFS on-flash format version.
                         'default_compr',    # Default compression used.
                         'padding1',         # Reserved for future, zeros.
-                        'rp_uid',           # Reserve pool UID
-                        'rp_gid',           # Reserve pool GID
-                        'rp_size',          # Reserve pool size in bytes
+                        'rp_uid',           # Reserve pool UID.
+                        'rp_gid',           # Reserve pool GID.
+                        'rp_size',          # Reserve pool size in bytes.
                         'time_gran',        # Time granularity in nanoseconds.
                         'uuid',             # UUID generated when the FS image
                                             # was created.
                         'ro_compat_version',# UBIFS R/O Compatibility version.
-                        'padding2']         #Reserved for future, zeros
+                        'hmac',             # HAMC to authenticate the 
superblock node.
+                        'hmac_wkm',         # HMAC of a well known message 
(the string "UBIFS").
+                                            # as a convenience to the user to 
chek if the correct
+                                            # key is past.
+                        'hash_algo',        # The has algo used for this 
feilseystem.
+                                            # (one of enum hash_algo).
+                        'hash_mst',         # Hash of the master node, only 
valid for
+                                            # signed images in which the 
master node
+                                            # does not contain a hmac.
+                        'padding2'          # Reserved for future, zeros.
+                        ]
 UBIFS_SB_NODE_SZ = struct.calcsize(UBIFS_SB_NODE_FORMAT)
 
 # Master node
-UBIFS_MST_NODE_FORMAT = '<QQIIIIIIIIQQQQQQIIIIIIIIIIII344s'
-UBIFS_MST_NODE_FIELDS = ['highest_inum',# Highest inode number in the
-                                        # committed index.
-                         'cmt_no',      # Commit Number.
-                         'flags',       # Various flags.
-                         'log_lnum',    # LEB num start of log.
-                         'root_lnum',   # LEB num of root indexing node.
-                         'root_offs',   # Offset within root_lnum
-                         'root_len',    # Root indexing node length.
-                         'gc_lnum',     # LEB reserved for garbage collection.
-                         'ihead_lnum',  # LEB num of index head.
-                         'ihead_offs',  # Offset of index head.
-                         'index_size',  # Size of index on flash.
-                         'total_free',  # Total free space in bytes.
-                         'total_dirty', # Total dirty space in bytes.
-                         'total_used',  # Total used space in bytes (data LEBs)
-                         'total_dead',  # Total dead space in bytes (data LEBs)
-                         'total_dark',  # Total dark space in bytes (data LEBs)
-                         'lpt_lnum',    # LEB num of LPT root nnode.
-                         'lpt_offs',    # Offset of LPT root nnode.
-                         'nhead_lnum',  # LEB num of LPT head.
-                         'nhead_offs',  # Offset of LPT head.
-                         'ltab_lnum',   # LEB num of LPT's own lprop table.
-                         'ltab_offs',   # Offset of LPT's own lprop table.
-                         'lsave_lnum',  # LEB num of LPT's save table.
-                         'lsave_offs',  # Offset of LPT's save table.
-                         'lscan_lnum',  # LEB num of last LPT scan.
-                         'empty_lebs',  # Number of empty LEBs.
-                         'idx_lebs',    # Number of indexing LEBs.
-                         'leb_cnt',     # Count of LEBs used by FS.
-                         'padding']     # Reserved for future, zeros.
+UBIFS_MST_NODE_FORMAT = '<QQIIIIIIIIQQQQQQIIIIIIIIIIII%ss%ss%ss152s' % 
(UBIFS_MAX_HASH_LEN, UBIFS_MAX_HASH_LEN, UBIFS_MAX_HMAC_LEN)
+UBIFS_MST_NODE_FIELDS = ['highest_inum',    # Highest inode number in the
+                                            # committed index.
+                         'cmt_no',          # Commit Number.
+                         'flags',           # Various flags.
+                         'log_lnum',        # LEB num start of log.
+                         'root_lnum',       # LEB num of root indexing node.
+                         'root_offs',       # Offset within root_lnum
+                         'root_len',        # Root indexing node length.
+                         'gc_lnum',         # LEB reserved for garbage 
collection.
+                         'ihead_lnum',      # LEB num of index head.
+                         'ihead_offs',      # Offset of index head.
+                         'index_size',      # Size of index on flash.
+                         'total_free',      # Total free space in bytes.
+                         'total_dirty',     # Total dirty space in bytes.
+                         'total_used',      # Total used space in bytes (data 
LEBs)
+                         'total_dead',      # Total dead space in bytes (data 
LEBs)
+                         'total_dark',      # Total dark space in bytes (data 
LEBs)
+                         'lpt_lnum',        # LEB num of LPT root nnode.
+                         'lpt_offs',        # Offset of LPT root nnode.
+                         'nhead_lnum',      # LEB num of LPT head.
+                         'nhead_offs',      # Offset of LPT head.
+                         'ltab_lnum',       # LEB num of LPT's own lprop table.
+                         'ltab_offs',       # Offset of LPT's own lprop table.
+                         'lsave_lnum',      # LEB num of LPT's save table.
+                         'lsave_offs',      # Offset of LPT's save table.
+                         'lscan_lnum',      # LEB num of last LPT scan.
+                         'empty_lebs',      # Number of empty LEBs.
+                         'idx_lebs',        # Number of indexing LEBs.
+                         'leb_cnt',         # Count of LEBs used by FS.
+                         'hash_root_idx',   # The hash of the root index node.
+                         'hash_lpt',        # The has of the LPT.
+                         'hmac',            # HMAC to athenticate the master 
node.
+                         'padding',         # Reserved for future, zeros.
+                         ]
 UBIFS_MST_NODE_SZ = struct.calcsize(UBIFS_MST_NODE_FORMAT)
 
 # LEB Reference node
 UBIFS_REF_NODE_FORMAT = '<III28s'
-UBIFS_REF_NODE_FIELDS = ['lnum',    # Referred LEB number.
-                         'offs',    # Start offset of referred LEB.
-                         'jhead',   # Journal head number.
-                         'padding'] # Reserved for future, zeros.
+UBIFS_REF_NODE_FIELDS = ['lnum',            # Referred LEB number.
+                         'offs',            # Start offset of referred LEB.
+                         'jhead',           # Journal head number.
+                         'padding',         # Reserved for future, zeros.
+                         ]
 UBIFS_REF_NODE_SZ = struct.calcsize(UBIFS_REF_NODE_FORMAT)
 
+# Signature node
+UBIFS_SIG_NODE_FORMAT = '<II32s'
+UBIFS_SIG_NODE_FIELDS = ['type',            # Type of the signature.
+                         'len',             # Length of signature data.
+                         'padding',         # Reserved for future, zeros.
+                         ]
+                                            # 'sig', no size.
+
+UBIFS_SIG_NODE_SZ = struct.calcsize(UBIFS_SIG_NODE_FORMAT)
+
 # key/reference/length branch
 UBIFS_BRANCH_FORMAT = '<III%ss' % (UBIFS_SK_LEN)
-UBIFS_BRANCH_FIELDS = ['lnum',  # LEB number of target node.
-                       'offs',  # Offset within lnum.
-                       'len',   # Target node length.
-                       'key']   # Using UBIFS_SK_LEN as size.
+UBIFS_BRANCH_FIELDS = ['lnum',              # LEB number of target node.
+                       'offs',              # Offset within lnum.
+                       'len',               # Target node length.
+                       'key',               # Using UBIFS_SK_LEN as size.
+                       ]
 UBIFS_BRANCH_SZ = struct.calcsize(UBIFS_BRANCH_FORMAT)
 
 # Indexing node
 UBIFS_IDX_NODE_FORMAT = '<HH'
-UBIFS_IDX_NODE_FIELDS = ['child_cnt',   # Number of child index nodes.
-                         'level']       # Tree level.
-                        # branches, no size.
+UBIFS_IDX_NODE_FIELDS = ['child_cnt',       # Number of child index nodes.
+                         'level',           # Tree level.
+                         ]
+                                            # 'branches', no size.
 UBIFS_IDX_NODE_SZ = struct.calcsize(UBIFS_IDX_NODE_FORMAT)
 
 # File chunk size for reads.
-FILE_CHUNK_SZ = 5 * 1024 *1024
\ No newline at end of file
+FILE_CHUNK_SZ = 5 * 1024 *1024
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/ubifs/display.py 
new/ubi_reader-0.7.1-master/ubireader/ubifs/display.py
--- old/ubi_reader-0.6.3-master/ubireader/ubifs/display.py      2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/ubifs/display.py      2021-05-22 
12:29:19.000000000 +0200
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #############################################################
+from ubireader.ubifs.defines import PRINT_UBIFS_FLGS, PRINT_UBIFS_MST
 
 def ubifs(ubifs, tab=''):
     buf = '%sUBIFS Image\n' % (tab)
@@ -41,6 +42,7 @@
 
 def sb_node(node, tab=''):
     buf = '%s%s\n' % (tab, node)
+    buf += '%sFile offset: %s\n' % (tab, node.file_offset)
     buf += '%s---------------------\n' % (tab)
     tab += '\t'
     for key, value in node:
@@ -50,6 +52,17 @@
             buf += '%s%s: %s\n' % (tab, key, ','.join(value))
         elif key == 'uuid':
             buf += '%s%s: %r\n' % (tab, key, value)
+        elif key == 'flags':
+            flags = ''
+            for flag in PRINT_UBIFS_FLGS:
+                if value & flag[0]:
+                    flags += '%s, ' % flag[1]
+
+            if flags.endswith(', '):
+                flags = flags[0:-2]
+
+            buf += '%s%s: %s\n' % (tab, key, flags)
+
         else:
             buf += '%s%s: %r\n' % (tab, key, value)
     return buf
@@ -57,6 +70,7 @@
 
 def mst_node(node, tab=''):
     buf = '%s%s\n' % (tab, node)
+    buf += '%sFile offset: %s\n' % (tab, node.file_offset)
     buf += '%s---------------------\n' % (tab)
     tab += '\t'
     for key, value in node:
@@ -64,6 +78,16 @@
             continue
         elif key == 'errors':
             buf += '%s%s: %s\n' % (tab, key, ','.join(value))
+        elif key == 'flags':
+            flags = ''
+            for flag in PRINT_UBIFS_MST:
+                if value & flag[0]:
+                    flags += '%s, ' % flag[1]
+
+            if flags.endswith(', '):
+                flags = flags[0:-2]
+
+            buf += '%s%s: %s\n' % (tab, key, flags)
         else:
             buf += '%s%s: %r\n' % (tab, key, value)
     return buf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/ubifs/nodes.py 
new/ubi_reader-0.7.1-master/ubireader/ubifs/nodes.py
--- old/ubi_reader-0.6.3-master/ubireader/ubifs/nodes.py        2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/ubifs/nodes.py        2021-05-22 
12:29:19.000000000 +0200
@@ -209,10 +209,12 @@
 
     Arguments:
     Bin:buf     -- Raw data to extract header information from.
+    Int:offset  -- Offset in LEB of data node.
 
     See ubifs/defines.py for object attributes.
     """
-    def __init__(self, buf):
+    def __init__(self, buf, file_offset=-1):
+        self.file_offset = file_offset
         fields = dict(list(zip(UBIFS_SB_NODE_FIELDS, 
struct.unpack(UBIFS_SB_NODE_FORMAT, buf))))
         for key in fields:
             setattr(self, key, fields[key])
@@ -236,10 +238,12 @@
 
     Arguments:
     Bin:buf     -- Raw data to extract header information from.
+    Int:offset  -- Offset in LEB of data node.
 
     See ubifs/defines.py for object attributes.
     """
-    def __init__(self, buf):
+    def __init__(self, buf, file_offset=-1):
+        self.file_offset = file_offset
         fields = dict(list(zip(UBIFS_MST_NODE_FIELDS, 
struct.unpack(UBIFS_MST_NODE_FORMAT, buf))))
         for key in fields:
             setattr(self, key, fields[key])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ubi_reader-0.6.3-master/ubireader/ubifs/output.py 
new/ubi_reader-0.7.1-master/ubireader/ubifs/output.py
--- old/ubi_reader-0.6.3-master/ubireader/ubifs/output.py       2019-04-16 
20:26:50.000000000 +0200
+++ new/ubi_reader-0.7.1-master/ubireader/ubifs/output.py       2021-05-22 
12:29:19.000000000 +0200
@@ -112,14 +112,14 @@
     elif dent_node.type in [UBIFS_ITYPE_BLK, UBIFS_ITYPE_CHR]:
         try:
             dev = struct.unpack('<II', inode['ino'].data)[0]
-            if True:
+            if not settings.use_dummy_devices:
                 os.mknod(dent_path, inode['ino'].mode, dev)
                 log(extract_dents, 'Make Device Node: %s' % (dent_path))
 
                 if perms:
-                    _set_file_perms(path, inode)
+                    _set_file_perms(dent_path, inode)
             else:
-                log(extract_dents, 'Create dummy node.')
+                log(extract_dents, 'Create dummy device.')
                 _write_reg_file(dent_path, str(dev))
 
                 if perms:
@@ -149,8 +149,8 @@
 
 
 def _set_file_perms(path, inode):
-    os.chmod(path, inode['ino'].mode)
     os.chown(path, inode['ino'].uid, inode['ino'].gid)
+    os.chmod(path, inode['ino'].mode)
     verbose_log(_set_file_perms, 'perms:%s, owner: %s.%s, path: %s' % 
(inode['ino'].mode, inode['ino'].uid, inode['ino'].gid, path))
 
 def _set_file_timestamps(path, inode):

Reply via email to