예제 #1
0
error_t ftpLogin(FtpClientContext *context, const char_t *username,
   const char_t *password, const char_t *account)
{
   error_t error;
   uint_t replyCode;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

   //Format the USER command
   sprintf(context->buffer, "USER %s\r\n", username);

   //Send the command to the server
   error = ftpSendCommand(context, context->buffer, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(FTP_REPLY_CODE_2YZ(replyCode))
      return NO_ERROR;
   else if(!FTP_REPLY_CODE_3YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Format the PASS command
   sprintf(context->buffer, "PASS %s\r\n", password);

   //Send the command to the server
   error = ftpSendCommand(context, context->buffer, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(FTP_REPLY_CODE_2YZ(replyCode))
      return NO_ERROR;
   else if(!FTP_REPLY_CODE_3YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Format the ACCT command
   sprintf(context->buffer, "ACCT %s\r\n", account);

   //Send the command to the server
   error = ftpSendCommand(context, context->buffer, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_2YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Successful processing
   return NO_ERROR;
}
예제 #2
0
error_t ftpCloseFile(FtpClientContext *context)
{
   error_t error;
   uint_t replyCode;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

   //Graceful shutdown
   socketShutdown(context->dataSocket, SOCKET_SD_BOTH);

   //Close the data socket
   socketClose(context->dataSocket);
   context->dataSocket = NULL;

   //Check the transfer status
   error = ftpSendCommand(context, NULL, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_2YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Successful processing
   return NO_ERROR;
}
예제 #3
0
error_t ftpRenameFile(FtpClientContext *context,
   const char_t *oldName, const char_t *newName)
{
   error_t error;
   uint_t replyCode;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

   //Format the RNFR command
   sprintf(context->buffer, "RNFR %s\r\n", oldName);

   //Send the command to the server
   error = ftpSendCommand(context, context->buffer, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_3YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Format the RNTO command
   sprintf(context->buffer, "RNTO %s\r\n", newName);

   //Send the command to the server
   error = ftpSendCommand(context, context->buffer, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_2YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Successful processing
   return NO_ERROR;
}
예제 #4
0
error_t ftpGetWorkingDir(FtpClientContext *context, char_t *path, size_t size)
{
   error_t error;
   size_t length;
   uint_t replyCode;
   char_t *p;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;
   //Check parameters
   if(path == NULL || size == 0)
      return ERROR_INVALID_PARAMETER;

   //Send the command to the server
   error = ftpSendCommand(context, "PWD\r\n", &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_2YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Search for the last double quote
   p = strrchr(context->buffer, '\"');
   //Failed to parse the response?
   if(!p) return ERROR_INVALID_SYNTAX;

   //Split the string
   *p = '\0';

   //Search for the first double quote
   p = strchr(context->buffer, '\"');
   //Failed to parse the response?
   if(!p) return ERROR_INVALID_SYNTAX;

   //Retrieve the length of the working directory
   length = strlen(p + 1);
   //Limit the number of characters to copy
   length = MIN(length, size - 1);

   //Copy the string
   strncpy(path, p + 1, length);
   //Properly terminate the string with a NULL character
   path[length] = '\0';

   //Successful processing
   return NO_ERROR;
}
예제 #5
0
error_t ftpChangeToParentDir(FtpClientContext *context)
{
   error_t error;
   uint_t replyCode;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

   //Send the command to the server
   error = ftpSendCommand(context, "CDUP\r\n", &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_2YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Successful processing
   return NO_ERROR;
}
예제 #6
0
error_t ftpMakeDir(FtpClientContext *context, const char_t *path)
{
   error_t error;
   uint_t replyCode;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

   //Format the MKD command
   sprintf(context->buffer, "MKD %s\r\n", path);

   //Send the command to the server
   error = ftpSendCommand(context, context->buffer, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_2YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Successful processing
   return NO_ERROR;
}
예제 #7
0
파일: ftpClient.c 프로젝트: zeuhl/myFTP
int main(int argc, char *argv[]){
		
		int mySock;
		char cmd[1024], *param,  *cp;
		char *par[3];
		int connecte = 0;
		ctxClient* client = (ctxClient*)malloc(1*sizeof(ctxClient));
		client->serverAddress = (char*)malloc(1*sizeof(char));
	
		printf("Pour voir la liste des commandes supportées tappez 'help' :\n");

		do{
			printPrompt();	
			fgets(cmd, sizeof(cmd), stdin);		
			param = strchr(cmd,' ');
			
				if (param) {
					strcpy(cp,param);
					par[0] = strtok (cp, " ");
					par[1] = strtok (cp, " ");
					printf("Par 1 : %s Par 2 %s", par[0], par[1]);
					}

			if(strcmp(cmd,"open\n\0")==0){
				if(connecte){
					printf("Vous êtes déja connecté à un serveur. \n");
				}
				else{
					printf("OK connect to server !\n");
					mySock = ftpConnect(client,"127.0.0.1", 21);
					connecte=1;
					ftpReceiveCommand(client);
					ftpSendCommand(client,"PASV");
					ftpReceiveCommand(client);
				}
			}
			else if(strcmp(cmd,"close\n\0")==0){
				ftpSendCommand(client,"close");
			}
			else if(strcmp(cmd,"cd\n\0")==0){
				ftpSendCommand(client,"cd");
			}
			else if(strcmp(cmd,"pwd\n\0")==0){
				ftpSendCommand(client,"pwd");
			}
			else if(strcmp(cmd,"get\n\0")==0){
				ftpSendCommand(client,"get");
			}
			else if(strcmp(cmd,"put\n\0")==0){
				ftpSendCommand(client,"put");
			}
			else if(strcmp(cmd,"del\n\0")==0){
				ftpSendCommand(client,"del");
			}
			else if(strcmp(cmd,"mkd\n\0")==0){
				ftpSendCommand(client,"mkd");
			}
			else if(strcmp(cmd,"rmd\n\0")==0){
				ftpSendCommand(client,"rmd");
			}
			else if(strcmp(cmd,"dir\n\0")==0){
				ftpSendCommand(client,"dir");
			}
			else if(strcmp(cmd,"help\n\0")==0){
				printHelp();
			}
			else if(strcmp(cmd,"exit\n\0")==0);
			else if(strcmp(cmd,"\n\0")==0);
			else{
				printf("Commande non reconnue \n");
			}
			
		}while(strcmp(cmd,"exit\n\0"));
	
	
    return 0;
}
예제 #8
0
error_t ftpOpenFile(FtpClientContext *context, const char_t *path, uint_t flags)
{
   error_t error;
   uint_t replyCode;
   IpAddr ipAddr;
   uint16_t port;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

   //Open data socket
   context->dataSocket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP);
   //Failed to open socket?
   if(!context->dataSocket)
      return ERROR_OPEN_FAILED;

   //Start of exception handling block
   do
   {
      //Bind the socket to a particular network interface?
      if(context->interface != NULL)
      {
         //Associate the socket with the relevant interface
         error = socketBindToInterface(context->dataSocket, context->interface);
         //Any error to report?
         if(error) break;
      }

      //Set timeout for blocking operations
      error = socketSetTimeout(context->dataSocket, FTP_CLIENT_DEFAULT_TIMEOUT);
      //Any error to report?
      if(error) break;

      //Check data transfer direction
      if(flags & (FTP_FOR_WRITING | FTP_FOR_APPENDING))
      {
         //Maximize transmission throughput by using a large buffer
         error = socketSetTxBufferSize(context->dataSocket,
            FTP_CLIENT_SOCKET_MAX_TX_BUFFER_SIZE);
         //Any error to report?
         if(error) break;

         //Use a small buffer for the reception path
         error = socketSetRxBufferSize(context->dataSocket,
            FTP_CLIENT_SOCKET_MIN_RX_BUFFER_SIZE);
         //Any error to report?
         if(error) break;
      }
      else
      {
         //Use a small buffer for the transmission path
         error = socketSetTxBufferSize(context->dataSocket,
            FTP_CLIENT_SOCKET_MIN_TX_BUFFER_SIZE);
         //Any error to report?
         if(error) break;

         //Maximize reception throughput by using a large buffer
         error = socketSetRxBufferSize(context->dataSocket,
            FTP_CLIENT_SOCKET_MAX_RX_BUFFER_SIZE);
         //Any error to report?
         if(error) break;
      }

      //Set representation type
      if(flags & FTP_TEXT_TYPE)
      {
         //Use ASCII type
         error = ftpSetType(context, 'A');
         //Any error to report?
         if(error) break;
      }
      else
      {
         //Use image type
         error = ftpSetType(context, 'I');
         //Any error to report?
         if(error) break;
      }

      //Check transfer mode
      if(!context->passiveMode)
      {
         //Place the data socket in the listening state
         error = socketListen(context->dataSocket, 1);
         //Any error to report?
         if(error) break;

         //Retrieve local IP address
         error = socketGetLocalAddr(context->controlSocket, &ipAddr, NULL);
         //Any error to report?
         if(error) break;

         //Retrieve local port number
         error = socketGetLocalAddr(context->dataSocket, NULL, &port);
         //Any error to report?
         if(error) break;

         //Set the port to be used in data connection
         error = ftpSetPort(context, &ipAddr, port);
         //Any error to report?
         if(error) break;
      }
      else
      {
         //Enter passive mode
         error = ftpSetPassiveMode(context, &port);
         //Any error to report?
         if(error) break;

         //Establish data connection
         error = socketConnect(context->dataSocket, &context->serverAddr, port);
         //Connection to server failed?
         if(error) break;
      }

      //Format the command
      if(flags & FTP_FOR_WRITING)
         sprintf(context->buffer, "STOR %s\r\n", path);
      else if(flags & FTP_FOR_APPENDING)
         sprintf(context->buffer, "APPE %s\r\n", path);
      else
         sprintf(context->buffer, "RETR %s\r\n", path);

      //Send the command to the server
      error = ftpSendCommand(context, context->buffer, &replyCode);
      //Any error to report?
      if(error) break;

      //Check FTP response code
      if(!FTP_REPLY_CODE_1YZ(replyCode))
      {
         //Report an error
         error = ERROR_UNEXPECTED_RESPONSE;
         break;
      }

      //Check transfer mode
      if(!context->passiveMode)
      {
         //Wait for the server to connect back to the client's data port
         Socket *socket = socketAccept(context->dataSocket, NULL, NULL);

         //No connection request?
         if(!socket)
         {
            //Report an error
            error = ERROR_FAILURE;
            break;
         }

         //Close the listening socket
         socketClose(context->dataSocket);
         //Save socket handle
         context->dataSocket = socket;

         //Set timeout for blocking operations
         error = socketSetTimeout(context->dataSocket, FTP_CLIENT_DEFAULT_TIMEOUT);
         //Any error to report?
         if(error) break;
      }

      //End of exception handling block
   } while(0);

   //Any error to report?
   if(error)
   {
      //Clean up side effects
      socketClose(context->dataSocket);
      context->dataSocket = NULL;
   }

   //Return status code
   return error;
}
예제 #9
0
error_t ftpConnect(FtpClientContext *context, NetInterface *interface,
   IpAddr *serverAddr, uint16_t serverPort, uint_t flags)
{
   error_t error;
   uint_t replyCode;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

   //Clear context
   memset(context, 0, sizeof(FtpClientContext));

   //Underlying network interface
   context->interface = interface;
   //Save the IP address of the FTP server
   context->serverAddr = *serverAddr;

   //Use passive mode?
   if(flags & FTP_PASSIVE_MODE)
      context->passiveMode = TRUE;

   //Open control socket
   context->controlSocket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP);
   //Failed to open socket?
   if(!context->controlSocket)
      return ERROR_OPEN_FAILED;

   //Start of exception handling block
   do
   {
      //Bind the socket to a particular network interface?
      if(context->interface != NULL)
      {
         //Associate the socket with the relevant interface
         error = socketBindToInterface(context->controlSocket, context->interface);
         //Any error to report?
         if(error) break;
      }

      //Set timeout for blocking operations
      error = socketSetTimeout(context->controlSocket, FTP_CLIENT_DEFAULT_TIMEOUT);
      //Any error to report?
      if(error) break;

      //Specify the size of the send buffer
      error = socketSetTxBufferSize(context->controlSocket,
         FTP_CLIENT_SOCKET_MIN_TX_BUFFER_SIZE);
      //Any error to report?
      if(error) break;

      //Specify the size of the receive buffer
      error = socketSetRxBufferSize(context->controlSocket,
         FTP_CLIENT_SOCKET_MIN_RX_BUFFER_SIZE);
      //Any error to report?
      if(error) break;

      //Connect to the FTP server
      error = socketConnect(context->controlSocket, serverAddr, serverPort);
      //Connection to server failed?
      if(error) break;

      //Wait for the connection greeting reply
      error = ftpSendCommand(context, NULL, &replyCode);
      //Any communication error to report?
      if(error) break;

      //Check FTP response code
      if(!FTP_REPLY_CODE_2YZ(replyCode))
         error = ERROR_UNEXPECTED_RESPONSE;

      //End of exception handling block
   } while(0);

   //Any error to report?
   if(error)
   {
      //Clean up side effects
      socketClose(context->controlSocket);
      context->controlSocket = NULL;
   }

   //Return status code
   return error;
}
예제 #10
0
error_t ftpSetPassiveMode(FtpClientContext *context, uint16_t *port)
{
   error_t error;
   uint_t replyCode;
   char_t delimiter;
   char_t *p;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

#if (IPV4_SUPPORT == ENABLED)
   //IPv4 FTP server?
   if(context->serverAddr.length == sizeof(Ipv4Addr))
   {
      //Send the command to the server
      error = ftpSendCommand(context, "PASV\r\n", &replyCode);
      //Any error to report?
      if(error) return error;

      //Check FTP response code
      if(!FTP_REPLY_CODE_2YZ(replyCode))
         return ERROR_UNEXPECTED_RESPONSE;

      //Delimiter character
      delimiter = ',';

      //Retrieve the low byte of the port number
      p = strrchr(context->buffer, delimiter);
      //Failed to parse the response?
      if(!p) return ERROR_INVALID_SYNTAX;

      //Convert the resulting string
      *port = atoi(p + 1);
      //Split the string
      *p = '\0';

      //Retrieve the high byte of the port number
      p = strrchr(context->buffer, delimiter);
      //Failed to parse the response?
      if(!p) return ERROR_INVALID_SYNTAX;

      //Convert the resulting string
      *port |= atoi(p + 1) << 8;
   }
   else
#endif
#if (IPV6_SUPPORT == ENABLED)
   //IPv6 FTP server?
   if(context->serverAddr.length == sizeof(Ipv6Addr))
   {
      //Send the command to the server
      error = ftpSendCommand(context, "EPSV\r\n", &replyCode);
      //Any error to report?
      if(error) return error;

      //Check FTP response code
      if(!FTP_REPLY_CODE_2YZ(replyCode))
         return ERROR_UNEXPECTED_RESPONSE;

      //Search for the opening parenthesis
      p = strrchr(context->buffer, '(');
      //Failed to parse the response?
      if(!p || p[1] == '\0') return ERROR_INVALID_SYNTAX;

      //Retrieve the delimiter character
      delimiter = p[1];

      //Search for the last delimiter character
      p = strrchr(context->buffer, delimiter);
      //Failed to parse the response?
      if(!p) return ERROR_INVALID_SYNTAX;

      //Split the string
      *p = '\0';

      //Search for the last but one delimiter character
      p = strrchr(context->buffer, delimiter);
      //Failed to parse the response?
      if(!p) return ERROR_INVALID_SYNTAX;

      //Convert the resulting string
      *port = atoi(p + 1);
   }
   else
#endif
   //Invalid IP address?
   {
      //Report an error
      return ERROR_INVALID_ADDRESS;
   }

   //Successful processing
   return NO_ERROR;
}
예제 #11
0
error_t ftpSetPort(FtpClientContext *context, const IpAddr *ipAddr, uint16_t port)
{
   error_t error;
   uint_t replyCode;
   char_t *p;

   //Invalid context?
   if(context == NULL)
      return ERROR_INVALID_PARAMETER;

#if (IPV4_SUPPORT == ENABLED)
   //IPv4 FTP client?
   if(ipAddr->length == sizeof(Ipv4Addr))
   {
      //Format the PORT command
      strcpy(context->buffer, "PORT ");

      //Append host address
      ipv4AddrToString(ipAddr->ipv4Addr, context->buffer + 5);

      //Parse the resulting string
      for(p = context->buffer; *p != '\0'; p++)
      {
         //Change dots to commas
         if(*p == '.') *p = ',';
      }

      //Append port number
      sprintf(p, ",%" PRIu8 ",%" PRIu8 "\r\n", MSB(port), LSB(port));
   }
   else
#endif
#if (IPV6_SUPPORT == ENABLED)
   //IPv6 FTP client?
   if(ipAddr->length == sizeof(Ipv6Addr))
   {
      //Format the EPRT command
      strcpy(context->buffer, "EPRT |2|");

      //Append host address
      ipv6AddrToString(&ipAddr->ipv6Addr, context->buffer + 8);

      //Point to the end of the resulting string
      p = context->buffer + strlen(context->buffer);
      //Append port number
      sprintf(p, "|%" PRIu16 "|\r\n", port);
   }
   else
#endif
   //Invalid IP address?
   {
      //Report an error
      return ERROR_INVALID_ADDRESS;
   }

   //Send the command to the server
   error = ftpSendCommand(context, context->buffer, &replyCode);
   //Any error to report?
   if(error) return error;

   //Check FTP response code
   if(!FTP_REPLY_CODE_2YZ(replyCode))
      return ERROR_UNEXPECTED_RESPONSE;

   //Successful processing
   return NO_ERROR;
}