mirror of
https://github.com/fosslinux/live-bootstrap.git
synced 2026-03-23 11:36:32 +01:00
fix(payload): switch raw payload metadata fields from u32 to u64
This commit is contained in:
parent
b8785e3742
commit
c742563d3b
4 changed files with 73 additions and 60 deletions
|
|
@ -43,10 +43,10 @@ The flow is:
|
||||||
### Format
|
### Format
|
||||||
|
|
||||||
- Magic: `LBPAYLD1` (8 bytes)
|
- Magic: `LBPAYLD1` (8 bytes)
|
||||||
- Then: little-endian `u32` file count
|
- Then: little-endian `u64` file count
|
||||||
- Repeated entries:
|
- Repeated entries:
|
||||||
- little-endian `u32` name length
|
- little-endian `u64` name length
|
||||||
- little-endian `u32` file size
|
- little-endian `u64` file size
|
||||||
- file name bytes (no terminator)
|
- file name bytes (no terminator)
|
||||||
- file bytes
|
- file bytes
|
||||||
|
|
||||||
|
|
@ -69,21 +69,21 @@ set -e
|
||||||
out="${1:-external.img}"
|
out="${1:-external.img}"
|
||||||
list="${2:-external.list}"
|
list="${2:-external.list}"
|
||||||
|
|
||||||
write_u32le() {
|
write_u64le() {
|
||||||
v="$1"
|
v="$1"
|
||||||
printf '%08x' "$v" | sed -E 's/(..)(..)(..)(..)/\4\3\2\1/' | xxd -r -p
|
printf '%016x' "$v" | sed -E 's/(..)(..)(..)(..)(..)(..)(..)(..)/\8\7\6\5\4\3\2\1/' | xxd -r -p
|
||||||
}
|
}
|
||||||
|
|
||||||
count="$(wc -l < "${list}" | tr -d ' ')"
|
count="$(wc -l < "${list}" | tr -d ' ')"
|
||||||
: > "${out}"
|
: > "${out}"
|
||||||
printf 'LBPAYLD1' >> "${out}"
|
printf 'LBPAYLD1' >> "${out}"
|
||||||
write_u32le "${count}" >> "${out}"
|
write_u64le "${count}" >> "${out}"
|
||||||
|
|
||||||
while read -r name path; do
|
while read -r name path; do
|
||||||
[ -n "${name}" ] || continue
|
[ -n "${name}" ] || continue
|
||||||
size="$(wc -c < "${path}" | tr -d ' ')"
|
size="$(wc -c < "${path}" | tr -d ' ')"
|
||||||
write_u32le "${#name}" >> "${out}"
|
write_u64le "${#name}" >> "${out}"
|
||||||
write_u32le "${size}" >> "${out}"
|
write_u64le "${size}" >> "${out}"
|
||||||
printf '%s' "${name}" >> "${out}"
|
printf '%s' "${name}" >> "${out}"
|
||||||
cat "${path}" >> "${out}"
|
cat "${path}" >> "${out}"
|
||||||
done < "${list}"
|
done < "${list}"
|
||||||
|
|
|
||||||
16
README.rst
16
README.rst
|
|
@ -71,9 +71,9 @@ Without using Python:
|
||||||
reach the importer; the rest of the distfiles live in ``external.img``.
|
reach the importer; the rest of the distfiles live in ``external.img``.
|
||||||
|
|
||||||
* Header magic: ``LBPAYLD1`` (8 bytes).
|
* Header magic: ``LBPAYLD1`` (8 bytes).
|
||||||
* Then: little-endian ``u32`` file count.
|
* Then: little-endian ``u64`` file count.
|
||||||
* Repeated for each file: little-endian ``u32`` name length,
|
* Repeated for each file: little-endian ``u64`` name length,
|
||||||
little-endian ``u32`` file size, raw file name bytes, raw file bytes.
|
little-endian ``u64`` file size, raw file name bytes, raw file bytes.
|
||||||
|
|
||||||
* With ``--repo``, the second disk remains an ext3 distfiles/repo disk.
|
* With ``--repo``, the second disk remains an ext3 distfiles/repo disk.
|
||||||
* Without ``--external-sources`` and without ``--repo``, no second disk is
|
* Without ``--external-sources`` and without ``--repo``, no second disk is
|
||||||
|
|
@ -104,21 +104,21 @@ with ``--external-sources`` (and no ``--repo``).
|
||||||
out="${1:-external.img}"
|
out="${1:-external.img}"
|
||||||
list="${2:-external.list}"
|
list="${2:-external.list}"
|
||||||
|
|
||||||
write_u32le() {
|
write_u64le() {
|
||||||
v="$1"
|
v="$1"
|
||||||
printf '%08x' "$v" | sed -E 's/(..)(..)(..)(..)/\4\3\2\1/' | xxd -r -p
|
printf '%016x' "$v" | sed -E 's/(..)(..)(..)(..)(..)(..)(..)(..)/\8\7\6\5\4\3\2\1/' | xxd -r -p
|
||||||
}
|
}
|
||||||
|
|
||||||
count="$(wc -l < "${list}" | tr -d ' ')"
|
count="$(wc -l < "${list}" | tr -d ' ')"
|
||||||
: > "${out}"
|
: > "${out}"
|
||||||
printf 'LBPAYLD1' >> "${out}"
|
printf 'LBPAYLD1' >> "${out}"
|
||||||
write_u32le "${count}" >> "${out}"
|
write_u64le "${count}" >> "${out}"
|
||||||
|
|
||||||
while read -r name path; do
|
while read -r name path; do
|
||||||
[ -n "${name}" ] || continue
|
[ -n "${name}" ] || continue
|
||||||
size="$(wc -c < "${path}" | tr -d ' ')"
|
size="$(wc -c < "${path}" | tr -d ' ')"
|
||||||
write_u32le "${#name}" >> "${out}"
|
write_u64le "${#name}" >> "${out}"
|
||||||
write_u32le "${size}" >> "${out}"
|
write_u64le "${size}" >> "${out}"
|
||||||
printf '%s' "${name}" >> "${out}"
|
printf '%s' "${name}" >> "${out}"
|
||||||
cat "${path}" >> "${out}"
|
cat "${path}" >> "${out}"
|
||||||
done < "${list}"
|
done < "${list}"
|
||||||
|
|
|
||||||
|
|
@ -153,18 +153,20 @@ class Generator():
|
||||||
ordered_names = sorted(files_by_name.keys())
|
ordered_names = sorted(files_by_name.keys())
|
||||||
with open(container_path, "wb") as container:
|
with open(container_path, "wb") as container:
|
||||||
container.write(self.raw_container_magic)
|
container.write(self.raw_container_magic)
|
||||||
container.write(struct.pack("<I", len(ordered_names)))
|
if len(ordered_names) > 0xFFFFFFFFFFFFFFFF:
|
||||||
|
raise ValueError("Too many files for raw container format.")
|
||||||
|
container.write(struct.pack("<Q", len(ordered_names)))
|
||||||
for file_name in ordered_names:
|
for file_name in ordered_names:
|
||||||
file_name_bytes = file_name.encode("utf_8")
|
file_name_bytes = file_name.encode("utf_8")
|
||||||
if len(file_name_bytes) > 0xFFFFFFFF:
|
if len(file_name_bytes) > 0xFFFFFFFFFFFFFFFF:
|
||||||
raise ValueError(f"Container file name too long: {file_name}")
|
raise ValueError(f"Container file name too long: {file_name}")
|
||||||
|
|
||||||
src_path = os.path.join(self.distfiles_dir, file_name)
|
src_path = os.path.join(self.distfiles_dir, file_name)
|
||||||
file_size = os.path.getsize(src_path)
|
file_size = os.path.getsize(src_path)
|
||||||
if file_size > 0xFFFFFFFF:
|
if file_size > 0xFFFFFFFFFFFFFFFF:
|
||||||
raise ValueError(f"Container file too large for raw container format: {file_name}")
|
raise ValueError(f"Container file too large for raw container format: {file_name}")
|
||||||
|
|
||||||
container.write(struct.pack("<II", len(file_name_bytes), file_size))
|
container.write(struct.pack("<QQ", len(file_name_bytes), file_size))
|
||||||
container.write(file_name_bytes)
|
container.write(file_name_bytes)
|
||||||
|
|
||||||
with open(src_path, "rb") as src_file:
|
with open(src_path, "rb") as src_file:
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,21 @@
|
||||||
#define COPY_BUFSZ 65536
|
#define COPY_BUFSZ 65536
|
||||||
#define SYS_MOUNT 21
|
#define SYS_MOUNT 21
|
||||||
|
|
||||||
static unsigned int read_u32le(const unsigned char *buf)
|
static unsigned long long read_u64le(const unsigned char *buf)
|
||||||
{
|
{
|
||||||
return (unsigned int)buf[0]
|
return (unsigned long long)buf[0]
|
||||||
| ((unsigned int)buf[1] << 8)
|
| ((unsigned long long)buf[1] << 8)
|
||||||
| ((unsigned int)buf[2] << 16)
|
| ((unsigned long long)buf[2] << 16)
|
||||||
| ((unsigned int)buf[3] << 24);
|
| ((unsigned long long)buf[3] << 24)
|
||||||
|
| ((unsigned long long)buf[4] << 32)
|
||||||
|
| ((unsigned long long)buf[5] << 40)
|
||||||
|
| ((unsigned long long)buf[6] << 48)
|
||||||
|
| ((unsigned long long)buf[7] << 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_exact(FILE *in, void *buf, unsigned int len)
|
static int read_exact(FILE *in, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
unsigned int got = 0;
|
size_t got = 0;
|
||||||
unsigned char *out = (unsigned char *)buf;
|
unsigned char *out = (unsigned char *)buf;
|
||||||
|
|
||||||
while (got < len) {
|
while (got < len) {
|
||||||
|
|
@ -32,16 +36,16 @@ static int read_exact(FILE *in, void *buf, unsigned int len)
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
got += (unsigned int)n;
|
got += n;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int copy_exact(FILE *in, FILE *out, unsigned int len,
|
static int copy_exact(FILE *in, FILE *out, unsigned long long len,
|
||||||
const char *device, const char *name, const char *out_path)
|
const char *device, const char *name, const char *out_path)
|
||||||
{
|
{
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
unsigned int remaining = len;
|
unsigned long long remaining = len;
|
||||||
|
|
||||||
buf = (unsigned char *)malloc(COPY_BUFSZ);
|
buf = (unsigned char *)malloc(COPY_BUFSZ);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
|
|
@ -50,24 +54,27 @@ static int copy_exact(FILE *in, FILE *out, unsigned int len,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
unsigned int chunk = remaining;
|
size_t chunk = (size_t)COPY_BUFSZ;
|
||||||
unsigned int copied = len - remaining;
|
unsigned long long copied = len - remaining;
|
||||||
size_t nread;
|
size_t nread;
|
||||||
size_t written;
|
size_t written;
|
||||||
if (chunk > COPY_BUFSZ) {
|
if (remaining < (unsigned long long)COPY_BUFSZ) {
|
||||||
chunk = COPY_BUFSZ;
|
chunk = (size_t)remaining;
|
||||||
}
|
}
|
||||||
nread = fread(buf, 1, chunk, in);
|
nread = fread(buf, 1, chunk, in);
|
||||||
if (nread != chunk) {
|
if (nread != chunk) {
|
||||||
if (feof(in)) {
|
if (feof(in)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"payload-import: truncated payload while reading %s from %s "
|
"payload-import: truncated payload while reading %s from %s "
|
||||||
"(offset=%u wanted=%u got=%u)\n",
|
"(offset=%llu wanted=%llu got=%llu)\n",
|
||||||
name, device, copied, chunk, (unsigned int)nread);
|
name, device,
|
||||||
|
copied,
|
||||||
|
(unsigned long long)chunk,
|
||||||
|
(unsigned long long)nread);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"payload-import: read error while reading %s from %s "
|
"payload-import: read error while reading %s from %s "
|
||||||
"(offset=%u): %s\n",
|
"(offset=%llu): %s\n",
|
||||||
name, device, copied, strerror(errno));
|
name, device, copied, strerror(errno));
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
@ -77,12 +84,16 @@ static int copy_exact(FILE *in, FILE *out, unsigned int len,
|
||||||
if (written != chunk) {
|
if (written != chunk) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"payload-import: write error while writing %s to %s "
|
"payload-import: write error while writing %s to %s "
|
||||||
"(offset=%u wanted=%u wrote=%u): %s\n",
|
"(offset=%llu wanted=%llu wrote=%llu): %s\n",
|
||||||
name, out_path, copied, chunk, (unsigned int)written, strerror(errno));
|
name, out_path,
|
||||||
|
copied,
|
||||||
|
(unsigned long long)chunk,
|
||||||
|
(unsigned long long)written,
|
||||||
|
strerror(errno));
|
||||||
free(buf);
|
free(buf);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
remaining -= chunk;
|
remaining -= (unsigned long long)chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
@ -133,7 +144,7 @@ static int sys_mount(const char *source, const char *target,
|
||||||
const char *fstype, unsigned int flags, const void *data)
|
const char *fstype, unsigned int flags, const void *data)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
// Only for x86 fiwix/linux
|
/* Only for x86 fiwix/linux */
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"int $0x80"
|
"int $0x80"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
|
|
@ -178,9 +189,9 @@ static int extract_payload(const char *device, const char *dest_dir)
|
||||||
{
|
{
|
||||||
FILE *in;
|
FILE *in;
|
||||||
char magic[MAGIC_LEN];
|
char magic[MAGIC_LEN];
|
||||||
unsigned char u32buf[4];
|
unsigned char u64buf[8];
|
||||||
unsigned int file_count;
|
unsigned long long file_count;
|
||||||
unsigned int i;
|
unsigned long long i;
|
||||||
|
|
||||||
in = fopen(device, "rb");
|
in = fopen(device, "rb");
|
||||||
if (in == NULL) {
|
if (in == NULL) {
|
||||||
|
|
@ -194,15 +205,15 @@ static int extract_payload(const char *device, const char *dest_dir)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_exact(in, u32buf, 4) != 0) {
|
if (read_exact(in, u64buf, 8) != 0) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fputs("payload-import: malformed payload header\n", stderr);
|
fputs("payload-import: malformed payload header\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
file_count = read_u32le(u32buf);
|
file_count = read_u64le(u64buf);
|
||||||
if (file_count > 200000U) {
|
if (file_count > 200000ULL) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fprintf(stderr, "payload-import: unreasonable file count: %u\n", file_count);
|
fprintf(stderr, "payload-import: unreasonable file count: %llu\n", file_count);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,47 +223,47 @@ static int extract_payload(const char *device, const char *dest_dir)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("payload-import: reading %u files from %s\n", file_count, device);
|
printf("payload-import: reading %llu files from %s\n", file_count, device);
|
||||||
for (i = 0; i < file_count; ++i) {
|
for (i = 0; i < file_count; ++i) {
|
||||||
unsigned int name_len;
|
unsigned long long name_len;
|
||||||
unsigned int data_len;
|
unsigned long long data_len;
|
||||||
char *name;
|
char *name;
|
||||||
char out_path[4096];
|
char out_path[4096];
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
|
||||||
if (read_exact(in, u32buf, 4) != 0) {
|
if (read_exact(in, u64buf, 8) != 0) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fputs("payload-import: truncated entry header\n", stderr);
|
fputs("payload-import: truncated entry header\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
name_len = read_u32le(u32buf);
|
name_len = read_u64le(u64buf);
|
||||||
if (read_exact(in, u32buf, 4) != 0) {
|
if (read_exact(in, u64buf, 8) != 0) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fputs("payload-import: truncated entry size\n", stderr);
|
fputs("payload-import: truncated entry size\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
data_len = read_u32le(u32buf);
|
data_len = read_u64le(u64buf);
|
||||||
|
|
||||||
if (name_len == 0 || name_len > MAX_NAME_LEN) {
|
if (name_len == 0ULL || name_len > (unsigned long long)MAX_NAME_LEN) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fprintf(stderr, "payload-import: invalid name length %u\n", name_len);
|
fprintf(stderr, "payload-import: invalid name length %llu\n", name_len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = (char *)malloc(name_len + 1);
|
name = (char *)malloc((size_t)name_len + 1U);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fputs("payload-import: out of memory\n", stderr);
|
fputs("payload-import: out of memory\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_exact(in, name, name_len) != 0) {
|
if (read_exact(in, name, (size_t)name_len) != 0) {
|
||||||
free(name);
|
free(name);
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fputs("payload-import: truncated file name\n", stderr);
|
fputs("payload-import: truncated file name\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
name[name_len] = 0;
|
name[(size_t)name_len] = 0;
|
||||||
|
|
||||||
if (!is_valid_name(name)) {
|
if (!is_valid_name(name)) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue