コード例 #1
0
ファイル: uploadthread.cpp プロジェクト: mtl1979/unizone
void
WUploadThread::timerEvent(QTimerEvent * /* e */)
{
	if (IsInternalThreadRunning())
	{
		if ((fLocallyQueued && !fForced) || fBlocked)
		{
			// Locally queued or blocked transfer don't need idle check restricting
			MessageRef nop(GetMessageFromPool(PR_COMMAND_NOOP));
			if ( nop() )
			{
				SendMessageToSessions(nop);
			}
			return;
		}
		// 1 minute maximum
		fIdles++;
		if (fIdles == 1)
		{
			MessageRef nop(GetMessageFromPool(PR_COMMAND_NOOP));
			if ( nop() )
			{
				SendMessageToSessions(nop);
			}
		}
		if (fIdles < 3)
			return;
	}
	// fall through
	ConnectTimer();
}
コード例 #2
0
void PacketTunnelIOGateway :: HandleIncomingMessage(AbstractGatewayMessageReceiver & receiver, const ByteBufferRef & buf, const IPAddressAndPort & fromIAP)
{
   if (_slaveGateway())
   {
      DataIORef oldIO = _slaveGateway()->GetDataIO(); // save slave gateway's old state

      _fakeReceiveIO.SetBuffer(buf); (void) _fakeReceiveIO.Seek(0, SeekableDataIO::IO_SEEK_SET);
      _slaveGateway()->SetDataIO(DataIORef(&_fakeReceiveIO, false));

      uint32 slaveBytesRead = 0;
      while(slaveBytesRead < buf()->GetNumBytes())
      {
         _scratchReceiver    = &receiver;
         _scratchReceiverArg = (void *) &fromIAP;
         int32 nextBytesRead = _slaveGateway()->DoInput(*this, buf()->GetNumBytes()-slaveBytesRead);
         if (nextBytesRead > 0) slaveBytesRead += nextBytesRead;
                           else break;
      }

      _slaveGateway()->SetDataIO(oldIO);  // restore slave gateway's old state
      _fakeReceiveIO.SetBuffer(ByteBufferRef());
   }
   else
   {
      MessageRef inMsg = GetMessageFromPool();
      if ((inMsg())&&(inMsg()->UnflattenFromByteBuffer(*buf()) == B_NO_ERROR)) receiver.CallMessageReceivedFromGateway(inMsg, (void *) &fromIAP);
   }
}
コード例 #3
0
static status_t ParseFileAux(StringTokenizer * optTok, FILE * fpIn, Message * optAddToMsg, Queue<String> * optAddToQueue, char * scratchBuf, uint32 bufSize, bool cs)
{
   status_t ret = B_NO_ERROR;
   while(1)
   {
      const char * lineOfText = (optTok) ? optTok->GetNextToken() : fgets(scratchBuf, bufSize, fpIn);
      if (lineOfText == NULL) break;

      String checkForSection(lineOfText);
      checkForSection = optAddToMsg ? checkForSection.Trim() : "";  // sections are only supported for Messages, not Queue<String>'s
      if (cs == false) checkForSection = checkForSection.ToLowerCase();
      if (((checkForSection == "begin")||(checkForSection.StartsWith("begin ")))&&(optAddToMsg))  // the check for (optAddToMsg) isn't really necessary, but it makes clang++ happy
      {
         checkForSection = checkForSection.Substring(6).Trim();
         const int32 hashIdx = checkForSection.IndexOf('#');
         if (hashIdx >= 0) checkForSection = checkForSection.Substring(0, hashIdx).Trim();

         // Don't allow the parsing to fail just because the user specified a section name the same as a param name!
         uint32 tc;
         if ((optAddToMsg->GetInfo(checkForSection, &tc) == B_NO_ERROR)&&(tc != B_MESSAGE_TYPE)) (void) optAddToMsg->RemoveName(checkForSection);

         MessageRef subMsg = GetMessageFromPool();
         if ((subMsg() == NULL)||(optAddToMsg->AddMessage(checkForSection, subMsg) != B_NO_ERROR)||(ParseFileAux(optTok, fpIn, subMsg(), optAddToQueue, scratchBuf, bufSize, cs) != B_NO_ERROR)) return B_ERROR;
      }
      else if ((checkForSection == "end")||(checkForSection.StartsWith("end "))) return B_NO_ERROR;
      else if (ParseArgsAux(lineOfText, optAddToMsg, optAddToQueue, cs) != B_NO_ERROR)
      {
         ret = B_ERROR;
         break;
      }
   }
   return ret;
}
コード例 #4
0
void 
PlainTextMessageIOGateway :: FlushInput(AbstractGatewayMessageReceiver & receiver)
{
   if (_incomingText.HasChars())
   {
      MessageRef inMsg = GetMessageFromPool(PR_COMMAND_TEXT_STRINGS);
      if ((inMsg())&&(inMsg()->AddString(PR_NAME_TEXT_LINE, _incomingText) == B_NO_ERROR))
      {
         _incomingText.Clear();
         receiver.CallMessageReceivedFromGateway(inMsg);
      }
   }
}
コード例 #5
0
ファイル: uploadthread.cpp プロジェクト: mtl1979/unizone
void
WUploadThread::SendRejectedNotification(bool direct)
{
	MessageRef q(GetMessageFromPool(WTransfer::TransferNotifyRejected));

	if (q())
	{

		if (fTimeLeft != -1)
			q()->AddInt64("timeleft", fTimeLeft);

		if (direct || (fPort == 0))
		{
			SendMessageToSessions(q);
		}
		else
		{
			QString node;
			if (fRemoteSessionID != QString::null)
			{
				node = "/*/";
				node += fRemoteSessionID;
			}
			else
			{
				// use /<ip>/* instead of /*/<sessionid>, because session id isn't yet known at this point
				node = "/";
				node += fStrRemoteIP;
				node += "/*";
			}
			if (
				(q()->AddString(PR_NAME_SESSION, "") == B_NO_ERROR) &&
				(AddStringToMessage(q, PR_NAME_KEYS, node) == B_NO_ERROR) &&
				(q()->AddInt32("port", (int32) fPort) == B_NO_ERROR)
				)
			{
				gWin->SendRejectedNotification(q);
			}
		}
	}
	WUploadEvent *b = new WUploadEvent(WUploadEvent::FileBlocked);
	if (b)
	{
		if (fTimeLeft != -1)
			b->SetTime(fTimeLeft);

		SendReply(b);
	}
}
コード例 #6
0
ファイル: uploadthread.cpp プロジェクト: mtl1979/unizone
void
WUploadThread::SendQueuedNotification()
{
	MessageRef q(GetMessageFromPool(WTransfer::TransferNotifyQueued));
	if (q())
	{
		SendMessageToSessions(q);

		WUploadEvent *qf = new WUploadEvent(WUploadEvent::FileQueued);
		if (qf)
		{
			SendReply(qf);
		}
	}
}
コード例 #7
0
MessageRef
PlainTextMessageIOGateway ::
AddIncomingText(const MessageRef & inMsg, const char * s)
{
   MessageRef ret = inMsg;
   if (ret() == NULL) ret = GetMessageFromPool(PR_COMMAND_TEXT_STRINGS);
   if (ret())
   {
      if (_incomingText.HasChars())
      {
         (void) ret()->AddString(PR_NAME_TEXT_LINE, _incomingText.Append(s));
         _incomingText.Clear();
      }
      else (void) ret()->AddString(PR_NAME_TEXT_LINE, s);
   }
   return ret;
}
コード例 #8
0
// This proxy implementation receives raw data from the superclass and SLIP-decodes it, building up a Message full of decoded data to send to our own caller later.
void SLIPFramedDataMessageIOGateway :: MessageReceivedFromGateway(const MessageRef & msg, void * /*userData*/)
{
   const uint8 * buf;
   uint32 numBytes;
   for (int32 x=0; msg()->FindData(PR_NAME_DATA_CHUNKS, B_ANY_TYPE, x, (const void **) &buf, &numBytes) == B_NO_ERROR; x++)
   {
      for (uint32 i=0; i<numBytes; i++)
      {
         uint8 b = buf[i];
         if (_lastReceivedCharWasEscape)
         {
            switch(b)
            {
               case SLIP_ESCAPE_END:  AddPendingByte(SLIP_END); break;
               case SLIP_ESCAPE_ESC:  AddPendingByte(SLIP_ESC); break;
               default:               AddPendingByte(b);        break;  // protocol violation, but we'll just let the byte through since that is what the reference implementation does
            }
            _lastReceivedCharWasEscape = false;
         }
         else
         { 
            switch(b)
            {
               case SLIP_END:
                  if ((_pendingBuffer())&&(_pendingBuffer()->GetNumBytes() > 0))
                  {
                     if (_pendingMessage() == NULL) _pendingMessage = GetMessageFromPool(msg()->what);
                     if (_pendingMessage()) (void) _pendingMessage()->AddFlat(PR_NAME_DATA_CHUNKS, _pendingBuffer);
                     _pendingBuffer.Reset();
                  }
               break;

               case SLIP_ESC:
                  // do nothing
               break;

               default:
                  AddPendingByte(b);
               break;
            } 
            _lastReceivedCharWasEscape = (b==SLIP_ESC);
         }
      }
   }
}
コード例 #9
0
status_t AssembleBatchMessage(MessageRef & batchMsg, const MessageRef & newMsg)
{
   if (batchMsg() == NULL)
   {
      batchMsg = newMsg;
      return B_NO_ERROR;
   }
   else if (batchMsg()->what == PR_COMMAND_BATCH) return batchMsg()->AddMessage(PR_NAME_KEYS, newMsg);
   else
   {
      MessageRef newBatchMsg = GetMessageFromPool(PR_COMMAND_BATCH);
      if ((newBatchMsg())&&(newBatchMsg()->AddMessage(PR_NAME_KEYS, batchMsg) == B_NO_ERROR)&&(newBatchMsg()->AddMessage(PR_NAME_KEYS, newMsg) == B_NO_ERROR))
      {
         batchMsg = newBatchMsg;
         return B_NO_ERROR;
      }
   }
   return B_ERROR;
}
コード例 #10
0
ファイル: uploadthread.cpp プロジェクト: mtl1979/unizone
status_t
WUploadThread::SendMessageToSessions(const MessageRef & msgRef, const char * optDistPath)
{
	if (fTunneled)
	{
		if (
			(msgRef()->what == NetClient::ACCEPT_TUNNEL) ||
			(msgRef()->what == NetClient::REJECT_TUNNEL)
			)
		{
			// Send directly...
			QString to("/*/");
			to += fRemoteSessionID;
			to += "/beshare";
			AddStringToMessage(msgRef, PR_NAME_KEYS, to);
			msgRef()->AddString(PR_NAME_SESSION, "");
			msgRef()->AddBool("upload", true);
			return static_cast<WUpload *>(fOwner)->netClient()->SendMessageToSessions(msgRef);
		}
		else
		{
			MessageRef up(GetMessageFromPool(NetClient::TUNNEL_MESSAGE));
			if (up())
			{
				QString to("/*/");
				to += fRemoteSessionID;
				to += "/beshare";
				AddStringToMessage(up, PR_NAME_KEYS, to);
				up()->AddString(PR_NAME_SESSION, "");
				up()->AddMessage("message", msgRef);
				up()->AddBool("upload", true);
				up()->AddInt64("tunnel_id", hisID);
				return static_cast<WUpload *>(fOwner)->netClient()->SendMessageToSessions(up);
			}
			else
				return B_ERROR;
		}
	}
	else
		return qmtt->SendMessageToSessions(msgRef, optDistPath);
}
コード例 #11
0
MessageRef ReadZipFile(DataIO & readFrom, bool loadData)
{
   TCHECKPOINT;

   static const int NAME_BUF_LEN = 8*1024;  // names longer than 8KB are ridiculous anyway!
   char * nameBuf = newnothrow_array(char, NAME_BUF_LEN);
   if (nameBuf)
   {
      MessageRef ret = GetMessageFromPool();
      if (ret())
      {
         zlib_filefunc_def zdefs = {
            fopen_dataio_func,
            fread_dataio_func,
            fwrite_dataio_func,
            ftell_dataio_func,
            fseek_dataio_func,
            fclose_dataio_func,
            ferror_dataio_func,
            &readFrom
         };
         zipFile zf = unzOpen2(NULL, &zdefs);
         if (zf != NULL)
         {
            if (ReadZipFileAux(zf, *ret(), nameBuf, NAME_BUF_LEN, loadData) != B_NO_ERROR) ret.Reset();
            unzClose(zf);
         }
         else ret.Reset();  // failure!
      }
      delete [] nameBuf;
      return ret;
   }
   else WARN_OUT_OF_MEMORY;

   return MessageRef();
}
コード例 #12
0
ファイル: uploadthread.cpp プロジェクト: mtl1979/unizone
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;
			}
		}
	}
}
コード例 #13
0
ファイル: listthread.cpp プロジェクト: mtl1979/unizone
void
WListThread::InternalThreadEntry()
{
	Lock();
	WinShareWindow * win = dynamic_cast<WinShareWindow *>(fOwner);

	// reset our shutdown flag
	if (fShutdownFlag)
		*fShutdownFlag = false;

	fFileScanThread->Lock();
	int numShares = fFileScanThread->GetNumFiles();
	if (win->Settings()->GetInfo())
	{
		QString shares;
		switch (numShares)
		{
		case 0:
			shares = tr("No shared files.");
			break;
		case 1:
			shares = tr("Sharing 1 file.");
			break;
		default:
			shares = tr("Sharing %1 files.").arg(numShares);
		}
		SystemEvent(fOwner, shares);
	}
	fNet->SetFileCount(numShares);
	PRINT("Doing a scan of the returned files for uploading.\n");
	int m = 0;
	MessageRef refScan(GetMessageFromPool(PR_COMMAND_SETDATA));

	if (refScan())
	{
		MessageRef mref;
		HashtableIterator<QString, QString> filesIter = fFileScanThread->GetSharedFilesIterator(HTIT_FLAG_NOREGISTER);
		while (filesIter.HasData())
		{
			// stop iterating if we are waiting for file scan thread to finish
			if (fShutdownFlag && *fShutdownFlag)
				break;

			QString s = filesIter.GetKey();
			filesIter++;
			MessageRef mref;

			if (fFileScanThread->FindFile(s, mref))
			{
				MakeNodePath(s);
				uint32 enc = win->Settings()->GetEncoding(GetServerName(win->CurrentServer()), GetServerPort(win->CurrentServer()));
				String ms = (const char *) s.utf8();
				// Use encoded file attributes?
				if (enc != 0)
				{
					MessageRef packed = DeflateMessage(mref, enc, true);
					if (packed())
					{
						refScan()->AddMessage(ms, packed);
						m++;
					}
					else
					{
						// Failed to pack the message?
						refScan()->AddMessage(ms, mref);
						m++;
					}
				}
				else
				{
					refScan()->AddMessage(ms, mref);
					m++;
				}
				if (m == 20)
				{
					m = 0;
					fNet->SendMessageToSessions(refScan, 0);
					refScan = GetMessageFromPool(PR_COMMAND_SETDATA);
				}
			}
		}
		if (refScan())
		{
			if (!refScan()->IsEmpty())
			{
				fNet->SendMessageToSessions(refScan, 0);
				refScan.Reset();
			}
		}
	}

	fFileScanThread->Unlock();

	QCustomEvent *qce = new QCustomEvent(ListDone);
	if (qce)
	{
		QApplication::postEvent(fOwner, qce);
	}
	Unlock();
}