static void de_run_gemmeta(deark *c, de_module_params *mparams) { lctx *d = NULL; de_int64 pos; de_int64 hdrlen_words; de_int64 version; de_int64 imgflag; de_int64 bytesused; d = de_malloc(c, sizeof(lctx)); de_msg(c, "Note: GEM VDI Metafiles can be parsed, but no files can be extracted from them.\n"); pos = 0; hdrlen_words = de_getui16le(pos+2); de_dbg(c, "header length: %d words\n", (int)hdrlen_words); version = de_getui16le(pos+4); de_dbg(c, "version number: %d\n", (int)version); // TODO: Read more header fields. imgflag = de_getui16le(pos+28); de_dbg(c, "image flag: %d\n", (int)imgflag); pos += hdrlen_words*2; while(1) { if(pos >= c->infile->len) break; if(!do_record(c, d, pos, &bytesused)) break; if(bytesused<=0) break; pos += bytesused; } de_free(c, d); }
static void do_modhelp(deark *c) { struct deark_module_info *module_to_use = NULL; de_register_modules(c); module_to_use = de_get_module_by_id(c, c->input_format_req); if(!module_to_use) { de_err(c, "Unknown module \"%s\"\n", c->input_format_req); goto done; } if(!module_to_use->help_fn) { de_msg(c, "No help available for module \"%s\"\n", c->input_format_req); goto done; } de_msg(c, "Help for module \"%s\":\n", c->input_format_req); module_to_use->help_fn(c); done: ; }
void de_run(deark *c) { dbuf *orig_ifile = NULL; dbuf *subfile = NULL; de_int64 subfile_size; struct deark_module_info *module_to_use = NULL; const char *friendly_infn; if(c->modhelp_req && c->input_format_req) { do_modhelp(c); goto done; } if(c->input_style==DE_INPUTSTYLE_STDIN) { friendly_infn = "[stdin]"; } else { friendly_infn = c->input_filename; } if(!friendly_infn) { de_err(c, "Input file not set\n"); de_fatalerror(c); return; } de_register_modules(c); if(c->input_format_req) { module_to_use = de_get_module_by_id(c, c->input_format_req); if(!module_to_use) { de_err(c, "Unknown module \"%s\"\n", c->input_format_req); goto done; } } if(c->slice_size_req_valid) { de_dbg(c, "Input file: %s[%d,%d]\n", friendly_infn, (int)c->slice_start_req, (int)c->slice_size_req); } else if(c->slice_start_req) { de_dbg(c, "Input file: %s[%d]\n", friendly_infn, (int)c->slice_start_req); } else { de_dbg(c, "Input file: %s\n", friendly_infn); } if(c->input_style==DE_INPUTSTYLE_STDIN) { orig_ifile = dbuf_open_input_stdin(c, c->input_filename); } else { orig_ifile = dbuf_open_input_file(c, c->input_filename); } if(!orig_ifile) { goto done; } c->infile = orig_ifile; // If we are only supposed to look at a segment of the original file, // do that by creating a child dbuf, using dbuf_open_input_subfile(). if(c->slice_start_req>0 || c->slice_size_req_valid) { if(c->slice_size_req_valid) subfile_size = c->slice_size_req; else subfile_size = dbuf_get_length(c->infile) - c->slice_start_req; subfile = dbuf_open_input_subfile(c->infile, c->slice_start_req, subfile_size); c->infile = subfile; } if(!module_to_use) { module_to_use = detect_module_for_file(c); } if(!module_to_use) { if(c->infile->len==0) de_err(c, "Unknown or unsupported file format (empty file)\n"); else de_err(c, "Unknown or unsupported file format\n"); goto done; } de_msg(c, "Module: %s\n", module_to_use->id); if(module_to_use->flags&DE_MODFLAG_NONWORKING) { de_warn(c, "The %s module is considered to be incomplete, and may " "not work properly. Caveat emptor.\n", module_to_use->id); } de_dbg2(c, "file size: %" INT64_FMT "\n", c->infile->len); if(!de_run_module(c, module_to_use, NULL)) { goto done; } // The DE_MODFLAG_NOEXTRACT flag means the module is not expected to extract // any files. if(c->num_files_extracted==0 && c->error_count==0 && !(module_to_use->flags&DE_MODFLAG_NOEXTRACT)) { de_msg(c, "No files found to extract!\n"); } done: if(subfile) dbuf_close(subfile); if(orig_ifile) dbuf_close(orig_ifile); }
static void de_help_psf(deark *c) { de_msg(c, "-opt font:noaliases : Restrict to one codepoint per glyph"); }
dbuf *dbuf_create_output_file(deark *c, const char *ext, de_finfo *fi, unsigned int createflags) { char nbuf[500]; char msgbuf[200]; dbuf *f; const char *basefn; int file_index; u8 is_directory = 0; char *name_from_finfo = NULL; i64 name_from_finfo_len = 0; if(ext && fi && fi->original_filename_flag) { de_dbg(c, "[internal warning: Incorrect use of create_output_file]"); } f = de_malloc(c, sizeof(dbuf)); f->c = c; f->max_len_hard = c->max_output_file_size; f->is_managed = 1; if(fi && fi->is_directory) { is_directory = 1; } if(is_directory && !c->keep_dir_entries) { de_dbg(c, "skipping 'directory' file"); f->btype = DBUF_TYPE_NULL; goto done; } if(c->extract_policy==DE_EXTRACTPOLICY_MAINONLY) { if(createflags&DE_CREATEFLAG_IS_AUX) { de_dbg(c, "skipping 'auxiliary' file"); f->btype = DBUF_TYPE_NULL; goto done; } } else if(c->extract_policy==DE_EXTRACTPOLICY_AUXONLY) { if(!(createflags&DE_CREATEFLAG_IS_AUX)) { de_dbg(c, "skipping 'main' file"); f->btype = DBUF_TYPE_NULL; goto done; } } file_index = c->file_count; c->file_count++; basefn = c->base_output_filename ? c->base_output_filename : "output"; if(fi && ucstring_isnonempty(fi->file_name_internal)) { name_from_finfo_len = 1 + ucstring_count_utf8_bytes(fi->file_name_internal); name_from_finfo = de_malloc(c, name_from_finfo_len); ucstring_to_sz(fi->file_name_internal, name_from_finfo, (size_t)name_from_finfo_len, 0, DE_ENCODING_UTF8); } if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE && !c->base_output_filename && fi && fi->is_directory && (fi->is_root_dir || (fi->detect_root_dot_dir && fi->orig_name_was_dot))) { de_strlcpy(nbuf, ".", sizeof(nbuf)); } else if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE && !c->base_output_filename && fi && fi->original_filename_flag && name_from_finfo) { // TODO: This is a "temporary" hack to allow us to, when both reading from // and writing to an archive format, use some semblance of the correct // filename (instead of "output.xxx.yyy"). // There are some things that we don't handle optimally, such as // subdirectories. // A major redesign of the file naming logic would be good. de_strlcpy(nbuf, name_from_finfo, sizeof(nbuf)); } else { char fn_suffix[256]; if(ext && name_from_finfo) { de_snprintf(fn_suffix, sizeof(fn_suffix), "%s.%s", name_from_finfo, ext); } else if(ext) { de_strlcpy(fn_suffix, ext, sizeof(fn_suffix)); } else if(is_directory && name_from_finfo) { de_snprintf(fn_suffix, sizeof(fn_suffix), "%s.dir", name_from_finfo); } else if(name_from_finfo) { de_strlcpy(fn_suffix, name_from_finfo, sizeof(fn_suffix)); } else if(is_directory) { de_strlcpy(fn_suffix, "dir", sizeof(fn_suffix)); } else { de_strlcpy(fn_suffix, "bin", sizeof(fn_suffix)); } de_snprintf(nbuf, sizeof(nbuf), "%s.%03d.%s", basefn, file_index, fn_suffix); } f->name = de_strdup(c, nbuf); if(fi) { // The finfo object passed to us at file creation is not required to // remain valid, so make a copy of anything in it that we might need // later. f->fi_copy = de_finfo_create(c); finfo_shallow_copy(c, fi, f->fi_copy); // Here's where we respect the -intz option, by using it to convert to // UTC in some cases. if(f->fi_copy->mod_time.is_valid && f->fi_copy->mod_time.tzcode==DE_TZCODE_LOCAL && c->input_tz_offs_seconds!=0) { de_timestamp_cvt_to_utc(&f->fi_copy->mod_time, -c->input_tz_offs_seconds); } if(f->fi_copy->image_mod_time.is_valid && f->fi_copy->image_mod_time.tzcode==DE_TZCODE_LOCAL && c->input_tz_offs_seconds!=0) { de_timestamp_cvt_to_utc(&f->fi_copy->image_mod_time, -c->input_tz_offs_seconds); } } if(file_index < c->first_output_file) { f->btype = DBUF_TYPE_NULL; goto done; } if(c->max_output_files>=0 && file_index >= c->first_output_file + c->max_output_files) { f->btype = DBUF_TYPE_NULL; goto done; } c->num_files_extracted++; if(c->extrlist_dbuf) { dbuf_printf(c->extrlist_dbuf, "%s\n", f->name); dbuf_flush(c->extrlist_dbuf); } if(c->list_mode) { f->btype = DBUF_TYPE_NULL; if(c->list_mode_include_file_id) { de_msg(c, "%d:%s", file_index, f->name); } else { de_msg(c, "%s", f->name); } goto done; } if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE && c->archive_fmt==DE_ARCHIVEFMT_TAR) { de_info(c, "Adding %s to TAR file", f->name); f->btype = DBUF_TYPE_ODBUF; // A dummy max_len_hard value. The parent will do the checking. f->max_len_hard = DE_DUMMY_MAX_FILE_SIZE; f->writing_to_tar_archive = 1; de_tar_start_member_file(c, f); } else if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE) { // ZIP i64 initial_alloc; de_info(c, "Adding %s to ZIP file", f->name); f->btype = DBUF_TYPE_MEMBUF; f->max_len_hard = DE_MAX_MEMBUF_SIZE; if(is_directory) { // A directory entry is not expected to have any data associated // with it (besides the files it contains). initial_alloc = 16; } else { initial_alloc = 65536; } f->membuf_buf = de_malloc(c, initial_alloc); f->membuf_alloc = initial_alloc; f->write_memfile_to_zip_archive = 1; } else if(c->output_style==DE_OUTPUTSTYLE_STDOUT) { de_info(c, "Writing %s to [stdout]", f->name); f->btype = DBUF_TYPE_STDOUT; // TODO: Should we increase f->max_len_hard? f->fp = stdout; } else { de_info(c, "Writing %s", f->name); f->btype = DBUF_TYPE_OFILE; f->fp = de_fopen_for_write(c, f->name, msgbuf, sizeof(msgbuf), c->overwrite_mode, 0); if(!f->fp) { de_err(c, "Failed to write %s: %s", f->name, msgbuf); f->btype = DBUF_TYPE_NULL; } } done: de_free(c, name_from_finfo); return f; }
static void de_help_ebml(deark *c) { de_msg(c, "-opt ebml:encodedid : Also print element ID numbers in raw form"); }
static void de_help_ogg(deark *c) { de_msg(c, "-opt ogg:hexdump : Hex dump the first part of all segments"); }
static void de_help_wri(deark *c) { de_msg(c, "-opt wri:extracttext=0 : Do not extract text"); de_msg(c, "-opt wri:extractole : Extract unidentified OLE objects"); }