bool FileSystem::LoadFileIntoBuffer(const char* filename, CharBuffer& buffer, bool addTrailingNull) { DiskFile file; if (!file.Open(filename, DiskFile::omRead)) { return false; } // obtain file size. file.Seek(0, DiskFile::soEnd); int size = (int)file.Position(); file.Seek(0); // allocate memory to contain the whole file. buffer.Reserve(size + (addTrailingNull ? 1 : 0)); // copy the file into the buffer. file.Read(buffer, size); file.Close(); if (addTrailingNull) { buffer[size] = 0; } return true; }
void WebProcessor::SendBodyResponse(const char* body, int bodyLen, const char* contentType) { const char* RESPONSE_HEADER = "HTTP/1.1 200 OK\r\n" "Connection: close\r\n" "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n" "Access-Control-Allow-Origin: %s\r\n" "Access-Control-Allow-Credentials: true\r\n" "Access-Control-Max-Age: 86400\r\n" "Access-Control-Allow-Headers: Content-Type, Authorization\r\n" "X-Auth-Token: %s\r\n" "Content-Length: %i\r\n" "%s" // Content-Type: xxx "%s" // Content-Encoding: gzip "Server: nzbget-%s\r\n" "\r\n"; #ifndef DISABLE_GZIP CharBuffer gbuf; bool gzip = m_gzip && bodyLen > MAX_UNCOMPRESSED_SIZE; if (gzip) { uint32 outLen = ZLib::GZipLen(bodyLen); gbuf.Reserve(outLen); int gzippedLen = ZLib::GZip(body, bodyLen, *gbuf, outLen); if (gzippedLen > 0 && gzippedLen < bodyLen) { body = gbuf; bodyLen = gzippedLen; } else { gzip = false; } } #else bool gzip = false; #endif BString<1024> contentTypeHeader; if (contentType) { contentTypeHeader.Format("Content-Type: %s\r\n", contentType); } BString<1024> responseHeader(RESPONSE_HEADER, m_origin.Str(), m_serverAuthToken[m_userAccess], bodyLen, *contentTypeHeader, gzip ? "Content-Encoding: gzip\r\n" : "", Util::VersionRevision()); // Send the request answer m_connection->Send(responseHeader, responseHeader.Length()); m_connection->Send(body, bodyLen); }
PathName SessionImpl::GetMyProgramFile(bool canonicalized) { // we do this once if (myProgramFile.Empty()) { #if defined(__APPLE__) CharBuffer<char> buf; uint32_t bufsize = buf.GetCapacity(); if (_NSGetExecutablePath(buf.GetData(), &bufsize) < 0) { buf.Reserve(bufsize); if (_NSGetExecutablePath(buf.GetData(), &bufsize) != 0) { MIKTEX_UNEXPECTED(); } } myProgramFile = buf.GetData(); #else string invocationName = initInfo.GetProgramInvocationName(); if (invocationName.empty()) { MIKTEX_FATAL_ERROR(T_("No invocation name has been set.")); } if (Utils::IsAbsolutePath(invocationName.c_str())) { myProgramFile = invocationName; } else if (invocationName.length() > 3 && (invocationName.substr(0, 2) == "./" || invocationName.substr(0, 3) == "../")) { myProgramFile = GetFullPath(invocationName.c_str()); } else if (!Utils::FindProgram(invocationName, myProgramFile)) { MIKTEX_FATAL_ERROR_2(T_("The invoked program could not be found in the PATH."), "invocationName", invocationName); } #endif myProgramFileCanon = myProgramFile; myProgramFileCanon.Canonicalize(); } if (canonicalized) { return myProgramFileCanon; } else { return myProgramFile; } }
bool RarVolume::ReadRar3File(DiskFile& file, RarBlock& block, RarFile& innerFile) { innerFile.m_splitBefore = block.flags & RAR3_FILE_SPLITBEFORE; innerFile.m_splitAfter = block.flags & RAR3_FILE_SPLITAFTER; uint16 namelen; uint32 size; if (!Read32(file, &block, &size)) return false; innerFile.m_size = size; if (!Skip(file, &block, 1)) return false; if (!Skip(file, &block, 4)) return false; if (!Read32(file, &block, &innerFile.m_time)) return false; if (!Skip(file, &block, 2)) return false; if (!Read16(file, &block, &namelen)) return false; if (!Read32(file, &block, &innerFile.m_attr)) return false; if (block.flags & RAR3_FILE_ADDSIZE) { uint32 highsize; if (!Read32(file, &block, &highsize)) return false; block.trailsize += (uint64)highsize << 32; if (!Read32(file, &block, &highsize)) return false; innerFile.m_size += (uint64)highsize << 32; } if (namelen > 8192) return false; // an error CharBuffer name; name.Reserve(namelen + 1); if (!Read(file, &block, (char*)name, namelen)) return false; name[namelen] = '\0'; innerFile.m_filename = name; debug("%i, %i, %s", (int)block.trailsize, (int)namelen, (const char*)name); return true; }
bool Frontend::RequestFileList() { const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp(); Connection connection(controlIp, g_Options->GetControlPort(), false); bool OK = connection.Connect(); if (!OK) { return false; } SNzbListRequest ListRequest; InitMessageBase(&ListRequest.m_messageBase, rrList, sizeof(ListRequest)); ListRequest.m_fileList = htonl(m_fileList); ListRequest.m_serverState = htonl(m_summary); if (!connection.Send((char*)(&ListRequest), sizeof(ListRequest))) { return false; } // Now listen for the returned list SNzbListResponse ListResponse; bool read = connection.Recv((char*) &ListResponse, sizeof(ListResponse)); if (!read || (int)ntohl(ListResponse.m_messageBase.m_signature) != (int)NZBMESSAGE_SIGNATURE || ntohl(ListResponse.m_messageBase.m_structSize) != sizeof(ListResponse)) { return false; } CharBuffer buf; if (ntohl(ListResponse.m_trailingDataLength) > 0) { buf.Reserve(ntohl(ListResponse.m_trailingDataLength)); if (!connection.Recv(buf, buf.Size())) { return false; } } connection.Disconnect(); if (m_summary) { m_pauseDownload = ntohl(ListResponse.m_downloadPaused); m_remainingSize = Util::JoinInt64(ntohl(ListResponse.m_remainingSizeHi), ntohl(ListResponse.m_remainingSizeLo)); m_currentDownloadSpeed = ntohl(ListResponse.m_downloadRate); m_downloadLimit = ntohl(ListResponse.m_downloadLimit); m_threadCount = ntohl(ListResponse.m_threadCount); m_postJobCount = ntohl(ListResponse.m_postJobCount); m_upTimeSec = ntohl(ListResponse.m_upTimeSec); m_dnTimeSec = ntohl(ListResponse.m_downloadTimeSec); m_standBy = ntohl(ListResponse.m_downloadStandBy); m_allBytes = Util::JoinInt64(ntohl(ListResponse.m_downloadedBytesHi), ntohl(ListResponse.m_downloadedBytesLo)); } if (m_fileList && ntohl(ListResponse.m_trailingDataLength) > 0) { RemoteClient client; client.SetVerbose(false); client.BuildFileList(&ListResponse, buf, DownloadQueue::Guard()); } return true; }
bool Frontend::RequestMessages() { const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp(); Connection connection(controlIp, g_Options->GetControlPort(), false); bool OK = connection.Connect(); if (!OK) { return false; } SNzbLogRequest LogRequest; InitMessageBase(&LogRequest.m_messageBase, rrLog, sizeof(LogRequest)); LogRequest.m_lines = htonl(m_neededLogEntries); if (m_neededLogEntries == 0) { LogRequest.m_idFrom = htonl(m_neededLogFirstId > 0 ? m_neededLogFirstId : 1); } else { LogRequest.m_idFrom = 0; } if (!connection.Send((char*)(&LogRequest), sizeof(LogRequest))) { return false; } // Now listen for the returned log SNzbLogResponse LogResponse; bool read = connection.Recv((char*) &LogResponse, sizeof(LogResponse)); if (!read || (int)ntohl(LogResponse.m_messageBase.m_signature) != (int)NZBMESSAGE_SIGNATURE || ntohl(LogResponse.m_messageBase.m_structSize) != sizeof(LogResponse)) { return false; } CharBuffer buf; if (ntohl(LogResponse.m_trailingDataLength) > 0) { buf.Reserve(ntohl(LogResponse.m_trailingDataLength)); if (!connection.Recv(buf, buf.Size())) { return false; } } connection.Disconnect(); if (ntohl(LogResponse.m_trailingDataLength) > 0) { char* bufPtr = (char*)buf; for (uint32 i = 0; i < ntohl(LogResponse.m_nrTrailingEntries); i++) { SNzbLogResponseEntry* logAnswer = (SNzbLogResponseEntry*) bufPtr; char* text = bufPtr + sizeof(SNzbLogResponseEntry); m_remoteMessages.emplace_back(ntohl(logAnswer->m_id), (Message::EKind)ntohl(logAnswer->m_kind), ntohl(logAnswer->m_time), text); bufPtr += sizeof(SNzbLogResponseEntry) + ntohl(logAnswer->m_textLen); } } return true; }
void TarExtractor::Extract (/*[in]*/ Stream * pStreamIn_, /*[in]*/ const PathName & destDir, /*[in]*/ bool makeDirectories, /*[in]*/ IExtractCallback * pCallback, /*[in]*/ const char * lpszPrefix) { try { pStreamIn = pStreamIn_; totalBytesRead = 0; traceStream->WriteFormattedLine ("libextractor", T_("extracting to %s (%s)"), Q_(destDir), (makeDirectories ? T_("make directories") : T_("don't make directories"))); size_t len; Header header; size_t prefixLen = (lpszPrefix == 0 ? 0 : StrLen(lpszPrefix)); unsigned fileCount = 0; bool checkHeader = true; CharBuffer<char> buffer; buffer.Reserve (1024 * 1024); while ((len = Read(&header, sizeof(header))) > 0) { // read next header if (len != sizeof(header)) { FATAL_EXTRACTOR_ERROR ("TarExtractor::Extract", T_("Invalid package archive file."), 0); } if (header.IsEndOfArchive()) { break; } if (checkHeader) { if (! header.Check()) { FATAL_EXTRACTOR_ERROR ("TarExtractor::Extract", T_("Invalid package archive file."), 0); } #if ! defined(MIKTEX_DEBUG) checkHeader = false; #endif } PathName dest = header.GetFileName(); size_t size = header.GetFileSize(); if (! header.IsNormalFile()) { if (header.GetType() == Header::LongName) { if (size >= BLOCKSIZE) { UNEXPECTED_CONDITION ("TarExtractor::Extract"); } char longNameData[BLOCKSIZE]; ReadBlock (longNameData); longNameData[size] = 0; longName = longNameData; haveLongName = true; } else { Skip (((size + sizeof(Header) - 1) / sizeof(Header)) * sizeof(Header)); } continue; } if (haveLongName) { dest = longName; haveLongName = false; } // skip directory prefix if (lpszPrefix != 0 && PathName::Compare(lpszPrefix, dest, prefixLen) == 0) { PathName tmp (dest); dest = tmp.Get() + prefixLen; } // make the destination path name PathName path (destDir); if (! makeDirectories) { dest.RemoveDirectorySpec (); } path += dest; // notify the client if (pCallback != 0) { pCallback->OnBeginFileExtraction (path.Get(), size); } // create the destination directory Directory::Create (PathName(path).RemoveFileSpec()); // remove the existing file if (File::Exists(path)) { File::Delete (path, true); } // extract the file FileStream streamOut (File::Open(path, FileMode::Create, FileAccess::Write, false)); size_t bytesRead = 0; while (bytesRead < size) { size_t remaining = size - bytesRead; size_t n = (remaining > buffer.GetCapacity() ? buffer.GetCapacity() : remaining); if (Read(buffer.GetBuffer(), n) != n) { FATAL_EXTRACTOR_ERROR ("TarExtractor::Extract", T_("Invalid package archive file."), 0); } streamOut.Write (buffer.Get(), n); bytesRead += n; } streamOut.Close (); // skip extra bytes if (bytesRead % sizeof(Header) > 0) { Skip (sizeof(Header) - bytesRead % sizeof(Header)); } fileCount += 1; // set time when the file was created time_t time = header.GetLastModificationTime(); File::SetTimes (path, time, time, time); #if 0 // set file attributes File::SetAttributes (path, todo); #endif // notify the client if (pCallback != 0) { pCallback->OnEndFileExtraction (0, size); } } traceStream->WriteFormattedLine ("libextractor", T_("extracted %u file(s)"), fileCount); } catch (const exception &) { traceStream->WriteFormattedLine ("libextractor", T_("%u bytes were read from the tar stream"), static_cast<unsigned>(totalBytesRead)); throw; } }
bool RarVolume::ReadRar5File(DiskFile& file, RarBlock& block, RarFile& innerFile) { innerFile.m_splitBefore = block.flags & RAR5_BLOCK_SPLITBEFORE; innerFile.m_splitAfter = block.flags & RAR5_BLOCK_SPLITAFTER; uint64 val; uint64 fileflags; if (!ReadV(file, &block, &fileflags)) return false; if (!ReadV(file, &block, &val)) return false; // skip innerFile.m_size = (int64)val; if (!ReadV(file, &block, &val)) return false; innerFile.m_attr = (uint32)val; if (fileflags & RAR5_FILE_TIME && !Read32(file, &block, &innerFile.m_time)) return false; if (fileflags & RAR5_FILE_CRC && !Skip(file, &block, 4)) return false; if (!ReadV(file, &block, &val)) return false; // skip if (!ReadV(file, &block, &val)) return false; // skip uint64 namelen; if (!ReadV(file, &block, &namelen)) return false; if (namelen > 8192) return false; // an error CharBuffer name; name.Reserve((uint32)namelen + 1); if (!Read(file, &block, (char*)name, namelen)) return false; name[namelen] = '\0'; innerFile.m_filename = name; // reading extra headers to find file time if (block.flags & RAR5_BLOCK_EXTRADATA) { uint64 remsize = block.addsize; while (remsize > 0) { uint64 trailsize = block.trailsize; uint64 len; if (!ReadV(file, &block, &len)) return false; remsize -= trailsize - block.trailsize + len; trailsize = block.trailsize; uint64 type; if (!ReadV(file, &block, &type)) return false; if (type == RAR5_FILE_EXTRATIME) { uint64 flags; if (!ReadV(file, &block, &flags)) return false; if (flags & RAR5_FILE_EXTRATIMEUNIXFORMAT) { if (!Read32(file, &block, &innerFile.m_time)) return false; } else { uint32 timelow, timehigh; if (!Read32(file, &block, &timelow)) return false; if (!Read32(file, &block, &timehigh)) return false; uint64 wintime = ((uint64)timehigh << 32) + timelow; innerFile.m_time = (uint32)(wintime / 10000000 - 11644473600LL); } } len -= trailsize - block.trailsize; if (!Skip(file, &block, len)) return false; } } debug("%llu, %i, %s", (long long)block.trailsize, (int)namelen, (const char*)name); return true; }
void ArticleWriter::CompleteFileParts() { debug("Completing file parts"); debug("ArticleFilename: %s", m_fileInfo->GetFilename()); bool directWrite = (g_Options->GetDirectWrite() || m_fileInfo->GetForceDirectWrite()) && m_fileInfo->GetOutputInitialized(); BString<1024> nzbName; BString<1024> nzbDestDir; BString<1024> filename; { GuardedDownloadQueue guard = DownloadQueue::Guard(); nzbName = m_fileInfo->GetNzbInfo()->GetName(); nzbDestDir = m_fileInfo->GetNzbInfo()->GetDestDir(); filename = m_fileInfo->GetFilename(); } BString<1024> infoFilename("%s%c%s", *nzbName, PATH_SEPARATOR, *filename); bool cached = m_fileInfo->GetCachedArticles() > 0; if (g_Options->GetRawArticle()) { detail("Moving articles for %s", *infoFilename); } else if (directWrite && cached) { detail("Writing articles for %s", *infoFilename); } else if (directWrite) { detail("Checking articles for %s", *infoFilename); } else { detail("Joining articles for %s", *infoFilename); } // Ensure the DstDir is created CString errmsg; if (!FileSystem::ForceDirectories(nzbDestDir, errmsg)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not create directory %s: %s", *nzbDestDir, *errmsg); return; } CString ofn; if (m_fileInfo->GetForceDirectWrite()) { ofn.Format("%s%c%s", *nzbDestDir, PATH_SEPARATOR, *filename); } else { ofn = FileSystem::MakeUniqueFilename(nzbDestDir, *filename); } DiskFile outfile; BString<1024> tmpdestfile("%s.tmp", *ofn); if (!g_Options->GetRawArticle() && !directWrite) { FileSystem::DeleteFile(tmpdestfile); if (!outfile.Open(tmpdestfile, DiskFile::omWrite)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not create file %s: %s", *tmpdestfile, *FileSystem::GetLastErrorMessage()); return; } } else if (directWrite && cached) { if (!outfile.Open(m_outputFilename, DiskFile::omReadWrite)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not open file %s: %s", *m_outputFilename, *FileSystem::GetLastErrorMessage()); return; } tmpdestfile = *m_outputFilename; } else if (g_Options->GetRawArticle()) { FileSystem::DeleteFile(tmpdestfile); if (!FileSystem::CreateDirectory(ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not create directory %s: %s", *ofn, *FileSystem::GetLastErrorMessage()); return; } } if (outfile.Active()) { SetWriteBuffer(outfile, 0); } uint32 crc = 0; { std::unique_ptr<ArticleCache::FlushGuard> flushGuard; if (cached) { flushGuard = std::make_unique<ArticleCache::FlushGuard>(g_ArticleCache->GuardFlush()); } CharBuffer buffer; bool firstArticle = true; if (!g_Options->GetRawArticle() && !directWrite) { buffer.Reserve(1024 * 64); } for (ArticleInfo* pa : m_fileInfo->GetArticles()) { if (pa->GetStatus() != ArticleInfo::aiFinished) { continue; } if (!g_Options->GetRawArticle() && !directWrite && pa->GetSegmentOffset() > -1 && pa->GetSegmentOffset() > outfile.Position() && outfile.Position() > -1) { memset(buffer, 0, buffer.Size()); if (!g_Options->GetSkipWrite()) { while (pa->GetSegmentOffset() > outfile.Position() && outfile.Position() > -1 && outfile.Write(buffer, std::min((int)(pa->GetSegmentOffset() - outfile.Position()), buffer.Size()))); } } if (pa->GetSegmentContent()) { if (!g_Options->GetSkipWrite()) { outfile.Seek(pa->GetSegmentOffset()); outfile.Write(pa->GetSegmentContent(), pa->GetSegmentSize()); } pa->DiscardSegment(); } else if (!g_Options->GetRawArticle() && !directWrite && !g_Options->GetSkipWrite()) { DiskFile infile; if (pa->GetResultFilename() && infile.Open(pa->GetResultFilename(), DiskFile::omRead)) { int cnt = buffer.Size(); while (cnt == buffer.Size()) { cnt = (int)infile.Read(buffer, buffer.Size()); outfile.Write(buffer, cnt); } infile.Close(); } else { m_fileInfo->SetFailedArticles(m_fileInfo->GetFailedArticles() + 1); m_fileInfo->SetSuccessArticles(m_fileInfo->GetSuccessArticles() - 1); m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not find file %s for %s [%i/%i]", pa->GetResultFilename(), *infoFilename, pa->GetPartNumber(), (int)m_fileInfo->GetArticles()->size()); } } else if (g_Options->GetRawArticle()) { BString<1024> dstFileName("%s%c%03i", *ofn, PATH_SEPARATOR, pa->GetPartNumber()); if (!FileSystem::MoveFile(pa->GetResultFilename(), dstFileName)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not move file %s to %s: %s", pa->GetResultFilename(), *dstFileName, *FileSystem::GetLastErrorMessage()); } } if (m_format == Decoder::efYenc) { crc = firstArticle ? pa->GetCrc() : Crc32::Combine(crc, pa->GetCrc(), pa->GetSegmentSize()); firstArticle = false; } } buffer.Clear(); } if (outfile.Active()) { outfile.Close(); if (!directWrite && !FileSystem::MoveFile(tmpdestfile, ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not move file %s to %s: %s", *tmpdestfile, *ofn, *FileSystem::GetLastErrorMessage()); } } if (directWrite) { if (!FileSystem::SameFilename(m_outputFilename, ofn) && !FileSystem::MoveFile(m_outputFilename, ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not move file %s to %s: %s", *m_outputFilename, *ofn, *FileSystem::GetLastErrorMessage()); } // if destination directory was changed delete the old directory (if empty) int len = strlen(nzbDestDir); if (!(!strncmp(nzbDestDir, m_outputFilename, len) && (m_outputFilename[len] == PATH_SEPARATOR || m_outputFilename[len] == ALT_PATH_SEPARATOR))) { debug("Checking old dir for: %s", *m_outputFilename); BString<1024> oldDestDir; oldDestDir.Set(m_outputFilename, (int)(FileSystem::BaseFileName(m_outputFilename) - m_outputFilename)); if (FileSystem::DirEmpty(oldDestDir)) { debug("Deleting old dir: %s", *oldDestDir); FileSystem::RemoveDirectory(oldDestDir); } } } if (!directWrite) { for (ArticleInfo* pa : m_fileInfo->GetArticles()) { if (pa->GetResultFilename()) { FileSystem::DeleteFile(pa->GetResultFilename()); } } } if (m_fileInfo->GetTotalArticles() == m_fileInfo->GetSuccessArticles()) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Successfully downloaded %s", *infoFilename); } else if (m_fileInfo->GetMissedArticles() + m_fileInfo->GetFailedArticles() > 0) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkWarning, "%i of %i article downloads failed for \"%s\"", m_fileInfo->GetMissedArticles() + m_fileInfo->GetFailedArticles(), m_fileInfo->GetTotalArticles(), *infoFilename); } else { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Partially downloaded %s", *infoFilename); } { GuardedDownloadQueue guard = DownloadQueue::Guard(); m_fileInfo->SetCrc(crc); m_fileInfo->SetOutputFilename(ofn); if (strcmp(m_fileInfo->GetFilename(), filename)) { // file was renamed during completion, need to move the file ofn = FileSystem::MakeUniqueFilename(nzbDestDir, m_fileInfo->GetFilename()); if (!FileSystem::MoveFile(m_fileInfo->GetOutputFilename(), ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not rename file %s to %s: %s", m_fileInfo->GetOutputFilename(), *ofn, *FileSystem::GetLastErrorMessage()); } m_fileInfo->SetOutputFilename(ofn); } if (strcmp(m_fileInfo->GetNzbInfo()->GetDestDir(), nzbDestDir)) { // destination directory was changed during completion, need to move the file MoveCompletedFiles(m_fileInfo->GetNzbInfo(), nzbDestDir); } } }