| #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); | 
 | } |