/* */ #include "common.h" #include #include #include #include #include #include "Option.h" #include "prefs.h" #include "OptionParser.h" #include "OptionHandlerFactory.h" #include "OptionHandler.h" #include "util.h" #include "message.h" #include "Exception.h" #include "a2io.h" #include "help_tags.h" #include "File.h" #include "StringFormat.h" #include "OptionHandlerException.h" #include "DownloadResultCode.h" #include "SimpleRandomizer.h" #include "bittorrent_helper.h" #ifndef HAVE_DAEMON #include "daemon.h" #endif // !HAVE_DAEMON namespace aria2 { extern void showVersion(); extern void showUsage(const std::string& keyword, const OptionParser& oparser); static void overrideWithEnv(Option& op, const OptionParser& optionParser, const std::string& pref, const std::string& envName) { char* value = getenv(envName.c_str()); if(value) { try { optionParser.findByName(pref)->parse(op, value); } catch(Exception& e) { std::cerr << "Caught Error while parsing environment variable" << " '" << envName << "'" << "\n" << e.stackTrace(); } } } void option_processing(Option& op, std::vector& uris, int argc, char* const argv[]) { OptionParser oparser; oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers()); try { bool noConf = false; std::string ucfname; std::stringstream cmdstream; oparser.parseArg(cmdstream, uris, argc, argv); { // first evaluate --no-conf and --conf-path options. Option op; oparser.parse(op, cmdstream); noConf = op.getAsBool(PREF_NO_CONF); ucfname = op.get(PREF_CONF_PATH); if(op.defined("version")) { showVersion(); exit(downloadresultcode::FINISHED); } if(op.defined("help")) { std::string keyword; if(op.get("help").empty()) { keyword = TAG_BASIC; } else { keyword = op.get("help"); if(util::startsWith(keyword, "--")) { keyword = keyword.substr(2); } std::string::size_type eqpos = keyword.find("="); if(eqpos != std::string::npos) { keyword = keyword.substr(0, eqpos); } } showUsage(keyword, oparser); exit(downloadresultcode::FINISHED); } } oparser.parseDefaultValues(op); if(!noConf) { std::string cfname = ucfname.empty() ? oparser.findByName(PREF_CONF_PATH)->getDefaultValue(): ucfname; if(File(cfname).isFile()) { std::ifstream cfstream(cfname.c_str(), std::ios::binary); try { oparser.parse(op, cfstream); } catch(OptionHandlerException& e) { std::cerr << "Parse error in " << cfname << "\n" << e.stackTrace() << std::endl; SharedHandle h = oparser.findByName(e.getOptionName()); if(!h.isNull()) { std::cerr << "Usage:" << "\n" << oparser.findByName(e.getOptionName())->getDescription() << std::endl; } exit(downloadresultcode::UNKNOWN_ERROR); } catch(Exception& e) { std::cerr << "Parse error in " << cfname << "\n" << e.stackTrace() << std::endl; exit(downloadresultcode::UNKNOWN_ERROR); } } else if(!ucfname.empty()) { std::cerr << StringFormat("Configuration file %s is not found.", cfname.c_str()) << "\n"; showUsage(TAG_HELP, oparser); exit(downloadresultcode::UNKNOWN_ERROR); } } // Override configuration with environment variables. overrideWithEnv(op, oparser, PREF_HTTP_PROXY, "http_proxy"); overrideWithEnv(op, oparser, PREF_HTTPS_PROXY, "https_proxy"); overrideWithEnv(op, oparser, PREF_FTP_PROXY, "ftp_proxy"); overrideWithEnv(op, oparser, PREF_ALL_PROXY, "all_proxy"); overrideWithEnv(op, oparser, PREF_NO_PROXY, "no_proxy"); // we must clear eof bit and seek to the beginning of the buffer. cmdstream.clear(); cmdstream.seekg(0, std::ios::beg); // finaly let's parse and store command-iine options. oparser.parse(op, cmdstream); } catch(OptionHandlerException& e) { std::cerr << e.stackTrace() << "\n" << "Usage:" << "\n" << oparser.findByName(e.getOptionName()) << std::endl; exit(downloadresultcode::UNKNOWN_ERROR); } catch(Exception& e) { std::cerr << e.stackTrace() << std::endl; showUsage(TAG_HELP, oparser); exit(downloadresultcode::UNKNOWN_ERROR); } if( #ifdef ENABLE_XML_RPC !op.getAsBool(PREF_ENABLE_XML_RPC) && #endif // ENABLE_XML_RPC #ifdef ENABLE_BITTORRENT op.blank(PREF_TORRENT_FILE) && #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK op.blank(PREF_METALINK_FILE) && #endif // ENABLE_METALINK op.blank(PREF_INPUT_FILE)) { if(uris.empty()) { std::cerr << MSG_URI_REQUIRED << std::endl; showUsage(TAG_HELP, oparser); exit(downloadresultcode::UNKNOWN_ERROR); } } if(op.getAsBool(PREF_DAEMON)) { if(daemon(0, 0) < 0) { perror(MSG_DAEMON_FAILED); exit(downloadresultcode::UNKNOWN_ERROR); } } } } // namespace aria2