From fbc214843d46da35aaf110533ea1e44c7ba4a3b0 Mon Sep 17 00:00:00 2001 From: Daniel Scharrer Date: Thu, 21 Feb 2013 20:12:28 +0100 Subject: [PATCH] Add a command-line option for the output directory --- README.md | 4 ++-- doc/innoextract.1 | 12 +++++++++--- src/cli/main.cpp | 24 +++++++++++++++++++++--- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 55cf2f7..416f510 100644 --- a/README.md +++ b/README.md @@ -86,11 +86,11 @@ Documentation is also available as a man page: * Included scripts and checks are not executed. -* Data is always extracted to the current directory and the mapping from Inno Setup variables like the application directory to subdirectories is hard-coded. +* The mapping from Inno Setup variables like the application directory to subdirectories is hard-coded. * innoextract does not check if an installer includes multiple files with the same name and will continually overwrite the destination file when extracting. -* Names for data files in multi-file installers must follow the standard naming scheme. +* Names for data slice/disk files in multi-file installers must follow the standard naming scheme. * Encrypted installers are not supported. diff --git a/doc/innoextract.1 b/doc/innoextract.1 index 967ad38..5b58286 100644 --- a/doc/innoextract.1 +++ b/doc/innoextract.1 @@ -36,15 +36,16 @@ Here is a short summary of the options available in innoextract. Please refer to \-l \-\-list Only list files, don't write anything .fi .TP -.B Filters: +.B Modifiers: .nf \-\-dump Dump contents without converting filenames \-L \-\-lowercase Convert extracted filenames to lower-case \-\-language=LANG Extract files for the given language \-T \-\-timestamps=TZ Timezone for file times or "local" or "none" + \-d \-\-output-dir=DIR Extract files into the given directory .fi .TP -.B I/O options: +.B Display options: .nf \-q \-\-quiet Output less information \-s \-\-silent Output only error/warning information @@ -83,6 +84,11 @@ The \fB--list\fP option can be combined with \fB--test\fP or \fB--extract\fP to \fB-L\fP, \fB--lowercase\fP Convert filenames stored in the installer to lower-case before extracting. .TP +\fB-d\fP, \fB--output-dir\fP=DIR +Extract all files into the given directory. By default, \fBinnoextract\fP will extract all files to the current directory. + +If the specified directory does not exist, it will be created. However, the parent directory must exist or extracting will fail. +.TP \fB-p\fP, \fB--progress\fP[=ENABLE] By default \fBinnoextract\fP will try to detect if the terminal supports shell escape codes and enable or disable progress bar output accordingly. Pass \fB1\fP or \fBtrue\fP to \fB--progress\fP to force progress bar output. Pass \fB0\fP or \fBfalse\fP to never show a progress bar. .TP @@ -123,7 +129,7 @@ Success .IP \fB1\fP Syntax or usage error .IP \fB2+\fP -Broken or unsupported setup file +Broken or unsupported setup file, or input/output error .SH LIMITATIONS \fBinnoextract\fP currently only supports extracting all the data. There is no support for extracting individual files or components and limited support for extracting language-specific files. diff --git a/src/cli/main.cpp b/src/cli/main.cpp index 43470ad..40434b3 100644 --- a/src/cli/main.cpp +++ b/src/cli/main.cpp @@ -117,6 +117,8 @@ struct options { setup::filename_map filenames; + fs::path output_dir; + }; @@ -375,7 +377,7 @@ static void process_file(const fs::path & file, const options & o) { if(!o.test) { output.reserve(output_names.size()); BOOST_FOREACH(const file_t & path, output_names) { - output.push_back(new file_output(path.first)); + output.push_back(new file_output(o.output_dir / path.first)); } } @@ -445,15 +447,16 @@ int main(int argc, char * argv[]) { ("list,l", "Only list files, don't write anything") ; - po::options_description filter("Filters"); + po::options_description filter("Modifiers"); filter.add_options() ("dump", "Dump contents without converting filenames") ("lowercase,L", "Convert extracted filenames to lower-case") ("language", po::value(), "Extract files for the given language") ("timestamps,T", po::value(), "Timezone for file times or \"local\" or \"none\"") + ("output-dir,d", po::value(), "Extract files into the given directory") ; - po::options_description io("I/O options"); + po::options_description io("Display options"); io.add_options() ("quiet,q", "Output less information") ("silent,s", "Output only error/warning information") @@ -590,6 +593,21 @@ int main(int argc, char * argv[]) { return ExitSuccess; } + { + po::variables_map::const_iterator i = options.find("output-dir"); + if(i != options.end()) { + o.output_dir = i->second.as(); + if(!fs::exists(o.output_dir)) { + try { + fs::create_directory(o.output_dir); + } catch(...) { + log_error << "could not create output directory " << o.output_dir; + return ExitDataError; + } + } + } + } + const std::vector & files = options["setup-files"] .as< std::vector >();