--- gen_init_cpio.c.orig 2026-01-05 01:58:57.204608452 -0600 +++ gen_init_cpio.c 2026-01-05 02:48:04.693026062 -0600 @@ -18,6 +18,7 @@ #include #include #include +#include /* * 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 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 @@ 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 @@ 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 @@ 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; + namesize = strlen(name); - 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 */ + 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 void usage(const char *prog) { fprintf(stderr, "Usage:\n" - "\t%s [-t ] [-c] [-o ] [-a ] \n" + "\t%s [-t ] [-o ] [-a ] \n" "\n" " is a file containing newline separated entries that\n" "describe the files to be included in the initramfs archive:\n" @@ -612,7 +558,6 @@ "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" ": write cpio to this file instead of stdout\n" ": 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 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 @@ 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 @@ } do_file_mtime = true; break; - case 'c': - do_csum = true; - break; case 'o': outfd = open(optarg, O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC,