Expand ${HOME} to user's home directory in several options

The following options implement this substitution:

* --ca-certificate
* --certificate
* --dht-file-path
* --dht-file-path6
* --dir
* --input-file
* --load-cookies
* --log
* --metalink-file
* --netrc-path
* --on-bt-download-complete
* --on-download-complete
* --on-download-error
* --on-download-start
* --on-download-stop
* --on-download_pause
* --out
* --private-key
* --rpc-certificate
* --rpc-private-key
* --save-cookies
* --save-session
* --server-stat-if
* --server-stat-of
* --torrent-file
pull/782/head
Tatsuhiro Tsujikawa 2016-11-23 22:30:39 +09:00
parent 9d58ad912a
commit 9214e72501
3 changed files with 90 additions and 64 deletions

View File

@ -200,9 +200,10 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op( OptionHandler* op(new LocalFilePathOptionHandler(
new DefaultOptionHandler(PREF_DIR, TEXT_DIR, File::getCurrentDir(), PREF_DIR, TEXT_DIR, File::getCurrentDir(), /* acceptStdin = */ false,
PATH_TO_DIR, OptionHandler::REQ_ARG, 'd')); 'd',
/* mustExist = */ false, PATH_TO_DIR));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_FILE); op->addTag(TAG_FILE);
op->setInitialOption(true); op->setInitialOption(true);
@ -390,9 +391,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_INPUT_FILE, TEXT_INPUT_FILE, NO_DEFAULT_VALUE, PATH_TO_FILE_STDIN, PREF_INPUT_FILE, TEXT_INPUT_FILE, NO_DEFAULT_VALUE,
OptionHandler::REQ_ARG, 'i')); /* acceptStdin = */ true, 'i', /* mustExist = */ false));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
handlers.push_back(op); handlers.push_back(op);
} }
@ -413,9 +414,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_LOG, TEXT_LOG, NO_DEFAULT_VALUE, PATH_TO_FILE_STDOUT, PREF_LOG, TEXT_LOG, NO_DEFAULT_VALUE, /* acceptStdin = */ false, 'l',
OptionHandler::REQ_ARG, 'l')); /* mustExist = */ false, PATH_TO_FILE_STDOUT));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->setChangeGlobalOption(true); op->setChangeGlobalOption(true);
handlers.push_back(op); handlers.push_back(op);
@ -542,41 +543,46 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_ON_DOWNLOAD_COMPLETE, TEXT_ON_DOWNLOAD_COMPLETE, NO_DEFAULT_VALUE, PREF_ON_DOWNLOAD_COMPLETE, TEXT_ON_DOWNLOAD_COMPLETE, NO_DEFAULT_VALUE,
/* acceptStdin = */ false, 0, /* mustExist = */ false,
PATH_TO_COMMAND)); PATH_TO_COMMAND));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
op->addTag(TAG_HOOK); op->addTag(TAG_HOOK);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op( OptionHandler* op(new LocalFilePathOptionHandler(
new DefaultOptionHandler(PREF_ON_DOWNLOAD_ERROR, TEXT_ON_DOWNLOAD_ERROR, PREF_ON_DOWNLOAD_ERROR, TEXT_ON_DOWNLOAD_ERROR, NO_DEFAULT_VALUE,
NO_DEFAULT_VALUE, PATH_TO_COMMAND)); /* acceptStdin = */ false, 0, /* mustExist = */ false,
PATH_TO_COMMAND));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
op->addTag(TAG_HOOK); op->addTag(TAG_HOOK);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op( OptionHandler* op(new LocalFilePathOptionHandler(
new DefaultOptionHandler(PREF_ON_DOWNLOAD_PAUSE, TEXT_ON_DOWNLOAD_PAUSE, PREF_ON_DOWNLOAD_PAUSE, TEXT_ON_DOWNLOAD_PAUSE, NO_DEFAULT_VALUE,
NO_DEFAULT_VALUE, PATH_TO_COMMAND)); /* acceptStdin = */ false, 0, /* mustExist = */ false,
PATH_TO_COMMAND));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
op->addTag(TAG_HOOK); op->addTag(TAG_HOOK);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op( OptionHandler* op(new LocalFilePathOptionHandler(
new DefaultOptionHandler(PREF_ON_DOWNLOAD_START, TEXT_ON_DOWNLOAD_START, PREF_ON_DOWNLOAD_START, TEXT_ON_DOWNLOAD_START, NO_DEFAULT_VALUE,
NO_DEFAULT_VALUE, PATH_TO_COMMAND)); /* acceptStdin = */ false, 0, /* mustExist = */ false,
PATH_TO_COMMAND));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
op->addTag(TAG_HOOK); op->addTag(TAG_HOOK);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op( OptionHandler* op(new LocalFilePathOptionHandler(
new DefaultOptionHandler(PREF_ON_DOWNLOAD_STOP, TEXT_ON_DOWNLOAD_STOP, PREF_ON_DOWNLOAD_STOP, TEXT_ON_DOWNLOAD_STOP, NO_DEFAULT_VALUE,
NO_DEFAULT_VALUE, PATH_TO_COMMAND)); /* acceptStdin = */ false, 0, /* mustExist = */ false,
PATH_TO_COMMAND));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
op->addTag(TAG_HOOK); op->addTag(TAG_HOOK);
handlers.push_back(op); handlers.push_back(op);
@ -645,8 +651,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_SAVE_SESSION, TEXT_SAVE_SESSION, NO_DEFAULT_VALUE, PATH_TO_FILE)); PREF_SAVE_SESSION, TEXT_SAVE_SESSION, NO_DEFAULT_VALUE,
/* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
op->setChangeGlobalOption(true); op->setChangeGlobalOption(true);
handlers.push_back(op); handlers.push_back(op);
@ -741,8 +748,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
{ {
OptionHandler* op( OptionHandler* op(
#ifdef HAVE_APPLETLS #ifdef HAVE_APPLETLS
new DefaultOptionHandler(PREF_RPC_CERTIFICATE, TEXT_RPC_CERTIFICATE, new LocalFilePathOptionHandler(
NO_DEFAULT_VALUE) PREF_RPC_CERTIFICATE, TEXT_RPC_CERTIFICATE, NO_DEFAULT_VALUE,
/* acceptStdin = */ false, 0, /* mustExist = */ false)
#else // HAVE_APPLETLS #else // HAVE_APPLETLS
new LocalFilePathOptionHandler( new LocalFilePathOptionHandler(
PREF_RPC_CERTIFICATE, TEXT_RPC_CERTIFICATE, NO_DEFAULT_VALUE, false) PREF_RPC_CERTIFICATE, TEXT_RPC_CERTIFICATE, NO_DEFAULT_VALUE, false)
@ -884,9 +892,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler(PREF_OUT, TEXT_OUT, OptionHandler* op(new LocalFilePathOptionHandler(
NO_DEFAULT_VALUE, PATH_TO_FILE, PREF_OUT, TEXT_OUT, NO_DEFAULT_VALUE,
OptionHandler::REQ_ARG, 'o')); /* acceptStdin = */ false, 'o', /* mustExist = */ false));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
@ -937,17 +945,17 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler(PREF_SERVER_STAT_IF, OptionHandler* op(new LocalFilePathOptionHandler(
TEXT_SERVER_STAT_IF, PREF_SERVER_STAT_IF, TEXT_SERVER_STAT_IF, NO_DEFAULT_VALUE,
NO_DEFAULT_VALUE, PATH_TO_FILE)); /* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler(PREF_SERVER_STAT_OF, OptionHandler* op(new LocalFilePathOptionHandler(
TEXT_SERVER_STAT_OF, PREF_SERVER_STAT_OF, TEXT_SERVER_STAT_OF, NO_DEFAULT_VALUE,
NO_DEFAULT_VALUE, PATH_TO_FILE)); /* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
op->setChangeGlobalOption(true); op->setChangeGlobalOption(true);
@ -1012,14 +1020,14 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
} }
// HTTP Specific Options // HTTP Specific Options
{ {
OptionHandler* op(new DefaultOptionHandler(PREF_CA_CERTIFICATE, OptionHandler* op(new LocalFilePathOptionHandler(
TEXT_CA_CERTIFICATE, PREF_CA_CERTIFICATE, TEXT_CA_CERTIFICATE,
#ifdef CA_BUNDLE #ifdef CA_BUNDLE
CA_BUNDLE, CA_BUNDLE,
#else #else
"", "",
#endif #endif
PATH_TO_FILE)); /* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
op->addTag(TAG_HTTPS); op->addTag(TAG_HTTPS);
handlers.push_back(op); handlers.push_back(op);
@ -1128,8 +1136,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_LOAD_COOKIES, TEXT_LOAD_COOKIES, NO_DEFAULT_VALUE, PATH_TO_FILE)); PREF_LOAD_COOKIES, TEXT_LOAD_COOKIES, NO_DEFAULT_VALUE,
/* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
op->addTag(TAG_COOKIE); op->addTag(TAG_COOKIE);
@ -1151,8 +1160,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_PRIVATE_KEY, TEXT_PRIVATE_KEY, NO_DEFAULT_VALUE, PATH_TO_FILE)); PREF_PRIVATE_KEY, TEXT_PRIVATE_KEY, NO_DEFAULT_VALUE,
/* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
op->addTag(TAG_HTTPS); op->addTag(TAG_HTTPS);
handlers.push_back(op); handlers.push_back(op);
@ -1166,8 +1176,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_SAVE_COOKIES, TEXT_SAVE_COOKIES, NO_DEFAULT_VALUE, PATH_TO_FILE)); PREF_SAVE_COOKIES, TEXT_SAVE_COOKIES, NO_DEFAULT_VALUE,
/* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
op->addTag(TAG_COOKIE); op->addTag(TAG_COOKIE);
op->setChangeGlobalOption(true); op->setChangeGlobalOption(true);
@ -1252,9 +1263,9 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler(PREF_NETRC_PATH, TEXT_NETRC_PATH, OptionHandler* op(new LocalFilePathOptionHandler(
util::getHomeDir() + "/.netrc", PREF_NETRC_PATH, TEXT_NETRC_PATH, util::getHomeDir() + "/.netrc",
PATH_TO_FILE)); /* acceptStdin = */ false, 0, /* mustExist = */ false));
handlers.push_back(op); handlers.push_back(op);
} }
// Proxy options // Proxy options
@ -1682,16 +1693,16 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op( OptionHandler* op(new LocalFilePathOptionHandler(
new DefaultOptionHandler(PREF_DHT_FILE_PATH, TEXT_DHT_FILE_PATH, PREF_DHT_FILE_PATH, TEXT_DHT_FILE_PATH, util::getDHTFile(false),
util::getDHTFile(false), PATH_TO_FILE)); /* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op( OptionHandler* op(new LocalFilePathOptionHandler(
new DefaultOptionHandler(PREF_DHT_FILE_PATH6, TEXT_DHT_FILE_PATH6, PREF_DHT_FILE_PATH6, TEXT_DHT_FILE_PATH6, util::getDHTFile(true),
util::getDHTFile(true), PATH_TO_FILE)); /* acceptStdin = */ false, 0, /* mustExist = */ false));
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
} }
@ -1795,9 +1806,11 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
OptionHandler* op(new DefaultOptionHandler( OptionHandler* op(new LocalFilePathOptionHandler(
PREF_ON_BT_DOWNLOAD_COMPLETE, TEXT_ON_BT_DOWNLOAD_COMPLETE, PREF_ON_BT_DOWNLOAD_COMPLETE, TEXT_ON_BT_DOWNLOAD_COMPLETE,
NO_DEFAULT_VALUE, PATH_TO_COMMAND)); NO_DEFAULT_VALUE,
/* acceptStdin = */ false, 0, /* mustExist = */ false,
PATH_TO_COMMAND));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
op->addTag(TAG_HOOK); op->addTag(TAG_HOOK);
handlers.push_back(op); handlers.push_back(op);

