/* */ #include "Netrc.h" #include #include #include "DlAbortEx.h" #include "StringFormat.h" #include "A2STR.h" #include "util.h" namespace aria2 { const std::string Netrc::A2_MACHINE("machine"); const std::string Netrc::A2_DEFAULT("default"); const std::string Netrc::A2_LOGIN("login"); const std::string Netrc::A2_PASSWORD("password"); const std::string Netrc::A2_ACCOUNT("account"); const std::string Netrc::A2_MACDEF("macdef"); void Netrc::skipMacdef(std::ifstream& f) const { std::string line; while(getline(f, line)) { if(line == A2STR::CR_C || line.empty()) { break; } } } void Netrc::parse(const std::string& path) { authenticators_.clear(); std::ifstream f(path.c_str(), std::ios::binary); if(!f) { throw DL_ABORT_EX (StringFormat("File not found: %s", path.c_str()).str()); } enum STATE { GET_TOKEN, SET_MACHINE, SET_LOGIN, SET_PASSWORD, SET_ACCOUNT, SET_MACDEF }; SharedHandle authenticator; std::string line; STATE state = GET_TOKEN; while(getline(f, line)) { if(util::startsWith(line, "#")) { continue; } std::vector tokens; util::split(line, std::back_inserter(tokens), " \t", true); for(std::vector::const_iterator iter = tokens.begin(), eoi = tokens.end(); iter != eoi; ++iter) { const std::string& token = *iter; if(state == GET_TOKEN) { if(token == Netrc::A2_MACHINE) { storeAuthenticator(authenticator); authenticator.reset(new Authenticator()); state = SET_MACHINE; } else if(token == Netrc::A2_DEFAULT) { storeAuthenticator(authenticator); authenticator.reset(new DefaultAuthenticator()); } else { if(authenticator.isNull()) { throw DL_ABORT_EX (StringFormat("Netrc:parse error. %s encounterd where 'machine'" " or 'default' expected.", token.c_str()).str()); } if(token == Netrc::A2_LOGIN) { state = SET_LOGIN; } else if(token == Netrc::A2_PASSWORD) { state = SET_PASSWORD; } else if(token == Netrc::A2_ACCOUNT) { state = SET_ACCOUNT; } else if(token == Netrc::A2_MACDEF) { state = SET_MACDEF; } } } else { if(state == SET_MACHINE) { authenticator->setMachine(token); } else if(state == SET_LOGIN) { authenticator->setLogin(token); } else if(state == SET_PASSWORD) { authenticator->setPassword(token); } else if(state == SET_ACCOUNT) { authenticator->setAccount(token); } else if(state == SET_MACDEF) { skipMacdef(f); } state = GET_TOKEN; } } } if(state != GET_TOKEN) { throw DL_ABORT_EX ("Netrc:parse error. EOF reached where a token expected."); } storeAuthenticator(authenticator); } void Netrc::storeAuthenticator(const SharedHandle& authenticator) { if(!authenticator.isNull()) { authenticators_.push_back(authenticator); } } namespace { class AuthHostMatch { private: std::string hostname; public: AuthHostMatch(const std::string& hostname):hostname(hostname) {} bool operator()(const SharedHandle& authenticator) { return authenticator->match(hostname); } }; } // namespace SharedHandle Netrc::findAuthenticator(const std::string& hostname) const { SharedHandle res; std::vector >::const_iterator itr = std::find_if(authenticators_.begin(), authenticators_.end(), AuthHostMatch(hostname)); if(itr != authenticators_.end()) { res = *itr; } return res; } } // namespace aria2