summaryrefslogtreecommitdiffstats
path: root/gen_init_cpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'gen_init_cpio.c')
-rw-r--r--gen_init_cpio.c270
1 files changed, 106 insertions, 164 deletions
diff --git a/gen_init_cpio.c b/gen_init_cpio.c
index 694b88c..ea8eb0a 100644
--- a/gen_init_cpio.c
+++ b/gen_init_cpio.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <ctype.h>
#include <limits.h>
+#include <endian.h>
/*
* Original work by Jeff Garzik
@@ -29,9 +30,7 @@
#define xstr(s) #s
#define str(s) xstr(s)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define CPIO_HDR_LEN 110
#define CPIO_TRAILER "TRAILER!!!"
-#define padlen(_off, _align) (((_align) - ((_off) & ((_align) - 1))) % (_align))
/* zero-padding the filename field for data alignment is limited by PATH_MAX */
static char padding[PATH_MAX];
@@ -39,36 +38,39 @@ static unsigned int offset;
static unsigned int ino = 721;
static time_t default_mtime;
static bool do_file_mtime;
-static bool do_csum = false;
static int outfd = STDOUT_FILENO;
static unsigned int dalign;
+#pragma pack(1)
+struct header_pwb_cpio {
+ uint16_t h_magic;
+ uint16_t h_dev;
+ uint16_t h_ino;
+ uint16_t h_mode;
+ uint16_t h_uid;
+ uint16_t h_gid;
+ uint16_t h_nlink;
+ uint16_t h_majmin;
+ uint32_t h_mtime;
+ uint16_t h_namesize;
+ uint32_t h_filesize;
+};
+#define CPIO_HDR_LEN sizeof(struct header_pwb_cpio)
+
struct file_handler {
const char *type;
int (*handler)(const char *line);
};
-static int push_buf(const char *name, size_t name_len)
-{
- ssize_t len;
-
- len = write(outfd, name, name_len);
- if (len != name_len)
- return -1;
-
- offset += name_len;
- return 0;
-}
-
-static int push_pad(size_t padlen)
+static int push_pad()
{
ssize_t len = 0;
+ size_t padlen = offset % 2;
if (!padlen)
return 0;
- if (padlen < sizeof(padding))
- len = write(outfd, padding, padlen);
+ len = write(outfd, padding, padlen);
if (len != padlen)
return -1;
@@ -76,7 +78,7 @@ static int push_pad(size_t padlen)
return 0;
}
-static int push_rest(const char *name, size_t name_len)
+static int push_buf(const char *name, size_t name_len)
{
ssize_t len;
@@ -85,36 +87,32 @@ static int push_rest(const char *name, size_t name_len)
return -1;
offset += name_len;
-
- return push_pad(padlen(name_len + CPIO_HDR_LEN, 4));
+ return push_pad();
}
static int cpio_trailer(void)
{
- int len;
+ int len;
unsigned int namesize = sizeof(CPIO_TRAILER);
- len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
- do_csum ? "070702" : "070701", /* magic */
- 0, /* ino */
- 0, /* mode */
- (long) 0, /* uid */
- (long) 0, /* gid */
- 1, /* nlink */
- (long) 0, /* mtime */
- 0, /* filesize */
- 0, /* major */
- 0, /* minor */
- 0, /* rmajor */
- 0, /* rminor */
- namesize, /* namesize */
- 0); /* chksum */
+ struct header_pwb_cpio header = {
+ .h_magic = 070707,
+ .h_dev = 0,
+ .h_ino = 0,
+ .h_mode = 0,
+ .h_uid = 0,
+ .h_gid = 0,
+ .h_nlink = 1,
+ .h_majmin = 0,
+ .h_mtime = 0,
+ .h_namesize = namesize,
+ .h_filesize = 0
+ };
+ len = write(outfd, &header, CPIO_HDR_LEN);
offset += len;
if (len != CPIO_HDR_LEN ||
- push_rest(CPIO_TRAILER, namesize) < 0 ||
- push_pad(padlen(offset, 512)) < 0)
+ push_buf(CPIO_TRAILER, namesize) < 0)
return -1;
if (fsync(outfd) < 0 && errno != EINVAL)
@@ -127,35 +125,31 @@ static int cpio_mkslink(const char *name, const char *target,
unsigned int mode, uid_t uid, gid_t gid)
{
int len;
- unsigned int namesize, targetsize = strlen(target) + 1;
+ unsigned int namesize, targetsize = strlen(target);
if (name[0] == '/')
name++;
- namesize = strlen(name) + 1;
-
- len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
- do_csum ? "070702" : "070701", /* magic */
- ino++, /* ino */
- S_IFLNK | mode, /* mode */
- (long) uid, /* uid */
- (long) gid, /* gid */
- 1, /* nlink */
- (long) default_mtime, /* mtime */
- targetsize, /* filesize */
- 3, /* major */
- 1, /* minor */
- 0, /* rmajor */
- 0, /* rminor */
- namesize, /* namesize */
- 0); /* chksum */
+ namesize = strlen(name);
+
+ struct header_pwb_cpio header = {
+ .h_magic = 070707,
+ .h_dev = 0,
+ .h_ino = ino++,
+ .h_mode = S_IFLNK | mode,
+ .h_uid = uid,
+ .h_gid = gid,
+ .h_nlink = 1,
+ .h_majmin = 0,
+ .h_mtime = default_mtime,
+ .h_namesize = namesize,
+ .h_filesize = htobe32(targetsize)
+ };
+ len = write(outfd, &header, CPIO_HDR_LEN);
offset += len;
if (len != CPIO_HDR_LEN ||
push_buf(name, namesize) < 0 ||
- push_pad(padlen(offset, 4)) < 0 ||
- push_buf(target, targetsize) < 0 ||
- push_pad(padlen(offset, 4)) < 0)
+ push_buf(target, targetsize) < 0)
return -1;
return 0;
@@ -190,26 +184,24 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
name++;
namesize = strlen(name) + 1;
- len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
- do_csum ? "070702" : "070701", /* magic */
- ino++, /* ino */
- mode, /* mode */
- (long) uid, /* uid */
- (long) gid, /* gid */
- 2, /* nlink */
- (long) default_mtime, /* mtime */
- 0, /* filesize */
- 3, /* major */
- 1, /* minor */
- 0, /* rmajor */
- 0, /* rminor */
- namesize, /* namesize */
- 0); /* chksum */
+ struct header_pwb_cpio header = {
+ .h_magic = 070707,
+ .h_dev = 0,
+ .h_ino = ino++,
+ .h_mode = mode,
+ .h_uid = uid,
+ .h_gid = gid,
+ .h_nlink = 2,
+ .h_majmin = 0,
+ .h_mtime = default_mtime,
+ .h_namesize = namesize,
+ .h_filesize = 0
+ };
+ len = write(outfd, &header, CPIO_HDR_LEN);
offset += len;
if (len != CPIO_HDR_LEN ||
- push_rest(name, namesize) < 0)
+ push_buf(name, namesize) < 0)
return -1;
return 0;
@@ -291,26 +283,24 @@ static int cpio_mknod(const char *name, unsigned int mode,
name++;
namesize = strlen(name) + 1;
- len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
- do_csum ? "070702" : "070701", /* magic */
- ino++, /* ino */
- mode, /* mode */
- (long) uid, /* uid */
- (long) gid, /* gid */
- 1, /* nlink */
- (long) default_mtime, /* mtime */
- 0, /* filesize */
- 3, /* major */
- 1, /* minor */
- maj, /* rmajor */
- min, /* rminor */
- namesize, /* namesize */
- 0); /* chksum */
+ struct header_pwb_cpio header = {
+ .h_magic = 070707,
+ .h_dev = 0,
+ .h_ino = ino++,
+ .h_mode = mode,
+ .h_uid = uid,
+ .h_gid = gid,
+ .h_nlink = 1,
+ .h_majmin = (maj << 8) | min,
+ .h_mtime = default_mtime,
+ .h_namesize = namesize,
+ .h_filesize = 0
+ };
+ len = write(outfd, &header, CPIO_HDR_LEN);
offset += len;
if (len != CPIO_HDR_LEN ||
- push_rest(name, namesize) < 0)
+ push_buf(name, namesize) < 0)
return -1;
return 0;
@@ -337,29 +327,6 @@ static int cpio_mknod_line(const char *line)
return rc;
}
-static int cpio_mkfile_csum(int fd, unsigned long size, uint32_t *csum)
-{
- while (size) {
- unsigned char filebuf[65536];
- ssize_t this_read;
- size_t i, this_size = MIN(size, sizeof(filebuf));
-
- this_read = read(fd, filebuf, this_size);
- if (this_read <= 0 || this_read > this_size)
- return -1;
-
- for (i = 0; i < this_read; i++)
- *csum += filebuf[i];
-
- size -= this_read;
- }
- /* seek back to the start for data segment I/O */
- if (lseek(fd, 0, SEEK_SET) < 0)
- return -1;
-
- return 0;
-}
-
static int cpio_mkfile(const char *name, const char *location,
unsigned int mode, uid_t uid, gid_t gid,
unsigned int nlinks)
@@ -369,9 +336,8 @@ static int cpio_mkfile(const char *name, const char *location,
int file, retval, len;
int rc = -1;
time_t mtime;
- int namesize, namepadlen;
+ int namesize;
unsigned int i;
- uint32_t csum = 0;
ssize_t this_read;
mode |= S_IFREG;
@@ -411,13 +377,7 @@ static int cpio_mkfile(const char *name, const char *location,
goto error;
}
- if (do_csum && cpio_mkfile_csum(file, buf.st_size, &csum) < 0) {
- fprintf(stderr, "Failed to checksum file %s\n", location);
- goto error;
- }
-
size = 0;
- namepadlen = 0;
for (i = 1; i <= nlinks; i++) {
if (name[0] == '/')
name++;
@@ -427,38 +387,24 @@ static int cpio_mkfile(const char *name, const char *location,
if (i == nlinks)
size = buf.st_size;
- if (dalign && size > dalign) {
- namepadlen = padlen(offset + CPIO_HDR_LEN + namesize,
- dalign);
- if (namesize + namepadlen > PATH_MAX) {
- fprintf(stderr,
- "%s: best-effort alignment %u missed\n",
- name, dalign);
- namepadlen = 0;
- }
- }
-
- len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
- "%08lX%08X%08X%08X%08X%08X%08X",
- do_csum ? "070702" : "070701", /* magic */
- ino, /* ino */
- mode, /* mode */
- (long) uid, /* uid */
- (long) gid, /* gid */
- nlinks, /* nlink */
- (long) mtime, /* mtime */
- size, /* filesize */
- 3, /* major */
- 1, /* minor */
- 0, /* rmajor */
- 0, /* rminor */
- namesize + namepadlen, /* namesize */
- size ? csum : 0); /* chksum */
+ struct header_pwb_cpio header = {
+ .h_magic = 070707,
+ .h_dev = buf.st_dev,
+ .h_ino = buf.st_ino,
+ .h_mode = mode,
+ .h_uid = uid,
+ .h_gid = gid,
+ .h_nlink = 1,
+ .h_majmin = 0,
+ .h_mtime = htobe32(mtime),
+ .h_namesize = namesize,
+ .h_filesize = htobe32(size)
+ };
+ len = write(outfd, &header, CPIO_HDR_LEN);
offset += len;
if (len != CPIO_HDR_LEN ||
- push_buf(name, namesize) < 0 ||
- push_pad(namepadlen ? namepadlen : padlen(offset, 4)) < 0)
+ push_buf(name, namesize) < 0)
goto error;
if (size) {
@@ -489,7 +435,7 @@ static int cpio_mkfile(const char *name, const char *location,
offset += this_read;
size -= this_read;
}
- if (push_pad(padlen(offset, 4)) < 0)
+ if (push_pad() < 0)
goto error;
name += namesize;
@@ -575,7 +521,7 @@ static int cpio_mkfile_line(const char *line)
static void usage(const char *prog)
{
fprintf(stderr, "Usage:\n"
- "\t%s [-t <timestamp>] [-c] [-o <output_file>] [-a <data_align>] <cpio_list>\n"
+ "\t%s [-t <timestamp>] [-o <output_file>] [-a <data_align>] <cpio_list>\n"
"\n"
"<cpio_list> is a file containing newline separated entries that\n"
"describe the files to be included in the initramfs archive:\n"
@@ -612,7 +558,6 @@ static void usage(const char *prog)
"as mtime for symlinks, directories, regular and special files.\n"
"The default is to use the current time for all files, but\n"
"preserve modification time for regular files.\n"
- "-c: calculate and store 32-bit checksums for file data.\n"
"<output_file>: write cpio to this file instead of stdout\n"
"<data_align>: attempt to align file data by zero-padding the\n"
"filename field up to data_align. Must be a multiple of 4.\n"
@@ -656,7 +601,7 @@ int main (int argc, char *argv[])
int line_nr = 0;
const char *filename;
- default_mtime = time(NULL);
+ default_mtime = htobe32(time(NULL));
while (1) {
int opt = getopt(argc, argv, "t:cho:a:");
char *invalid;
@@ -665,7 +610,7 @@ int main (int argc, char *argv[])
break;
switch (opt) {
case 't':
- default_mtime = strtol(optarg, &invalid, 10);
+ default_mtime = htobe32(strtol(optarg, &invalid, 10));
if (!*optarg || *invalid) {
fprintf(stderr, "Invalid timestamp: %s\n",
optarg);
@@ -674,9 +619,6 @@ int main (int argc, char *argv[])
}
do_file_mtime = true;
break;
- case 'c':
- do_csum = true;
- break;
case 'o':
outfd = open(optarg,
O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC,