Example #1
0
static ftRequest_t* FT_CreateRequest(const char* address, const char* url)
{
	void* buf;
	
	ftRequest_t* request;
	
	request = Z_Malloc(sizeof(ftRequest_t));
	if(request == NULL)
		return NULL;
	
	Com_Memset(request, 0, sizeof(ftRequest_t));
	request->lock = qtrue;
	request->finallen = -1;
	request->socket = -1;
	request->transfersocket = -1;
	
	if(address != NULL)
	{
		Q_strncpyz(request->address, address, sizeof(request->address));
		/* Open the connection */
		request->socket = NET_TcpClientConnect(request->address);
	
	    if(request->socket < 0)
		{	
			request->socket = -1;
			FT_FreeRequest(request);
			return NULL;
		}
		
	}

	buf = Z_Malloc(INITIAL_BUFFERLEN);
	if( buf == NULL)
	{
		FT_FreeRequest(request);
		return NULL;
	}
	MSG_Init(&request->recvmsg, buf, INITIAL_BUFFERLEN);
	
	buf = Z_Malloc(INITIAL_BUFFERLEN);
	if( buf == NULL)
	{
		FT_FreeRequest(request);
		return NULL;
	}
	MSG_Init(&request->sendmsg, buf, INITIAL_BUFFERLEN);
	
	if(url != NULL)
	{
		Q_strncpyz(request->url, url, sizeof(request->url));
	}
	
	request->startTime = Sys_Milliseconds();
	return request;
	
}
qboolean PHandler_TcpConnect(int pID, const char* remote, int connection)
{
    if(pluginFunctions.plugins[pID].sockets[connection].sock < 1){
        pluginFunctions.plugins[pID].sockets[connection].sock = NET_TcpClientConnect( remote );

        if(pluginFunctions.plugins[pID].sockets[connection].sock < 1){
            Com_Printf("Plugins: Notice! Error connecting to server: %s for plugin #%d!\n", remote, pID);
            return qfalse;
        }
        NET_StringToAdr(remote, &pluginFunctions.plugins[pID].sockets[connection].remote, NA_UNSPEC);
        return qtrue;
    }
    Com_PrintError("Plugin_TcpConnect: Connection id %d is already in use for plugin #%d!\n",connection ,pID );

    return qfalse;
}
Example #3
0
static int FTP_SendReceiveData(ftRequest_t* request)
{
	char* line;
	char command[MAX_STRING_CHARS];
	int status, bytes;
	byte* buf;
	netadr_t pasvadr;
	char stringlinebuf[MAX_STRING_CHARS];

	status = FT_ReceiveData(request);
	
	if (status == -1 && request->stage < 9999) {
		return -1;
	}
	if(status == 0 && request->stage < 9999)
	{
		status = FT_SendData(request);
	}
	if (status == -1 && request->stage < 9999) {
		return -1;
	}
	
	while ((line = MSG_ReadStringLine(&request->recvmsg, stringlinebuf, sizeof(stringlinebuf))) && line[0] != '\0' )
	{	
		if(isNumeric(line, 0) == qfalse)
			continue;
		
		request->code = atoi(line);
		
		if(request->stage > 60)
			Com_DPrintf("\n");
	
		Com_DPrintf("Response Code = %d\n", request->code);
		
		if (request->stage < 0)
		{
			continue;
		}
		
		switch (request->code)
		{
				
			case 220:
				if(request->stage == 0)
				{
					// Initial OK response received /
					Com_DPrintf("FTP_SendReceiveData: Inital OK response received\n");
					request->stage = 1;
				}else {
					Com_PrintWarning("\nFTP_SendReceiveData: Received: %s - Should not happen!\n", line);
				}
				break;
			case 202:
				if(request->stage < 21 && request->stage > 10)
				{
					request->stage = 21;
				}else {
					Com_Printf("\nFTP_SendReceiveData: Received unexpected response: %s - Will abort!\n", line);
					request->stage = -20;
				}
				break;								
			case 331:
				if(request->stage == 10)
				{
					Com_DPrintf("FTP_SendReceiveData: Need Password\n");
					request->stage = 11;
					
				}else if(request->stage == 16){
					Com_DPrintf("FTP_SendReceiveData: Need Password\n");
					request->stage = 17;
				}else {
					Com_Printf("FTP_SendReceiveData: Received unexpected response: %s - Will abort!\n", line);
					request->stage = -20;
				}
				break;
			case 332:
				if(request->stage == 10 || request->stage == 12)
				{
					Com_DPrintf("FTP_SendReceiveData: Need Account\n");
					request->stage = 15;
				}else {
					Com_Printf("\nFTP_SendReceiveData: Received unexpected response: %s - Will abort!\n", line);
					request->stage = -20;
				}
				break;				
			case 230:
				if (request->stage <= 20)
				{
					Com_DPrintf("FTP_SendReceiveData: Logged in OK\n");
					request->stage = 21;
				}else {
					Com_Printf("\nFTP_SendReceiveData: Received unexpected response: %s - Will abort!\n", line);
					request->stage = -20;
				}
				break;
			case 227:
				if(request->stage == 36)
				{
					FTP_GetPassiveAddress(line, &pasvadr);
					if(pasvadr.type == NA_IP)
					{
						Com_DPrintf("FTP_SendReceiveData: Entering Passive Mode at %s OK\n", NET_AdrToString(&pasvadr));
						request->transfersocket = NET_TcpClientConnect(NET_AdrToString(&pasvadr));
						if(request->transfersocket < 0)
						{	
							request->transfersocket = -1;
							return -1;
						}
						request->stage = 41;
					}else {
						Com_PrintWarning("FTP_SendReceiveData: Couldn't read the address/port of passive mode response\n");
						return -1;
					}
	
				}else {
					Com_Printf("\nFTP_SendReceiveData: Received unexpected response: %s - Will abort!\n", line);
					request->stage = -20;
				}
				break;
			case 229:
				if(request->stage == 32)
				{
					FTP_GetExtendedPassiveAddress(line, request->address, &pasvadr);
					if(pasvadr.type == NA_IP || pasvadr.type == NA_IP6)
					{
						Com_DPrintf("FTP_SendReceiveData: Entering Extended Passive Mode at %s OK\n", NET_AdrToString(&pasvadr));
						request->transfersocket = NET_TcpClientConnect(NET_AdrToString(&pasvadr));
						if(request->transfersocket < 0)
						{	
							request->transfersocket = -1;
							return -1;
						}
						request->stage = 41;
					}else {
						Com_PrintWarning("FTP_SendReceiveData: Couldn't read the address/port of passive mode response\n");
						return -1;
					}
					
				}else {
					Com_Printf("\nFTP_SendReceiveData: Received unexpected response: %s - Will abort!\n", line);
					request->stage = -20;
				}
				break;			
			case 213:
				if(request->stage == 50)
				{	
					bytes = atoi(&line[4]);
					Com_DPrintf("FTP_SendReceiveData: Requested file will have %d bytes\n", bytes);
					if(bytes < 1 || bytes > 1024*1024*1024)
					{
						Com_PrintWarning("FTP_SendReceiveData: Requested file would exceed %d bytes. Will not download!\n", 1024*1024*1024);
				
					}
					buf = Z_Malloc(bytes);
					if( buf == NULL)
					{
						Com_PrintWarning("FTP_SendReceiveData: Failed to allocate %d bytes for download file!\n", bytes);
						return -1;
					}
					MSG_Init(&request->transfermsg, buf, bytes);
					request->stage = 51;
				}
				break;
			case 150:
			case 125:
				if (request->stage == 60) {
					request->stage = 61;
					Com_DPrintf("FTP_SendReceiveData: Begin File Transfer\n");
				}
				break;
			case 226:
				/* File transfer is completed from the servers view */
				if(request->stage < 9999) 
					request->stage = 9999;
				break;
			case 221:
				if(request->stage < 10000)
				{
					Com_Printf("\nThe FTP server closed the control connection before the transfer was completed!\n");
					request->stage = -1;
				}
				break;
			case 228:
				Com_Printf( "\nLong Passive Mode not supported and not requested!\n" );
				request->stage = -20;
				break;
				
			case 120:
				Com_Printf( "The FTP server is not ready at the moment!\n" );
				request->stage = -20;
				break;
			case 231:
				if(request->stage < 10000)
				{
					Com_Printf("\nThe FTP server logged us out before the transfer was completed!\n");
					request->stage = -20;
				}
				break;
			case 350:
				if(request->stage < 10000)
				{
					Com_Printf("\nThe FTP server returned \'%s\' before the transfer was completed. Must not happen!\n", line);
					request->stage = -20;
				}
				break;
			case 421:
				request->stage = -1;
				break;
			case 500:
			case 501:
			case 502:
			case 503:
				if (request->stage == 32) {
					request->stage = 35;
					Com_DPrintf("FTP_SendReceiveData: Command EPSV is not implemented on FTP server. Trying PASV...\n");
					break;
				}else if (request->stage == 36) {
					Com_Printf("FTP_SendReceiveData: FTP Server does not support passive mode. Request failed!\n");
					request->stage = -10;
				} 
			default:
				if (request->code >= 200 && request->code < 300 && request->stage >= 30){
					Com_DPrintf("\n");
					Com_DPrintf("FTP_SendReceiveData: %s\n", line);					
					request->stage ++;
					break;
				}else if (request->code >= 400) {
					Com_Printf("\nThe FTP server connection got ended with the message: %s\n", line);
					request->stage = -20;
				}
				break;
		}
	}
	
	
	switch(request->stage)
	{
		case 1:
			/* Waiting for OK response code (220) */
			Com_sprintf(command, sizeof(command), "USER %s\r\n", "anonymous");
			FT_AddData(request, command, strlen(command));
			request->stage = 10;
			break;
		case 11:
			Com_sprintf(command, sizeof(command), "PASS %s\r\n", "*****@*****.**");
			FT_AddData(request, command, strlen(command));
			request->stage = 12;
			break;
		case 15:
			Com_sprintf(command, sizeof(command), "ACCT %s\r\n", "nil");
			FT_AddData(request, command, strlen(command));
			request->stage = 16;
			break;
		case 17:
			Com_sprintf(command, sizeof(command), "PASS %s\r\n", "*****@*****.**");
			FT_AddData(request, command, strlen(command));
			request->stage = 20;
			break;			
		case 21:
			Com_sprintf(command, sizeof(command), "TYPE I\r\n");
			FT_AddData(request, command, strlen(command));
			request->stage = 30;
			break;
		case 31:
			Com_sprintf(command, sizeof(command), "EPSV\r\n");
			FT_AddData(request, command, strlen(command));
			request->stage = 32;
			break;
		case 35:
			Com_sprintf(command, sizeof(command), "PASV\r\n");
			FT_AddData(request, command, strlen(command));
			request->stage = 36;
			break;
		case 41:
			Com_sprintf(command, sizeof(command), "SIZE %s\r\n", request->url);
			FT_AddData(request, command, strlen(command));
			request->stage = 50;
			break;
		case 51:
			Com_sprintf(command, sizeof(command), "RETR %s\r\n", request->url);
			FT_AddData(request, command, strlen(command));
			request->stage = 60;
			break;			

		case 61:
			/* Receive new bytes */
			request->transferactive = qtrue;
			status = NET_ReceiveData(request->transfersocket, &request->transfermsg);
			
			if (status == -1){

				request->transfersocket = -1;
				
			}else if(status == -2){
				
				request->transfersocket = -1;			
			}
			if(request->transfermsg.cursize == request->transfermsg.maxsize && request->transfermsg.maxsize != 0)
			{
				/* Comple file retrived */
				request->stage = 9999;
				break;
			}else if(request->transfersocket == -1){
				request->stage = -20;
			}
			break;
			
		case 9999:
			
			status = -1;
			request->transferactive = qfalse;
			
			if(request->transfersocket >= 0)
				status = NET_ReceiveData(request->transfersocket, &request->transfermsg);
			
			if (status == -1 || status == -2){
				request->transfersocket = -1;
			}
			if(request->transfermsg.cursize == request->transfermsg.maxsize && request->transfermsg.maxsize != 0)
			{
				/* Comple file retrived */
				Com_sprintf(command, sizeof(command), "QUIT\r\n");
				FT_AddData(request, command, strlen(command));
				request->stage = 10000;
				break;
			}else {
				Com_Printf("\nThe FTP server closed the data connection before the transfer was completed!\n");
				request->stage = -20;
				break;
			}
		case -20:
			request->transferactive = qfalse;
			Com_Printf("\nFTP File Transfer has failed!\n");
		case -10:
			request->transferactive = qfalse;
			if(request->socket >= 0 )
			{
				Com_sprintf(command, sizeof(command), "QUIT\r\n", request->url);
				FT_AddData(request, command, strlen(command));
			}
			request->stage = -1;
			break;

		case -1:
			Com_Printf("\n");
			return -1;
			break;
			
		case 10000:
			request->transferactive = qfalse;

			if(request->socket >= 0)
			{
				NET_TcpCloseSocket(request->socket);
				request->socket = -1;
			}
			if(request->transfersocket >= 0)
			{
				NET_TcpCloseSocket(request->transfersocket);
				request->transfersocket = -1;
			}
			if(request->recvmsg.data != NULL)
			{
				Z_Free(request->recvmsg.data);
				request->recvmsg.data = NULL;
			}
			if(request->transfermsg.data == NULL)
			{
				request->stage = -1;
				Com_PrintError("\nReceived complete message but message buffer is NULL!\n");
				break;
			}
			Com_Memcpy(&request->recvmsg, &request->transfermsg, sizeof(msg_t));
			Com_Memset(&request->transfermsg, 0, sizeof(msg_t));
			request->contentLength = request->recvmsg.cursize;
			request->headerLength = 0;
			request->stage = 10001;
			request->code = 200;
			Q_strncpyz(request->status, "OK", sizeof(request->status));
			break;
		case 10001:
			Com_Printf("\n");
			return 1;
		default:
			return 0;
	}
	return 0;
	
}