View File

@ -531,10 +531,13 @@ std::string HttpProxyOptionHandler::createPossibleValuesString() const
LocalFilePathOptionHandler::LocalFilePathOptionHandler( LocalFilePathOptionHandler::LocalFilePathOptionHandler(
PrefPtr pref, const char* description, const std::string& defaultValue, PrefPtr pref, const char* description, const std::string& defaultValue,
bool acceptStdin, char shortName) bool acceptStdin, char shortName, bool mustExist,
const std::string& possibleValuesString)
: AbstractOptionHandler(pref, description, defaultValue, : AbstractOptionHandler(pref, description, defaultValue,
OptionHandler::REQ_ARG, shortName), OptionHandler::REQ_ARG, shortName),
acceptStdin_(acceptStdin) possibleValuesString_(possibleValuesString),
acceptStdin_(acceptStdin),
mustExist_(mustExist)
{ {
} }
@ -545,16 +548,22 @@ void LocalFilePathOptionHandler::parseArg(Option& option,
option.put(pref_, DEV_STDIN); option.put(pref_, DEV_STDIN);
} }
else { else {
File f(optarg); auto path = util::replace(optarg, "${HOME}", util::getHomeDir());
if (!f.exists() || f.isDir()) { if (mustExist_) {
throw DL_ABORT_EX(fmt(MSG_NOT_FILE, optarg.c_str())); File f(path);
if (!f.exists() || f.isDir()) {
throw DL_ABORT_EX(fmt(MSG_NOT_FILE, optarg.c_str()));
}
} }
option.put(pref_, optarg); option.put(pref_, path);
} }
} }
std::string LocalFilePathOptionHandler::createPossibleValuesString() const std::string LocalFilePathOptionHandler::createPossibleValuesString() const
{ {
if (!possibleValuesString_.empty()) {
return possibleValuesString_;
}
if (acceptStdin_) { if (acceptStdin_) {
return PATH_TO_FILE_STDIN; return PATH_TO_FILE_STDIN;
} }

View File

@ -232,13 +232,17 @@ public:
class LocalFilePathOptionHandler : public AbstractOptionHandler { class LocalFilePathOptionHandler : public AbstractOptionHandler {
private: private:
std::string possibleValuesString_;
bool acceptStdin_; bool acceptStdin_;
bool mustExist_;
public: public:
LocalFilePathOptionHandler(PrefPtr pref, LocalFilePathOptionHandler(PrefPtr pref,
const char* description = NO_DESCRIPTION, const char* description = NO_DESCRIPTION,
const std::string& defaultValue = NO_DEFAULT_VALUE, const std::string& defaultValue = NO_DEFAULT_VALUE,
bool acceptStdin = false, char shortName = 0); bool acceptStdin = false, char shortName = 0,
bool mustExist = true,
const std::string& possibleValuesString = "");
virtual void parseArg(Option& option, virtual void parseArg(Option& option,
const std::string& optarg) const CXX11_OVERRIDE; const std::string& optarg) const CXX11_OVERRIDE;
virtual std::string createPossibleValuesString() const CXX11_OVERRIDE; virtual std::string createPossibleValuesString() const CXX11_OVERRIDE;