22import io
33import posixpath
44import re
5- from enum import Enum
65from pathlib import Path
76from typing import Optional
87from urllib .parse import parse_qsl , urlparse
1312from lxml .html import document_fromstring
1413from pakler import PAK , Section , is_pak_file
1514from pycramfs import Cramfs
16- from pycramfs .const import MAGIC_BYTES as CRAMFS_MAGIC
1715from PySquashfsImage import SquashFsImage
18- from PySquashfsImage .const import SQUASHFS_MAGIC
19- from ubireader .ubi .defines import UBI_EC_HDR_MAGIC as UBI_MAGIC
2016from ubireader .ubifs import ubifs , walk
21- from ubireader .ubifs .defines import UBIFS_NODE_MAGIC as UBIFS_MAGIC
2217from ubireader .ubifs .output import _process_reg_file
2318
19+ from reolinkfw .uboot import get_arch_name , get_uboot_version , get_uimage_header
2420from reolinkfw .util import (
2521 DummyLEB ,
22+ FileType ,
2623 get_cache_file ,
2724 get_fs_from_ubi ,
2825 has_cache ,
3936FS_SECTIONS = ROOTFS_SECTIONS + ["app" ]
4037
4138
42- class FileSystem (Enum ):
43- CRAMFS = CRAMFS_MAGIC
44- SQUASHFS = SQUASHFS_MAGIC .to_bytes (4 , "little" )
45- UBI = UBI_MAGIC # Not a file system
46- UBIFS = UBIFS_MAGIC
47-
48- @classmethod
49- def from_magic (cls , key , default = None ):
50- try :
51- return cls (key )
52- except ValueError :
53- return default
54-
55-
5639async def download (url ):
5740 """Return resource as bytes.
5841
@@ -118,10 +101,10 @@ def get_files_from_ubifs(binbytes):
118101
119102def get_files_from_ubi (fd , size , offset = 0 ):
120103 fsbytes = get_fs_from_ubi (fd , size , offset )
121- fs = FileSystem .from_magic (fsbytes [:4 ])
122- if fs == FileSystem .UBIFS :
104+ fs = FileType .from_magic (fsbytes [:4 ])
105+ if fs == FileType .UBIFS :
123106 return get_files_from_ubifs (fsbytes )
124- elif fs == FileSystem .SQUASHFS :
107+ elif fs == FileType .SQUASHFS :
125108 return get_files_from_squashfs (io .BytesIO (fsbytes ))
126109 raise Exception ("Unknown file system in UBI" )
127110
@@ -150,7 +133,7 @@ def get_fs_info(pak: PAK, fs_sections: list[Section]) -> list[dict[str, str]]:
150133 result = []
151134 for section in fs_sections :
152135 pak ._fd .seek (section .start )
153- fs = FileSystem .from_magic (pak ._fd .read (4 ))
136+ fs = FileType .from_magic (pak ._fd .read (4 ))
154137 result .append ({
155138 "name" : section .name ,
156139 "type" : fs .name .lower () if fs is not None else "unknown"
@@ -163,17 +146,25 @@ async def get_info_from_pak(pak: PAK):
163146 fs_sections = [s for s in pak .sections if s .name in FS_SECTIONS ]
164147 app = fs_sections [- 1 ]
165148 pak ._fd .seek (app .start )
166- fs = FileSystem .from_magic (pak ._fd .read (4 ))
167- if fs == FileSystem .CRAMFS :
149+ fs = FileType .from_magic (pak ._fd .read (4 ))
150+ if fs == FileType .CRAMFS :
168151 files = await asyncio .to_thread (get_files_from_cramfs , pak ._fd , app .start , False )
169- elif fs == FileSystem .UBI :
152+ elif fs == FileType .UBI :
170153 files = await asyncio .to_thread (get_files_from_ubi , pak ._fd , app .len , app .start )
171- elif fs == FileSystem .SQUASHFS :
154+ elif fs == FileType .SQUASHFS :
172155 files = await asyncio .to_thread (get_files_from_squashfs , pak ._fd , app .start , False )
173156 else :
174157 return {"error" : "Unrecognized image type" , "sha256" : ha }
175- info = get_info_from_files (files )
176- return {** info , "filesystems" : get_fs_info (pak , fs_sections ), "sha256" : ha }
158+ uimage = get_uimage_header (pak )
159+ return {
160+ ** get_info_from_files (files ),
161+ "os" : "Linux" if uimage .os == 5 else "Unknown" ,
162+ "architecture" : get_arch_name (uimage .arch ),
163+ "kernel_image_name" : uimage .name ,
164+ "uboot_version" : get_uboot_version (pak ),
165+ "filesystems" : get_fs_info (pak , fs_sections ),
166+ "sha256" : ha
167+ }
177168
178169
179170async def direct_download_url (url ):
0 commit comments