1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "cpiofs.h"
4
5#include "bootstrapper.h"
6
7#include <mos/mos_global.h>
8#include <mos/types.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13size_t read_initrd(void *buf, size_t size, size_t offset)
14{
15 memcpy(dest: buf, src: (void *) (MOS_INITRD_BASE + offset), size);
16 return size;
17}
18
19bool cpio_read_metadata(const char *target, cpio_header_t *header, cpio_metadata_t *metadata)
20{
21 if (unlikely(strcmp(target, "TRAILER!!!") == 0))
22 {
23 fputs(string: "what the heck are you doing?", stream: stderr);
24 abort();
25 }
26
27 size_t offset = 0;
28
29 while (true)
30 {
31 read_initrd(buf: header, size: sizeof(cpio_header_t), offset);
32
33 if (strncmp(a: header->magic, b: "07070", max_size: 5) != 0 || (header->magic[5] != '1' && header->magic[5] != '2'))
34 {
35 fprintf(stream: stderr, format: "WARN: invalid cpio header magic, possibly corrupt archive\n");
36 return false;
37 }
38
39 offset += sizeof(cpio_header_t);
40
41 const size_t filename_len = strntoll(str: header->namesize, NULL, base: 16, n: sizeof(header->namesize) / sizeof(char));
42
43 char filename[filename_len + 1]; // +1 for null terminator
44 read_initrd(buf: filename, size: filename_len, offset);
45 filename[filename_len] = '\0';
46
47 const bool found = strncmp(a: filename, b: target, max_size: filename_len) == 0;
48
49 if (found)
50 {
51 metadata->header_offset = offset - sizeof(cpio_header_t);
52 metadata->name_offset = offset;
53 metadata->name_length = filename_len;
54 }
55
56 if (unlikely(strcmp(filename, "TRAILER!!!") == 0))
57 return false;
58
59 offset += filename_len;
60 offset = ALIGN_UP(offset, 4);
61
62 const size_t data_len = strntoll(str: header->filesize, NULL, base: 16, n: sizeof(header->filesize) / sizeof(char));
63 if (found)
64 {
65 metadata->data_offset = offset;
66 metadata->data_length = data_len;
67 }
68
69 offset += data_len;
70 offset = ALIGN_UP(offset, 4);
71
72 if (found)
73 return true;
74 }
75
76 unreachable();
77}
78