| #include <cpio.h> |
| #include <kmalloc.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| void parse_cpio_entries(void *cpio_b, size_t cpio_sz, |
| int (*cb)(struct cpio_bin_hdr*, void *), void *cb_arg) |
| { |
| struct cpio_newc_header *c_hdr; |
| char buf[9] = {0}; /* temp space for strol conversions */ |
| size_t namesize = 0; |
| int offset = 0; /* offset in the cpio archive */ |
| struct cpio_bin_hdr *c_bhdr = kzmalloc(sizeof(*c_bhdr), MEM_WAIT); |
| |
| /* read all files and paths */ |
| for (;;) { |
| c_hdr = (struct cpio_newc_header*)(cpio_b + offset); |
| offset += sizeof(*c_hdr); |
| if (offset > cpio_sz) { |
| printk("CPIO offset %d beyond size %d, aborting.\n", |
| offset, cpio_sz); |
| return; |
| } |
| if (strncmp(c_hdr->c_magic, "070701", 6)) { |
| printk("Invalid magic number in CPIO header, aborting.\n"); |
| return; |
| } |
| c_bhdr->c_filename = (char*)c_hdr + sizeof(*c_hdr); |
| namesize = cpio_strntol(buf, c_hdr->c_namesize, 8); |
| printd("Namesize: %d\n", namesize); |
| if (!strcmp(c_bhdr->c_filename, "TRAILER!!!")) |
| break; |
| c_bhdr->c_ino = cpio_strntol(buf, c_hdr->c_ino, 8); |
| c_bhdr->c_mode = (int)cpio_strntol(buf, c_hdr->c_mode, 8); |
| c_bhdr->c_uid = cpio_strntol(buf, c_hdr->c_uid, 8); |
| c_bhdr->c_gid = cpio_strntol(buf, c_hdr->c_gid, 8); |
| c_bhdr->c_nlink = (unsigned int)cpio_strntol(buf, |
| c_hdr->c_nlink, 8); |
| c_bhdr->c_mtime = cpio_strntol(buf, c_hdr->c_mtime, 8); |
| c_bhdr->c_filesize = cpio_strntol(buf, c_hdr->c_filesize, 8); |
| c_bhdr->c_dev_maj = cpio_strntol(buf, c_hdr->c_dev_maj, 8); |
| c_bhdr->c_dev_min = cpio_strntol(buf, c_hdr->c_dev_min, 8); |
| c_bhdr->c_rdev_maj = cpio_strntol(buf, c_hdr->c_rdev_maj, 8); |
| c_bhdr->c_rdev_min = cpio_strntol(buf, c_hdr->c_rdev_min, 8); |
| printd("File: %s: %d Bytes\n", c_bhdr->c_filename, |
| c_bhdr->c_filesize); |
| offset += namesize; |
| /* header + name will be padded out to 4-byte alignment */ |
| offset = ROUNDUP(offset, 4); |
| c_bhdr->c_filestart = cpio_b + offset; |
| offset += c_bhdr->c_filesize; |
| offset = ROUNDUP(offset, 4); |
| if (offset > cpio_sz) { |
| printk("CPIO offset %d beyond size %d, aborting.\n", |
| offset, cpio_sz); |
| return; |
| } |
| if (cb(c_bhdr, cb_arg)) { |
| printk("Failed to handle CPIO callback, aborting!\n"); |
| break; |
| } |
| //printk("offset is %d bytes\n", offset); |
| } |
| kfree(c_bhdr); |
| } |