void HttpConnection::on(BufferedSocketListener::Line, const string& aLine) throw() { if(!ok) { if(aLine.find("200") == string::npos) { if(aLine.find("301") != string::npos || aLine.find("302") != string::npos){ moved302 = true; } else { socket->disconnect(); socket->removeListener(this); BufferedSocket::putSocket(socket); socket = NULL; fire(HttpConnectionListener::Failed(), this, aLine + " (" + currentUrl + ")"); coralizeState = CST_DEFAULT; return; } } ok = true; dcdebug("%s\n",aLine.c_str()); } else if(moved302 && Util::findSubString(aLine, "Location") != string::npos){ dcassert(socket); socket->removeListener(this); socket->disconnect(); BufferedSocket::putSocket(socket); socket = NULL; string location302 = aLine.substr(10, aLine.length() - 11); // make sure we can also handle redirects with relative paths if(Util::strnicmp(location302.c_str(), "http://", 7) != 0) { if(location302[0] == '/') { Util::decodeUrl(currentUrl, server, port, file); string tmp = "http://" + server; if(port != 80) tmp += ':' + Util::toString(port); location302 = tmp + location302; } else { string::size_type i = currentUrl.rfind('/'); dcassert(i != string::npos); location302 = currentUrl.substr(0, i + 1) + location302; } } fire(HttpConnectionListener::Redirected(), this, location302); coralizeState = CST_DEFAULT; downloadFile(location302); } else if(aLine == "\x0d") { socket->setDataMode(size); } else if(Util::findSubString(aLine, "Content-Length") != string::npos) { size = Util::toInt(aLine.substr(16, aLine.length() - 17)); } else if(Util::findSubString(aLine, "Content-Encoding") != string::npos) { if(aLine.substr(18, aLine.length() - 19) == "x-bzip2") fire(HttpConnectionListener::TypeBZ2(), this); } }
void BufferedSocket::accept(const Socket& srv, bool secure, bool allowUntrusted) throw(SocketException) { dcdebug("BufferedSocket::accept() %p\n", (void*)this); std::auto_ptr<Socket> s(secure ? CryptoManager::getInstance()->getServerSocket(allowUntrusted) : new Socket); s->accept(srv); setSocket(s); Lock l(cs); addTask(ACCEPTED, 0); }
void BufferedSocket::connect(const string& aAddress, uint16_t aPort, bool secure, bool allowUntrusted, bool proxy) throw(SocketException) { dcdebug("BufferedSocket::connect() %p\n", (void*)this); std::auto_ptr<Socket> s(secure ? CryptoManager::getInstance()->getClientSocket(allowUntrusted) : new Socket); s->create(); s->bind(0, SETTING(BIND_ADDRESS)); setSocket(s); Lock l(cs); addTask(CONNECT, new ConnectInfo(aAddress, aPort, proxy && (SETTING(OUTGOING_CONNECTIONS) == SettingsManager::OUTGOING_SOCKS5))); }
void UploadManager::on(UserConnectionListener::Failed, UserConnection* aSource, const string& aError) throw() { Upload* u = aSource->getUpload(); if(u) { fire(UploadManagerListener::Failed(), u, aError); dcdebug("UM::onFailed: Removing upload\n"); removeUpload(u); } removeConnection(aSource); }
bool ZFilter::operator()(const void* in, size_t& insize, void* out, size_t& outsize) { if(outsize == 0) return false; zs.next_in = (Bytef*)in; zs.next_out = (Bytef*)out; // Check if there's any use compressing; if not, save some cpu... if(compressing && insize > 0 && outsize > 16 && (totalIn > (64*1024)) && ((static_cast<double>(totalOut) / totalIn) > 0.95)) { zs.avail_in = 0; zs.avail_out = outsize; if(deflateParams(&zs, 0, Z_DEFAULT_STRATEGY) != Z_OK) { throw Exception(_("Error during compression")); } zs.avail_in = insize; compressing = false; dcdebug("Dynamically disabled compression"); // Check if we ate all space already... if(zs.avail_out == 0) { outsize = outsize - zs.avail_out; insize = insize - zs.avail_in; totalOut += outsize; totalIn += insize; return true; } } else { zs.avail_in = insize; zs.avail_out = outsize; } if(insize == 0) { int err = ::deflate(&zs, Z_FINISH); if(err != Z_OK && err != Z_STREAM_END) throw Exception(_("Error during compression")); outsize = outsize - zs.avail_out; insize = insize - zs.avail_in; totalOut += outsize; totalIn += insize; return err == Z_OK; } else { int err = ::deflate(&zs, Z_NO_FLUSH); if(err != Z_OK) throw Exception(_("Error during compression")); outsize = outsize - zs.avail_out; insize = insize - zs.avail_in; totalOut += outsize; totalIn += insize; return true; } }
bool CAGEmotionSetup::LoadEmotion(const string& p_file_name) { const string l_fileName = Util::getDataPath() + "EmoPacks\\" + p_file_name + ".xml"; if ((p_file_name == "Disabled") || !Util::fileExists(l_fileName)) { return true; } try { SimpleXML xml; xml.fromXML(File(l_fileName, File::READ, File::OPEN).read()); if (xml.findChild("Emoticons")) { xml.stepIn(); while (xml.findChild("Emoticon")) { string strEmotionText = xml.getChildAttrib("PasteText"); if (strEmotionText.empty()) { strEmotionText = xml.getChildAttrib("Expression"); } while (strEmotionText[0] == ' ') // ltrim strEmotionText.erase(0, 1); if (!strEmotionText.empty()) { // dcdebug("CAGEmotionSetup::Create: emotion:[%s]\n", Text::fromT(strEmotionText).c_str()); if (m_FilterEmotiion.count(strEmotionText)) { // dcdebug("CAGEmotionSetup::Create: dup emotion:[%s]\n", strEmotionText.c_str()); continue; } m_FilterEmotiion.insert(strEmotionText); string strEmotionBmpPath = xml.getChildAttrib("Bitmap"); if (strEmotionBmpPath.size() > 0) { if (strEmotionBmpPath[0] == '.') { // Relativni cesta - dame od aplikace strEmotionBmpPath = Util::getDataPath() + "EmoPacks\\" + strEmotionBmpPath; } else strEmotionBmpPath = "EmoPacks\\" + strEmotionBmpPath; } CAGEmotion* pEmotion = new CAGEmotion(); //[!]PPA for lock bmp //File* l__f = new File (Util::getDataPath() + strEmotionBmpPath, File::READ, File::OPEN); if (!pEmotion->Create(Text::toT(strEmotionText), strEmotionBmpPath)) { delete pEmotion; continue; } m_CountSelEmotions++; EmotionsList.push_back(pEmotion); } } xml.stepOut(); } } catch(const Exception& e) { dcdebug("CAGEmotionSetup::Create: %s\n", e.getError().c_str()); return false; } return true; }
bool BufferedSocket::checkEvents() { while(state == RUNNING ? taskSem.wait(0) : taskSem.wait()) { pair<Tasks, std::tr1::shared_ptr<TaskData> > p; { Lock l(cs); dcassert(tasks.size() > 0); p = tasks.front(); tasks.erase(tasks.begin()); } if(p.first == SHUTDOWN) { return false; } else if(p.first == UPDATED) { fire(BufferedSocketListener::Updated()); } if(state == STARTING) { if(p.first == CONNECT) { ConnectInfo* ci = static_cast<ConnectInfo*>(p.second.get()); threadConnect(ci->addr, ci->port, ci->proxy); } else if(p.first == ACCEPTED) { state = RUNNING; } else { dcdebug("%d unexpected in STARTING state", p.first); } } else if(state == RUNNING) { if(p.first == SEND_DATA) { threadSendData(); } else if(p.first == SEND_FILE) { threadSendFile(static_cast<SendFileInfo*>(p.second.get())->stream); break; } else if(p.first == DISCONNECT) { fail(_("Disconnected")); } else { dcdebug("%d unexpected in RUNNING state", p.first); } } } return true; }
void IpManager::WatchLoad() { try { SimpleXML xml; xml.fromXML(File(Util::getPath(Util::PATH_USER_CONFIG) + "IPWatch.xml", File::READ, File::OPEN).read()); if(xml.findChild("IPWatch")) { xml.stepIn(); loadWatch(xml); xml.stepOut(); } } catch(const Exception& e) { dcdebug("IpManager::WatchLoad: %s\n", e.getError().c_str()); } }
void HttpConnection::on(BufferedSocketListener::Failed, const string& aLine) throw() { socket->removeListener(this); BufferedSocket::putSocket(socket); socket = NULL; if(BOOLSETTING(CORAL) && coralizeState == CST_DEFAULT) { coralizeState = CST_NOCORALIZE; dcdebug("Coralized address failed, retrying : %s\n",currentUrl.c_str()); downloadFile(currentUrl); return; } coralizeState = CST_DEFAULT; fire(HttpConnectionListener::Failed(), this, aLine + " (" + currentUrl + ")"); }
void SSLSocket::accept(const Socket& listeningSocket) throw(SocketException) { Socket::accept(listeningSocket); if(ssl) SSL_free(ssl); ssl = SSL_new(ctx); if(!ssl) checkSSL(-1); checkSSL(SSL_set_fd(ssl, sock)); checkSSL(SSL_accept(ssl)); dcdebug("Connected to SSL client using %s\n", SSL_get_cipher(ssl)); }
bool SSLSocket::waitWant(int ret, uint64_t millis) { int err = SSL_get_error(ssl, ret); switch(err) { case SSL_ERROR_WANT_READ: return wait(millis, true, false).first; case SSL_ERROR_WANT_WRITE: return wait(millis, true, false).second; // Check if this is a fatal error... default: checkSSL(ret); } dcdebug("SSL: Unexpected fallthrough"); // There was no error? return true; }
void UploadManager::on(UserConnectionListener::Send, UserConnection* aSource) throw() { if(aSource->getState() != UserConnection::STATE_SEND) { dcdebug("UM::onSend Bad state, ignoring\n"); return; } Upload* u = aSource->getUpload(); dcassert(u != NULL); u->setStart(GET_TICK()); aSource->setState(UserConnection::STATE_RUNNING); aSource->transmitFile(u->getStream()); fire(UploadManagerListener::Starting(), u); }
void RawManager::loadActionRaws() { try { SimpleXML xml; xml.fromXML(File(Util::getPath(Util::PATH_USER_CONFIG) + "Raws.xml", File::READ, File::OPEN).read()); if(xml.findChild("ActionRaws")) { xml.stepIn(); loadActionRaws(xml); xml.stepOut(); } } catch(const Exception& e) { dcdebug("RawManager::loadActionRaws: %s\n", e.getError().c_str()); } }
IOleObject *CImageDataObject::GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage) { dcassert(m_stgmed.hBitmap); IOleObject *pOleObject; SCODE sc = ::OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, &m_fromat, pOleClientSite, pStorage, (void **)&pOleObject); if (sc != S_OK) { dcdebug("Thrown OLE Exception: %d\n", sc); return NULL; } return pOleObject; }
void ClientProfileManager::loadClientProfiles() { try { SimpleXML xml; xml.fromXML(File(Util::getConfigPath() + "Profiles.xml", File::READ, File::OPEN).read()); if(xml.findChild("Profiles")) { xml.stepIn(); loadClientProfiles(&xml); xml.stepOut(); } } catch(const Exception& e) { dcdebug("FavoriteManager::loadClientProfiles: %s\n", e.getError().c_str()); } }
void ConnectionManager::on(UserConnectionListener::Key, UserConnection* aSource, const string&/* aKey*/) throw() { if(aSource->getState() != UserConnection::STATE_KEY) { dcdebug("CM::onKey Bad state, ignoring"); return; } dcassert(aSource->getUser()); if(aSource->isSet(UserConnection::FLAG_DOWNLOAD)) { addDownloadConnection(aSource); } else { addUploadConnection(aSource); } }
int SSLSocket::checkSSL(int ret) { if(!ssl) { return -1; } if(ret <= 0) { /* inspired by boost.asio (asio/ssl/detail/impl/engine.ipp, function engine::perform) and the SSL_get_error doc at <https://www.openssl.org/docs/ssl/SSL_get_error.html>. */ auto err = SSL_get_error(ssl, ret); switch(err) { case SSL_ERROR_NONE: // Fallthrough - YaSSL doesn't for example return an openssl compatible error on recv fail case SSL_ERROR_WANT_READ: // Fallthrough case SSL_ERROR_WANT_WRITE: return -1; case SSL_ERROR_ZERO_RETURN: throw SocketException(STRING(CONNECTION_CLOSED)); case SSL_ERROR_SYSCALL: { auto sys_err = ERR_get_error(); if(sys_err == 0) { if(ret == 0) { dcdebug("TLS error: call ret = %d, SSL_get_error = %d, ERR_get_error = %d\n", ret, err, sys_err); throw SSLSocketException(STRING(CONNECTION_CLOSED)); } sys_err = getLastError(); } throw SSLSocketException(sys_err); } default: /* don't bother getting error messages from the codes because 1) there is some additional management necessary (eg SSL_load_error_strings) and 2) openssl error codes aren't shown to the end user; they only hit standard output in debug builds. */ dcdebug("TLS error: call ret = %d, SSL_get_error = %d, ERR_get_error = %d\n", ret, err, ERR_get_error()); throw SSLSocketException(STRING(TLS_ERROR)); } } return ret; }
void DownloadManager::on(UserConnectionListener::MaxedOut, UserConnection* aSource) throw() { if(aSource->getState() != UserConnection::STATE_FILELENGTH && aSource->getState() != UserConnection::STATE_TREE) { dcdebug("DM::onMaxedOut Bad state, ignoring\n"); return; } Download* d = aSource->getDownload(); dcassert(d != NULL); fire(DownloadManagerListener::Failed(), d, STRING(NO_SLOTS_AVAILABLE)); aSource->setDownload(NULL); removeDownload(d, true); removeConnection(aSource); }
BOOL AdviceBrowser::OnBeforeNavigate2(IDispatch* /*pDisp*/, const String& szURL, DWORD /*dwFlags*/, const String& /*szTargetFrameName*/, CSimpleArray<BYTE>& /*pPostedData*/, const String& /*szHeaders*/) { #ifdef _DEBUG dcdebug("AdviceBrowser::OnBeforeNavigate2(%s)\n", Text::fromT(tstring(szURL)).c_str()); #endif tstring urlT = tstring(szURL); if (WinUtil::handleLink(urlT)) { return TRUE; } const string url = Text::wideToAcp(urlT); if (url == m_currentURL || url.substr(0, 4) != "http") { return FALSE; } ShellExecute(m_hWnd, _T("open"), szURL, NULL, NULL, SW_SHOWMAXIMIZED); return TRUE; }
void ConnectionManager::listen() throw(SocketException) { disconnect(); uint16_t port = static_cast<uint16_t>(SETTING(TCP_PORT)); server = new Server(false, port, SETTING(BIND_ADDRESS)); if(!CryptoManager::getInstance()->TLSOk()) { dcdebug("Skipping secure port: %d\n", SETTING(USE_TLS)); return; } port = static_cast<uint16_t>(SETTING(TLS_PORT)); secureServer = new Server(true, port, SETTING(BIND_ADDRESS)); }
void SSLSocket::connect(const string& aIp, short aPort) throw(SocketException) { Socket::setBlocking(true); Socket::connect(aIp, aPort); if(ssl) SSL_free(ssl); ssl = SSL_new(ctx); if(!ssl) checkSSL(-1); checkSSL(SSL_set_fd(ssl, sock)); checkSSL(SSL_connect(ssl)); dcdebug("Connected to SSL server using %s\n", SSL_get_cipher(ssl)); Socket::setBlocking(false); }
void HttpConnection::on(BufferedSocketListener::Failed, const string & aLine) noexcept { socket_cleanup(false); #ifdef RIP_USE_CORAL if (SETTING(CORAL) && coralizeState == CST_DEFAULT) { fly_fire1(HttpConnectionListener::Retried(), this, coralizeState == CST_CONNECTED); coralizeState = CST_NOCORALIZE; dcdebug("Coralized address failed, retrying : %s\n", currentUrl.c_str()); downloadFile(currentUrl); return; } coralizeState = CST_DEFAULT; #endif fly_fire1(HttpConnectionListener::Failed(), this, aLine + " (" + currentUrl + ")"); }
void ConnectionManager::putDownloadConnection(UserConnection* aSource, bool reuse /* = false */) { // Pool it for later usage... if(reuse) { aSource->addListener(this); { Lock l(cs); aSource->getCQI()->setState(ConnectionQueueItem::IDLE); dcassert(find(active.begin(), active.end(), aSource->getCQI()) != active.end()); active.erase(find(active.begin(), active.end(), aSource->getCQI())); downPool.push_back(aSource->getCQI()); } dcdebug("ConnectionManager::putDownloadConnection Pooling reusable connection %p to %s\n", aSource, aSource->getUser()->getNick().c_str()); } else { if(QueueManager::getInstance()->hasDownload(aSource->getCQI()->getUser())) { aSource->removeListeners(); aSource->disconnect(); Lock l(cs); ConnectionQueueItem* cqi = aSource->getCQI(); dcassert(cqi); // Remove the userconnection, don't need it any more dcassert(find(userConnections.begin(), userConnections.end(), aSource) != userConnections.end()); userConnections.erase(find(userConnections.begin(), userConnections.end(), aSource)); pendingDelete.push_back(aSource); cqi->setConnection(NULL); cqi->setState(ConnectionQueueItem::WAITING); dcassert(find(active.begin(), active.end(), aSource->getCQI()) != active.end()); active.erase(find(active.begin(), active.end(), aSource->getCQI())); cqi->setLastAttempt(GET_TICK()); pendingDown.push_back(cqi); } else { { Lock l(cs); dcassert(find(active.begin(), active.end(), aSource->getCQI()) != active.end()); active.erase(find(active.begin(), active.end(), aSource->getCQI())); } putConnection(aSource); } } }
void ConnectionManager::on(AdcCommand::SUP, UserConnection* aSource, const AdcCommand& cmd) throw() { if(aSource->getState() != UserConnection::STATE_SUPNICK) { // Already got this once, ignore...@todo fix support updates dcdebug("CM::onMyNick %p sent nick twice\n", (void*)aSource); return; } bool baseOk = false; for(StringIterC i = cmd.getParameters().begin(); i != cmd.getParameters().end(); ++i) { if(i->compare(0, 2, "AD") == 0) { string feat = i->substr(2); if(feat == UserConnection::FEATURE_ADC_BASE) { baseOk = true; // ADC clients must support all these... aSource->setFlag(UserConnection::FLAG_SUPPORTS_ADCGET); aSource->setFlag(UserConnection::FLAG_SUPPORTS_MINISLOTS); aSource->setFlag(UserConnection::FLAG_SUPPORTS_TTHF); aSource->setFlag(UserConnection::FLAG_SUPPORTS_TTHL); // For compatibility with older clients... aSource->setFlag(UserConnection::FLAG_SUPPORTS_XML_BZLIST); } else if(feat == UserConnection::FEATURE_ZLIB_GET) { aSource->setFlag(UserConnection::FLAG_SUPPORTS_ZLIB_GET); } else if(feat == UserConnection::FEATURE_ADC_BZIP) { aSource->setFlag(UserConnection::FLAG_SUPPORTS_XML_BZLIST); } } } if(!baseOk) { aSource->send(AdcCommand(AdcCommand::SEV_FATAL, AdcCommand::ERROR_PROTOCOL_GENERIC, "Invalid SUP")); aSource->disconnect(); return; } if(aSource->isSet(UserConnection::FLAG_INCOMING)) { StringList defFeatures = adcFeatures; if(BOOLSETTING(COMPRESS_TRANSFERS)) { defFeatures.push_back("AD" + UserConnection::FEATURE_ZLIB_GET); } aSource->sup(defFeatures); aSource->inf(false); } else { aSource->inf(true); } aSource->setState(UserConnection::STATE_INF); }
void ConnectionManager::on(UserConnectionListener::Failed, UserConnection* aSource, const string& /*aError*/) throw() { if(aSource->isSet(UserConnection::FLAG_DOWNLOAD) && aSource->getCQI()) { { Lock l(cs); for(ConnectionQueueItem::Iter i = downPool.begin(); i != downPool.end(); ++i) { dcassert((*i)->getConnection()); if((*i)->getConnection() == aSource) { dcdebug("ConnectionManager::onError Removing connection %p to %s from active pool\n", aSource, aSource->getUser()->getNick().c_str()); downPool.erase(i); break; } } } } putConnection(aSource); }
void Parser::parseColor(size_t& contextColor, const string& s) { auto sharp = s.find('#'); if(sharp != string::npos && s.size() > sharp + 6) { try { #if defined(__MINGW32__) && defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF) /// @todo use stol on MinGW when it's available unsigned int color = 0; auto colStr = s.substr(sharp + 1, 6); sscanf(colStr.c_str(), "%X", &color); #else size_t pos = 0; auto color = std::stol(s.substr(sharp + 1, 6), &pos, 16); #endif contextColor = addColor(RGB((color & 0xFF0000) >> 16, (color & 0xFF00) >> 8, color & 0xFF)); } catch(const std::exception& e) { dcdebug("color parsing exception: %s with str: %s\n", e.what(), s.c_str()); } } }
int PeersToolbarSearchPrompt::selectWidth() const { const int len = GetWindowTextLength(); if (len > 0) { AutoArray<TCHAR> caption(len + 1); GetWindowText(caption, len + 1); CRect r; GetClientRect(r); CClientDC dc(m_hWnd); const HFONT oldFont = dc.SelectFont(WinUtil::boldFont); dc.DrawText(caption, len, r, DT_SINGLELINE | DT_CALCRECT); dc.SelectFont(oldFont); dcdebug("selectWidth %d %d\n", r.left, r.right); return r.Width() + 1 + m_leftPadding; } else { return 1; } }
void BufferedSocket::setMode (Modes aMode, size_t aRollback) { if (mode == aMode) { dcdebug ("WARNING: Re-entering mode %d\n", mode); return; } switch (aMode) { case MODE_LINE: rollback = aRollback; break; case MODE_ZPIPE: filterIn = std::auto_ptr<UnZFilter>(new UnZFilter); break; case MODE_DATA: break; } mode = aMode; }
void ClientManager::send(AdcCommand& cmd, const CID& cid) { Lock l(cs); OnlineIter i = onlineUsers.find(cid); if(i != onlineUsers.end()) { OnlineUser& u = *i->second; if(cmd.getType() == AdcCommand::TYPE_UDP && !u.getIdentity().isUdpActive()) { cmd.setType(AdcCommand::TYPE_DIRECT); cmd.setTo(u.getIdentity().getSID()); u.getClient().send(cmd); } else { try { udp.writeTo(u.getIdentity().getIp(), static_cast<uint16_t>(Util::toInt(u.getIdentity().getUdpPort())), cmd.toString(getMe()->getCID())); } catch(const SocketException&) { dcdebug("Socket exception sending ADC UDP command\n"); } } } }
void DownloadManager::on(AdcCommand::SND, UserConnection* aSource, const AdcCommand& cmd) noexcept { if(aSource->getState() != UserConnection::STATE_SND) { dcdebug("DM::onFileLength Bad state, ignoring\n"); return; } const string& type = cmd.getParam(0); int64_t start = Util::toInt64(cmd.getParam(2)); int64_t bytes = Util::toInt64(cmd.getParam(3)); if(type != Transfer::names[aSource->getDownload()->getType()]) { // Uhh??? We didn't ask for this... aSource->disconnect(); return; } startData(aSource, start, bytes, cmd.hasFlag("ZL", 4)); }