176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * cpio.c 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Write a compressed CPIO file 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h> 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <inttypes.h> 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdbool.h> 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <zlib.h> 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "upload_backend.h" 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "ctime.h" 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint cpio_pad(struct upload_backend *be) 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static char pad[4]; /* Up to 4 zero bytes */ 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (be->dbytes & 3) 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return write_data(be, pad, -be->dbytes & 3); 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen, 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *filename) 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static uint32_t inode = 2; 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char hdr[6+13*8+1]; 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int nlen = strlen(filename)+1; 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int rv = 0; 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cpio_pad(be); 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sprintf(hdr, "%06o%08x%08x%08x%08x%08x%08x%08zx%08x%08x%08x%08x%08x%08x", 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 070701, /* c_magic */ 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman inode++, /* c_ino */ 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mode, /* c_mode */ 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0, /* c_uid */ 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0, /* c_gid */ 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1, /* c_nlink */ 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman be->now, /* c_mtime */ 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman datalen, /* c_filesize */ 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0, /* c_maj */ 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0, /* c_min */ 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0, /* c_rmaj */ 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0, /* c_rmin */ 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nlen, /* c_namesize */ 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0); /* c_chksum */ 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rv |= write_data(be, hdr, 6+13*8); 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rv |= write_data(be, filename, nlen); 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rv |= cpio_pad(be); 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rv; 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint cpio_mkdir(struct upload_backend *be, const char *filename) 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return cpio_hdr(be, MODE_DIR, 0, filename); 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint cpio_writefile(struct upload_backend *be, const char *filename, 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const void *data, size_t len) 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int rv; 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rv = cpio_hdr(be, MODE_FILE, len, filename); 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rv |= write_data(be, data, len); 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rv |= cpio_pad(be); 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rv; 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint cpio_close(struct upload_backend *be) 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return cpio_hdr(be, 0, 0, "TRAILER!!!"); 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 76