/*
* cpio.c
*
* Write a compressed CPIO file
*/
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include <zlib.h>
#include "upload_backend.h"
#include "ctime.h"
int cpio_pad(struct upload_backend *be)
{
static char pad[4]; /* Up to 4 zero bytes */
if (be->dbytes & 3)
return write_data(be, pad, -be->dbytes & 3);
else
return 0;
}
int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen,
const char *filename)
{
static uint32_t inode = 2;
char hdr[6+13*8+1];
int nlen = strlen(filename)+1;
int rv = 0;
cpio_pad(be);
sprintf(hdr, "%06o%08x%08x%08x%08x%08x%08x%08zx%08x%08x%08x%08x%08x%08x",
070701, /* c_magic */
inode++, /* c_ino */
mode, /* c_mode */
0, /* c_uid */
0, /* c_gid */
1, /* c_nlink */
be->now, /* c_mtime */
datalen, /* c_filesize */
0, /* c_maj */
0, /* c_min */
0, /* c_rmaj */
0, /* c_rmin */
nlen, /* c_namesize */
0); /* c_chksum */
rv |= write_data(be, hdr, 6+13*8);
rv |= write_data(be, filename, nlen);
rv |= cpio_pad(be);
return rv;
}
int cpio_mkdir(struct upload_backend *be, const char *filename)
{
return cpio_hdr(be, MODE_DIR, 0, filename);
}
int cpio_writefile(struct upload_backend *be, const char *filename,
const void *data, size_t len)
{
int rv;
rv = cpio_hdr(be, MODE_FILE, len, filename);
rv |= write_data(be, data, len);
rv |= cpio_pad(be);
return rv;
}
int cpio_close(struct upload_backend *be)
{
return cpio_hdr(be, 0, 0, "TRAILER!!!");
}