Add stdin/stdout support

This commit is contained in:
topjohnwu 2017-11-10 20:25:41 +08:00
parent 2487ec94e6
commit 9136573596
4 changed files with 85 additions and 42 deletions

View File

@ -117,6 +117,7 @@ void clone_attr(const char *source, const char *target);
void restorecon(int dirfd, int force);
void mmap_ro(const char *filename, void **buf, size_t *size);
void mmap_rw(const char *filename, void **buf, size_t *size);
void full_read(int fd, void **buf, size_t *size);
void write_zero(int fd, size_t size);
void mem_align(size_t *pos, size_t align);
void file_align(int fd, size_t align, int out);

View File

@ -87,7 +87,6 @@ size_t gzip(int mode, int fd, const void *buf, size_t size) {
return total;
}
// Mode: 0 = decode xz/lzma; 1 = encode xz; 2 = encode lzma
size_t lzma(int mode, int fd, const void *buf, size_t size) {
size_t have, pos = 0, total = 0;
@ -405,7 +404,6 @@ long long decomp(file_t type, int to, const void *from, size_t size) {
}
}
// Output will be to.ext
long long comp(file_t type, int to, const void *from, size_t size) {
switch (type) {
case GZIP:
@ -431,60 +429,68 @@ long long comp(file_t type, int to, const void *from, size_t size) {
*/
void decomp_file(char *from, const char *to) {
int ok = 1;
int strip = 1;
void *file;
size_t size;
mmap_ro(from, &file, &size);
size_t size = 0;
if (strcmp(from, "-") == 0)
full_read(STDIN_FILENO, &file, &size);
else
mmap_ro(from, &file, &size);
file_t type = check_type(file);
char *ext;
ext = strrchr(from, '.');
if (ext == NULL)
LOGE("Bad filename extention\n");
// File type and extension should match
switch (type) {
if (to == NULL)
to = from;
if (ext != NULL) {
// Strip out a matched file extension
switch (type) {
case GZIP:
if (strcmp(ext, ".gz") != 0)
ok = 0;
strip = 0;
break;
case XZ:
if (strcmp(ext, ".xz") != 0)
ok = 0;
strip = 0;
break;
case LZMA:
if (strcmp(ext, ".lzma") != 0)
ok = 0;
strip = 0;
break;
case BZIP2:
if (strcmp(ext, ".bz2") != 0)
ok = 0;
strip = 0;
break;
case LZ4_LEGACY:
case LZ4:
if (strcmp(ext, ".lz4") != 0)
ok = 0;
strip = 0;
break;
default:
LOGE("Provided file \'%s\' is not a supported archive format\n", from);
}
if (ok) {
// If all match, strip out the suffix
if (!to) {
}
if (strip)
*ext = '\0';
to = from;
}
int fd = creat(to, 0644);
fprintf(stderr, "Decompressing to [%s]\n\n", to);
decomp(type, fd, file, size);
close(fd);
if (to == from) {
*ext = '.';
unlink(from);
}
} else {
LOGE("Bad filename extention \'%s\'\n", ext);
}
munmap(file, size);
int fd;
if (strcmp(to, "-") == 0) {
fd = STDOUT_FILENO;
} else {
fd = creat(to, 0644);
fprintf(stderr, "Decompressing to [%s]\n\n", to);
}
decomp(type, fd, file, size);
close(fd);
if (to == from && ext != NULL) {
*ext = '.';
unlink(from);
}
if (strcmp(from, "-") == 0)
free(file);
else
munmap(file, size);
}
void comp_file(const char *method, const char *from, const char *to) {
@ -517,17 +523,31 @@ void comp_file(const char *method, const char *from, const char *to) {
}
void *file;
size_t size;
mmap_ro(from, &file, &size);
if (!to)
snprintf(dest, sizeof(dest), "%s.%s", from, ext);
if (strcmp(from, "-") == 0)
full_read(STDIN_FILENO, &file, &size);
else
mmap_ro(from, &file, &size);
if (to == NULL) {
if (strcmp(from, "-") == 0)
strcpy(dest, "-");
else
snprintf(dest, sizeof(dest), "%s.%s", from, ext);
} else
strcpy(dest, to);
fprintf(stderr, "Compressing to [%s]\n\n", dest);
int fd = creat(dest, 0644);
int fd;
if (strcmp(dest, "-") == 0) {
fd = STDOUT_FILENO;
} else {
fd = creat(dest, 0644);
fprintf(stderr, "Compressing to [%s]\n\n", dest);
}
comp(type, fd, file, size);
close(fd);
munmap(file, size);
if (!to)
if (strcmp(from, "-") == 0)
free(file);
else
munmap(file, size);
if (to == NULL)
unlink(from);
}

View File

@ -18,8 +18,8 @@ static void usage(char *arg0) {
"\n"
"Supported actions:\n"
" --unpack <bootimg>\n"
" Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb) into the\n"
" current directory\n"
" Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb), (extra) into\n"
" the current directory\n"
"\n"
" --repack <origbootimg> [outbootimg]\n"
" Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n"
@ -66,6 +66,7 @@ static void usage(char *arg0) {
"\n"
" --compress[=method] <infile> [outfile]\n"
" Compress <infile> with [method] (default: gzip), optionally to [outfile]\n"
" <infile>/[outfile] can be '-' to be STDIN/STDOUT\n"
" Supported methods: "
, arg0);
for (int i = 0; SUP_LIST[i]; ++i)
@ -74,7 +75,9 @@ static void usage(char *arg0) {
"\n"
"\n"
" --decompress <infile> [outfile]\n"
" Detect method and decompress <infile>, optionally to [outfile]\n Supported methods: ");
" Detect method and decompress <infile>, optionally to [outfile]\n"
" <infile>/[outfile] can be '-' to be STDIN/STDOUT\n"
" Supported methods: ");
for (int i = 0; SUP_LIST[i]; ++i)
fprintf(stderr, "%s ", SUP_LIST[i]);
fprintf(stderr,

View File

@ -351,6 +351,25 @@ void mmap_rw(const char *filename, void **buf, size_t *size) {
close(fd);
}
void full_read(int fd, void **buf, size_t *size) {
size_t cap = 1 << 20;
uint8_t tmp[1 << 20];
*buf = xmalloc(cap);
ssize_t read;
*size = 0;
while (1) {
read = xread(fd, tmp, sizeof(tmp));
if (read <= 0)
break;
if (*size + read > cap) {
cap *= 2;
*buf = realloc(*buf, cap);
}
memcpy(*buf + *size, tmp, read);
*size += read;
}
}
void write_zero(int fd, size_t size) {
size_t pos = lseek(fd, 0, SEEK_CUR);
ftruncate(fd, pos + size);