1 /* 2 * cpio.c 3 * 4 * Write a compressed CPIO file 5 */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <inttypes.h> 10 #include <stdbool.h> 11 #include <zlib.h> 12 #include "upload_backend.h" 13 #include "ctime.h" 14 15 int cpio_pad(struct upload_backend *be) 16 { 17 static char pad[4]; /* Up to 4 zero bytes */ 18 if (be->dbytes & 3) 19 return write_data(be, pad, -be->dbytes & 3); 20 else 21 return 0; 22 } 23 24 int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen, 25 const char *filename) 26 { 27 static uint32_t inode = 2; 28 char hdr[6+13*8+1]; 29 int nlen = strlen(filename)+1; 30 int rv = 0; 31 32 cpio_pad(be); 33 34 sprintf(hdr, "%06o%08x%08x%08x%08x%08x%08x%08zx%08x%08x%08x%08x%08x%08x", 35 070701, /* c_magic */ 36 inode++, /* c_ino */ 37 mode, /* c_mode */ 38 0, /* c_uid */ 39 0, /* c_gid */ 40 1, /* c_nlink */ 41 be->now, /* c_mtime */ 42 datalen, /* c_filesize */ 43 0, /* c_maj */ 44 0, /* c_min */ 45 0, /* c_rmaj */ 46 0, /* c_rmin */ 47 nlen, /* c_namesize */ 48 0); /* c_chksum */ 49 rv |= write_data(be, hdr, 6+13*8); 50 rv |= write_data(be, filename, nlen); 51 rv |= cpio_pad(be); 52 return rv; 53 } 54 55 int cpio_mkdir(struct upload_backend *be, const char *filename) 56 { 57 return cpio_hdr(be, MODE_DIR, 0, filename); 58 } 59 60 int cpio_writefile(struct upload_backend *be, const char *filename, 61 const void *data, size_t len) 62 { 63 int rv; 64 65 rv = cpio_hdr(be, MODE_FILE, len, filename); 66 rv |= write_data(be, data, len); 67 rv |= cpio_pad(be); 68 69 return rv; 70 } 71 72 int cpio_close(struct upload_backend *be) 73 { 74 return cpio_hdr(be, 0, 0, "TRAILER!!!"); 75 } 76