void DownloadUrlBinCommand::Execute() { SNZBDownloadUrlRequest DownloadUrlRequest; if (!ReceiveRequest(&DownloadUrlRequest, sizeof(DownloadUrlRequest))) { return; } URL url(DownloadUrlRequest.m_szURL); if (!url.IsValid()) { char tmp[1024]; snprintf(tmp, 1024, "Url %s is not valid", DownloadUrlRequest.m_szURL); tmp[1024-1] = '\0'; SendBoolResponse(true, tmp); return; } UrlInfo* pUrlInfo = new UrlInfo(); pUrlInfo->SetURL(DownloadUrlRequest.m_szURL); pUrlInfo->SetNZBFilename(DownloadUrlRequest.m_szNZBFilename); pUrlInfo->SetCategory(DownloadUrlRequest.m_szCategory); pUrlInfo->SetPriority(ntohl(DownloadUrlRequest.m_iPriority)); pUrlInfo->SetAddTop(ntohl(DownloadUrlRequest.m_bAddFirst)); pUrlInfo->SetAddPaused(ntohl(DownloadUrlRequest.m_bAddPaused)); g_pUrlCoordinator->AddUrlToQueue(pUrlInfo, ntohl(DownloadUrlRequest.m_bAddFirst)); info("Request: Queue url %s", DownloadUrlRequest.m_szURL); char tmp[1024]; snprintf(tmp, 1024, "Url %s added to queue", DownloadUrlRequest.m_szURL); tmp[1024-1] = '\0'; SendBoolResponse(true, tmp); }
void PauseUnpauseBinCommand::Execute() { SNZBPauseUnpauseRequest PauseUnpauseRequest; if (!ReceiveRequest(&PauseUnpauseRequest, sizeof(PauseUnpauseRequest))) { return; } switch (ntohl(PauseUnpauseRequest.m_iAction)) { case eRemotePauseUnpauseActionDownload: g_pOptions->SetPauseDownload(ntohl(PauseUnpauseRequest.m_bPause)); break; case eRemotePauseUnpauseActionDownload2: g_pOptions->SetPauseDownload2(ntohl(PauseUnpauseRequest.m_bPause)); break; case eRemotePauseUnpauseActionPostProcess: g_pOptions->SetPausePostProcess(ntohl(PauseUnpauseRequest.m_bPause)); break; case eRemotePauseUnpauseActionScan: g_pOptions->SetPauseScan(ntohl(PauseUnpauseRequest.m_bPause)); break; } SendBoolResponse(true, "Pause-/Unpause-Command completed successfully"); }
void IPCommandReceiverBase::Run() { bool writeResultOnFailure = true; try { ReceiveRequest(); CallCommand(); WriteResultSuccess(); writeResultOnFailure = false; SendResponse(); } catch (pipe_error&) { DoWriteResultFailure(writeResultOnFailure); } catch (...) { DoWriteResultFailure(writeResultOnFailure); throw; } }
void WriteLogBinCommand::Execute() { SNZBWriteLogRequest WriteLogRequest; if (!ReceiveRequest(&WriteLogRequest, sizeof(WriteLogRequest))) { return; } char* pRecvBuffer = (char*)malloc(ntohl(WriteLogRequest.m_iTrailingDataLength) + 1); char* pBufPtr = pRecvBuffer; // Read from the socket until nothing remains int iResult = 0; int NeedBytes = ntohl(WriteLogRequest.m_iTrailingDataLength); pRecvBuffer[NeedBytes] = '\0'; while (NeedBytes > 0) { iResult = recv(m_iSocket, pBufPtr, NeedBytes, 0); // Did the recv succeed? if (iResult <= 0) { error("invalid request"); break; } pBufPtr += iResult; NeedBytes -= iResult; } if (NeedBytes == 0) { bool OK = true; switch ((Message::EKind)ntohl(WriteLogRequest.m_iKind)) { case Message::mkDetail: detail(pRecvBuffer); break; case Message::mkInfo: info(pRecvBuffer); break; case Message::mkWarning: warn(pRecvBuffer); break; case Message::mkError: error(pRecvBuffer); break; case Message::mkDebug: debug(pRecvBuffer); break; default: OK = false; } SendBoolResponse(OK, OK ? "Message added to log" : "Invalid message-kind"); } free(pRecvBuffer); }
void VersionBinCommand::Execute() { SNZBVersionRequest VersionRequest; if (!ReceiveRequest(&VersionRequest, sizeof(VersionRequest))) { return; } SendBoolResponse(true, Util::VersionRevision()); }
void CI2CEchoServer::Run (void) { while (1) { if (ReceiveRequest ()) { SendResponse (); } } }
void ReloadBinCommand::Execute() { SNZBReloadRequest ReloadRequest; if (!ReceiveRequest(&ReloadRequest, sizeof(ReloadRequest))) { return; } SendBoolResponse(true, "Reloading server"); Reload(); }
void ShutdownBinCommand::Execute() { SNZBShutdownRequest ShutdownRequest; if (!ReceiveRequest(&ShutdownRequest, sizeof(ShutdownRequest))) { return; } SendBoolResponse(true, "Stopping server"); ExitProc(); }
void SetDownloadRateBinCommand::Execute() { SNZBSetDownloadRateRequest SetDownloadRequest; if (!ReceiveRequest(&SetDownloadRequest, sizeof(SetDownloadRequest))) { return; } g_pOptions->SetDownloadRate(ntohl(SetDownloadRequest.m_iDownloadRate) / 1024.0f); SendBoolResponse(true, "Rate-Command completed successfully"); }
/* * Fake SRPC worker thread: receive requests, send a bad response. */ static void *worker(void *arg) { struct worker_state *state = (struct worker_state *) arg; /* Receive message, send request back. */ while (1) { /* Get the message. */ ReceiveRequest(state->d); /* Send back a request */ SendBadResponse(state->d); } free(arg); return 0; }
void DumpDebugBinCommand::Execute() { SNZBDumpDebugRequest DumpDebugRequest; if (!ReceiveRequest(&DumpDebugRequest, sizeof(DumpDebugRequest))) { return; } g_pQueueCoordinator->LogDebugInfo(); g_pUrlCoordinator->LogDebugInfo(); SendBoolResponse(true, "Debug-Command completed successfully"); }
void ScanBinCommand::Execute() { SNZBScanRequest ScanRequest; if (!ReceiveRequest(&ScanRequest, sizeof(ScanRequest))) { return; } bool bSyncMode = ntohl(ScanRequest.m_bSyncMode); g_pPrePostProcessor->ScanNZBDir(bSyncMode); SendBoolResponse(true, bSyncMode ? "Scan-Command completed" : "Scan-Command scheduled successfully"); }
int PrimeWorker::HandleRequest(zmq_pollitem_t *item) { proto::Request& req = mRequest; zmsg_t* msg = ReceiveRequest(req, item->socket); if(!msg) return 0; //req.PrintDebugString(); proto::Request::Type rtype = req.type(); proto::Reply::ErrType etype = proto::Reply::NONE; proto::Reply& rep = mReply; rep.Clear(); rep.set_type(rtype); rep.set_reqid(req.reqid()); if(!proto::Request::Type_IsValid(rtype)){ printf("ERROR: !proto::Request::Type_IsValid.\n"); rtype = proto::Request::NONE; etype = proto::Reply::INVALID; } while(etype == proto::Reply::NONE) { int vstatus = CheckVersion(req.version()); if(vstatus <= 0){ rep.set_errstr("Your miner version is no longer supported. Please upgrade."); etype = proto::Reply::VERSION; break; } if(rtype == proto::Request::CONNECT){ rep.mutable_sinfo()->CopyFrom(mServerInfo); if(vstatus == 1){ etype = proto::Reply::VERSION; rep.set_errstr("Your miner version will no longer be supported in the near future. Please upgrade."); } }else if(rtype == proto::Request::GETWORK){ if(!mCurrBlock.has_height()){ etype = proto::Reply::HEIGHT; break; } if(req.height() != mCurrHeight){ etype = proto::Reply::HEIGHT; break; } CBlock *pblock = &mBlockTemplate->block; IncrementExtraNonce(pblock, mIndexPrev, mExtraNonce); pblock->nTime = std::max(pblock->nTime, (unsigned int)GetAdjustedTime()); mNonceMap[pblock->hashMerkleRoot] = mExtraNonce; proto::Work* work = rep.mutable_work(); work->set_height(mCurrHeight); work->set_merkle(pblock->hashMerkleRoot.GetHex()); work->set_time(pblock->nTime); work->set_bits(pblock->nBits); }else if(rtype == proto::Request::SHARE){ if(!mCurrBlock.has_height()){ etype = proto::Reply::STALE; break; } if(!req.has_share()){ printf("ERROR: !req.has_share().\n"); etype = proto::Reply::INVALID; break; } const proto::Share& share = req.share(); if(share.height() != mCurrHeight){ etype = proto::Reply::STALE; break; } if(share.length() < mCurrBlock.minshare()){ printf("ERROR: share.length too short.\n"); etype = proto::Reply::INVALID; break; } uint256 merkleRoot; merkleRoot.SetHex(share.merkle()); unsigned extraNonce = mNonceMap[merkleRoot]; if(!extraNonce){ etype = proto::Reply::STALE; break; } unsigned nCandidateType = share.chaintype(); if(nCandidateType > 2){ printf("ERROR: share.chaintype invalid.\n"); etype = proto::Reply::INVALID; break; } CBlock *pblock = &mBlockTemplate->block; extraNonce--; IncrementExtraNonce(pblock, mIndexPrev, extraNonce); pblock->nTime = share.time(); pblock->nBits = share.bits(); pblock->nNonce = share.nonce(); uint256 headerHash = pblock->GetHeaderHash(); { uint256 headerHashClient; headerHashClient.SetHex(share.hash()); if(headerHashClient != headerHash){ printf("ERROR: headerHashClient != headerHash.\n"); etype = proto::Reply::INVALID; break; } } pblock->bnPrimeChainMultiplier.SetHex(share.multi()); uint256 blockhash = pblock->GetHash(); if(!mShares.insert(blockhash).second){ etype = proto::Reply::DUPLICATE; break; } CBigNum bnChainOrigin = CBigNum(headerHash) * pblock->bnPrimeChainMultiplier; unsigned int nChainLength = 0; bool isblock = ProbablePrimeChainTestForMiner(bnChainOrigin, pblock->nBits, nCandidateType+1, nChainLength); nChainLength = TargetGetLength(nChainLength); if(nChainLength >= mCurrBlock.minshare()){ if(isblock) isblock = CheckWork(pblock, *mWallet, mReserveKey); if(share.length() != nChainLength){ printf("ERROR: share.length() != nChainLength.\n"); etype = proto::Reply::INVALID; } mData.Clear(); proto::Share* mshare = mData.mutable_share(); mshare->CopyFrom(share); mshare->set_blockhash(blockhash.GetHex()); mshare->set_length(nChainLength); mshare->set_isblock(isblock); if(isblock){ mshare->set_genvalue(pblock->vtx[0].vout[0].nValue); } SendData(mData, mBackend); CBitcoinAddress address(share.addr()); if(!address.IsValid()){ printf("ERROR: invalid address for share: %s\n", share.addr().c_str()); etype = proto::Reply::INVALID; std::string errstr = "Your payment address '"; errstr.append(share.addr()); errstr.append("' is INVALID!!!"); rep.set_errstr(errstr); break; } }else{ printf("ERROR: share.length too short after test: %d/%d\n", nChainLength, share.length()); etype = proto::Reply::INVALID; break; } }else if(rtype == proto::Request::STATS){ if(!req.has_stats()){ printf("ERROR: !req.has_stats().\n"); etype = proto::Reply::INVALID; break; } const proto::ClientStats& stats = req.stats(); std::pair<std::string,uint64> key = std::make_pair(stats.addr(), stats.clientid() * stats.instanceid()); std::map<std::pair<std::string,uint64>, proto::Data>::iterator iter = mStats.find(key); if(iter != mStats.end()){ proto::ClientStats* s = mStats[key].mutable_clientstats(); s->set_version(std::min(s->version(), stats.version())); s->set_cpd(s->cpd() + stats.cpd()); s->set_errors(s->errors() + stats.errors()); s->set_temp(std::max(s->temp(), stats.temp())); s->set_latency(std::max(s->latency(), stats.latency())); s->set_ngpus(s->ngpus() + stats.ngpus()); /*if(s->name() != stats.name()){ s->mutable_name()->append("+"); s->mutable_name()->append(stats.name()); }*/ }else if(mStats.size() < 100000){ mStats[key].mutable_clientstats()->CopyFrom(stats); } } break; } if(req.height() < mCurrHeight){ rep.mutable_block()->CopyFrom(mCurrBlock); } mReqStats[std::make_pair(rtype,etype)]++; rep.set_error(etype); SendReply(rep, &msg, item->socket); zmsg_destroy(&msg); return 0; }
void gfserver_serve(gfserver_t *gfs) { // Get listening socket connection int listeningSocket = ConnectToListeningSocket(gfs->Port); if (listen(listeningSocket, gfs->MaxNumberConnections) == -1) { perror("Error listening for connections\n"); exit(1); } ReapZombieProcesses(); printf("Listening for connections...\n"); int clientSocket; struct sockaddr_storage clientAddress; char s[INET6_ADDRSTRLEN]; while(1) { socklen_t addressLength = sizeof clientAddress; clientSocket = accept(listeningSocket, (struct sockaddr *)&clientAddress, &addressLength); if (clientSocket == -1) { perror("accept"); continue; } inet_ntop(clientAddress.ss_family, get_in_addr((struct sockaddr *)&clientAddress), s, sizeof s); printf("server: got connection from %s\n", s); if (!fork()) { char *incomingRequest = ReceiveRequest(clientSocket); printf("Request: %s\n", incomingRequest); if(incomingRequest) { // Get path and parse request gfcontext_t *context = BuildContextFromRequestString(incomingRequest); context->SocketDescriptor = clientSocket; // Create context and send to handler ssize_t bytesTransfered = gfs->Handle(context, context->FilePath, gfs->HandlerArg); printf("Total bytes transfered = %ld\n", bytesTransfered); } free(incomingRequest); close(clientSocket); close(listeningSocket); printf("Requested file complete\n"); exit(0); } else { close(clientSocket); } } }
void HistoryBinCommand::Execute() { SNZBHistoryRequest HistoryRequest; if (!ReceiveRequest(&HistoryRequest, sizeof(HistoryRequest))) { return; } SNZBHistoryResponse HistoryResponse; memset(&HistoryResponse, 0, sizeof(HistoryResponse)); HistoryResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE); HistoryResponse.m_MessageBase.m_iStructSize = htonl(sizeof(HistoryResponse)); HistoryResponse.m_iEntrySize = htonl(sizeof(SNZBHistoryResponseEntry)); char* buf = NULL; int bufsize = 0; // Make a data structure and copy all the elements of the list into it DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue(); // calculate required buffer size for nzbs int iNrEntries = pDownloadQueue->GetHistoryList()->size(); bufsize += iNrEntries * sizeof(SNZBHistoryResponseEntry); for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++) { HistoryInfo* pHistoryInfo = *it; char szNicename[1024]; pHistoryInfo->GetName(szNicename, sizeof(szNicename)); bufsize += strlen(szNicename) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; } buf = (char*) malloc(bufsize); char* bufptr = buf; // write nzb entries for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++) { HistoryInfo* pHistoryInfo = *it; SNZBHistoryResponseEntry* pListAnswer = (SNZBHistoryResponseEntry*) bufptr; pListAnswer->m_iID = htonl(pHistoryInfo->GetID()); pListAnswer->m_iKind = htonl((int)pHistoryInfo->GetKind()); pListAnswer->m_tTime = htonl((int)pHistoryInfo->GetTime()); char szNicename[1024]; pHistoryInfo->GetName(szNicename, sizeof(szNicename)); pListAnswer->m_iNicenameLen = htonl(strlen(szNicename) + 1); if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo) { NZBInfo* pNZBInfo = pHistoryInfo->GetNZBInfo(); unsigned long iSizeHi, iSizeLo; Util::SplitInt64(pNZBInfo->GetSize(), &iSizeHi, &iSizeLo); pListAnswer->m_iSizeLo = htonl(iSizeLo); pListAnswer->m_iSizeHi = htonl(iSizeHi); pListAnswer->m_iFileCount = htonl(pNZBInfo->GetFileCount()); pListAnswer->m_iParStatus = htonl(pNZBInfo->GetParStatus()); pListAnswer->m_iScriptStatus = htonl(pNZBInfo->GetScriptStatus()); } else if (pHistoryInfo->GetKind() == HistoryInfo::hkUrlInfo) { UrlInfo* pUrlInfo = pHistoryInfo->GetUrlInfo(); pListAnswer->m_iUrlStatus = htonl(pUrlInfo->GetStatus()); } bufptr += sizeof(SNZBHistoryResponseEntry); strcpy(bufptr, szNicename); bufptr += ntohl(pListAnswer->m_iNicenameLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pListAnswer->m_iNicenameLen = htonl(ntohl(pListAnswer->m_iNicenameLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } g_pQueueCoordinator->UnlockQueue(); HistoryResponse.m_iNrTrailingEntries = htonl(iNrEntries); HistoryResponse.m_iTrailingDataLength = htonl(bufsize); // Send the request answer send(m_iSocket, (char*) &HistoryResponse, sizeof(HistoryResponse), 0); // Send the data if (bufsize > 0) { send(m_iSocket, buf, bufsize, 0); } free(buf); }
void PostQueueBinCommand::Execute() { SNZBPostQueueRequest PostQueueRequest; if (!ReceiveRequest(&PostQueueRequest, sizeof(PostQueueRequest))) { return; } SNZBPostQueueResponse PostQueueResponse; memset(&PostQueueResponse, 0, sizeof(PostQueueResponse)); PostQueueResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE); PostQueueResponse.m_MessageBase.m_iStructSize = htonl(sizeof(PostQueueResponse)); PostQueueResponse.m_iEntrySize = htonl(sizeof(SNZBPostQueueResponseEntry)); char* buf = NULL; int bufsize = 0; // Make a data structure and copy all the elements of the list into it PostQueue* pPostQueue = g_pQueueCoordinator->LockQueue()->GetPostQueue(); int NrEntries = pPostQueue->size(); // calculate required buffer size bufsize = NrEntries * sizeof(SNZBPostQueueResponseEntry); for (PostQueue::iterator it = pPostQueue->begin(); it != pPostQueue->end(); it++) { PostInfo* pPostInfo = *it; bufsize += strlen(pPostInfo->GetNZBInfo()->GetFilename()) + 1; bufsize += strlen(pPostInfo->GetParFilename()) + 1; bufsize += strlen(pPostInfo->GetInfoName()) + 1; bufsize += strlen(pPostInfo->GetNZBInfo()->GetDestDir()) + 1; bufsize += strlen(pPostInfo->GetProgressLabel()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; } time_t tCurTime = time(NULL); buf = (char*) malloc(bufsize); char* bufptr = buf; for (PostQueue::iterator it = pPostQueue->begin(); it != pPostQueue->end(); it++) { PostInfo* pPostInfo = *it; SNZBPostQueueResponseEntry* pPostQueueAnswer = (SNZBPostQueueResponseEntry*) bufptr; pPostQueueAnswer->m_iID = htonl(pPostInfo->GetID()); pPostQueueAnswer->m_iStage = htonl(pPostInfo->GetStage()); pPostQueueAnswer->m_iStageProgress = htonl(pPostInfo->GetStageProgress()); pPostQueueAnswer->m_iFileProgress = htonl(pPostInfo->GetFileProgress()); pPostQueueAnswer->m_iTotalTimeSec = htonl((int)(pPostInfo->GetStartTime() ? tCurTime - pPostInfo->GetStartTime() : 0)); pPostQueueAnswer->m_iStageTimeSec = htonl((int)(pPostInfo->GetStageTime() ? tCurTime - pPostInfo->GetStageTime() : 0)); pPostQueueAnswer->m_iNZBFilenameLen = htonl(strlen(pPostInfo->GetNZBInfo()->GetFilename()) + 1); pPostQueueAnswer->m_iParFilename = htonl(strlen(pPostInfo->GetParFilename()) + 1); pPostQueueAnswer->m_iInfoNameLen = htonl(strlen(pPostInfo->GetInfoName()) + 1); pPostQueueAnswer->m_iDestDirLen = htonl(strlen(pPostInfo->GetNZBInfo()->GetDestDir()) + 1); pPostQueueAnswer->m_iProgressLabelLen = htonl(strlen(pPostInfo->GetProgressLabel()) + 1); bufptr += sizeof(SNZBPostQueueResponseEntry); strcpy(bufptr, pPostInfo->GetNZBInfo()->GetFilename()); bufptr += ntohl(pPostQueueAnswer->m_iNZBFilenameLen); strcpy(bufptr, pPostInfo->GetParFilename()); bufptr += ntohl(pPostQueueAnswer->m_iParFilename); strcpy(bufptr, pPostInfo->GetInfoName()); bufptr += ntohl(pPostQueueAnswer->m_iInfoNameLen); strcpy(bufptr, pPostInfo->GetNZBInfo()->GetDestDir()); bufptr += ntohl(pPostQueueAnswer->m_iDestDirLen); strcpy(bufptr, pPostInfo->GetProgressLabel()); bufptr += ntohl(pPostQueueAnswer->m_iProgressLabelLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pPostQueueAnswer->m_iProgressLabelLen = htonl(ntohl(pPostQueueAnswer->m_iProgressLabelLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } g_pQueueCoordinator->UnlockQueue(); PostQueueResponse.m_iNrTrailingEntries = htonl(NrEntries); PostQueueResponse.m_iTrailingDataLength = htonl(bufsize); // Send the request answer send(m_iSocket, (char*) &PostQueueResponse, sizeof(PostQueueResponse), 0); // Send the data if (bufsize > 0) { send(m_iSocket, buf, bufsize, 0); } free(buf); }
void EditQueueBinCommand::Execute() { SNZBEditQueueRequest EditQueueRequest; if (!ReceiveRequest(&EditQueueRequest, sizeof(EditQueueRequest))) { return; } int iNrIDEntries = ntohl(EditQueueRequest.m_iNrTrailingIDEntries); int iNrNameEntries = ntohl(EditQueueRequest.m_iNrTrailingNameEntries); int iNameEntriesLen = ntohl(EditQueueRequest.m_iTrailingNameEntriesLen); int iAction = ntohl(EditQueueRequest.m_iAction); int iMatchMode = ntohl(EditQueueRequest.m_iMatchMode); int iOffset = ntohl(EditQueueRequest.m_iOffset); int iTextLen = ntohl(EditQueueRequest.m_iTextLen); bool bSmartOrder = ntohl(EditQueueRequest.m_bSmartOrder); unsigned int iBufLength = ntohl(EditQueueRequest.m_iTrailingDataLength); if (iNrIDEntries * sizeof(int32_t) + iTextLen + iNameEntriesLen != iBufLength) { error("Invalid struct size"); return; } char* pBuf = (char*)malloc(iBufLength); // Read from the socket until nothing remains char* pBufPtr = pBuf; int NeedBytes = iBufLength; int iResult = 0; while (NeedBytes > 0) { iResult = recv(m_iSocket, pBufPtr, NeedBytes, 0); // Did the recv succeed? if (iResult <= 0) { error("invalid request"); break; } pBufPtr += iResult; NeedBytes -= iResult; } bool bOK = NeedBytes == 0; if (iNrIDEntries <= 0 && iNrNameEntries <= 0) { SendBoolResponse(false, "Edit-Command failed: no IDs/Names specified"); return; } if (bOK) { char* szText = iTextLen > 0 ? pBuf : NULL; int32_t* pIDs = (int32_t*)(pBuf + iTextLen); char* pNames = (pBuf + iTextLen + iNrIDEntries * sizeof(int32_t)); IDList cIDList; NameList cNameList; if (iNrIDEntries > 0) { cIDList.reserve(iNrIDEntries); for (int i = 0; i < iNrIDEntries; i++) { cIDList.push_back(ntohl(pIDs[i])); } } if (iNrNameEntries > 0) { cNameList.reserve(iNrNameEntries); for (int i = 0; i < iNrNameEntries; i++) { cNameList.push_back(pNames); pNames += strlen(pNames) + 1; } } if (iAction < eRemoteEditActionPostMoveOffset) { bOK = g_pQueueCoordinator->GetQueueEditor()->EditList( iNrIDEntries > 0 ? &cIDList : NULL, iNrNameEntries > 0 ? &cNameList : NULL, (QueueEditor::EMatchMode)iMatchMode, bSmartOrder, (QueueEditor::EEditAction)iAction, iOffset, szText); } else { bOK = g_pPrePostProcessor->QueueEditList(&cIDList, (PrePostProcessor::EEditAction)iAction, iOffset); } } free(pBuf); if (bOK) { SendBoolResponse(true, "Edit-Command completed successfully"); } else { #ifndef HAVE_REGEX_H if ((QueueEditor::EMatchMode)iMatchMode == QueueEditor::mmRegEx) { SendBoolResponse(false, "Edit-Command failed: the program was compiled without RegEx-support"); return; } #endif SendBoolResponse(false, "Edit-Command failed"); } }
void LogBinCommand::Execute() { SNZBLogRequest LogRequest; if (!ReceiveRequest(&LogRequest, sizeof(LogRequest))) { return; } Log::Messages* pMessages = g_pLog->LockMessages(); int iNrEntries = ntohl(LogRequest.m_iLines); unsigned int iIDFrom = ntohl(LogRequest.m_iIDFrom); int iStart = pMessages->size(); if (iNrEntries > 0) { if (iNrEntries > (int)pMessages->size()) { iNrEntries = pMessages->size(); } iStart = pMessages->size() - iNrEntries; } if (iIDFrom > 0 && !pMessages->empty()) { iStart = iIDFrom - pMessages->front()->GetID(); if (iStart < 0) { iStart = 0; } iNrEntries = pMessages->size() - iStart; if (iNrEntries < 0) { iNrEntries = 0; } } // calculate required buffer size int bufsize = iNrEntries * sizeof(SNZBLogResponseEntry); for (unsigned int i = (unsigned int)iStart; i < pMessages->size(); i++) { Message* pMessage = (*pMessages)[i]; bufsize += strlen(pMessage->GetText()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; } char* buf = (char*) malloc(bufsize); char* bufptr = buf; for (unsigned int i = (unsigned int)iStart; i < pMessages->size(); i++) { Message* pMessage = (*pMessages)[i]; SNZBLogResponseEntry* pLogAnswer = (SNZBLogResponseEntry*) bufptr; pLogAnswer->m_iID = htonl(pMessage->GetID()); pLogAnswer->m_iKind = htonl(pMessage->GetKind()); pLogAnswer->m_tTime = htonl((int)pMessage->GetTime()); pLogAnswer->m_iTextLen = htonl(strlen(pMessage->GetText()) + 1); bufptr += sizeof(SNZBLogResponseEntry); strcpy(bufptr, pMessage->GetText()); bufptr += ntohl(pLogAnswer->m_iTextLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pLogAnswer->m_iTextLen = htonl(ntohl(pLogAnswer->m_iTextLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } g_pLog->UnlockMessages(); SNZBLogResponse LogResponse; LogResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE); LogResponse.m_MessageBase.m_iStructSize = htonl(sizeof(LogResponse)); LogResponse.m_iEntrySize = htonl(sizeof(SNZBLogResponseEntry)); LogResponse.m_iNrTrailingEntries = htonl(iNrEntries); LogResponse.m_iTrailingDataLength = htonl(bufsize); // Send the request answer send(m_iSocket, (char*) &LogResponse, sizeof(LogResponse), 0); // Send the data if (bufsize > 0) { send(m_iSocket, buf, bufsize, 0); } free(buf); }
void ListBinCommand::Execute() { SNZBListRequest ListRequest; if (!ReceiveRequest(&ListRequest, sizeof(ListRequest))) { return; } SNZBListResponse ListResponse; memset(&ListResponse, 0, sizeof(ListResponse)); ListResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE); ListResponse.m_MessageBase.m_iStructSize = htonl(sizeof(ListResponse)); ListResponse.m_iEntrySize = htonl(sizeof(SNZBListResponseFileEntry)); ListResponse.m_bRegExValid = 0; char* buf = NULL; int bufsize = 0; if (ntohl(ListRequest.m_bFileList)) { eRemoteMatchMode eMatchMode = (eRemoteMatchMode)ntohl(ListRequest.m_iMatchMode); bool bMatchGroup = ntohl(ListRequest.m_bMatchGroup); const char* szPattern = ListRequest.m_szPattern; RegEx *pRegEx = NULL; if (eMatchMode == eRemoteMatchModeRegEx) { pRegEx = new RegEx(szPattern); ListResponse.m_bRegExValid = pRegEx->IsValid(); } // Make a data structure and copy all the elements of the list into it DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue(); // calculate required buffer size for nzbs int iNrNZBEntries = pDownloadQueue->GetNZBInfoList()->size(); int iNrPPPEntries = 0; bufsize += iNrNZBEntries * sizeof(SNZBListResponseNZBEntry); for (NZBInfoList::iterator it = pDownloadQueue->GetNZBInfoList()->begin(); it != pDownloadQueue->GetNZBInfoList()->end(); it++) { NZBInfo* pNZBInfo = *it; bufsize += strlen(pNZBInfo->GetFilename()) + 1; bufsize += strlen(pNZBInfo->GetName()) + 1; bufsize += strlen(pNZBInfo->GetDestDir()) + 1; bufsize += strlen(pNZBInfo->GetCategory()) + 1; bufsize += strlen(pNZBInfo->GetQueuedFilename()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; // calculate required buffer size for pp-parameters for (NZBParameterList::iterator it = pNZBInfo->GetParameters()->begin(); it != pNZBInfo->GetParameters()->end(); it++) { NZBParameter* pNZBParameter = *it; bufsize += sizeof(SNZBListResponsePPPEntry); bufsize += strlen(pNZBParameter->GetName()) + 1; bufsize += strlen(pNZBParameter->GetValue()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; iNrPPPEntries++; } } // calculate required buffer size for files int iNrFileEntries = pDownloadQueue->GetFileQueue()->size(); bufsize += iNrFileEntries * sizeof(SNZBListResponseFileEntry); for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; bufsize += strlen(pFileInfo->GetSubject()) + 1; bufsize += strlen(pFileInfo->GetFilename()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; } buf = (char*) malloc(bufsize); char* bufptr = buf; // write nzb entries for (NZBInfoList::iterator it = pDownloadQueue->GetNZBInfoList()->begin(); it != pDownloadQueue->GetNZBInfoList()->end(); it++) { unsigned long iSizeHi, iSizeLo; NZBInfo* pNZBInfo = *it; SNZBListResponseNZBEntry* pListAnswer = (SNZBListResponseNZBEntry*) bufptr; Util::SplitInt64(pNZBInfo->GetSize(), &iSizeHi, &iSizeLo); pListAnswer->m_iSizeLo = htonl(iSizeLo); pListAnswer->m_iSizeHi = htonl(iSizeHi); pListAnswer->m_bMatch = htonl(bMatchGroup && (!pRegEx || pRegEx->Match(pNZBInfo->GetName()))); pListAnswer->m_iFilenameLen = htonl(strlen(pNZBInfo->GetFilename()) + 1); pListAnswer->m_iNameLen = htonl(strlen(pNZBInfo->GetName()) + 1); pListAnswer->m_iDestDirLen = htonl(strlen(pNZBInfo->GetDestDir()) + 1); pListAnswer->m_iCategoryLen = htonl(strlen(pNZBInfo->GetCategory()) + 1); pListAnswer->m_iQueuedFilenameLen = htonl(strlen(pNZBInfo->GetQueuedFilename()) + 1); bufptr += sizeof(SNZBListResponseNZBEntry); strcpy(bufptr, pNZBInfo->GetFilename()); bufptr += ntohl(pListAnswer->m_iFilenameLen); strcpy(bufptr, pNZBInfo->GetName()); bufptr += ntohl(pListAnswer->m_iNameLen); strcpy(bufptr, pNZBInfo->GetDestDir()); bufptr += ntohl(pListAnswer->m_iDestDirLen); strcpy(bufptr, pNZBInfo->GetCategory()); bufptr += ntohl(pListAnswer->m_iCategoryLen); strcpy(bufptr, pNZBInfo->GetQueuedFilename()); bufptr += ntohl(pListAnswer->m_iQueuedFilenameLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pListAnswer->m_iQueuedFilenameLen = htonl(ntohl(pListAnswer->m_iQueuedFilenameLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } // write ppp entries int iNZBIndex = 1; for (NZBInfoList::iterator it = pDownloadQueue->GetNZBInfoList()->begin(); it != pDownloadQueue->GetNZBInfoList()->end(); it++, iNZBIndex++) { NZBInfo* pNZBInfo = *it; for (NZBParameterList::iterator it = pNZBInfo->GetParameters()->begin(); it != pNZBInfo->GetParameters()->end(); it++) { NZBParameter* pNZBParameter = *it; SNZBListResponsePPPEntry* pListAnswer = (SNZBListResponsePPPEntry*) bufptr; pListAnswer->m_iNZBIndex = htonl(iNZBIndex); pListAnswer->m_iNameLen = htonl(strlen(pNZBParameter->GetName()) + 1); pListAnswer->m_iValueLen = htonl(strlen(pNZBParameter->GetValue()) + 1); bufptr += sizeof(SNZBListResponsePPPEntry); strcpy(bufptr, pNZBParameter->GetName()); bufptr += ntohl(pListAnswer->m_iNameLen); strcpy(bufptr, pNZBParameter->GetValue()); bufptr += ntohl(pListAnswer->m_iValueLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pListAnswer->m_iValueLen = htonl(ntohl(pListAnswer->m_iValueLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } } // write file entries for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { unsigned long iSizeHi, iSizeLo; FileInfo* pFileInfo = *it; SNZBListResponseFileEntry* pListAnswer = (SNZBListResponseFileEntry*) bufptr; pListAnswer->m_iID = htonl(pFileInfo->GetID()); int iNZBIndex = 0; for (unsigned int i = 0; i < pDownloadQueue->GetNZBInfoList()->size(); i++) { iNZBIndex++; if (pDownloadQueue->GetNZBInfoList()->at(i) == pFileInfo->GetNZBInfo()) { break; } } pListAnswer->m_iNZBIndex = htonl(iNZBIndex); if (pRegEx && !bMatchGroup) { char szFilename[MAX_PATH]; snprintf(szFilename, sizeof(szFilename) - 1, "%s/%s", pFileInfo->GetNZBInfo()->GetName(), Util::BaseFileName(pFileInfo->GetFilename())); pListAnswer->m_bMatch = htonl(pRegEx->Match(szFilename)); } Util::SplitInt64(pFileInfo->GetSize(), &iSizeHi, &iSizeLo); pListAnswer->m_iFileSizeLo = htonl(iSizeLo); pListAnswer->m_iFileSizeHi = htonl(iSizeHi); Util::SplitInt64(pFileInfo->GetRemainingSize(), &iSizeHi, &iSizeLo); pListAnswer->m_iRemainingSizeLo = htonl(iSizeLo); pListAnswer->m_iRemainingSizeHi = htonl(iSizeHi); pListAnswer->m_bFilenameConfirmed = htonl(pFileInfo->GetFilenameConfirmed()); pListAnswer->m_bPaused = htonl(pFileInfo->GetPaused()); pListAnswer->m_iActiveDownloads = htonl(pFileInfo->GetActiveDownloads()); pListAnswer->m_iPriority = htonl(pFileInfo->GetPriority()); pListAnswer->m_iSubjectLen = htonl(strlen(pFileInfo->GetSubject()) + 1); pListAnswer->m_iFilenameLen = htonl(strlen(pFileInfo->GetFilename()) + 1); bufptr += sizeof(SNZBListResponseFileEntry); strcpy(bufptr, pFileInfo->GetSubject()); bufptr += ntohl(pListAnswer->m_iSubjectLen); strcpy(bufptr, pFileInfo->GetFilename()); bufptr += ntohl(pListAnswer->m_iFilenameLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pListAnswer->m_iFilenameLen = htonl(ntohl(pListAnswer->m_iFilenameLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } g_pQueueCoordinator->UnlockQueue(); if (pRegEx) { delete pRegEx; } ListResponse.m_iNrTrailingNZBEntries = htonl(iNrNZBEntries); ListResponse.m_iNrTrailingPPPEntries = htonl(iNrPPPEntries); ListResponse.m_iNrTrailingFileEntries = htonl(iNrFileEntries); ListResponse.m_iTrailingDataLength = htonl(bufsize); } if (htonl(ListRequest.m_bServerState)) { unsigned long iSizeHi, iSizeLo; ListResponse.m_iDownloadRate = htonl((int)(g_pQueueCoordinator->CalcCurrentDownloadSpeed() * 1024)); Util::SplitInt64(g_pQueueCoordinator->CalcRemainingSize(), &iSizeHi, &iSizeLo); ListResponse.m_iRemainingSizeHi = htonl(iSizeHi); ListResponse.m_iRemainingSizeLo = htonl(iSizeLo); ListResponse.m_iDownloadLimit = htonl((int)(g_pOptions->GetDownloadRate() * 1024)); ListResponse.m_bDownloadPaused = htonl(g_pOptions->GetPauseDownload()); ListResponse.m_bDownload2Paused = htonl(g_pOptions->GetPauseDownload2()); ListResponse.m_bPostPaused = htonl(g_pOptions->GetPausePostProcess()); ListResponse.m_bScanPaused = htonl(g_pOptions->GetPauseScan()); ListResponse.m_iThreadCount = htonl(Thread::GetThreadCount() - 1); // not counting itself PostQueue* pPostQueue = g_pQueueCoordinator->LockQueue()->GetPostQueue(); ListResponse.m_iPostJobCount = htonl(pPostQueue->size()); g_pQueueCoordinator->UnlockQueue(); int iUpTimeSec, iDnTimeSec; long long iAllBytes; bool bStandBy; g_pQueueCoordinator->CalcStat(&iUpTimeSec, &iDnTimeSec, &iAllBytes, &bStandBy); ListResponse.m_iUpTimeSec = htonl(iUpTimeSec); ListResponse.m_iDownloadTimeSec = htonl(iDnTimeSec); ListResponse.m_bDownloadStandBy = htonl(bStandBy); Util::SplitInt64(iAllBytes, &iSizeHi, &iSizeLo); ListResponse.m_iDownloadedBytesHi = htonl(iSizeHi); ListResponse.m_iDownloadedBytesLo = htonl(iSizeLo); } // Send the request answer send(m_iSocket, (char*) &ListResponse, sizeof(ListResponse), 0); // Send the data if (bufsize > 0) { send(m_iSocket, buf, bufsize, 0); } if (buf) { free(buf); } }
void DownloadBinCommand::Execute() { SNZBDownloadRequest DownloadRequest; if (!ReceiveRequest(&DownloadRequest, sizeof(DownloadRequest))) { return; } char* pRecvBuffer = (char*)malloc(ntohl(DownloadRequest.m_iTrailingDataLength) + 1); char* pBufPtr = pRecvBuffer; // Read from the socket until nothing remains int iResult = 0; int NeedBytes = ntohl(DownloadRequest.m_iTrailingDataLength); while (NeedBytes > 0) { iResult = recv(m_iSocket, pBufPtr, NeedBytes, 0); // Did the recv succeed? if (iResult <= 0) { error("invalid request"); break; } pBufPtr += iResult; NeedBytes -= iResult; } if (NeedBytes == 0) { int iPriority = ntohl(DownloadRequest.m_iPriority); bool bAddPaused = ntohl(DownloadRequest.m_bAddPaused); NZBFile* pNZBFile = NZBFile::CreateFromBuffer(DownloadRequest.m_szFilename, DownloadRequest.m_szCategory, pRecvBuffer, ntohl(DownloadRequest.m_iTrailingDataLength)); if (pNZBFile) { info("Request: Queue collection %s", DownloadRequest.m_szFilename); for (NZBFile::FileInfos::iterator it = pNZBFile->GetFileInfos()->begin(); it != pNZBFile->GetFileInfos()->end(); it++) { FileInfo* pFileInfo = *it; pFileInfo->SetPriority(iPriority); pFileInfo->SetPaused(bAddPaused); } g_pQueueCoordinator->AddNZBFileToQueue(pNZBFile, ntohl(DownloadRequest.m_bAddFirst)); delete pNZBFile; char tmp[1024]; snprintf(tmp, 1024, "Collection %s added to queue", Util::BaseFileName(DownloadRequest.m_szFilename)); tmp[1024-1] = '\0'; SendBoolResponse(true, tmp); } else { char tmp[1024]; snprintf(tmp, 1024, "Download Request failed for %s", Util::BaseFileName(DownloadRequest.m_szFilename)); tmp[1024-1] = '\0'; SendBoolResponse(false, tmp); } } free(pRecvBuffer); }
void UrlQueueBinCommand::Execute() { SNZBUrlQueueRequest UrlQueueRequest; if (!ReceiveRequest(&UrlQueueRequest, sizeof(UrlQueueRequest))) { return; } SNZBUrlQueueResponse UrlQueueResponse; memset(&UrlQueueResponse, 0, sizeof(UrlQueueResponse)); UrlQueueResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE); UrlQueueResponse.m_MessageBase.m_iStructSize = htonl(sizeof(UrlQueueResponse)); UrlQueueResponse.m_iEntrySize = htonl(sizeof(SNZBUrlQueueResponseEntry)); char* buf = NULL; int bufsize = 0; // Make a data structure and copy all the elements of the list into it UrlQueue* pUrlQueue = g_pQueueCoordinator->LockQueue()->GetUrlQueue(); int NrEntries = pUrlQueue->size(); // calculate required buffer size bufsize = NrEntries * sizeof(SNZBUrlQueueResponseEntry); for (UrlQueue::iterator it = pUrlQueue->begin(); it != pUrlQueue->end(); it++) { UrlInfo* pUrlInfo = *it; bufsize += strlen(pUrlInfo->GetURL()) + 1; bufsize += strlen(pUrlInfo->GetNZBFilename()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; } buf = (char*) malloc(bufsize); char* bufptr = buf; for (UrlQueue::iterator it = pUrlQueue->begin(); it != pUrlQueue->end(); it++) { UrlInfo* pUrlInfo = *it; SNZBUrlQueueResponseEntry* pUrlQueueAnswer = (SNZBUrlQueueResponseEntry*) bufptr; pUrlQueueAnswer->m_iID = htonl(pUrlInfo->GetID()); pUrlQueueAnswer->m_iURLLen = htonl(strlen(pUrlInfo->GetURL()) + 1); pUrlQueueAnswer->m_iNZBFilenameLen = htonl(strlen(pUrlInfo->GetNZBFilename()) + 1); bufptr += sizeof(SNZBUrlQueueResponseEntry); strcpy(bufptr, pUrlInfo->GetURL()); bufptr += ntohl(pUrlQueueAnswer->m_iURLLen); strcpy(bufptr, pUrlInfo->GetNZBFilename()); bufptr += ntohl(pUrlQueueAnswer->m_iNZBFilenameLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pUrlQueueAnswer->m_iNZBFilenameLen = htonl(ntohl(pUrlQueueAnswer->m_iNZBFilenameLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } g_pQueueCoordinator->UnlockQueue(); UrlQueueResponse.m_iNrTrailingEntries = htonl(NrEntries); UrlQueueResponse.m_iTrailingDataLength = htonl(bufsize); // Send the request answer send(m_iSocket, (char*) &UrlQueueResponse, sizeof(UrlQueueResponse), 0); // Send the data if (bufsize > 0) { send(m_iSocket, buf, bufsize, 0); } free(buf); }