2015-09-29 14:29:10 +02:00
# include "Parser.h"
# include "utils.h"
# include <iostream>
2015-10-17 18:31:17 +02:00
# include <boost/optional.hpp>
2015-09-29 14:29:10 +02:00
namespace po = boost : : program_options ;
using namespace cryfs : : program_options ;
using std : : pair ;
using std : : vector ;
using std : : cerr ;
2015-10-16 04:06:00 +02:00
using std : : endl ;
2015-09-29 14:29:10 +02:00
using std : : string ;
2015-10-17 18:31:17 +02:00
using boost : : optional ;
using boost : : none ;
2015-09-29 14:29:10 +02:00
2015-10-30 19:53:15 +01:00
Parser : : Parser ( int argc , char * argv [ ] )
: _options ( _argsToVector ( argc , argv ) ) {
}
2015-09-29 14:29:10 +02:00
vector < char * > Parser : : _argsToVector ( int argc , char * argv [ ] ) {
vector < char * > result ;
for ( int i = 0 ; i < argc ; + + i ) {
result . push_back ( argv [ i ] ) ;
}
return result ;
}
2015-10-30 19:53:15 +01:00
ProgramOptions Parser : : parse ( const vector < string > & supportedCiphers ) const {
2015-09-29 14:29:10 +02:00
pair < vector < char * > , vector < char * > > options = splitAtDoubleDash ( _options ) ;
2015-10-30 19:53:15 +01:00
po : : variables_map vm = _parseOptionsOrShowHelp ( options . first , supportedCiphers ) ;
2015-09-29 14:29:10 +02:00
string baseDir = vm [ " base-dir " ] . as < string > ( ) ;
string mountDir = vm [ " mount-dir " ] . as < string > ( ) ;
2015-10-24 19:56:05 +02:00
optional < string > configfile = none ;
if ( vm . count ( " config " ) ) {
configfile = vm [ " config " ] . as < string > ( ) ;
}
2015-10-15 03:38:44 +02:00
bool foreground = vm . count ( " foreground " ) ;
2015-10-30 21:40:38 +01:00
if ( foreground ) {
options . second . push_back ( const_cast < char * > ( " -f " ) ) ;
}
2015-11-13 00:06:53 +01:00
optional < double > unmountAfterIdleMinutes = none ;
2015-11-12 20:43:11 +01:00
if ( vm . count ( " unmount-idle " ) ) {
2015-11-13 00:06:53 +01:00
unmountAfterIdleMinutes = vm [ " unmount-idle " ] . as < double > ( ) ;
2015-11-12 20:43:11 +01:00
}
2015-10-17 18:31:17 +02:00
optional < string > logfile = none ;
if ( vm . count ( " logfile " ) ) {
logfile = vm [ " logfile " ] . as < string > ( ) ;
}
2015-10-30 19:53:15 +01:00
optional < string > cipher = none ;
if ( vm . count ( " cipher " ) ) {
cipher = vm [ " cipher " ] . as < string > ( ) ;
_checkValidCipher ( * cipher , supportedCiphers ) ;
}
2015-11-03 21:22:35 +01:00
optional < string > extPass = none ;
if ( vm . count ( " extpass " ) ) {
extPass = vm [ " extpass " ] . as < string > ( ) ;
}
2015-09-29 14:29:10 +02:00
2015-11-12 20:43:11 +01:00
return ProgramOptions ( baseDir , mountDir , configfile , foreground , unmountAfterIdleMinutes , logfile , cipher , extPass , options . second ) ;
2015-10-30 19:53:15 +01:00
}
void Parser : : _checkValidCipher ( const string & cipher , const vector < string > & supportedCiphers ) {
if ( std : : find ( supportedCiphers . begin ( ) , supportedCiphers . end ( ) , cipher ) = = supportedCiphers . end ( ) ) {
std : : cerr < < " Invalid cipher: " < < cipher < < std : : endl ;
exit ( 1 ) ;
}
2015-09-29 14:29:10 +02:00
}
2015-10-30 19:53:15 +01:00
po : : variables_map Parser : : _parseOptionsOrShowHelp ( const vector < char * > options , const vector < string > & supportedCiphers ) {
2015-09-29 14:29:10 +02:00
try {
2015-10-30 19:53:15 +01:00
return _parseOptions ( options , supportedCiphers ) ;
2015-09-29 14:29:10 +02:00
} catch ( const std : : exception & e ) {
2015-11-03 22:01:51 +01:00
std : : cerr < < e . what ( ) < < std : : endl ;
2015-09-29 14:29:10 +02:00
_showHelpAndExit ( ) ;
}
}
2015-10-30 19:53:15 +01:00
po : : variables_map Parser : : _parseOptions ( const vector < char * > options , const vector < string > & supportedCiphers ) {
2015-09-29 14:29:10 +02:00
po : : options_description desc ;
po : : positional_options_description positional_desc ;
_addAllowedOptions ( & desc ) ;
_addPositionalOptionForBaseDir ( & desc , & positional_desc ) ;
po : : variables_map vm ;
po : : store ( po : : command_line_parser ( options . size ( ) , options . data ( ) )
. options ( desc ) . positional ( positional_desc ) . run ( ) , vm ) ;
if ( vm . count ( " help " ) ) {
_showHelpAndExit ( ) ;
}
2015-10-30 19:53:15 +01:00
if ( vm . count ( " show-ciphers " ) ) {
_showCiphersAndExit ( supportedCiphers ) ;
}
2015-09-29 14:29:10 +02:00
po : : notify ( vm ) ;
return vm ;
}
void Parser : : _addAllowedOptions ( po : : options_description * desc ) {
po : : options_description options ( " Allowed options " ) ;
options . add_options ( )
( " help,h " , " show help message " )
2015-10-24 19:56:05 +02:00
( " config,c " , po : : value < string > ( ) , " Configuration file " )
2015-10-15 03:38:44 +02:00
( " foreground,f " , " Run CryFS in foreground. " )
2015-10-30 19:53:15 +01:00
( " cipher " , po : : value < string > ( ) , " Cipher to use for encryption. See possible values by calling cryfs with --show-ciphers " )
( " show-ciphers " , " Show list of supported ciphers. " )
2015-11-13 00:06:53 +01:00
( " unmount-idle " , po : : value < double > ( ) , " Automatically unmount after specified number of idle minutes. " )
2015-11-03 21:22:35 +01:00
( " extpass " , po : : value < string > ( ) , " External program to use for password input " )
2015-10-17 18:31:17 +02:00
( " logfile " , po : : value < string > ( ) , " Specify the file to write log messages to. If this is not specified, log messages will go to stdout, or syslog if CryFS is running in the background. " )
2015-09-29 14:29:10 +02:00
;
desc - > add ( options ) ;
}
void Parser : : _addPositionalOptionForBaseDir ( po : : options_description * desc , po : : positional_options_description * positional ) {
positional - > add ( " base-dir " , 1 ) ;
positional - > add ( " mount-dir " , 1 ) ;
po : : options_description hidden ( " Hidden options " ) ;
hidden . add_options ( )
( " base-dir " , po : : value < string > ( ) - > required ( ) , " Base directory " )
( " mount-dir " , po : : value < string > ( ) - > required ( ) , " Mount directory " )
;
desc - > add ( hidden ) ;
}
2015-10-30 19:53:15 +01:00
[[noreturn]] void Parser : : _showCiphersAndExit ( const vector < string > & supportedCiphers ) {
for ( const auto & cipher : supportedCiphers ) {
std : : cerr < < cipher < < " \n " ;
}
exit ( 0 ) ;
}
2015-09-29 14:29:10 +02:00
[[noreturn]] void Parser : : _showHelpAndExit ( ) {
2015-10-24 20:00:54 +02:00
cerr < < " Usage: cryfs [options] rootDir mountPoint [-- [FUSE Mount Options]] \n " ;
2015-09-29 14:29:10 +02:00
po : : options_description desc ;
_addAllowedOptions ( & desc ) ;
2015-10-16 04:06:00 +02:00
cerr < < desc < < endl ;
2015-09-29 14:29:10 +02:00
exit ( 1 ) ;
}