void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServerInfo *pInfo) { CServerEntry *pEntry = 0; if(Type == IServerBrowser::SET_MASTER_ADD) { if(m_ServerlistType != IServerBrowser::TYPE_INTERNET) return; if(!Find(Addr)) { pEntry = Add(Addr); QueueRequest(pEntry); } } else if(Type == IServerBrowser::SET_FAV_ADD) { if(m_ServerlistType != IServerBrowser::TYPE_FAVORITES) return; if(!Find(Addr)) { pEntry = Add(Addr); QueueRequest(pEntry); } } else if(Type == IServerBrowser::SET_RECENT) { if(m_ServerlistType != IServerBrowser::TYPE_RECENT) return; if(!Find(Addr)) { pEntry = Add(Addr); QueueRequest(pEntry); } } else if(Type == IServerBrowser::SET_TOKEN) { if(Token != m_CurrentToken) return; pEntry = Find(Addr); if(!pEntry) pEntry = Add(Addr); if(pEntry) { SetInfo(pEntry, *pInfo); if(m_ServerlistType == IServerBrowser::TYPE_LAN) pEntry->m_Info.m_Latency = min(static_cast<int>((time_get()-m_BroadcastTime)*1000/time_freq()), 999); else pEntry->m_Info.m_Latency = min(static_cast<int>((time_get()-pEntry->m_RequestTime)*1000/time_freq()), 999); RemoveRequest(pEntry); } } Sort(); }
// WorkerThread Method unsigned int cSQLPool::WorkerThread(void) { PerSQLConnection* perSQLConnection = NULL; while ( !_is_exit ) { _condition.wait(_mutex); mc_system_db::PPerhandleDataDB tmpData = GetData(); // SQLConnection. perSQLConnection = GetPool( ); // SQLConnection. if ( perSQLConnection == NULL ) { // 10/1000(s) - CPU Sleep( 10 ); QueueRequest( tmpData ); continue; } // SQLConnection. ReleasePool( perSQLConnection ); } return 0L; }
void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) override { if (i == NULL) throw LDAPException("No interface"); LDAPSearch *s = new LDAPSearch(this, i, base, filter); QueueRequest(s); }
void ItemsManagerWorker::OnFirstTabReceived() { QNetworkReply *reply = qobject_cast<QNetworkReply *>(QObject::sender()); QByteArray bytes = reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); if (!doc.IsObject()) { QLOG_ERROR() << "Can't even fetch first tab. Failed to update items."; updating_ = false; return; } if (!doc.HasMember("tabs") || doc["tabs"].Size() == 0) { QLOG_WARN() << "There are no tabs, this should not happen, bailing out."; updating_ = false; return; } tabs_as_string_ = Util::RapidjsonSerialize(doc["tabs"]); QLOG_DEBUG() << "Received tabs list, there are" << doc["tabs"].Size() << "tabs"; tabs_.clear(); // Create tab location objects for (auto &tab : doc["tabs"]) { std::string label = tab["n"].GetString(); auto index = tab["i"].GetInt(); // Ignore hidden locations if (!doc["tabs"][index].HasMember("hidden") || !doc["tabs"][index]["hidden"].GetBool()) tabs_.push_back(ItemLocation(index, label, ItemLocationType::STASH)); } // Immediately parse items received from this tab (first_fetch_tab_) and Queue requests for the others for (auto const &tab: tabs_) { auto index = tab.get_tab_id(); if (index == first_fetch_tab_) { ParseItems(&doc["items"], tab, doc.GetAllocator()); } else { QueueRequest(MakeTabRequest(index, tab), tab); } } total_needed_ = queue_.size() + 1; total_completed_ = 1; total_cached_ = reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool() ? 1:0; FetchItems(kThrottleRequests - 1); connect(signal_mapper_, SIGNAL(mapped(int)), this, SLOT(OnTabReceived(int))); reply->deleteLater(); }
void ItemsManagerWorker::OnFirstTabReceived() { QNetworkReply *reply = qobject_cast<QNetworkReply *>(QObject::sender()); QByteArray bytes = reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); int index = 0; if (!doc.IsObject()) { QLOG_ERROR() << "Can't even fetch first tab. Failed to update items."; updating_ = false; return; } if (!doc.HasMember("tabs") || doc["tabs"].Size() == 0) { QLOG_WARN() << "There are no tabs, this should not happen, bailing out."; updating_ = false; return; } tabs_as_string_ = Util::RapidjsonSerialize(doc["tabs"]); QLOG_DEBUG() << "Received tabs list, there are" << doc["tabs"].Size() << "tabs"; tabs_.clear(); for (auto &tab : doc["tabs"]) { std::string label = tab["n"].GetString(); tabs_.push_back(label); if (index > 0) { ItemLocation location; location.set_type(ItemLocationType::STASH); location.set_tab_id(index); location.set_tab_label(label); if (!tab.HasMember("hidden") || !tab["hidden"].GetBool()) QueueRequest(MakeTabRequest(index), location); } ++index; } ItemLocation first_tab_location; first_tab_location.set_type(ItemLocationType::STASH); first_tab_location.set_tab_id(0); first_tab_location.set_tab_label(tabs_[0]); if (!doc["tabs"][0].HasMember("hidden") || !doc["tabs"][0]["hidden"].GetBool()) ParseItems(&doc["items"], first_tab_location, doc.GetAllocator()); total_needed_ = queue_.size() + 1; total_completed_ = 1; FetchItems(kThrottleRequests - 1); connect(signal_mapper_, SIGNAL(mapped(int)), this, SLOT(OnTabReceived(int))); reply->deleteLater(); }
nsresult nsMsgCopyService::DoCopy(nsCopyRequest* aRequest) { NS_ENSURE_ARG(aRequest); bool copyImmediately; QueueRequest(aRequest, ©Immediately); m_copyRequests.AppendElement(aRequest); if (PR_LOG_TEST(gCopyServiceLog, PR_LOG_ALWAYS)) LogCopyRequest(copyImmediately ? "DoCopy" : "QueueRequest", aRequest); // if no active request for this dest folder then we can copy immediately if (copyImmediately) return DoNextCopy(); return NS_OK; }
void ItemsManagerWorker::OnCharacterListReceived() { QNetworkReply *reply = qobject_cast<QNetworkReply *>(QObject::sender()); QByteArray bytes = reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); if (doc.HasParseError() || !doc.IsArray()) { QLOG_ERROR() << "Received invalid reply instead of character list. The reply was" << bytes.constData(); if (doc.HasParseError()) { QLOG_ERROR() << "The error was" << rapidjson::GetParseError_En(doc.GetParseError()); } updating_ = false; return; } QLOG_DEBUG() << "Received character list, there are" << doc.Size() << "characters"; for (auto &character : doc) { if (!character.HasMember("league") || !character.HasMember("name") || !character["league"].IsString() || !character["name"].IsString()) { QLOG_ERROR() << "Malformed character entry, the reply is most likely invalid" << bytes.constData(); continue; } if (character["league"].GetString() == league_) { std::string name = character["name"].GetString(); ItemLocation location; location.set_type(ItemLocationType::CHARACTER); location.set_character(name); QueueRequest(MakeCharacterRequest(name, location), location); } } // Fetch a single tab and also request tabs list. We can fetch any tab here with tabs list // appended, so prefer one that the user has already 'checked'. Default to index '1' which is // first user visible tab. first_fetch_tab_ = 1; for (auto const &tab : tabs_) { if (bo_manager_.GetRefreshChecked(tab)) { first_fetch_tab_ = tab.get_tab_id(); break; } } QNetworkReply *first_tab = network_manager_.get(MakeTabRequest(first_fetch_tab_, ItemLocation(), true)); connect(first_tab, SIGNAL(finished()), this, SLOT(OnFirstTabReceived())); reply->deleteLater(); }
void ItemsManagerWorker::OnCharacterListReceived() { QNetworkReply *reply = qobject_cast<QNetworkReply *>(QObject::sender()); QByteArray bytes = reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); if (doc.HasParseError() || !doc.IsArray()) { QLOG_ERROR() << "Received invalid reply instead of character list. The reply was" << bytes.constData(); if (doc.HasParseError()) { QLOG_ERROR() << "The error was" << rapidjson::GetParseError_En(doc.GetParseError()); } updating_ = false; StatusFinished(); return; } QLOG_INFO() << "Received character list, there are" << doc.Size() << "characters"; for (auto &character : doc) { if (!character.HasMember("league") || !character.HasMember("name") || !character["league"].IsString() || !character["name"].IsString()) { QLOG_ERROR() << "Malformed character entry, the reply is most likely invalid" << bytes.constData(); continue; } if (character["league"].GetString() == league_) { std::string name = character["name"].GetString(); ItemLocation location; location.set_type(ItemLocationType::CHARACTER); location.set_character(name); QueueRequest(MakeCharacterRequest(name), location); } } // now get first tab and tab list QNetworkReply *first_tab = network_manager_.get(MakeTabRequest(0, true)); connect(first_tab, SIGNAL(finished()), this, SLOT(OnFirstTabReceived())); reply->deleteLater(); }
void ItemsManagerWorker::OnTabReceived(int request_id) { if (!replies_.count(request_id)) { QLOG_WARN() << "Received a reply for request" << request_id << "that was not requested."; return; } ItemsReply reply = replies_[request_id]; QLOG_INFO() << "Received a reply for" << reply.request.location.GetHeader().c_str(); QByteArray bytes = reply.network_reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); bool error = false; if (!doc.IsObject()) { QLOG_WARN() << request_id << "got a non-object response"; error = true; } else if (doc.HasMember("error")) { // this can happen if user is browsing stash in background and we can't know about it QLOG_WARN() << request_id << "got 'error' instead of stash tab contents"; error = true; } // re-queue a failed request if (error) QueueRequest(reply.request.network_request, reply.request.location); ++requests_completed_; if (!error) ++total_completed_; bool throttled = false; if (requests_completed_ == requests_needed_ && queue_.size() > 0) { throttled = true; QLOG_INFO() << "Sleeping one minute to prevent throttling."; QTimer::singleShot(kThrottleSleep * 1000, this, SLOT(FetchItems())); } CurrentStatusUpdate status = CurrentStatusUpdate(); status.state = throttled ? ProgramState::ItemsPaused : ProgramState::ItemsReceive; status.progress = total_completed_; status.total = total_needed_; if (total_completed_ == total_needed_) status.state = ProgramState::ItemsCompleted; emit StatusUpdate(status); if (error) return; ParseItems(&doc["items"], reply.request.location, doc.GetAllocator()); if (total_completed_ == total_needed_) { // all requests completed emit ItemsRefreshed(items_, tabs_, false); // since we build items_as_string_ in a hackish way inside ParseItems last character will either be // ' ' when no items were parsed or ',' when at least one item is parsed, and the first character is '[' items_as_string_[items_as_string_.size() - 1] = ']'; // DataManager is thread safe so it's ok to call it here data_manager_.Set("items", items_as_string_); data_manager_.Set("tabs", tabs_as_string_); updating_ = false; QLOG_INFO() << "Finished updating stash."; // if we're at the verge of getting throttled, sleep so we don't if (requests_completed_ == kThrottleRequests) QTimer::singleShot(kThrottleSleep, this, SLOT(PreserveSelectedCharacter())); else PreserveSelectedCharacter(); } reply.network_reply->deleteLater(); }
void ItemsManagerWorker::OnFirstTabReceived() { QNetworkReply *reply = qobject_cast<QNetworkReply *>(QObject::sender()); QByteArray bytes = reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); int index = 0; if (!doc.IsObject()) { QLOG_ERROR() << "Can't even fetch first tab. Failed to update items."; updating_ = false; StatusFinished(); return; } if (!doc.HasMember("tabs") || doc["tabs"].Size() == 0) { QLOG_WARN() << "There are no tabs, this should not happen, bailing out."; updating_ = false; StatusFinished(); return; } tabs_as_string_ = Util::RapidjsonSerialize(doc["tabs"]); QLOG_INFO() << "Received tabs list, there are" << doc["tabs"].Size() << "tabs"; // Setup tab exclusions std::string exclusions = data_manager_.Get("tab_exclusions"); QList<QRegularExpression> expressions; rapidjson::Document exclusionDoc; exclusionDoc.Parse(exclusions.c_str()); if (exclusionDoc.IsArray()) { for (auto &excl : exclusionDoc) { QRegularExpression expr(excl.GetString()); if (!expr.pattern().isEmpty() && expr.isValid()) expressions.append(expr); } } int tabsParsed = 0; tabs_.clear(); for (auto &tab : doc["tabs"]) { std::string label = tab["n"].GetString(); bool skip = false; for (QRegularExpression expr : expressions) { QRegularExpressionMatch match = expr.match(QString::fromStdString(label)); if (match.isValid() && match.hasMatch()) { skip = true; break; } } if (!skip) { tabs_.push_back(label); ItemLocation location; location.set_type(ItemLocationType::STASH); location.set_tab_id(index); location.set_tab_label(label); if (index == 0) { // We already have this tab (it's the first one we get). // Parse the items now that we have them if (!doc["tabs"][0].HasMember("hidden") || !doc["tabs"][0]["hidden"].GetBool()) { ParseItems(&doc["items"], location, doc.GetAllocator()); ++tabsParsed; } } else if (!tab.HasMember("hidden") || !tab["hidden"].GetBool()) { // If it's not hidden, then we need to download QueueRequest(MakeTabRequest(index), location); } } ++index; } if (tabs_.size() == 0) { QLOG_WARN() << "There are no tabs to be downloaded. Try clearing your tab exclusions list."; updating_ = false; StatusFinished(); return; } // tabsParsed will be 1 if the first tab was included in the initial download total_needed_ = queue_.size() + tabsParsed; total_completed_ = tabsParsed; FetchItems(kThrottleRequests - tabsParsed); connect(signal_mapper_, SIGNAL(mapped(int)), this, SLOT(OnTabReceived(int))); reply->deleteLater(); }
void ItemsManagerWorker::OnFirstTabReceived() { QNetworkReply *reply = qobject_cast<QNetworkReply *>(QObject::sender()); QByteArray bytes = reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); int index = 0; if (!doc.IsObject()) { QLOG_ERROR() << "Can't even fetch first tab. Failed to update items."; updating_ = false; return; } if (!doc.HasMember("tabs") || doc["tabs"].Size() == 0) { QLOG_WARN() << "There are no tabs, this should not happen, bailing out."; updating_ = false; return; } tabs_as_string_ = Util::RapidjsonSerialize(doc["tabs"]); QLOG_INFO() << "Received tabs list, there are" << doc["tabs"].Size() << "tabs"; // Setup tab exclusions std::string exclusions = data_manager_.Get("tab_exclusions"); QList<QRegularExpression> expressions; rapidjson::Document exclusionDoc; exclusionDoc.Parse(exclusions.c_str()); if (exclusionDoc.IsArray()) { for (auto &excl : exclusionDoc) { expressions.append(QRegularExpression(excl.GetString())); } } tabs_.clear(); for (auto &tab : doc["tabs"]) { std::string label = tab["n"].GetString(); bool skip = false; for (QRegularExpression expr : expressions) { QRegularExpressionMatch match = expr.match(QString::fromStdString(label)); if (match.isValid() && match.hasMatch()) { skip = true; break; } } tabs_.push_back(label); if (index > 0 || skip) { ItemLocation location; location.set_type(ItemLocationType::STASH); location.set_tab_id(index); location.set_tab_label(label); if (!tab.HasMember("hidden") || !tab["hidden"].GetBool()) QueueRequest(MakeTabRequest(skip ? 0 : index), location); } ++index; } ItemLocation first_tab_location; first_tab_location.set_type(ItemLocationType::STASH); first_tab_location.set_tab_id(0); first_tab_location.set_tab_label(tabs_[0]); if (!doc["tabs"][0].HasMember("hidden") || !doc["tabs"][0]["hidden"].GetBool()) ParseItems(&doc["items"], first_tab_location, doc.GetAllocator()); total_needed_ = queue_.size() + 1; total_completed_ = 1; FetchItems(kThrottleRequests - 1); connect(signal_mapper_, SIGNAL(mapped(int)), this, SLOT(OnTabReceived(int))); reply->deleteLater(); }
void CServerBrowser::Set(const NETADDR &Addr, int SetType, int Token, const CServerInfo *pInfo) { CServerEntry *pEntry = 0; switch(SetType) { case SET_MASTER_ADD: { if(!(m_RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET)) return; if(!Find(IServerBrowser::TYPE_INTERNET, Addr)) { pEntry = Add(IServerBrowser::TYPE_INTERNET, Addr); QueueRequest(pEntry); } } break; case SET_FAV_ADD: { if(!(m_RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET)) return; if(!Find(IServerBrowser::TYPE_INTERNET, Addr)) { pEntry = Add(IServerBrowser::TYPE_INTERNET, Addr); QueueRequest(pEntry); } } break; case SET_TOKEN: { int Type; // internet entry if(m_RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET) { Type = IServerBrowser::TYPE_INTERNET; pEntry = Find(Type, Addr); if(pEntry && (pEntry->m_InfoState != CServerEntry::STATE_PENDING || Token != pEntry->m_CurrentToken)) pEntry = 0; } // lan entry if(!pEntry && (m_RefreshFlags&IServerBrowser::REFRESHFLAG_LAN) && m_BroadcastTime+time_freq() >= time_get()) { Type = IServerBrowser::TYPE_LAN; pEntry = Add(Type, Addr); } // set info if(pEntry) { SetInfo(Type, pEntry, *pInfo); if(Type == IServerBrowser::TYPE_LAN) pEntry->m_Info.m_Latency = min(static_cast<int>((time_get()-m_BroadcastTime)*1000/time_freq()), 999); else pEntry->m_Info.m_Latency = min(static_cast<int>((time_get()-pEntry->m_RequestTime)*1000/time_freq()), 999); RemoveRequest(pEntry); } } } if(pEntry) m_ServerBrowserFilter.Sort(m_aServerlist[m_ActServerlistType].m_ppServerlist, m_aServerlist[m_ActServerlistType].m_NumServers, CServerBrowserFilter::RESORT_FLAG_FORCE); }
void ItemsManagerWorker::OnTabReceived(int request_id) { if (!replies_.count(request_id)) { QLOG_WARN() << "Received a reply for request" << request_id << "that was not requested."; return; } ItemsReply reply = replies_[request_id]; bool cache_status = reply.network_reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(); if (cache_status) { QLOG_DEBUG() << "Received a cached reply for" << reply.request.location.GetHeader().c_str(); ++cached_requests_completed_; ++total_cached_; } else { QLOG_DEBUG() << "Received a reply for" << reply.request.location.GetHeader().c_str(); } QByteArray bytes = reply.network_reply->readAll(); rapidjson::Document doc; doc.Parse(bytes.constData()); bool error = false; if (!doc.IsObject()) { QLOG_WARN() << request_id << "got a non-object response"; error = true; } else if (doc.HasMember("error")) { // this can happen if user is browsing stash in background and we can't know about it QLOG_WARN() << request_id << "got 'error' instead of stash tab contents"; error = true; } // re-queue a failed request if (error) { // We can 'cache' error response document so make sure we remove it // before reque tab_cache_->remove(reply.request.network_request.url()); QueueRequest(reply.request.network_request, reply.request.location); } ++requests_completed_; if (!error) ++total_completed_; bool throttled = false; if (requests_completed_ == requests_needed_ && queue_.size() > 0) { if (cached_requests_completed_ > 0) { // We basically don't want cached requests to count against throttle limit // so if we did get any cached requests fetch up to that number without a // large delay QTimer::singleShot(1, [&]() { FetchItems(cached_requests_completed_); }); } else { throttled = true; QLOG_DEBUG() << "Sleeping one minute to prevent throttling."; QTimer::singleShot(kThrottleSleep * 1000, this, SLOT(FetchItems())); } } CurrentStatusUpdate status = CurrentStatusUpdate(); status.state = throttled ? ProgramState::ItemsPaused : ProgramState::ItemsReceive; status.progress = total_completed_; status.total = total_needed_; status.cached = total_cached_; if (total_completed_ == total_needed_) status.state = ProgramState::ItemsCompleted; emit StatusUpdate(status); if (error) return; ParseItems(&doc["items"], reply.request.location, doc.GetAllocator()); if (total_completed_ == total_needed_) { // It's possible that we receive character vs stash tabs out of order, or users // move items around in a tab and we get them in a different order. For // consistency we want to present the tab data in a deterministic way to the rest // of the application. Especially so we don't try to update shop when nothing actually // changed. So sort items_ here before emitting and then generate // item list as strings. std::sort(begin(items_), end(items_), [](const std::shared_ptr<Item> &a, const std::shared_ptr<Item> &b) { return b->location() < a->location(); }); QStringList tmp; for (auto const &item: items_) { tmp.push_back(item->json().c_str()); } auto items_as_string = std::string("[") + tmp.join(",").toStdString() + "]"; // all requests completed emit ItemsRefreshed(items_, tabs_, false); // DataStore is thread safe so it's ok to call it here data_.Set("items", items_as_string); data_.Set("tabs", tabs_as_string_); updating_ = false; QLOG_DEBUG() << "Finished updating stash."; // if we're at the verge of getting throttled, sleep so we don't if (requests_completed_ == kThrottleRequests) QTimer::singleShot(kThrottleSleep, this, SLOT(PreserveSelectedCharacter())); else PreserveSelectedCharacter(); } reply.network_reply->deleteLater(); }
void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) override { LDAPBind *b = new LDAPBind(this, i, who, pass); QueueRequest(b); }
int _DtCmdCommandInvokerExecute ( char *errorMessage, /* MODIFIED */ DtSvcMsgContext replyContext, /* OBSOLETE -- always NULL */ int winMask, char *contextHost, char *contextDir, char *contextFile, /* OBSOLETE -- always NULL */ char *execParms, char *execHost, char *execString, char *procId, char *tmpFiles, DtCmdInvExecuteProc success_proc, void *success_data, DtCmdInvExecuteProc failure_proc, void *failure_data) { int ioMode, i, index1; int windowType; pid_t commandPid; char context[MAXPATHLEN]; char tmpDir [MAXPATHLEN]; char **commandArray; SPC_Channel_Ptr cmdChannel; char *theCommand = NULL; Boolean terminalRequest = False; char *commandArray2[MAX_EXEC_ARGS]; Boolean localExecution = True; Boolean xhostError; static unsigned long requestNum = 0; char *toolRequest = NULL; /* backward compatibility kludge */ myassert( !(contextFile && replyContext) ); /* * Check for a valid window-type. * This check is probably redundant but it converts the mask bits into * small integer values used by the rest of the command invoker code. */ if ((windowType= DtCmdGetWindowType(winMask))== -1) { (void) sprintf (errorMessage, errorRequest, toolRequest, DtTERMINAL, DtPERM_TERMINAL, DtOUTPUT_ONLY, DtSHARED_OUTPUT, "" /* Obsolete shell window */, DtNO_STDIO); return (_CMD_EXECUTE_FATAL); } /* * Create the command to be exec'ed. */ if (windowType == PERM_TERMINAL || windowType == TERMINAL) { _DtCmdCreateTerminalCommand (&theCommand, windowType, execString, execParms, execHost, procId, tmpFiles); terminalRequest = True; } else { /* * NO-STDIO || START-SESSION request. */ theCommand = XtMalloc( + strlen (cmd_Resources.dtexecPath) + strlen(" -open ") + 4 /* waitTime len */ + strlen(" -ttprocid ") + strlen(_DtActNULL_GUARD(procId)) + strlen(_DtActNULL_GUARD(tmpFiles)) + strlen (execString) + 5 /* for 2 quotes,2 blanks,null */); sprintf(theCommand,"%s -open %d -ttprocid '%s' %s %s", cmd_Resources.dtexecPath, 0 /* wait time zero for NO_STDIO */, _DtActNULL_GUARD(procId), _DtActNULL_GUARD(tmpFiles), execString); } /* * See if the request requires Remote Execution. */ localExecution = _DtIsSameHost(execHost,NULL); /* * If this is a terminalRequest and the Command Invoker subprocess * is not executable, return now. */ if (localExecution && terminalRequest && !cmd_Globals.subprocess_ok) { if (!(_DtCmdCheckForExecutable (cmd_Resources.dtexecPath))) { (void) sprintf (errorMessage, cmd_Globals.error_subprocess, cmd_Resources.dtexecPath); XtFree ((char *) theCommand); return (_CMD_EXECUTE_FAILURE); } else cmd_Globals.subprocess_ok = True; } /* * If this is a terminalRequest and the terminal emulator * is not executable, return now. */ if (localExecution && terminalRequest && !cmd_Globals.terminal_ok) { if (!(_DtCmdCheckForExecutable (cmd_Resources.localTerminal))) { (void) sprintf (errorMessage, cmd_Globals.error_terminal, cmd_Resources.localTerminal); XtFree ((char *) theCommand); return (_CMD_EXECUTE_FAILURE); } else cmd_Globals.terminal_ok = True; } /* * Break the command into something execvp or SPCSpawn can handle * and then free "theCommand" if this is a termianl-based request. */ commandArray = (char **) XtMalloc (MAX_EXEC_ARGS * sizeof (char *)); _DtCmdStringToArrayOfStrings (theCommand, commandArray); XtFree (theCommand); if (!localExecution) { char *netfile; char *argv[4]; char *tmp; /* REMOTE Execution */ ioMode = SPCIO_NOIO | SPCIO_SYNC_TERMINATOR | SPCIO_FORCE_CONTEXT; if ((cmdChannel = (_DtSPCOpen(execHost, ioMode, errorMessage))) == SPC_ERROR) { Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } /* Old syntax should no longer appear in contextHost/Dir */ myassert( (contextHost?*contextHost != '*':1) && (contextDir?*contextDir != '*':1) ); /* * Create a "netfile" for the cwd to be used. */ netfile = (char *) tt_host_file_netfile ( ((contextHost == NULL) ? execHost : contextHost), ((contextDir == NULL) ? (char *) getenv ("HOME") : contextDir)); if (tt_pointer_error (netfile) != TT_OK) { (void) sprintf (errorMessage, cmd_Globals.error_directory_name_map, ((contextDir == NULL) ? (char *) getenv ("HOME") : contextDir), ((contextHost == NULL) ? execHost : contextHost), tt_status_message (tt_pointer_error(netfile))); Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } (void) strcpy (context, netfile); tt_free (netfile); /* * First check to see if the "dtexecPath" is executable on * the remote execution host by executing it with no * options which will cause it to immediately die. * * There is no need to set up termination handler for this * because we don't care when it dies, we only care about * whether or not it can be executed. */ argv[0] = cmd_Resources.dtexecPath; argv[1] = (char *) NULL; if ((_DtSPCSpawn(argv[0], context, argv, NULL, cmdChannel, execHost, contextHost, contextDir, errorMessage)) == SPC_ERROR) { if (DtSPCErrorNumber != SPC_cannot_Chdir && DtSPCErrorNumber != SPC_Cannot_Fork && DtSPCErrorNumber != SPC_Env_Too_Big && DtSPCErrorNumber != SPC_Arg_Too_Long) /* * The Error message must mention that the dtexec * process is not executable so must overwrite the * error message returned by the Spawn function with * an appropriate message. */ (void) sprintf (errorMessage, errorRemoteSubprocess, execHost, cmd_Resources.dtexecPath); DtSPCClose(cmdChannel); Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } /* The dtexec process is now known to exist on the remote host */ /* * Now run a test to see if the command is executable * on this exec host. */ _DtCmdStringToArrayOfStrings (execString, commandArray2); tmp = (char *) XtMalloc (strlen (commandArray2[0]) + strlen ("whence ") + 2); (void) sprintf (tmp, "whence %s", commandArray2[0]); _DtCmdFreeStringVector (commandArray2); argv[0] = "ksh"; argv[1] = "-c"; argv[2] = tmp; argv[3] = (char *) NULL; /* * Reopen the channel */ if ((cmdChannel = (_DtSPCOpen(execHost, ioMode, errorMessage))) == SPC_ERROR) { Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } /* * Set up a callback to be invoked when the test command * terminates. */ _DtSvcProcessLock(); if ((DtSPCRegisterTerminator(cmdChannel, (SPC_TerminateHandlerType) CheckCommandTerminator, (void *) ++requestNum)) == SPC_ERROR) { DtSPCClose(cmdChannel); Cmd_FreeAllocatedStringVector (commandArray); (void) strcpy (errorMessage, errorSpcTerminator); XtFree ((char *) tmp); _DtSvcProcessUnlock(); return (_CMD_EXECUTE_FAILURE); } if ((_DtSPCSpawn(argv[0], context, argv, NULL, cmdChannel, execHost, contextHost, contextDir, errorMessage)) == SPC_ERROR) { DtSPCClose(cmdChannel); (void) sprintf (errorMessage, errorRemoteSubprocess, execHost, argv[0]); Cmd_FreeAllocatedStringVector (commandArray); XtFree ((char *) tmp); _DtSvcProcessUnlock(); return (_CMD_EXECUTE_FAILURE); } /* * The command line checking process has been spawned. * There is nothing left to do but to queue the request * and return to the client's main loop. The command * line will be executed after the above spawned process * terminates. */ QueueRequest (cmdChannel, context, execHost, execString, commandArray, windowType, requestNum, replyContext, success_proc, success_data, failure_proc, failure_data); _DtSvcProcessUnlock(); XtFree(tmp); return (_CMD_EXECUTE_QUEUED); } else { /* LOCAL Execution */ /* * Must first check to see if the execvp will potentially fail. * * Since the terminal emulator is pre-appended onto the execution * string, don't want to check it (should have been done during * startup (in _DtInitializeCommandInvoker)) but must check the * execution string that was passed in as part of the message. */ /* Break the command into something execvp can handle */ _DtCmdStringToArrayOfStrings (execString, commandArray2); if (!_DtCmdCheckForExecutable (commandArray2[0])) { (void) sprintf (errorMessage, errorExec, commandArray2[0]); Cmd_FreeAllocatedStringVector (commandArray); _DtCmdFreeStringVector (commandArray2); return (_CMD_EXECUTE_FAILURE); } _DtCmdFreeStringVector (commandArray2); /* * Save the current directory and then "chdir" to the directory * to do the execution. If the chdir fails, return. */ (void) getcwd (tmpDir, MAXPATHLEN); if (!_DtCmdValidDir (_cmdClientHost, contextDir, contextHost)) { Cmd_FreeAllocatedStringVector (commandArray); (void) sprintf (errorMessage, errorChdir, contextDir, execHost); (void) chdir (tmpDir); return (_CMD_EXECUTE_FAILURE); } /* * Restore the original environment and remove any DT * specific environment variables that were added. */ (void) _DtEnvControl (DT_ENV_RESTORE_PRE_DT); /* Fork and then execvp the execution string */ for (index1 = 0; (index1 < 10) && ((commandPid = fork ()) < 0); index1++) { /* Out of resources ? */ if (errno != EAGAIN) break; /* If not out of resources, sleep and try again */ (void) sleep ((unsigned long) 2); } if (commandPid < 0) { Cmd_FreeAllocatedStringVector (commandArray); (void) chdir (tmpDir); (void) sprintf(errorMessage, errorFork, execHost); (void) _DtEnvControl (DT_ENV_RESTORE_POST_DT); return (_CMD_EXECUTE_FAILURE); } if (commandPid == 0) { #if defined(__hp_osf) || defined(__osf__) || defined(CSRG_BASED) setsid() ; #else (void) setpgrp (); #endif if (!terminalRequest ) { int fd; /* * Close stdout and redirect it to /dev/null. If this * is not done and the request writes to stdout, the * output will be queued in an "unlinked" file in * /tmp until the client using this code terminates. */ if ((fd = open ("/dev/null", O_RDWR)) > 0) (void) dup2 (fd, fileno (stdout)); } /* * Mark file descriptiors >=3 as "Close on Exec". */ { long open_max; open_max = sysconf(_SC_OPEN_MAX); if (open_max == -1) { #ifdef _SUN_OS open_max = NOFILE; #else #if defined(USL) || defined(__uxp__) || defined(_AIX) open_max = FOPEN_MAX; #else open_max = FD_SETSIZE; #endif #endif /* _SUN_OS */ } for (i=3; i < open_max; i++) (void) fcntl (i, F_SETFD, 1); } (void) execvp (commandArray[0], commandArray); /* Should never get here, but if you do, must exit */ /* * The following message will be written to the errorlog * file if the request is not a terminal requests or * to the terminal window if the request requires a * terminal. */ (void) sprintf (errorMessage, errorExec, commandArray[0]); (void) printf ("%s\n", errorMessage); (void) _exit (1); } /* * Restore the pre-fork environment. */ (void) chdir (tmpDir); (void) _DtEnvControl (DT_ENV_RESTORE_POST_DT); } Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_SUCCESS); }
void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) override { LDAPAdd *add = new LDAPAdd(this, i, dn, attributes); QueueRequest(add); }
void Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) override { LDAPModify *mod = new LDAPModify(this, i, base, attributes); QueueRequest(mod); }
void Del(LDAPInterface *i, const Anope::string &dn) override { LDAPDel *del = new LDAPDel(this, i, dn); QueueRequest(del); }