/******************************************************* Function: create_unique_file *******************************************************/ string create_unique_file (const string path, char suffix) { string p; string base = basename (path); string new_path; int fd; /* length of tmpdir + basename of path and '/' between the dir and the basename + null terminator */ p = (string) MALLOC (strlen(tmpdir) + strlen(base) + 2); MALLOC_ASSERT (p); strcpy (p, tmpdir); strcat (p, "/"); strcat (p, base); new_path = make_temp_file (p, suffix); FREE (p); if ((fd = creat (new_path, 0666 & ~cmask)) == -1) { perror(new_path); exit(1); } CLOSE (fd); return new_path; } /* create_unique_file */
/* Generate a temporary file name based on OBJ, FLAGS, and NAME. Return NULL if we were unable to reserve a temporary filename. If non-NULL, the result is either allocated with malloc, or the same pointer as NAME. */ static char * temp_file (struct pex_obj *obj, int flags, char *name) { if (name == NULL) { if (obj->tempbase == NULL) { name = make_temp_file (NULL); } else { int len = strlen (obj->tempbase); int out; if (len >= 6 && strcmp (obj->tempbase + len - 6, "XXXXXX") == 0) name = xstrdup (obj->tempbase); else name = concat (obj->tempbase, "XXXXXX", NULL); out = mkstemps (name, 0); if (out < 0) { free (name); return NULL; } /* This isn't obj->funcs->close because we got the descriptor from mkstemps, not from a function in obj->funcs. Calling close here is just like what make_temp_file does. */ close (out); } } else if ((flags & PEX_SUFFIX) != 0) { if (obj->tempbase == NULL) name = make_temp_file (name); else name = concat (obj->tempbase, name, NULL); } return name; }
/* suffix includes the `.` */ static const char * newtempfile (const char *suffix, const char *org_filename) { const char *fname; if (save_temps) { fname = replace_suffix(org_filename, suffix); } else { fname = make_temp_file(suffix); pushstring(&all_tempfiles, fname); } return fname; }
FILE *open_temp_file(const char *basename, const char *extension, const char **final_name) { char uniquenum_extension[32]; static unsigned nextnum = 0; snprintf(uniquenum_extension, sizeof(uniquenum_extension), "-%u%s", nextnum++, extension); const char *tmpname = get_output_name(basename, uniquenum_extension); return make_temp_file(tmpname, final_name); }
static void do_compile (const char **current_argv, int current_argc) { char *errmsg_fmt, *errmsg_arg; int index = 0; int dash_o_index = current_argc; int of_index = current_argc + 1; int argc_count = current_argc + 2; while (index < num_arches) { int additional_arch_options = 0; current_argv[0] = get_driver_name (get_arch_name (arches[index])); /* setup output file. */ out_files[num_outfiles] = make_temp_file (".out"); current_argv[dash_o_index] = "-o"; current_argv[of_index] = out_files [num_outfiles]; num_outfiles++; /* Add arch option as the last option. Do not add any other option before removing this option. */ additional_arch_options = add_arch_options (index, current_argv, argc_count); argc_count += additional_arch_options; commands[index].prog = current_argv[0]; commands[index].argv = current_argv; current_argv[argc_count] = NULL; #ifdef DEBUG debug_command_line (current_argv, argc_count); #endif commands[index].pid = pexecute (current_argv[0], (char *const *)current_argv, progname, NULL, &errmsg_fmt, &errmsg_arg, PEXECUTE_SEARCH | PEXECUTE_ONE); if (commands[index].pid == -1) pfatal_pexecute (errmsg_fmt, errmsg_arg); do_wait (commands[index].pid, commands[index].prog); fflush (stdout); /* Remove the last arch option added in the current_argv list. */ if (additional_arch_options) argc_count -= remove_arch_options (current_argv, argc_count); index++; } }
struct pex_obj * collect_execute (const char *prog, char **argv, const char *outname, const char *errname, int flags, bool use_atfile) { struct pex_obj *pex; const char *errmsg; int err; char *response_arg = NULL; char *response_argv[3]; if (use_atfile && argv[0] != NULL) { /* If using @file arguments, create a temporary file and put the contents of argv into it. Then change argv to an array corresponding to a single argument @FILE, where FILE is the temporary filename. */ char **current_argv = argv + 1; char *argv0 = argv[0]; int status; FILE *f; /* Note: we assume argv contains at least one element; this is checked above. */ response_file = make_temp_file (""); f = fopen (response_file, "w"); if (f == NULL) fatal_error (input_location, "could not open response file %s", response_file); status = writeargv (current_argv, f); if (status) fatal_error (input_location, "could not write to response file %s", response_file); status = fclose (f); if (EOF == status) fatal_error (input_location, "could not close response file %s", response_file); response_arg = concat ("@", response_file, NULL); response_argv[0] = argv0; response_argv[1] = response_arg; response_argv[2] = NULL; argv = response_argv; } if (verbose || debug) { char **p_argv; const char *str; if (argv[0]) fprintf (stderr, "%s", argv[0]); else notice ("[cannot find %s]", prog); for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++) fprintf (stderr, " %s", str); fprintf (stderr, "\n"); } fflush (stdout); fflush (stderr); /* If we cannot find a program we need, complain error. Do this here since we might not end up needing something that we could not find. */ if (argv[0] == 0) fatal_error (input_location, "cannot find '%s'", prog); pex = pex_init (0, "collect2", NULL); if (pex == NULL) fatal_error (input_location, "pex_init failed: %m"); errmsg = pex_run (pex, flags, argv[0], argv, outname, errname, &err); if (errmsg != NULL) { if (err != 0) { errno = err; fatal_error (input_location, "%s: %m", _(errmsg)); } else fatal_error (input_location, errmsg); } free (response_arg); return pex; }
static enum ld_plugin_status all_symbols_read_handler (void) { unsigned i; unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 2 + !linker_output_known; char **lto_argv; const char *linker_output_str = NULL; const char **lto_arg_ptr; if (num_claimed_files + num_offload_files == 0) return LDPS_OK; if (nop) { use_original_files (); return LDPS_OK; } lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args); lto_arg_ptr = (const char **) lto_argv; assert (lto_wrapper_argv); write_resolution (); free_1 (claimed_files, num_claimed_files); for (i = 0; i < lto_wrapper_num_args; i++) *lto_arg_ptr++ = lto_wrapper_argv[i]; if (!linker_output_known) { assert (linker_output_set); switch (linker_output) { case LDPO_REL: if (non_claimed_files) { message (LDPL_WARNING, "incremental linking of LTO and non-LTO " "objects; using -flinker-output=nolto-rel which will " "bypass whole program optimization"); linker_output_str = "-flinker-output=nolto-rel"; } else linker_output_str = "-flinker-output=rel"; break; case LDPO_DYN: linker_output_str = "-flinker-output=dyn"; break; case LDPO_PIE: linker_output_str = "-flinker-output=pie"; break; case LDPO_EXEC: linker_output_str = "-flinker-output=exec"; break; default: message (LDPL_FATAL, "unsupported linker output %i", linker_output); break; } *lto_arg_ptr++ = xstrdup (linker_output_str); } if (num_offload_files > 0) { FILE *f; char *arg; char *offload_objects_file_name; struct plugin_offload_file *ofld; offload_objects_file_name = make_temp_file (".ofldlist"); check (offload_objects_file_name, LDPL_FATAL, "Failed to generate a temporary file name"); f = fopen (offload_objects_file_name, "w"); check (f, LDPL_FATAL, "could not open file with offload objects"); fprintf (f, "%u\n", num_offload_files); /* Skip the dummy item at the start of the list. */ ofld = offload_files->next; while (ofld) { fprintf (f, "%s\n", ofld->name); ofld = ofld->next; } fclose (f); arg = concat ("-foffload-objects=", offload_objects_file_name, NULL); check (arg, LDPL_FATAL, "could not allocate"); *lto_arg_ptr++ = arg; } for (i = 0; i < num_claimed_files; i++) { struct plugin_file_info *info = &claimed_files[i]; *lto_arg_ptr++ = info->name; } *lto_arg_ptr++ = NULL; exec_lto_wrapper (lto_argv); free (lto_argv); /* --pass-through is not needed when using gold 1.11 or later. */ if (pass_through_items && gold_version < 111) { unsigned int i; for (i = 0; i < num_pass_through_items; i++) { if (strncmp (pass_through_items[i], "-l", 2) == 0) add_input_library (pass_through_items[i] + 2); else add_input_file (pass_through_items[i]); free (pass_through_items[i]); pass_through_items[i] = NULL; } free (pass_through_items); pass_through_items = NULL; } return LDPS_OK; }
static void exec_lto_wrapper (char *argv[]) { int t, i; int status; char *at_args; FILE *args; FILE *wrapper_output; char *new_argv[3]; struct pex_obj *pex; const char *errmsg; /* Write argv to a file to avoid a command line that is too long. */ arguments_file_name = make_temp_file (""); check (arguments_file_name, LDPL_FATAL, "Failed to generate a temorary file name"); args = fopen (arguments_file_name, "w"); check (args, LDPL_FATAL, "could not open arguments file"); t = writeargv (&argv[1], args); check (t == 0, LDPL_FATAL, "could not write arguments"); t = fclose (args); check (t == 0, LDPL_FATAL, "could not close arguments file"); at_args = concat ("@", arguments_file_name, NULL); check (at_args, LDPL_FATAL, "could not allocate"); for (i = 1; argv[i]; i++) { char *a = argv[i]; if (a[0] == '-' && a[1] == 'v' && a[2] == '\0') { for (i = 0; argv[i]; i++) fprintf (stderr, "%s ", argv[i]); fprintf (stderr, "\n"); break; } } new_argv[0] = argv[0]; new_argv[1] = at_args; new_argv[2] = NULL; if (debug) { for (i = 0; new_argv[i]; i++) fprintf (stderr, "%s ", new_argv[i]); fprintf (stderr, "\n"); } pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL); check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper"); errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t); check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper"); check (t == 0, LDPL_FATAL, "could not run lto-wrapper"); wrapper_output = pex_read_output (pex, 0); check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output"); add_output_files (wrapper_output); t = pex_get_status (pex, 1, &status); check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status"); check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL, "lto-wrapper failed"); pex_free (pex); free (at_args); }
named_temp_file::named_temp_file (const char *suffix) { m_filename = make_temp_file (suffix); ASSERT_NE (m_filename, NULL); }
int wmain(int argc, wchar_t** argv) { _setmode(_fileno(stdout), _O_U16TEXT); _setmode(_fileno(stderr), _O_U16TEXT); #else int main(int argc, char** argv) { #endif struct Arguments args = parse_args(argc, argv); if(!args.valid) { return EXIT_FAILURE; } bool success = true; for(size_t i = 0; i < args.num_filenames; ++i) { FILE* file = open_file(args.filenames[i]); struct TempFile* temp_file = make_temp_file("newline_%.tmp"); if(file == NULL) { arg_printerr( arg_f arg_s(": ") arg_f arg_s(": ") arg_f, argv[0], args.filenames[i], arg_strerror(errno) ); if(temp_file != NULL) { fclose(temp_file->file); delete(temp_file->filename); free_temp_file(temp_file); } success = false; } else if(temp_file == NULL) { arg_printerr( arg_f arg_s(": ") arg_f arg_s(": Unable to create temporary ") arg_s("file"), argv[0], args.filenames[i] ); fclose(file); success = false; } else { bool result = trim_file( file, temp_file->file, args.newline_type, args.trailing_newline, args.strip_whitespace ); if(result) { // Need to copy the temp file to original file. It would be // faster to just rename() the temporary file to the original // file, but this won't preserve file metadata such as // permission bits or owners. ReplaceFile() does this on // Windows, but an easy solution for Unix systems doesn't seem // to exist. fseeko(file, 0, SEEK_SET); fseeko(temp_file->file, 0, SEEK_SET); uint8_t* buffer = malloc(FileBufferLen); size_t read_bytes = fread( buffer, 1, FileBufferLen, temp_file->file ); while(read_bytes) { fwrite(buffer, 1, read_bytes, file); read_bytes = fread( buffer, 1, FileBufferLen, temp_file->file ); } free(buffer); off_t file_len = ftello(file); fflush(file); ftruncate(fileno(file), file_len); } if(args.verbose) { if(result) { arg_print( arg_s("Processed ") arg_f, args.filenames[i] ); } else { arg_print( arg_s("No changes made to ") arg_f, args.filenames[i] ); } } fclose(file); fclose(temp_file->file); delete(temp_file->filename); free_temp_file(temp_file); } } free_args(&args); if(!success) { return EXIT_FAILURE; } return EXIT_SUCCESS; }
static int pw_load(struct module_data *m, HIO_HANDLE *h, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; struct mod_header mh; uint8 mod_event[4]; HIO_HANDLE *f; FILE *temp; char *name; char *temp_name; int i, j; /* Prowizard depacking */ if ((temp = make_temp_file(&temp_name)) == NULL) { goto err; } if (pw_wizardry(h, temp, &name) < 0) { fclose(temp); goto err2; } /* Module loading */ if ((f = hio_open_file(temp)) == NULL) { goto err2; } if (hio_seek(f, 0, start) < 0) { goto err3; } hio_read(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); mh.ins[i].size = hio_read16b(f); mh.ins[i].finetune = hio_read8(f); mh.ins[i].volume = hio_read8(f); mh.ins[i].loop_start = hio_read16b(f); mh.ins[i].loop_size = hio_read16b(f); } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); hio_read(&mh.magic, 4, 1, f); if (memcmp(mh.magic, "M.K.", 4)) { goto err3; } mod->ins = 31; mod->smp = mod->ins; mod->chn = 4; mod->len = mh.len; mod->rst = mh.restart; memcpy(mod->xxo, mh.order, 128); for (i = 0; i < 128; i++) { if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; mod->trk = mod->chn * mod->pat; snprintf(mod->name, XMP_NAME_SIZE, "%s", (char *)mh.name); snprintf(mod->type, XMP_NAME_SIZE, "%s", name); MODULE_INFO(); if (libxmp_init_instrument(m) < 0) { goto err3; } for (i = 0; i < mod->ins; i++) { if (libxmp_alloc_subinstrument(mod, i, 1) < 0) goto err3; mod->xxs[i].len = 2 * mh.ins[i].size; mod->xxs[i].lps = 2 * mh.ins[i].loop_start; mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size; mod->xxs[i].flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].fin = (int8) (mh.ins[i].finetune << 4); mod->xxi[i].sub[0].vol = mh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxi[i].rls = 0xfff; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; libxmp_instrument_name(mod, i, mh.ins[i].name, 22); D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mh.ins[i].loop_size > 1 ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4); } if (libxmp_init_pattern(mod) < 0) { goto err3; } /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) goto err3; for (j = 0; j < (64 * 4); j++) { event = &EVENT(i, j % 4, j / 4); hio_read(mod_event, 1, 4, f); libxmp_decode_protracker_event(event, mod_event); } } m->period_type = PERIOD_MODRNG; /* Load samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->smp; i++) { if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) goto err3; } hio_close(f); unlink_temp_file(temp_name); return 0; err3: hio_close(f); err2: unlink_temp_file(temp_name); err: return -1; }
void process_file(char *ifile, char *ofile) { int old_flags, old_stack, new_flags, new_stack; stream ifp, ofp; struct flat_hdr old_hdr, new_hdr; char *tfile, tmpbuf[256]; int input_error, output_error; *tmpbuf = '\0'; if (fopen_stream_u(&ifp, ifile, "r" BINARY_FILE_OPTS)) { fprintf(stderr, "Cannot open %s\n", ifile); return; } if (fread_stream(&old_hdr, sizeof(old_hdr), 1, &ifp) != 1) { fprintf(stderr, "Cannot read header of %s\n", ifile); fclose_stream(&ifp); return; } if (strncmp(old_hdr.magic, "bFLT", 4) != 0) { fprintf(stderr, "Cannot read header of %s\n", ifile); fclose_stream(&ifp); return; } new_flags = old_flags = ntohl(old_hdr.flags); new_stack = old_stack = ntohl(old_hdr.stack_size); new_hdr = old_hdr; if (docompress == 1) { new_flags |= FLAT_FLAG_GZIP; new_flags &= ~FLAT_FLAG_GZDATA; } else if (docompress == 2) { new_flags |= FLAT_FLAG_GZDATA; new_flags &= ~FLAT_FLAG_GZIP; } else if (docompress < 0) new_flags &= ~(FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA); if (ramload > 0) new_flags |= FLAT_FLAG_RAM; else if (ramload < 0) new_flags &= ~FLAT_FLAG_RAM; if (ktrace > 0) new_flags |= FLAT_FLAG_KTRACE; else if (ktrace < 0) new_flags &= ~FLAT_FLAG_KTRACE; if (l1stack > 0) new_flags |= FLAT_FLAG_L1STK; else if (l1stack < 0) new_flags &= ~FLAT_FLAG_L1STK; if (stacksize) new_stack = stacksize; if (print == 1) { time_t t; uint32_t reloc_count, reloc_start; printf("%s\n", ifile); printf(" Magic: %4.4s\n", old_hdr.magic); printf(" Rev: %d\n", ntohl(old_hdr.rev)); t = (time_t) htonl(old_hdr.build_date); printf(" Build Date: %s", t?ctime(&t):"not specified\n"); printf(" Entry: 0x%x\n", ntohl(old_hdr.entry)); printf(" Data Start: 0x%x\n", ntohl(old_hdr.data_start)); printf(" Data End: 0x%x\n", ntohl(old_hdr.data_end)); printf(" BSS End: 0x%x\n", ntohl(old_hdr.bss_end)); printf(" Stack Size: 0x%x\n", ntohl(old_hdr.stack_size)); reloc_start = ntohl(old_hdr.reloc_start); printf(" Reloc Start: 0x%x\n", reloc_start); reloc_count = ntohl(old_hdr.reloc_count); printf(" Reloc Count: 0x%x\n", reloc_count); printf(" Flags: 0x%x ( ", ntohl(old_hdr.flags)); if (old_flags) { if (old_flags & FLAT_FLAG_RAM) printf("Load-to-Ram "); if (old_flags & FLAT_FLAG_GOTPIC) printf("Has-PIC-GOT "); if (old_flags & FLAT_FLAG_GZIP) printf("Gzip-Compressed "); if (old_flags & FLAT_FLAG_GZDATA) printf("Gzip-Data-Compressed "); if (old_flags & FLAT_FLAG_KTRACE) printf("Kernel-Traced-Load "); if (old_flags & FLAT_FLAG_L1STK) printf("L1-Scratch-Stack "); printf(")\n"); } if (print_relocs) { uint32_t *relocs = xcalloc(reloc_count, sizeof(uint32_t)); uint32_t i; unsigned long r; printf(" Relocs:\n"); printf(" #\treloc ( address )\tdata\n"); if (old_flags & FLAT_FLAG_GZIP) reopen_stream_compressed(&ifp); if (fseek_stream(&ifp, reloc_start, SEEK_SET)) { fprintf(stderr, "Cannot seek to relocs of %s\n", ifile); fclose_stream(&ifp); return; } if (fread_stream(relocs, sizeof(uint32_t), reloc_count, &ifp) == -1) { fprintf(stderr, "Cannot read relocs of %s\n", ifile); fclose_stream(&ifp); return; } for (i = 0; i < reloc_count; ++i) { uint32_t raddr, addr; r = ntohl(relocs[i]); raddr = flat_get_relocate_addr(r); printf(" %u\t0x%08lx (0x%08"PRIx32")\t", i, r, raddr); #if defined(TARGET_h8300) raddr &= ~0x00000001; #endif fseek_stream(&ifp, sizeof(old_hdr) + raddr, SEEK_SET); fread_stream(&addr, sizeof(addr), 1, &ifp); #if defined(TARGET_h8300) addr = ntohl(addr); if (r & 1) addr &= 0x00ffffff; #endif printf("%"PRIx32"\n", addr); } /* reset file position for below */ fseek_stream(&ifp, sizeof(old_hdr), SEEK_SET); } } else if (print > 1) { static int first = 1; unsigned int text, data, bss, stk, rel, tot; if (first) { printf("Flag Rev Text Data BSS Stack Relocs RAM Filename\n"); printf("-----------------------------------------------------------\n"); first = 0; } *tmpbuf = '\0'; strcat(tmpbuf, (old_flags & FLAT_FLAG_KTRACE) ? "k" : ""); strcat(tmpbuf, (old_flags & FLAT_FLAG_RAM) ? "r" : ""); strcat(tmpbuf, (old_flags & FLAT_FLAG_GOTPIC) ? "p" : ""); strcat(tmpbuf, (old_flags & FLAT_FLAG_GZIP) ? "z" : ((old_flags & FLAT_FLAG_GZDATA) ? "d" : "")); printf("-%-3.3s ", tmpbuf); printf("%3d ", ntohl(old_hdr.rev)); printf("%6d ", text=ntohl(old_hdr.data_start)-sizeof(struct flat_hdr)); printf("%6d ", data=ntohl(old_hdr.data_end)-ntohl(old_hdr.data_start)); printf("%6d ", bss=ntohl(old_hdr.bss_end)-ntohl(old_hdr.data_end)); printf("%6d ", stk=ntohl(old_hdr.stack_size)); printf("%6d ", rel=ntohl(old_hdr.reloc_count) * 4); /* * work out how much RAM is needed per invocation, this * calculation is dependent on the binfmt_flat implementation */ tot = data; /* always need data */ if (old_flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) tot += text + sizeof(struct flat_hdr); if (bss + stk > rel) /* which is bigger ? */ tot += bss + stk; else tot += rel; printf("%6d ", tot); /* * the total depends on whether the relocs are smaller/bigger than * the BSS */ printf("%s\n", ifile); } /* if there is nothing else to do, leave */ if (new_flags == old_flags && new_stack == old_stack) { fclose_stream(&ifp); return; } new_hdr.flags = htonl(new_flags); new_hdr.stack_size = htonl(new_stack); tfile = make_temp_file("flthdr"); if (fopen_stream_u(&ofp, tfile, "w" BINARY_FILE_OPTS)) { unlink(tfile); fatal("Failed to open %s for writing\n", tfile); } /* Copy header (always uncompressed). */ if (fwrite_stream(&new_hdr, sizeof(new_hdr), 1, &ofp) != 1) { unlink(tfile); fatal("Failed to write to %s\n", tfile); } /* Whole input file (including text) is compressed: start decompressing now. */ if (old_flags & FLAT_FLAG_GZIP) reopen_stream_compressed(&ifp); /* Likewise, output file is compressed. Start compressing now. */ if (new_flags & FLAT_FLAG_GZIP) { printf("zflat %s --> %s\n", ifile, ofile); reopen_stream_compressed(&ofp); } transfer(&ifp, &ofp, ntohl(old_hdr.data_start) - sizeof(struct flat_hdr)); /* Only data and relocs were compressed in input. Start decompressing from here. */ if (old_flags & FLAT_FLAG_GZDATA) reopen_stream_compressed(&ifp); /* Only data/relocs to be compressed in output. Start compressing from here. */ if (new_flags & FLAT_FLAG_GZDATA) { printf("zflat-data %s --> %s\n", ifile, ofile); reopen_stream_compressed(&ofp); } transfer(&ifp, &ofp, -1); input_error = ferror_stream(&ifp); output_error = ferror_stream(&ofp); if (input_error || output_error) { unlink(tfile); fatal("Error on file pointer%s%s\n", input_error ? " input" : "", output_error ? " output" : ""); } fclose_stream(&ifp); fclose_stream(&ofp); /* Copy temporary file to output location. */ fopen_stream_u(&ifp, tfile, "r" BINARY_FILE_OPTS); fopen_stream_u(&ofp, ofile, "w" BINARY_FILE_OPTS); transfer(&ifp, &ofp, -1); fclose_stream(&ifp); fclose_stream(&ofp); unlink(tfile); free(tfile); }
static int decrunch(HIO_HANDLE **h, char *filename, char **temp) { unsigned char b[1024]; char *cmd; FILE *f, *t; int res; int headersize; int i; struct depacker *depacker = NULL; cmd = NULL; res = 0; *temp = NULL; f = (*h)->handle.file; fseek(f, 0, SEEK_SET); headersize = fread(b, 1, 1024, f); if (headersize < 100) /* minimum valid file size */ return 0; /* Check built-in depackers */ for (i = 0; depacker_list[i] != NULL; i++) { if (depacker_list[i]->test(b)) { depacker = depacker_list[i]; D_(D_INFO "Use depacker %d", i); break; } } /* Check external commands */ if (depacker == NULL) { if (b[0] == 'M' && b[1] == 'O' && b[2] == '3') { /* MO3 */ D_(D_INFO "mo3"); cmd = "unmo3 -s \"%s\" STDOUT"; } else if (memcmp(b, "Rar", 3) == 0) { /* rar */ D_(D_INFO "rar"); cmd = "unrar p -inul -xreadme -x*.diz -x*.nfo -x*.txt " "-x*.exe -x*.com \"%s\""; } else if (test_oxm(f) == 0) { /* oggmod */ D_(D_INFO "oggmod"); depacker = &oxm_depacker; } } fseek(f, 0, SEEK_SET); if (depacker == NULL && cmd == NULL) { D_(D_INFO "Not packed"); return 0; } #if defined ANDROID || defined __native_client__ /* Don't use external helpers in android */ if (cmd) { return 0; } #endif D_(D_WARN "Depacking file... "); if ((t = make_temp_file(temp)) == NULL) return -1; /* Depack file */ if (cmd) { D_(D_INFO "External depacker: %s", cmd); if (execute_command(cmd, filename, t) < 0) { D_(D_CRIT "failed"); fclose(t); return -1; } } else if (depacker) { D_(D_INFO "Internal depacker"); if (depacker->depack(f, t) < 0) { D_(D_CRIT "failed"); fclose(t); return -1; } } D_(D_INFO "done"); fseek(t, 0, SEEK_SET); hio_close(*h); *h = hio_open_file(t); return res; }