dissect.target 3.19.dev25__py3-none-any.whl → 3.19.dev26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dissect/target/tools/fs.py +92 -14
- {dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/RECORD +8 -8
- {dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/WHEEL +0 -0
- {dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/top_level.txt +0 -0
dissect/target/tools/fs.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# -*- coding: utf-8 -*-
|
3
3
|
|
4
4
|
import argparse
|
5
|
+
import datetime
|
5
6
|
import logging
|
6
7
|
import operator
|
7
8
|
import os
|
@@ -12,6 +13,7 @@ import sys
|
|
12
13
|
from dissect.target import Target
|
13
14
|
from dissect.target.exceptions import TargetError
|
14
15
|
from dissect.target.helpers.fsutil import TargetPath
|
16
|
+
from dissect.target.tools.shell import stat_modestr
|
15
17
|
from dissect.target.tools.utils import (
|
16
18
|
catch_sigpipe,
|
17
19
|
configure_generic_arguments,
|
@@ -23,24 +25,90 @@ logging.lastResort = None
|
|
23
25
|
logging.raiseExceptions = False
|
24
26
|
|
25
27
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
28
|
+
def human_size(bytes: int, units: list[str] = ["", "K", "M", "G", "T", "P", "E"]) -> str:
|
29
|
+
"""Helper function to return the human readable string representation of bytes."""
|
30
|
+
return str(bytes) + units[0] if bytes < 1024 else human_size(bytes >> 10, units[1:])
|
29
31
|
|
30
32
|
|
31
|
-
def
|
33
|
+
def ls(t: Target, path: TargetPath, args: argparse.Namespace) -> None:
|
34
|
+
if args.use_ctime and args.use_atime:
|
35
|
+
log.error("Can't specify -c and -u at the same time")
|
36
|
+
return
|
37
|
+
if not path or not path.exists():
|
38
|
+
return
|
39
|
+
|
40
|
+
_print_ls(args, path, 0)
|
41
|
+
|
42
|
+
|
43
|
+
def _print_ls(args: argparse.Namespace, path: TargetPath, depth: int) -> None:
|
44
|
+
subdirs = []
|
45
|
+
|
46
|
+
if path.is_dir():
|
47
|
+
contents = sorted(path.iterdir(), key=operator.attrgetter("name"))
|
48
|
+
elif path.is_file():
|
49
|
+
contents = [path]
|
50
|
+
|
51
|
+
if depth > 0:
|
52
|
+
print(f"\n{str(path)}:")
|
53
|
+
|
54
|
+
if not args.l:
|
55
|
+
for entry in contents:
|
56
|
+
print(entry.name)
|
57
|
+
|
58
|
+
if entry.is_dir():
|
59
|
+
subdirs.append(entry)
|
60
|
+
else:
|
61
|
+
if len(contents) > 1:
|
62
|
+
print(f"total {len(contents)}")
|
63
|
+
|
64
|
+
for entry in contents:
|
65
|
+
_print_extensive_file_stat(args, entry, entry.name)
|
66
|
+
|
67
|
+
if entry.is_dir():
|
68
|
+
subdirs.append(entry)
|
69
|
+
|
70
|
+
if args.recursive and subdirs:
|
71
|
+
for subdir in subdirs:
|
72
|
+
_print_ls(args, subdir, depth + 1)
|
73
|
+
|
74
|
+
|
75
|
+
def _print_extensive_file_stat(args: argparse.Namespace, path: TargetPath, name: str) -> None:
|
76
|
+
try:
|
77
|
+
entry = path.get()
|
78
|
+
stat = entry.lstat()
|
79
|
+
symlink = f" -> {entry.readlink()}" if entry.is_symlink() else ""
|
80
|
+
show_time = stat.st_mtime
|
81
|
+
|
82
|
+
if args.use_ctime:
|
83
|
+
show_time = stat.st_ctime
|
84
|
+
elif args.use_atime:
|
85
|
+
show_time = stat.st_atime
|
86
|
+
|
87
|
+
utc_time = datetime.datetime.utcfromtimestamp(show_time).isoformat()
|
88
|
+
|
89
|
+
if args.human_readable:
|
90
|
+
size = human_size(stat.st_size)
|
91
|
+
else:
|
92
|
+
size = stat.st_size
|
93
|
+
|
94
|
+
print(f"{stat_modestr(stat)} {stat.st_uid:4d} {stat.st_gid:4d} {size:>6s} {utc_time} {name}{symlink}")
|
95
|
+
except FileNotFoundError:
|
96
|
+
print(f"?????????? ? ? ? ????-??-??T??:??:??.?????? {name}")
|
97
|
+
|
98
|
+
|
99
|
+
def cat(t: Target, path: TargetPath, args: argparse.Namespace) -> None:
|
32
100
|
stdout = sys.stdout
|
33
101
|
if hasattr(stdout, "buffer"):
|
34
102
|
stdout = stdout.buffer
|
35
103
|
shutil.copyfileobj(path.open(), stdout)
|
36
104
|
|
37
105
|
|
38
|
-
def walk(t, path, args):
|
106
|
+
def walk(t: Target, path: TargetPath, args: argparse.Namespace) -> None:
|
39
107
|
for e in path.rglob("*"):
|
40
108
|
print(str(e))
|
41
109
|
|
42
110
|
|
43
|
-
def cp(t, path, args):
|
111
|
+
def cp(t: Target, path: TargetPath, args: argparse.Namespace) -> None:
|
44
112
|
output = os.path.abspath(os.path.expanduser(args.output))
|
45
113
|
if path.is_file():
|
46
114
|
_extract_path(path, os.path.join(output, path.name))
|
@@ -75,7 +143,7 @@ def _extract_path(path: TargetPath, output_path: str) -> None:
|
|
75
143
|
|
76
144
|
|
77
145
|
@catch_sigpipe
|
78
|
-
def main():
|
146
|
+
def main() -> None:
|
79
147
|
help_formatter = argparse.ArgumentDefaultsHelpFormatter
|
80
148
|
parser = argparse.ArgumentParser(
|
81
149
|
description="dissect.target",
|
@@ -85,24 +153,34 @@ def main():
|
|
85
153
|
parser.add_argument("target", type=pathlib.Path, help="Target to load", metavar="TARGET")
|
86
154
|
|
87
155
|
baseparser = argparse.ArgumentParser(add_help=False)
|
88
|
-
baseparser.add_argument("path", type=str, help="
|
156
|
+
baseparser.add_argument("path", type=str, help="path to perform an action on", metavar="PATH")
|
89
157
|
|
90
|
-
subparsers = parser.add_subparsers(dest="subcommand", help="
|
91
|
-
parser_ls = subparsers.add_parser(
|
158
|
+
subparsers = parser.add_subparsers(dest="subcommand", help="subcommands for performing various actions")
|
159
|
+
parser_ls = subparsers.add_parser(
|
160
|
+
"ls", help="Show a directory listing", parents=[baseparser], conflict_handler="resolve"
|
161
|
+
)
|
162
|
+
parser_ls.add_argument("-l", action="store_true")
|
163
|
+
parser_ls.add_argument("-a", "--all", action="store_true") # ignored but included for proper argument parsing
|
164
|
+
parser_ls.add_argument("-h", "--human-readable", action="store_true")
|
165
|
+
parser_ls.add_argument("-R", "--recursive", action="store_true", help="recursively list subdirectories encountered")
|
166
|
+
parser_ls.add_argument(
|
167
|
+
"-c", action="store_true", dest="use_ctime", help="show time when file status was last changed"
|
168
|
+
)
|
169
|
+
parser_ls.add_argument("-u", action="store_true", dest="use_atime", help="show time of last access")
|
92
170
|
parser_ls.set_defaults(handler=ls)
|
93
171
|
|
94
|
-
parser_cat = subparsers.add_parser("cat", help="
|
172
|
+
parser_cat = subparsers.add_parser("cat", help="dump file contents", parents=[baseparser])
|
95
173
|
parser_cat.set_defaults(handler=cat)
|
96
174
|
|
97
|
-
parser_find = subparsers.add_parser("walk", help="
|
175
|
+
parser_find = subparsers.add_parser("walk", help="perform a walk", parents=[baseparser])
|
98
176
|
parser_find.set_defaults(handler=walk)
|
99
177
|
|
100
178
|
parser_cp = subparsers.add_parser(
|
101
179
|
"cp",
|
102
|
-
help="
|
180
|
+
help="copy multiple files to a directory specified by --output",
|
103
181
|
parents=[baseparser],
|
104
182
|
)
|
105
|
-
parser_cp.add_argument("-o", "--output", type=str, default=".", help="
|
183
|
+
parser_cp.add_argument("-o", "--output", type=str, default=".", help="output directory")
|
106
184
|
parser_cp.set_defaults(handler=cp)
|
107
185
|
|
108
186
|
configure_generic_arguments(parser)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.19.
|
3
|
+
Version: 3.19.dev26
|
4
4
|
Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
6
6
|
License: Affero General Public License v3
|
@@ -325,7 +325,7 @@ dissect/target/plugins/os/windows/task_helpers/tasks_xml.py,sha256=oOsYse2-BrliV
|
|
325
325
|
dissect/target/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
326
326
|
dissect/target/tools/build_pluginlist.py,sha256=5fomcuMwsVzcnYx5Htf5f9lSwsLeUUvomLUXNA4t7m4,849
|
327
327
|
dissect/target/tools/dd.py,sha256=rTM-lgXxrYBpVAtJqFqAatDz45bLoD8-mFt_59Q3Lio,1928
|
328
|
-
dissect/target/tools/fs.py,sha256=
|
328
|
+
dissect/target/tools/fs.py,sha256=bdFSckOO-dyvvBpxOgPIx_UKGEbWGbOHF7kl6rWyt7U,6654
|
329
329
|
dissect/target/tools/info.py,sha256=3smHr8I71yj3kCjsQ5nXkOHI9T_N8UwvkVa1CNOxB-s,5461
|
330
330
|
dissect/target/tools/logging.py,sha256=5ZnumtMWLyslxfrUGZ4ntRyf3obOOhmn8SBjKfdLcEg,4174
|
331
331
|
dissect/target/tools/mount.py,sha256=L_0tSmiBdW4aSaF0vXjB0bAkTC0kmT2N1hrbW6s5Jow,3254
|
@@ -346,10 +346,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
346
346
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
347
347
|
dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
|
348
348
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
349
|
-
dissect.target-3.19.
|
350
|
-
dissect.target-3.19.
|
351
|
-
dissect.target-3.19.
|
352
|
-
dissect.target-3.19.
|
353
|
-
dissect.target-3.19.
|
354
|
-
dissect.target-3.19.
|
355
|
-
dissect.target-3.19.
|
349
|
+
dissect.target-3.19.dev26.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
350
|
+
dissect.target-3.19.dev26.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
351
|
+
dissect.target-3.19.dev26.dist-info/METADATA,sha256=JqWUrdsr0XSeyFrdAPCqZYCIrmYfCWdPRFP13XZ4v1o,12719
|
352
|
+
dissect.target-3.19.dev26.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
353
|
+
dissect.target-3.19.dev26.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
354
|
+
dissect.target-3.19.dev26.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
355
|
+
dissect.target-3.19.dev26.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.19.dev25.dist-info → dissect.target-3.19.dev26.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|