// SPDX-License-Identifier: GPL-2.0-or-later /* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2012-2014 Intel Corporation. All rights reserved. * * */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include /* * The "new" ASCII format uses 8-byte hexadecimal fields for all numbers and * separates device numbers into separate fields for major and minor numbers. * * struct cpio_newc_header { * char c_magic[6]; * char c_ino[8]; * char c_mode[8]; * char c_uid[8]; * char c_gid[8]; * char c_nlink[8]; * char c_mtime[8]; * char c_filesize[8]; * char c_devmajor[8]; * char c_devminor[8]; * char c_rdevmajor[8]; * char c_rdevminor[8]; * char c_namesize[8]; * char c_check[8]; * }; * */ #define HDR_FMT "%s%08X%08X%08X%08X%08X%08X%08jX%08X%08X%08X%08X%08X%08X%s" #define HDR_MAGIC "070701" static unsigned int ino_cnt = 721; #define REG_EXE S_IFREG | 0555 static const struct { const char *source; const char *target; mode_t mode; } file_list[] = { { "tools/test-runner", "init", REG_EXE }, { } }; static void write_block(FILE *fp, const char *pathname, unsigned int ino, mode_t mode, const char *name) { int i, pad, namelen = strlen(name); struct stat st; void *map; int fd; if (!pathname) { fd = -1; map = NULL; st.st_size = 0; goto done; } fd = open(pathname, O_RDONLY | O_CLOEXEC); if (fd < 0) { fd = -1; map = NULL; st.st_size = 0; goto done; } if (fstat(fd, &st) < 0) { close(fd); fd = -1; map = NULL; st.st_size = 0; goto done; } map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (!map || map == MAP_FAILED) { map = NULL; st.st_size = 0; } close(fd); fd = -1; done: fprintf(fp, HDR_FMT, HDR_MAGIC, ino, mode, 0, 0, 1, 0, (uintmax_t) st.st_size, 0, 0, 0, 0, namelen + 1, 0, name); pad = 4 - ((110 + namelen) % 4); for (i = 0; i < pad; i++) fputc(0, fp); if (st.st_size > 0) { fwrite(map, st.st_size, 1, fp); pad = 3 - ((st.st_size + 3) % 4); for (i = 0; i < pad; i++) fputc(0, fp); munmap(map, st.st_size); } } static void usage(void) { printf("create-image - CPIO image creation utility\n" "Usage:\n"); printf("\tcreate-image [options]\n"); printf("Options:\n" "\t-o, --output Output CPIO image\n" "\t-h, --help Show help options\n"); } static const struct option main_options[] = { { "output", required_argument, NULL, 'o' }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { } }; int main(int argc, char *argv[]) { const char *output_pathname = NULL; FILE *fp; int i; for (;;) { int opt; opt = getopt_long(argc, argv, "o:vh", main_options, NULL); if (opt < 0) break; switch (opt) { case 'o': output_pathname = optarg; break; case 'v': printf("%s\n", VERSION); return EXIT_SUCCESS; case 'h': usage(); return EXIT_SUCCESS; default: return EXIT_FAILURE; } } if (argc - optind > 0) { fprintf(stderr, "Invalid command line parameters\n"); return EXIT_FAILURE; } if (!output_pathname) { fprintf(stderr, "Failed to specify output file\n"); return EXIT_FAILURE; } fp = fopen(output_pathname, "we"); for (i = 0; file_list[i].source; i++) write_block(fp, file_list[i].source, ino_cnt++, file_list[i].mode, file_list[i].target); write_block(fp, NULL, ino_cnt++, 0, "TRAILER!!!"); fclose(fp); return EXIT_SUCCESS; }