示例#1
0
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();
	}
}
示例#2
0
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();
}
示例#3
0
void Test(const std::string &path) {
    std::cout << "original path is " << path << std::endl;
    std::cout << "path after simplify is " << SimplifyPath(path) << std::endl;
}
示例#4
0
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;
			}
		}
	}
}
示例#5
0
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;
		}

	}
}