Skip to content

Instantly share code, notes, and snippets.

@packz
Last active December 11, 2015 02:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save packz/4530094 to your computer and use it in GitHub Desktop.
Save packz/4530094 to your computer and use it in GitHub Desktop.
Find cpio archive
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
//http://people.freebsd.org/~kientzle/libarchive/man/cpio.5.txt
struct cpio_newc_header {
char c_magic[6];// "070701"
char c_ino[8]; //
char c_mode[8];
char c_uid[8];
char c_gid[8];
char c_nlink[8];
char c_mtime[8];
char c_filesize[8];
char c_devmajor[8];
char c_devminor[8];
char c_rdevmajor[8];
char c_rdevminor[8];
char c_namesize[8];
char c_check[8]; // always 0
};
#define CPIO_MAGIC "070701\0"
#define CPIO_MAGIC_SIZE strlen(CPIO_MAGIC)
static struct stat g_stat;
static struct cpio_newc_header g_cpio_header;
void usage(char *progname) {
fprintf(stderr, "usage: %s <file>\n", progname);
}
int main(int argc, char* argv[]) {
if (argc < 2) {
usage(argv[0]);
exit(0);
}
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
// save the data about original file
fstat(fd, &g_stat);
fprintf(stdout, "original size: %tu\n", g_stat.st_size);
off_t offset = 0;
char cursor[7]= "\0\0\0\0\0\0\0";
while (offset < (g_stat.st_size - CPIO_MAGIC_SIZE)) {
offset = lseek(fd, offset, SEEK_SET);
if (offset < 0) {
perror("seek");
exit(2);
}
ssize_t count = read(fd, cursor, CPIO_MAGIC_SIZE);
if (count == 0) {// EOF
break;
} else if (count < CPIO_MAGIC_SIZE) {
perror("read");
exit(3);
}
if (strcmp(CPIO_MAGIC, cursor) == 0) {
char filename[1024];
// came back to the start of the finding
lseek(fd, offset, SEEK_SET);
// read the header
read(fd, &g_cpio_header, sizeof(g_cpio_header));
// find the size of the filename
unsigned int header_filename_size;
char* namesize = strdup(g_cpio_header.c_namesize);
namesize[9] = '\0';
if (sscanf(namesize, "%x", &header_filename_size) == 1) {
read(fd, filename, header_filename_size);
filename[header_filename_size] = '\0';
printf("offset: %tu filename: %s size: %zu\n", offset, filename, (size_t)g_cpio_header.c_filesize);
}
lseek(fd, offset, SEEK_SET);
}
offset++;
fprintf(stdout, "%tu\r", offset);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment