punchboot 2.0.0__tar.gz → 2.2.0__tar.gz
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.
- {punchboot-2.0.0 → punchboot-2.2.0}/PKG-INFO +1 -1
- {punchboot-2.0.0 → punchboot-2.2.0}/punchboot.egg-info/PKG-INFO +1 -1
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/punchboot/__init__.py +2 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/punchboot/helpers.py +2 -1
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/punchboot/session.py +29 -10
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/python_wrapper.c +34 -10
- {punchboot-2.0.0 → punchboot-2.2.0}/LICENSE +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/README.md +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/punchboot.egg-info/SOURCES.txt +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/punchboot.egg-info/dependency_links.txt +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/punchboot.egg-info/entry_points.txt +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/punchboot.egg-info/requires.txt +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/punchboot.egg-info/top_level.txt +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/pyproject.toml +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/setup.cfg +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/setup.py +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/src/lib/bpak.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/src/wire.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_authentication.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_board.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_boot.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_device.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_misc.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_partition.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_slc.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/api_stream.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/error.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/exceptions.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/punchboot/__main__.py +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/punchboot/partition.py +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/punchboot/py.typed +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/punchboot/slc.py +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/socket.c +0 -0
- {punchboot-2.0.0 → punchboot-2.2.0}/tools/punchboot/usb.c +0 -0
|
@@ -4,6 +4,7 @@ from _punchboot import ( # type: ignore # noqa: F401
|
|
|
4
4
|
ArgumentError,
|
|
5
5
|
AuthenticationError,
|
|
6
6
|
CommandError,
|
|
7
|
+
Error,
|
|
7
8
|
GenericError,
|
|
8
9
|
IOError,
|
|
9
10
|
KeyRevokedError,
|
|
@@ -26,6 +27,7 @@ from .session import Session
|
|
|
26
27
|
from .slc import SLC
|
|
27
28
|
|
|
28
29
|
_pb_exceptions = [
|
|
30
|
+
"Error",
|
|
29
31
|
"GenericError",
|
|
30
32
|
"AuthenticationError",
|
|
31
33
|
"NotAuthenticatedError",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Various punchboot helper functions."""
|
|
2
2
|
|
|
3
3
|
import uuid
|
|
4
|
+
from importlib.metadata import version
|
|
4
5
|
from typing import Iterable
|
|
5
6
|
|
|
6
7
|
import _punchboot # type: ignore
|
|
@@ -9,7 +10,7 @@ import semver
|
|
|
9
10
|
|
|
10
11
|
def library_version() -> semver.Version:
|
|
11
12
|
"""Return the version string of the C library."""
|
|
12
|
-
return semver.
|
|
13
|
+
return semver.Version.parse(version('punchboot'))
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def pb_id(cmd: str) -> int:
|
|
@@ -7,7 +7,7 @@ import hashlib
|
|
|
7
7
|
import io
|
|
8
8
|
import pathlib
|
|
9
9
|
import uuid
|
|
10
|
-
from typing import Any, Callable, Iterable, Optional, Tuple, Union
|
|
10
|
+
from typing import IO, Any, Callable, Iterable, Optional, Tuple, Union
|
|
11
11
|
|
|
12
12
|
import _punchboot # type: ignore
|
|
13
13
|
import semver
|
|
@@ -17,6 +17,18 @@ from .partition import Partition, PartitionFlags
|
|
|
17
17
|
from .slc import SLC
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
def _has_fileno(file: IO[bytes]) -> bool:
|
|
21
|
+
if not hasattr(file, "fileno"):
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
file.fileno()
|
|
26
|
+
except io.UnsupportedOperation:
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
|
|
20
32
|
class Session(object):
|
|
21
33
|
"""Punchboot session class.
|
|
22
34
|
|
|
@@ -45,6 +57,13 @@ class Session(object):
|
|
|
45
57
|
)
|
|
46
58
|
self._s = _punchboot.Session(_device_uuid, _socket_path)
|
|
47
59
|
|
|
60
|
+
def close(self):
|
|
61
|
+
"""Close the current session.
|
|
62
|
+
|
|
63
|
+
This will invalidate the session object.
|
|
64
|
+
"""
|
|
65
|
+
self._s.close()
|
|
66
|
+
|
|
48
67
|
def authenticate(self, password: str):
|
|
49
68
|
"""Authenticate session using a password.
|
|
50
69
|
|
|
@@ -101,7 +120,7 @@ class Session(object):
|
|
|
101
120
|
]
|
|
102
121
|
|
|
103
122
|
def part_verify(
|
|
104
|
-
self, file: Union[pathlib.Path,
|
|
123
|
+
self, file: Union[pathlib.Path, IO[bytes], bytes], part: Union[uuid.UUID, str]
|
|
105
124
|
):
|
|
106
125
|
"""Verify the contents of a partition.
|
|
107
126
|
|
|
@@ -123,7 +142,7 @@ class Session(object):
|
|
|
123
142
|
_bpak_header_valid: bool = False
|
|
124
143
|
_hash_ctx = hashlib.sha256()
|
|
125
144
|
|
|
126
|
-
def _chunk_reader(fh:
|
|
145
|
+
def _chunk_reader(fh: IO[bytes]) -> int:
|
|
127
146
|
_length: int = 0
|
|
128
147
|
nonlocal _bpak_header_valid
|
|
129
148
|
# Check if the first 4k contains a valid BPAK header
|
|
@@ -141,18 +160,18 @@ class Session(object):
|
|
|
141
160
|
if isinstance(file, pathlib.Path):
|
|
142
161
|
with file.open("rb") as f:
|
|
143
162
|
_data_length = _chunk_reader(f)
|
|
144
|
-
elif isinstance(file, io.BufferedReader):
|
|
145
|
-
_data_length = _chunk_reader(file)
|
|
146
163
|
elif isinstance(file, bytes):
|
|
147
164
|
_hash_ctx.update(file)
|
|
148
165
|
_bpak_header_valid = valid_bpak_magic(file)
|
|
149
166
|
_data_length = len(file)
|
|
167
|
+
elif _has_fileno(file):
|
|
168
|
+
_data_length = _chunk_reader(file)
|
|
150
169
|
else:
|
|
151
170
|
raise ValueError("Unacceptable input")
|
|
152
171
|
|
|
153
172
|
self._s.part_verify(_uu.bytes, _hash_ctx.digest(), _data_length, _bpak_header_valid)
|
|
154
173
|
|
|
155
|
-
def part_write(self, file: Union[pathlib.Path,
|
|
174
|
+
def part_write(self, file: Union[pathlib.Path, IO[bytes]], part: Union[uuid.UUID, str]):
|
|
156
175
|
"""Write data to a partition.
|
|
157
176
|
|
|
158
177
|
Keyword arguments:
|
|
@@ -163,12 +182,12 @@ class Session(object):
|
|
|
163
182
|
if isinstance(file, pathlib.Path):
|
|
164
183
|
with file.open("rb") as f:
|
|
165
184
|
self._s.part_write(f, _uu.bytes)
|
|
166
|
-
elif
|
|
185
|
+
elif _has_fileno(file):
|
|
167
186
|
self._s.part_write(file, _uu.bytes)
|
|
168
187
|
else:
|
|
169
188
|
raise ValueError("Unacceptable input")
|
|
170
189
|
|
|
171
|
-
def part_read(self, file: Union[pathlib.Path,
|
|
190
|
+
def part_read(self, file: Union[pathlib.Path, IO[bytes]], part: Union[uuid.UUID, str]):
|
|
172
191
|
"""Read data from a partition to a file.
|
|
173
192
|
|
|
174
193
|
Keyword arguments:
|
|
@@ -179,7 +198,7 @@ class Session(object):
|
|
|
179
198
|
if isinstance(file, pathlib.Path):
|
|
180
199
|
with file.open("wb") as f:
|
|
181
200
|
self._s.part_read(f, _uu.bytes)
|
|
182
|
-
elif
|
|
201
|
+
elif _has_fileno(file):
|
|
183
202
|
self._s.part_read(file, _uu.bytes)
|
|
184
203
|
else:
|
|
185
204
|
raise ValueError("Unacceptable input")
|
|
@@ -330,7 +349,7 @@ class Session(object):
|
|
|
330
349
|
_ver_str: str = self._s.device_get_punchboot_version()
|
|
331
350
|
if _ver_str.startswith("v"):
|
|
332
351
|
_ver_str = _ver_str[1:]
|
|
333
|
-
return semver.
|
|
352
|
+
return semver.Version.parse(_ver_str)
|
|
334
353
|
|
|
335
354
|
def device_get_uuid(self) -> uuid.UUID:
|
|
336
355
|
"""Read the device UUID."""
|
|
@@ -24,17 +24,25 @@
|
|
|
24
24
|
|
|
25
25
|
static int log_cb(struct pb_context *ctx, int level, const char *fmt, ...)
|
|
26
26
|
{
|
|
27
|
-
static PyObject *
|
|
27
|
+
static PyObject *logger = NULL;
|
|
28
28
|
static PyObject *log_msg = NULL;
|
|
29
29
|
char msg_buf[1024];
|
|
30
30
|
int rc;
|
|
31
31
|
(void)ctx;
|
|
32
32
|
(void)level;
|
|
33
33
|
|
|
34
|
-
if (
|
|
35
|
-
logging = PyImport_ImportModuleNoBlock("logging");
|
|
34
|
+
if (logger == NULL) {
|
|
35
|
+
PyObject *logging = PyImport_ImportModuleNoBlock("logging");
|
|
36
36
|
if (logging == NULL) {
|
|
37
37
|
PyErr_SetString(PyExc_ImportError, "Could not import module 'logging'");
|
|
38
|
+
return -1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
logger = PyObject_CallMethod(logging, "getLogger", "s", "pb");
|
|
42
|
+
|
|
43
|
+
if (logger == NULL) {
|
|
44
|
+
PyErr_SetString(PyExc_RuntimeError, "Can't configure logger");
|
|
45
|
+
return -1;
|
|
38
46
|
}
|
|
39
47
|
}
|
|
40
48
|
|
|
@@ -48,7 +56,7 @@ static int log_cb(struct pb_context *ctx, int level, const char *fmt, ...)
|
|
|
48
56
|
msg_buf[rc - 1] = 0;
|
|
49
57
|
|
|
50
58
|
log_msg = Py_BuildValue("s", msg_buf);
|
|
51
|
-
PyObject_CallMethod(
|
|
59
|
+
PyObject_CallMethod(logger, "debug", "O", log_msg);
|
|
52
60
|
Py_DECREF(log_msg);
|
|
53
61
|
}
|
|
54
62
|
va_end(args);
|
|
@@ -124,14 +132,27 @@ static int PbSession_init(struct pb_session *self, PyObject *args, PyObject *kwd
|
|
|
124
132
|
return 0;
|
|
125
133
|
}
|
|
126
134
|
|
|
127
|
-
static void
|
|
135
|
+
static void close_pb_session(struct pb_session *self)
|
|
128
136
|
{
|
|
129
137
|
if (self->ctx) {
|
|
130
138
|
pb_api_free_context(self->ctx);
|
|
131
139
|
}
|
|
140
|
+
self->ctx = NULL;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static void PbSession_dealloc(struct pb_session *self)
|
|
144
|
+
{
|
|
145
|
+
close_pb_session(self);
|
|
132
146
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
|
133
147
|
}
|
|
134
148
|
|
|
149
|
+
static PyObject *session_close(PyObject *self, PyObject *Py_UNUSED(args))
|
|
150
|
+
{
|
|
151
|
+
struct pb_session *session = (struct pb_session *)self;
|
|
152
|
+
close_pb_session(session);
|
|
153
|
+
Py_RETURN_NONE;
|
|
154
|
+
}
|
|
155
|
+
|
|
135
156
|
static PyObject *authenticate(PyObject *self, PyObject *args, PyObject *kwds)
|
|
136
157
|
{
|
|
137
158
|
struct pb_session *session = (struct pb_session *)self;
|
|
@@ -849,6 +870,10 @@ static PyObject *board_run_command(PyObject *self, PyObject *args, PyObject *kwd
|
|
|
849
870
|
}
|
|
850
871
|
|
|
851
872
|
static PyMethodDef PbSession_methods[] = {
|
|
873
|
+
{ "close",
|
|
874
|
+
session_close,
|
|
875
|
+
METH_NOARGS,
|
|
876
|
+
"Close the current session (invalidates the session object)" },
|
|
852
877
|
/* Password API */
|
|
853
878
|
{
|
|
854
879
|
"authenticate",
|
|
@@ -1042,13 +1067,12 @@ static PyObject *wait_for_device(PyObject *self, PyObject *args, PyObject *kwds)
|
|
|
1042
1067
|
|
|
1043
1068
|
while (true) {
|
|
1044
1069
|
rc = init_transport(NULL, NULL, &ctx);
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1070
|
+
|
|
1071
|
+
if (rc == PB_RESULT_OK) {
|
|
1072
|
+
rc = get_uuid(ctx, uuid);
|
|
1073
|
+
pb_api_free_context(ctx);
|
|
1048
1074
|
}
|
|
1049
1075
|
|
|
1050
|
-
rc = get_uuid(ctx, uuid);
|
|
1051
|
-
pb_api_free_context(ctx);
|
|
1052
1076
|
if (rc != PB_RESULT_OK) {
|
|
1053
1077
|
if (timeout > 0) {
|
|
1054
1078
|
sleep(1);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|