summaryrefslogtreecommitdiff
path: root/com32/libupload/cpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/libupload/cpio.c')
-rw-r--r--com32/libupload/cpio.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/com32/libupload/cpio.c b/com32/libupload/cpio.c
new file mode 100644
index 00000000..25b464d4
--- /dev/null
+++ b/com32/libupload/cpio.c
@@ -0,0 +1,75 @@
+/*
+ * 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!!!");
+}