vfs: Remove the last references to struct file *
[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", offset,
21                                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, c_hdr->c_nlink, 8);
38                 c_bhdr->c_mtime = cpio_strntol(buf, c_hdr->c_mtime, 8);
39                 c_bhdr->c_filesize = cpio_strntol(buf, c_hdr->c_filesize, 8);
40                 c_bhdr->c_dev_maj = cpio_strntol(buf, c_hdr->c_dev_maj, 8);
41                 c_bhdr->c_dev_min = cpio_strntol(buf, c_hdr->c_dev_min, 8);
42                 c_bhdr->c_rdev_maj = cpio_strntol(buf, c_hdr->c_rdev_maj, 8);
43                 c_bhdr->c_rdev_min = cpio_strntol(buf, c_hdr->c_rdev_min, 8);
44                 printd("File: %s: %d Bytes\n", c_bhdr->c_filename, c_bhdr->c_filesize);
45                 offset += namesize;
46                 /* header + name will be padded out to 4-byte alignment */
47                 offset = ROUNDUP(offset, 4);
48                 c_bhdr->c_filestart = cpio_b + offset;
49                 offset += c_bhdr->c_filesize;
50                 offset = ROUNDUP(offset, 4);
51                 if (offset > cpio_sz) {
52                         printk("CPIO offset %d beyond size %d, aborting.\n", offset,
53                                cpio_sz);
54                         return;
55                 }
56                 if (cb(c_bhdr, cb_arg)) {
57                         printk("Failed to handle CPIO callback, aborting!\n");
58                         break;
59                 }
60                 //printk("offset is %d bytes\n", offset);
61         }
62         kfree(c_bhdr);
63 }