void ClientManager::privateMessage(const User::Ptr& p, const string& msg) { Lock l(cs); OnlineIter i = onlineUsers.find(p->getCID()); if(i != onlineUsers.end()) { OnlineUser* u = i->second; u->getClient().privateMessage(*u, msg); } }
void ClientManager::connect(const User::Ptr& p) { Lock l(cs); OnlineIter i = onlineUsers.find(p->getCID()); if(i != onlineUsers.end()) { OnlineUser* u = i->second; u->getClient().connect(*u); } }
bool ClientManager::isOp(const User::Ptr& user, const string& aHubUrl) const { Lock l(cs); OnlinePairC p = onlineUsers.equal_range(user->getCID()); for(OnlineIterC i = p.first; i != p.second; ++i) { if(i->second->getClient().getHubUrl() == aHubUrl) { return i->second->getIdentity().isOp(); } } return false; }
void ClientManager::userCommand(const User::Ptr& p, const ::UserCommand& uc, StringMap& params, bool compatibility) { Lock l(cs); OnlineIter i = onlineUsers.find(p->getCID()); if(i == onlineUsers.end()) return; OnlineUser& ou = *i->second; ou.getIdentity().getParams(params, "user", compatibility); ou.getClient().getHubIdentity().getParams(params, "hub", false); ou.getClient().getMyIdentity().getParams(params, "my", compatibility); ou.getClient().escapeParams(params); ou.getClient().sendUserCmd(Util::formatParams(uc.getCommand(), params, false)); }
void SearchManager::onRES(const AdcCommand& cmd, const User::Ptr& from, const string& remoteIp) { int freeSlots = -1; int64_t size = -1; string file; string tth; string token; for(StringIterC i = cmd.getParameters().begin(); i != cmd.getParameters().end(); ++i) { const string& str = *i; if(str.compare(0, 2, "FN") == 0) { file = Util::toNmdcFile(str.substr(2)); } else if(str.compare(0, 2, "SL") == 0) { freeSlots = Util::toInt(str.substr(2)); } else if(str.compare(0, 2, "SI") == 0) { size = Util::toInt64(str.substr(2)); } else if(str.compare(0, 2, "TR") == 0) { tth = str.substr(2); } else if(str.compare(0, 2, "TO") == 0) { token = str.substr(2); } } if(!file.empty() && freeSlots != -1 && size != -1) { StringList names = ClientManager::getInstance()->getHubNames(from->getCID()); string hubName = names.empty() ? STRING(OFFLINE) : Util::toString(names); StringList hubs = ClientManager::getInstance()->getHubs(from->getCID()); string hub = hubs.empty() ? STRING(OFFLINE) : Util::toString(hubs); SearchResult::Types type = (file[file.length() - 1] == '\\' ? SearchResult::TYPE_DIRECTORY : SearchResult::TYPE_FILE); if(type == SearchResult::TYPE_FILE && tth.empty()) return; /// @todo Something about the slots SearchResult* sr = new SearchResult(from, type, 0, freeSlots, size, file, hubName, hub, remoteIp, TTHValue(tth), token); fire(SearchManagerListener::SR(), sr); sr->decRef(); } }
void SearchManager::onData(const uint8_t* buf, size_t aLen, const string& remoteIp) { string x((char*)buf, aLen); if(x.compare(0, 4, "$SR ") == 0) { string::size_type i, j; // Directories: $SR <nick><0x20><directory><0x20><free slots>/<total slots><0x05><Hubname><0x20>(<Hubip:port>) // Files: $SR <nick><0x20><filename><0x05><filesize><0x20><free slots>/<total slots><0x05><Hubname><0x20>(<Hubip:port>) i = 4; if( (j = x.find(' ', i)) == string::npos) { return; } string nick = x.substr(i, j-i); i = j + 1; // A file has 2 0x05, a directory only one size_t cnt = count(x.begin() + j, x.end(), 0x05); SearchResult::Types type = SearchResult::TYPE_FILE; string file; int64_t size = 0; if(cnt == 1) { // We have a directory...find the first space beyond the first 0x05 from the back // (dirs might contain spaces as well...clever protocol, eh?) type = SearchResult::TYPE_DIRECTORY; // Get past the hubname that might contain spaces if((j = x.rfind(0x05)) == string::npos) { return; } // Find the end of the directory info if((j = x.rfind(' ', j-1)) == string::npos) { return; } if(j < i + 1) { return; } file = x.substr(i, j-i) + '\\'; } else if(cnt == 2) { if( (j = x.find((char)5, i)) == string::npos) { return; } file = x.substr(i, j-i); i = j + 1; if( (j = x.find(' ', i)) == string::npos) { return; } size = Util::toInt64(x.substr(i, j-i)); } i = j + 1; if( (j = x.find('/', i)) == string::npos) { return; } int freeSlots = Util::toInt(x.substr(i, j-i)); i = j + 1; if( (j = x.find((char)5, i)) == string::npos) { return; } int slots = Util::toInt(x.substr(i, j-i)); i = j + 1; if( (j = x.rfind(" (")) == string::npos) { return; } string hubName = x.substr(i, j-i); i = j + 2; if( (j = x.rfind(')')) == string::npos) { return; } string hubIpPort = x.substr(i, j-i); string url = ClientManager::getInstance()->findHub(hubIpPort); string encoding = ClientManager::getInstance()->findHubEncoding(url); nick = Text::toUtf8(nick, encoding); file = Text::toUtf8(file, encoding); hubName = Text::toUtf8(hubName, encoding); User::Ptr user = ClientManager::getInstance()->findUser(nick, url); if(!user) { // Could happen if hub has multiple URLs / IPs user = ClientManager::getInstance()->findLegacyUser(nick); if(!user) return; } string tth; if(hubName.compare(0, 4, "TTH:") == 0) { tth = hubName.substr(4); StringList names = ClientManager::getInstance()->getHubNames(user->getCID()); hubName = names.empty() ? STRING(OFFLINE) : Util::toString(names); } if(tth.empty() && type == SearchResult::TYPE_FILE) { return; } SearchResult* sr = new SearchResult(user, type, slots, freeSlots, size, file, hubName, url, remoteIp, TTHValue(tth), Util::emptyString); fire(SearchManagerListener::SR(), sr); sr->decRef(); } else if(x.compare(1, 4, "RES ") == 0 && x[x.length() - 1] == 0x0a) { AdcCommand c(x.substr(0, x.length()-1)); if(c.getParameters().empty()) return; string cid = c.getParam(0); if(cid.size() != 39) return; User::Ptr user = ClientManager::getInstance()->findUser(CID(cid)); if(!user) return; // This should be handled by AdcCommand really... c.getParameters().erase(c.getParameters().begin()); onRES(c, user, remoteIp); } /*else if(x.compare(1, 4, "SCH ") == 0 && x[x.length() - 1] == 0x0a) { try { respond(AdcCommand(x.substr(0, x.length()-1))); } catch(ParseException& ) { } }*/ // Needs further DoS investigation }