Support loading CPIO from a chunk of bytes
This commit is contained in:
parent
4a398642b8
commit
1d3ce9fef1
@ -47,23 +47,6 @@ static uint32_t x8u(const char *hex) {
|
|||||||
cpio_entry_base::cpio_entry_base(const cpio_newc_header *h)
|
cpio_entry_base::cpio_entry_base(const cpio_newc_header *h)
|
||||||
: mode(x8u(h->mode)), uid(x8u(h->uid)), gid(x8u(h->gid)), filesize(x8u(h->filesize)) {};
|
: mode(x8u(h->mode)), uid(x8u(h->uid)), gid(x8u(h->gid)), filesize(x8u(h->filesize)) {};
|
||||||
|
|
||||||
#define fd_align() lseek(fd, do_align(lseek(fd, 0, SEEK_CUR), 4), SEEK_SET)
|
|
||||||
cpio_entry::cpio_entry(int fd, cpio_newc_header &header) : cpio_entry_base(&header) {
|
|
||||||
uint32_t namesize = x8u(header.namesize);
|
|
||||||
filename.resize(namesize - 1);
|
|
||||||
xxread(fd, &filename[0], namesize);
|
|
||||||
fd_align();
|
|
||||||
if (filesize) {
|
|
||||||
data = xmalloc(filesize);
|
|
||||||
xxread(fd, data, filesize);
|
|
||||||
fd_align();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cpio_entry::~cpio_entry() {
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpio::dump(const char *file) {
|
void cpio::dump(const char *file) {
|
||||||
fprintf(stderr, "Dump cpio: [%s]\n", file);
|
fprintf(stderr, "Dump cpio: [%s]\n", file);
|
||||||
FDOutStream fd_out(xopen(file, O_WRONLY | O_CREAT | O_TRUNC, 0644), true);
|
FDOutStream fd_out(xopen(file, O_WRONLY | O_CREAT | O_TRUNC, 0644), true);
|
||||||
@ -167,19 +150,12 @@ void cpio::output(OutStream &out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpio_rw::cpio_rw(const char *filename) {
|
cpio_rw::cpio_rw(const char *filename) {
|
||||||
int fd = xopen(filename, O_RDONLY);
|
char *buf;
|
||||||
|
size_t sz;
|
||||||
|
mmap_ro(filename, (void **) &buf, &sz);
|
||||||
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
||||||
cpio_newc_header header;
|
load_cpio(buf, sz);
|
||||||
unique_ptr<cpio_entry> entry;
|
munmap(buf, sz);
|
||||||
while(xxread(fd, &header, sizeof(cpio_newc_header)) != -1) {
|
|
||||||
entry = make_unique<cpio_entry>(fd, header);
|
|
||||||
if (entry->filename == "." || entry->filename == "..")
|
|
||||||
continue;
|
|
||||||
if (entry->filename == "TRAILER!!!")
|
|
||||||
break;
|
|
||||||
entries[entry->filename] = std::move(entry);
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpio_rw::insert(cpio_entry *e) {
|
void cpio_rw::insert(cpio_entry *e) {
|
||||||
@ -239,6 +215,31 @@ bool cpio_rw::mv(const char *from, const char *to) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define pos_align(p) p = do_align(p, 4)
|
#define pos_align(p) p = do_align(p, 4)
|
||||||
|
|
||||||
|
void cpio_rw::load_cpio(char *buf, size_t sz) {
|
||||||
|
size_t pos = 0;
|
||||||
|
cpio_newc_header *header;
|
||||||
|
unique_ptr<cpio_entry> entry;
|
||||||
|
while (pos < sz) {
|
||||||
|
header = (cpio_newc_header *)(buf + pos);
|
||||||
|
entry = make_unique<cpio_entry>(header);
|
||||||
|
pos += sizeof(*header);
|
||||||
|
string_view name_view(buf + pos);
|
||||||
|
pos += x8u(header->namesize);
|
||||||
|
pos_align(pos);
|
||||||
|
if (name_view == "." || name_view == "..")
|
||||||
|
continue;
|
||||||
|
if (name_view == "TRAILER!!!")
|
||||||
|
break;
|
||||||
|
entry->filename = name_view;
|
||||||
|
entry->data = xmalloc(entry->filesize);
|
||||||
|
memcpy(entry->data, buf + pos, entry->filesize);
|
||||||
|
pos += entry->filesize;
|
||||||
|
entries[entry->filename] = std::move(entry);
|
||||||
|
pos_align(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cpio_mmap::cpio_mmap(const char *filename) {
|
cpio_mmap::cpio_mmap(const char *filename) {
|
||||||
mmap_ro(filename, (void **) &buf, &sz);
|
mmap_ro(filename, (void **) &buf, &sz);
|
||||||
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
||||||
|
@ -30,8 +30,9 @@ struct cpio_entry : public cpio_entry_base {
|
|||||||
explicit cpio_entry(const char *name, uint32_t mode) : filename(name) {
|
explicit cpio_entry(const char *name, uint32_t mode) : filename(name) {
|
||||||
this->mode = mode;
|
this->mode = mode;
|
||||||
}
|
}
|
||||||
cpio_entry(int fd, cpio_newc_header &header);
|
explicit cpio_entry(cpio_newc_header *h) : cpio_entry_base(h) {}
|
||||||
~cpio_entry() override;
|
|
||||||
|
~cpio_entry() override { free(data); };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string_view, std::unique_ptr<cpio_entry_base>> entry_map;
|
typedef std::map<std::string_view, std::unique_ptr<cpio_entry_base>> entry_map;
|
||||||
@ -61,6 +62,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mv(entry_map::iterator &it, const char *to);
|
void mv(entry_map::iterator &it, const char *to);
|
||||||
|
void load_cpio(char *buf, size_t sz);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cpio_mmap : public cpio {
|
class cpio_mmap : public cpio {
|
||||||
|
Loading…
Reference in New Issue
Block a user