vmm: refactor userspace's emsr_fakewrite()
[akaros.git] / kern / lib / cpio.c
1 #include <cpio.h>
2 #include <kmalloc.h>
3 #include <stdio.h>
4 #include <string.h>
5
6 void parse_cpio_entries(void *cpio_b, size_t cpio_sz,
7                         int (*cb)(struct cpio_bin_hdr*, void *), void *cb_arg)
8 {
9         struct cpio_newc_header *c_hdr;
10         char buf[9] = {0};      /* temp space for strol conversions */
11         size_t namesize = 0;
12         int offset = 0;         /* offset in the cpio archive */
13         struct cpio_bin_hdr *c_bhdr = kzmalloc(sizeof(*c_bhdr), MEM_WAIT);
14
15         /* read all files and paths */
16         for (;;) {
17                 c_hdr = (struct cpio_newc_header*)(cpio_b + offset);
18                 offset += sizeof(*c_hdr);
19                 if (offset > cpio_sz) {
20                         printk("CPIO offset %d beyond size %d, aborting.\n",
21                                offset, cpio_sz);
22                         return;
23                 }
24                 if (strncmp(c_hdr->c_magic, "070701", 6)) {
25                         printk("Invalid magic number in CPIO header, aborting.\n");
26                         return;
27                 }
28                 c_bhdr->c_filename = (char*)c_hdr + sizeof(*c_hdr);
29                 namesize = cpio_strntol(buf, c_hdr->c_namesize, 8);
30                 printd("Namesize: %d\n", namesize);
31                 if (!strcmp(c_bhdr->c_filename, "TRAILER!!!"))
32                         break;
33                 c_bhdr->c_ino = cpio_strntol(buf, c_hdr->c_ino, 8);
34                 c_bhdr->c_mode = (int)cpio_strntol(buf, c_hdr->c_mode, 8);
35                 c_bhdr->c_uid = cpio_strntol(buf, c_hdr->c_uid, 8);
36                 c_bhdr->c_gid = cpio_strntol(buf, c_hdr->c_gid, 8);
37                 c_bhdr->c_nlink = (unsigned int)cpio_strntol(buf,
38                                                              c_hdr->c_nlink, 8);
39                 c_bhdr->c_mtime = cpio_strntol(buf, c_hdr->c_mtime, 8);
40                 c_bhdr->c_filesize = cpio_strntol(buf, c_hdr->c_filesize, 8);
41                 c_bhdr->c_dev_maj = cpio_strntol(buf, c_hdr->c_dev_maj, 8);
42                 c_bhdr->c_dev_min = cpio_strntol(buf, c_hdr->c_dev_min, 8);
43                 c_bhdr->c_rdev_maj = cpio_strntol(buf, c_hdr->c_rdev_maj, 8);
44                 c_bhdr->c_rdev_min = cpio_strntol(buf, c_hdr->c_rdev_min, 8);
45                 printd("File: %s: %d Bytes\n", c_bhdr->c_filename,
46                        c_bhdr->c_filesize);
47                 offset += namesize;
48                 /* header + name will be padded out to 4-byte alignment */
49                 offset = ROUNDUP(offset, 4);
50                 c_bhdr->c_filestart = cpio_b + offset;
51                 offset += c_bhdr->c_filesize;
52                 offset = ROUNDUP(offset, 4);
53                 if (offset > cpio_sz) {
54                         printk("CPIO offset %d beyond size %d, aborting.\n",
55                                offset, cpio_sz);
56                         return;
57                 }
58                 if (cb(c_bhdr, cb_arg)) {
59                         printk("Failed to handle CPIO callback, aborting!\n");
60                         break;
61                 }
62                 //printk("offset is %d bytes\n", offset);
63         }
64         kfree(c_bhdr);
65 }