aboutsummaryrefslogtreecommitdiffstats
path: root/com32/sysdump/cpio.c
blob: 984ed3cf68002366f5e3214a2977bbac5b704e88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * cpio.c
 *
 * Write a compressed CPIO file
 */

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include <zlib.h>
#include "backend.h"

static char pad[4];		/* Up to 4 zero bytes */

static int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
		    const char *filename, bool flush)
{
    static uint32_t inode = 2;
    char hdr[6+13*8+1];
    int nlen = strlen(filename)+1;
    int rv = 0;

    sprintf(hdr, "%06o%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
	    070701,		/* c_magic */
	    inode++,		/* c_ino */
	    mode,		/* c_mode */
	    0,			/* c_uid */
	    0,			/* c_gid */
	    1,			/* c_nlink */
	    0,			/* 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, false);
    rv |= write_data(be, filename, nlen, false);
    rv |= write_data(be, pad, -nlen & 3, flush);
    return rv;
}

int cpio_mkdir(struct backend *be, const char *filename)
{
    return cpio_hdr(be, 0040755, 0, filename, false);
}

int cpio_writefile(struct backend *be, const char *filename,
		   const void *data, size_t len)
{
    int rv;

    rv = cpio_hdr(be, 0100755, len, filename, false);
    rv |= write_data(be, data, len, false);
    rv |= write_data(be, pad, -len & 3, false);
}

int cpio_close(struct backend *be)
{
    return cpio_hdr(be, 0, 0, "TRAILER!!!", true);
}