Add ramdisk compression option
This commit is contained in:
parent
267c59b1f1
commit
9c89e56c56
@ -44,7 +44,7 @@ void decompress(char *infile, const char *outfile) {
|
|||||||
if (!COMPRESSED(type))
|
if (!COMPRESSED(type))
|
||||||
LOGE("Input file is not a compressed type!\n");
|
LOGE("Input file is not a compressed type!\n");
|
||||||
|
|
||||||
cmp = std::move(unique_ptr<Compression>(get_decoder(type)));
|
cmp.reset(get_decoder(type));
|
||||||
fprintf(stderr, "Detected format: [%s]\n", fmt2name[type]);
|
fprintf(stderr, "Detected format: [%s]\n", fmt2name[type]);
|
||||||
|
|
||||||
/* If user does not provide outfile, infile has to be either
|
/* If user does not provide outfile, infile has to be either
|
||||||
@ -66,7 +66,8 @@ void decompress(char *infile, const char *outfile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out_fd = strcmp(outfile, "-") == 0 ? STDOUT_FILENO : creat(outfile, 0644);
|
out_fd = strcmp(outfile, "-") == 0 ?
|
||||||
|
STDOUT_FILENO : xopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
cmp->set_out(make_unique<FDOutStream>(out_fd));
|
cmp->set_out(make_unique<FDOutStream>(out_fd));
|
||||||
if (ext) *ext = '.';
|
if (ext) *ext = '.';
|
||||||
}
|
}
|
||||||
@ -103,13 +104,14 @@ void compress(const char *method, const char *infile, const char *outfile) {
|
|||||||
* STDIN, output to <infile>.[ext] */
|
* STDIN, output to <infile>.[ext] */
|
||||||
char *tmp = new char[strlen(infile) + 5];
|
char *tmp = new char[strlen(infile) + 5];
|
||||||
sprintf(tmp, "%s%s", infile, fmt2ext[it->second]);
|
sprintf(tmp, "%s%s", infile, fmt2ext[it->second]);
|
||||||
out_fd = creat(tmp, 0644);
|
out_fd = xopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
fprintf(stderr, "Compressing to [%s]\n", tmp);
|
fprintf(stderr, "Compressing to [%s]\n", tmp);
|
||||||
delete[] tmp;
|
delete[] tmp;
|
||||||
rm_in = true;
|
rm_in = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out_fd = strcmp(outfile, "-") == 0 ? STDOUT_FILENO : creat(outfile, 0644);
|
out_fd = strcmp(outfile, "-") == 0 ?
|
||||||
|
STDOUT_FILENO : xopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmp->set_out(make_unique<FDOutStream>(out_fd));
|
cmp->set_out(make_unique<FDOutStream>(out_fd));
|
||||||
@ -127,9 +129,6 @@ void compress(const char *method, const char *infile, const char *outfile) {
|
|||||||
unlink(infile);
|
unlink(infile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Compression Streams */
|
|
||||||
|
|
||||||
Compression *get_encoder(format_t type) {
|
Compression *get_encoder(format_t type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case XZ:
|
case XZ:
|
||||||
@ -184,7 +183,7 @@ GZStream::GZStream(int mode) : mode(mode), strm({}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GZStream::write(const void *in, size_t size) {
|
bool GZStream::write(const void *in, size_t size) {
|
||||||
return write(in, size, Z_NO_FLUSH);
|
return size ? write(in, size, Z_NO_FLUSH) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t GZStream::finalize() {
|
uint64_t GZStream::finalize() {
|
||||||
@ -237,7 +236,7 @@ BZStream::BZStream(int mode) : mode(mode), strm({}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool BZStream::write(const void *in, size_t size) {
|
bool BZStream::write(const void *in, size_t size) {
|
||||||
return write(in, size, BZ_RUN);
|
return size ? write(in, size, BZ_RUN) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t BZStream::finalize() {
|
uint64_t BZStream::finalize() {
|
||||||
@ -304,7 +303,7 @@ LZMAStream::LZMAStream(int mode) : mode(mode), strm(LZMA_STREAM_INIT) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool LZMAStream::write(const void *in, size_t size) {
|
bool LZMAStream::write(const void *in, size_t size) {
|
||||||
return write(in, size, LZMA_RUN);
|
return size ? write(in, size, LZMA_RUN) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t LZMAStream::finalize() {
|
uint64_t LZMAStream::finalize() {
|
||||||
@ -394,6 +393,8 @@ LZ4FEncoder::~LZ4FEncoder() {
|
|||||||
bool LZ4FEncoder::write(const void *in, size_t size) {
|
bool LZ4FEncoder::write(const void *in, size_t size) {
|
||||||
if (!outbuf)
|
if (!outbuf)
|
||||||
write_header();
|
write_header();
|
||||||
|
if (size == 0)
|
||||||
|
return true;
|
||||||
auto inbuf = (const uint8_t *) in;
|
auto inbuf = (const uint8_t *) in;
|
||||||
size_t read, write;
|
size_t read, write;
|
||||||
do {
|
do {
|
||||||
@ -507,6 +508,8 @@ bool LZ4Encoder::write(const void *in, size_t size) {
|
|||||||
FilterOutStream::write("\x02\x21\x4c\x18", 4);
|
FilterOutStream::write("\x02\x21\x4c\x18", 4);
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
|
if (size == 0)
|
||||||
|
return true;
|
||||||
in_total += size;
|
in_total += size;
|
||||||
const char *inbuf = (const char *) in;
|
const char *inbuf = (const char *) in;
|
||||||
size_t consumed;
|
size_t consumed;
|
||||||
|
@ -6,17 +6,29 @@
|
|||||||
#include <cpio.h>
|
#include <cpio.h>
|
||||||
|
|
||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
static const char *ramdisk_xz = "ramdisk.cpio.xz";
|
||||||
|
|
||||||
|
static const char *UNSUPPORT_LIST[] =
|
||||||
|
{ "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc",
|
||||||
|
"boot/sbin/launch_daemonsu.sh" };
|
||||||
|
|
||||||
|
static const char *MAGISK_LIST[] =
|
||||||
|
{ ".backup/.magisk", "init.magisk.rc",
|
||||||
|
"overlay/init.magisk.rc", ramdisk_xz };
|
||||||
|
|
||||||
class magisk_cpio : public cpio_rw {
|
class magisk_cpio : public cpio_rw {
|
||||||
public:
|
public:
|
||||||
explicit magisk_cpio(const char *filename) : cpio_rw(filename) {}
|
explicit magisk_cpio(const char *filename) : cpio_rw(filename) {}
|
||||||
void patch(bool keepverity, bool keepforceencrypt);
|
void patch(bool keepverity, bool keepforceencrypt);
|
||||||
int test();
|
int test();
|
||||||
char * sha1();
|
char *sha1();
|
||||||
void restore();
|
void restore();
|
||||||
void backup(const char *orig);
|
void backup(const char *orig);
|
||||||
|
void compress();
|
||||||
};
|
};
|
||||||
|
|
||||||
void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
|
void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
|
||||||
@ -47,13 +59,6 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
|
|||||||
#define MAGISK_PATCH 0x1
|
#define MAGISK_PATCH 0x1
|
||||||
#define UNSUPPORT_PATCH 0x2
|
#define UNSUPPORT_PATCH 0x2
|
||||||
int magisk_cpio::test() {
|
int magisk_cpio::test() {
|
||||||
static const char *UNSUPPORT_LIST[] =
|
|
||||||
{ "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc",
|
|
||||||
"boot/sbin/launch_daemonsu.sh" };
|
|
||||||
static const char *MAGISK_LIST[] =
|
|
||||||
{ ".backup/.magisk", "init.magisk.rc",
|
|
||||||
"overlay/init.magisk.rc" };
|
|
||||||
|
|
||||||
for (auto file : UNSUPPORT_LIST)
|
for (auto file : UNSUPPORT_LIST)
|
||||||
if (exists(file))
|
if (exists(file))
|
||||||
return UNSUPPORT_PATCH;
|
return UNSUPPORT_PATCH;
|
||||||
@ -202,6 +207,21 @@ void magisk_cpio::backup(const char *orig) {
|
|||||||
entries.merge(bkup_entries);
|
entries.merge(bkup_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void magisk_cpio::compress() {
|
||||||
|
fprintf(stderr, "Compressing cpio -> [%s]\n", ramdisk_xz);
|
||||||
|
auto init = entries.extract("init");
|
||||||
|
XZEncoder encoder;
|
||||||
|
encoder.set_out(make_unique<BufOutStream>());
|
||||||
|
output(encoder);
|
||||||
|
encoder.finalize();
|
||||||
|
entries.clear();
|
||||||
|
entries.insert(std::move(init));
|
||||||
|
auto xz = new cpio_entry(ramdisk_xz);
|
||||||
|
xz->mode = S_IFREG;
|
||||||
|
static_cast<BufOutStream *>(encoder.get_out())->release(xz->data, xz->filesize);
|
||||||
|
insert(xz);
|
||||||
|
}
|
||||||
|
|
||||||
int cpio_commands(int argc, char *argv[]) {
|
int cpio_commands(int argc, char *argv[]) {
|
||||||
char *incpio = argv[0];
|
char *incpio = argv[0];
|
||||||
++argv;
|
++argv;
|
||||||
@ -232,6 +252,8 @@ int cpio_commands(int argc, char *argv[]) {
|
|||||||
char *sha1 = cpio.sha1();
|
char *sha1 = cpio.sha1();
|
||||||
if (sha1) printf("%s\n", sha1);
|
if (sha1) printf("%s\n", sha1);
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (strcmp(cmdv[0], "compress") == 0){
|
||||||
|
cpio.compress();
|
||||||
} else if (cmdc == 2 && strcmp(cmdv[0], "exists") == 0) {
|
} else if (cmdc == 2 && strcmp(cmdv[0], "exists") == 0) {
|
||||||
exit(!cpio.exists(cmdv[1]));
|
exit(!cpio.exists(cmdv[1]));
|
||||||
} else if (cmdc == 2 && strcmp(cmdv[0], "backup") == 0) {
|
} else if (cmdc == 2 && strcmp(cmdv[0], "backup") == 0) {
|
||||||
|
@ -19,6 +19,8 @@ public:
|
|||||||
|
|
||||||
void set_out(strm_ptr &&ptr) { out = std::move(ptr); }
|
void set_out(strm_ptr &&ptr) { out = std::move(ptr); }
|
||||||
|
|
||||||
|
OutStream *get_out() { return out.get(); }
|
||||||
|
|
||||||
bool write(const void *buf, size_t len) override {
|
bool write(const void *buf, size_t len) override {
|
||||||
return out ? out->write(buf, len) : false;
|
return out ? out->write(buf, len) : false;
|
||||||
}
|
}
|
||||||
@ -44,3 +46,38 @@ protected:
|
|||||||
int fd;
|
int fd;
|
||||||
bool close;
|
bool close;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BufOutStream : public OutStream {
|
||||||
|
public:
|
||||||
|
BufOutStream() : buf(nullptr), off(0), cap(0) {};
|
||||||
|
|
||||||
|
bool write(const void *b, size_t len) override {
|
||||||
|
bool resize = false;
|
||||||
|
while (off + len > cap) {
|
||||||
|
cap = cap ? cap << 1 : 1 << 19;
|
||||||
|
resize = true;
|
||||||
|
}
|
||||||
|
if (resize)
|
||||||
|
buf = (char *) xrealloc(buf, cap);
|
||||||
|
memcpy(buf + off, b, len);
|
||||||
|
off += len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void release(void *&b, T &len) {
|
||||||
|
b = buf;
|
||||||
|
len = off;
|
||||||
|
buf = nullptr;
|
||||||
|
off = cap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~BufOutStream() override {
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char *buf;
|
||||||
|
size_t off;
|
||||||
|
size_t cap;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user