#include #include #include #include #include #include #include #include static const char* str_usage = "Usage: %s [--nologo / -n] [--kernel / -k] [--unpack / -u] []\n"; static void error_load_infile() { printf("Error: cannot load input file\n"); exit(1); } static void error_malloc_failed() { printf("Error: memory allocation failed\n"); exit(1); } int main(int argc, char *argv[]) { bool flag_nologo = false; bool flag_kernel = false; bool flag_unpack = false; char *infile_name = NULL; char *outfile_name = NULL; int opt; static struct option long_options[] = { {"nologo", no_argument, NULL, 'n'}, {"kernel", no_argument, NULL, 'k'}, {"unpack", no_argument, NULL, 'u'}, {0, 0, 0, 0} // must be zeros here }; while ((opt = getopt_long(argc, argv, "nku", long_options, NULL)) != -1) { switch (opt) { case 'n': flag_nologo = true; break; case 'k': flag_kernel = true; break; case 'u': flag_unpack = true; break; default: // '?' fprintf(stderr, str_usage, argv[0]); return 1; } } // check for required infile if (optind >= argc) { printf("Error: Input file is required.\n"); printf(str_usage, argv[0]); return 1; } infile_name = argv[optind]; // optional outfile if (optind + 1 < argc) { outfile_name = argv[optind + 1]; optind++; } // printf("argc = %d, optind = %d\n", argc - 1, optind); if (argc - 1 > optind) { printf("Error: too many arguments\n"); printf(str_usage, argv[0]); return 1; } // for debug: print parsed options and args printf("nologo: %s\n", flag_nologo ? "true" : "false"); printf("kernel: %s\n", flag_kernel ? "true" : "false"); printf("unpack: %s\n", flag_unpack ? "true" : "false"); printf("infile: %s\n", infile_name); printf("outfile: %s\n", outfile_name ? outfile_name : "Not specified"); printf("\n"); if (!flag_nologo) { printf("KPackC - Kolibri Packer in C\nUses LZMA v4.32 compression library\n\n"); } struct stat64 statbuf; int res_stat = stat64(infile_name, &statbuf); if (res_stat == -1) { error_load_infile(); } // printf("statbuf.st_size = %lld\n", statbuf.st_size); if (statbuf.st_size == 0 || statbuf.st_size >= 4294967296LL) { printf("Error: input file must be non zero and less than 4G\n"); return 1; } unsigned infile_size = (unsigned int)statbuf.st_size; printf("infile_size = %u\n", infile_size); FILE *infile_handle = fopen(infile_name, "rb"); if (!infile_handle) { error_load_infile(); } unsigned char *infile_buf = malloc(infile_size); if (infile_buf == NULL) { error_malloc_failed(); } size_t bytes_read = fread(infile_buf, 1, infile_size, infile_handle); if (bytes_read != infile_size) { error_load_infile(); } fclose(infile_handle); // calculate maximum size of the output: unsigned bufsize = infile_size*9/8 + 0x400; // should be enough for header printf("bufsize = 0x%x\n", bufsize); unsigned char *buf = malloc(2*bufsize); // allocate memory for two copies of maximum output if (buf == NULL) { error_malloc_failed(); } // TODO ... // https://git.kolibrios.org/KolibriOS/kolibrios/src/commit/293e1d195a14d01a0f8812a954ff1449048f6209/programs/other/kpack/kerpack_linux/kpack64.asm#L236 return 0; }