void WUploadThread::_OutputQueuesDrained() { fIdles = 0; if (fWaitingForUploadToFinish) { PRINT("\tfWaitingForUploadToFinish\n"); SetFinished(true); fWaitingForUploadToFinish = false; PRINT("\t\tSending message\n"); { WUploadEvent *wue = new WUploadEvent(WUploadEvent::FileDone); if (wue) { wue->SetDone(true); wue->SetFile(SimplifyPath(fFileUl)); PRINT("\t\tSending...\n"); SendReply(wue); PRINT("\t\tSent...\n"); // <*****@*****.**> 20021023 -- Fixed typo } else { PRINT("\t\tNot sent!\n"); } } PRINT("\t\tDisconnecting...\n"); { WUploadEvent *dis = new WUploadEvent(WUploadEvent::Disconnected); if (dis) { dis->SetDone(true); SendReply(dis); PRINT("\t\tDisconnected...\n"); } else { PRINT("\t\tCould not disconnect!\n"); } } PRINT("\tfWaitingForUploadToFinish OK\n"); } else if (!fFinished) { SignalUpload(); } }
void WUploadThread::_nobuffer() { WUploadEvent *status = new WUploadEvent(WUploadEvent::FileError); if (status) { status->SetFile(SimplifyPath(fFileUl)); status->SetError( QT_TR_NOOP( "Critical error: Upload buffer allocation failed!" ) ); SendReply(status); } NextFile(); }
void Test(const std::string &path) { std::cout << "original path is " << path << std::endl; std::cout << "path after simplify is " << SimplifyPath(path) << std::endl; }
void WUploadThread::DoUpload() { PRINT("WUploadThread::DoUpload\n"); if (fShutdownFlag && *fShutdownFlag) // Do we need to interrupt? { ConnectTimer(); return; } // Still connected? if (!IsInternalThreadRunning()) { ConnectTimer(); return; } // Small files get to bypass queue if (IsLocallyQueued()) { if ( (fFile && (fFileSize >= gWin->fSettings->GetMinQueuedSize())) || IsManuallyQueued() ) { // not yet fForced = false; WUploadEvent *lq = new WUploadEvent(WUploadEvent::FileQueued); if (lq) { SendReply(lq); } return; } fForced = true; // Set this here to avoid duplicate call to DoUpload() } // Recheck if IP is ignored or not // if (gWin->IsIgnoredIP(fStrRemoteIP) && !IsBlocked()) { SetBlocked(true); } if (IsBlocked()) { WUploadEvent *wue = new WUploadEvent(WUploadEvent::FileBlocked); if (wue) { if (fTimeLeft != -1) wue->SetTime(fTimeLeft); SendReply(wue); } return; } if (fStartTime == 0) fStartTime = GetRunTime64(); if (fFile) { MessageRef uref(GetMessageFromPool(WTransfer::TransferFileData)); if (uref()) { // think about doing this in a dynamic way (depending on connection) double dpps = GetPacketSize() * 1024.0; uint32 bufferSize = lrint(dpps); ByteBufferRef buf = GetByteBufferFromPool(bufferSize); uint8 * scratchBuffer = buf()->GetBuffer(); if (scratchBuffer == NULL) { _nobuffer(); return; } int32 numBytes = 0; numBytes = fFile->ReadBlock32(scratchBuffer, bufferSize); if (numBytes > 0) { buf()->SetNumBytes(numBytes, true); // munge mode switch (fMungeMode) { case WTransfer::MungeModeNone: { uref()->AddInt32("mm", WTransfer::MungeModeNone); break; } case WTransfer::MungeModeXOR: { for (int32 x = 0; x < numBytes; x++) scratchBuffer[x] ^= 0xFF; uref()->AddInt32("mm", WTransfer::MungeModeXOR); break; } default: { break; } } if (uref()->AddFlat("data", buf) == B_OK) { // possibly do checksums here uref()->AddInt32("chk", CalculateFileChecksum(buf)); // a little paranoia, due to file-resumes not working.... (TCP should handle this BUT...) SendMessageToSessions(uref); // NOTE: RequestOutputQueuesDrainedNotification() can recurse, so we need to update the offset before // calling it! fCurrentOffset += numBytes; if (fTunneled) { SignalUpload(); } else { MessageRef drain(GetMessageFromPool()); if (drain()) qmtt->RequestOutputQueuesDrainedNotification(drain); } WUploadEvent *update = new WUploadEvent(WUploadEvent::FileDataSent); if (update) { update->SetOffset(fCurrentOffset); update->SetSize(fFileSize); update->SetSent(numBytes); if (fCurrentOffset >= fFileSize) { update->SetDone(true); // file done! update->SetFile(SimplifyPath(fFileUl)); if (gWin->fSettings->GetUploads()) { SystemEvent( gWin, tr("%1 has finished downloading %2.").arg( GetRemoteUser() ).arg( SimplifyPath(fFileUl) ) ); } } SendReply(update); } return; } else { _nobuffer(); return; } } if (numBytes <= 0) { NextFile(); SignalUpload(); return; } } } else { while (!fFile) { if (fUploads.GetNumItems() != 0) { // grab the ref and remove it from the list fUploads.RemoveHead(fCurrentRef); fFileUl = MakeUploadPath(fCurrentRef); #ifdef _DEBUG // <*****@*****.**> 20021023, 20030702 -- Add additional debug message WString wul(fFileUl); PRINT("WUploadThread::DoUpload: filePath = %S\n", wul.getBuffer()); #endif fFile = new WFile(); Q_CHECK_PTR(fFile); if (!fFile->Open(fFileUl, QIODevice::ReadOnly)) // probably doesn't exist { delete fFile; fFile = NULL; fCurFile++; continue; // onward } // got our file! fFileSize = fFile->Size(); fCurrentOffset = 0; // from the start if (fCurrentRef()->FindInt64("secret:offset", fCurrentOffset) == B_OK) { if (!fFile->Seek(fCurrentOffset)) // <*****@*****.**> 20021026 { fFile->Seek(0); // this can't fail :) (I hope) fCurrentOffset = 0; } } // copy the message in our current file ref MessageRef headRef = fCurrentRef.Clone(); if (headRef()) { headRef()->what = WTransfer::TransferFileHeader; headRef()->AddInt64("beshare:StartOffset", fCurrentOffset); SendMessageToSessions(headRef); } fCurFile++; // Reset statistics InitTransferRate(); InitTransferETA(); WUploadEvent *started = new WUploadEvent(WUploadEvent::FileStarted); if (started) { started->SetFile(SimplifyPath(fFileUl)); started->SetStart(fCurrentOffset); started->SetSize(fFileSize); #ifdef _DEBUG started->SetSession(fRemoteSessionID); #endif SendReply(started); } if (gWin->fSettings->GetUploads()) { SystemEvent( gWin, tr("%1 is downloading %2.").arg( GetRemoteUser() ).arg( SimplifyPath(fFileUl) ) ); } // nested call SignalUpload(); return; } else { PRINT("No more files!\n"); fWaitingForUploadToFinish = true; SetFinished(true); if (fTunneled) { _OutputQueuesDrained(); } else { MessageRef drain(GetMessageFromPool()); if (drain()) qmtt->RequestOutputQueuesDrainedNotification(drain); } break; } } } }
void WUploadThread::TransferFileList(MessageRef msg) { PRINT("WUploadThread::TransferFileList\n"); if (msg()) { if (fShutdownFlag && *fShutdownFlag) // do we need to abort? { Reset(); return; } if (gWin->IsScanning()) { fSavedFileList = msg; if (!fBlocked) { SetLocallyQueued(true); SendQueuedNotification(); } return; } QString user; if (GetInt32FromMessage(msg, "mm", fMungeMode) != B_OK) fMungeMode = WTransfer::MungeModeNone; GetStringFromMessage(msg, "beshare:FromSession", fRemoteSessionID); if (GetStringFromMessage(msg, "beshare:FromUserName", user) == B_OK) { if (!user.isEmpty() && (user != fRemoteSessionID)) fRemoteUser = user; } if (fRemoteUser == QString::null) { fRemoteUser = GetUserName(fRemoteSessionID); } QString file; for (int i = 0; (GetStringFromMessage(msg, "files", i, file) == B_OK); i++) { MessageRef fileRef; if (fFileThread->FindFile(file, fileRef)) { if (fileRef()) // <*****@*****.**> 20021023 { // see if we need to add them int64 offset = 0L; ByteBufferRef hisDigest; uint32 numBytes = 0L; if (msg()->FindInt64("offsets", i, offset) == B_OK && msg()->FindFlat("md5", i, hisDigest) == B_OK && numBytes == MD5_DIGEST_SIZE) { uint8 myDigest[MD5_DIGEST_SIZE]; uint64 readLen = 0; int64 onSuccessOffset = offset; for (uint32 j = 0; j < ARRAYITEMS(myDigest); j++) myDigest[j] = 'x'; if ((msg()->FindInt64("numbytes", i, readLen) == B_OK) && (readLen > 0)) { PRINT("\t\tULT: peer requested partial resume\n"); int64 temp = readLen; readLen = offset - readLen; // readLen is now the seekTo value offset = temp; // offset is now the numBytes value } // figure the path to our requested file QString file = MakeUploadPath(fileRef); // Notify window of our hashing WUploadEvent *hash = new WUploadEvent(WUploadEvent::FileHashing); if (hash) { hash->SetFile(SimplifyPath(file)); SendReply(hash); } // Hash if (HashFileMD5(file, offset, readLen, NULL, myDigest, fShutdownFlag) == B_OK && memcmp((const uint8*) hisDigest()->GetBuffer(), myDigest, sizeof(myDigest)) == 0) { // put this into our message ref fileRef.EnsureRefIsPrivate(); fileRef()->AddInt64("secret:offset", (int64) onSuccessOffset); } } fUploads.AddTail(fileRef); fNames.AddTail(file); } } } msg()->GetInfo("files", NULL, &fNumFiles); fWaitingForUploadToFinish = false; SendQueuedNotification(); // also send a message along to our GUI telling it what the first file is if (fUploads.IsEmpty()) { PRINT("WUploadThread: No Files!!!\n"); Reset(); return; } if (IsLocallyQueued()) { MessageRef fref; fUploads.GetItemAt(0, fref); if (fref()) { QString filename = MakeUploadPath(fref); if (!filename.isEmpty()) { // Check file size if is smaller than minimum size wanted for queue int64 filesize; if (fref()->FindInt64("beshare:File Size", filesize) == B_OK) { if (filesize < gWin->fSettings->GetMinQueuedSize()) { SignalUpload(); return; } } WUploadEvent *init = new WUploadEvent(WUploadEvent::Init); if (init) { init->SetFile(SimplifyPath(filename)); // init->SetSession(fRemoteSessionID); SendReply(init); } } } } else { SignalUpload(); return; } } }