3 * @author nicolas.brulez@parrot.com
5 * Copyright Parrot SA. 2011
8 #include <utils/ardrone_ftp.h>
13 #include <sys/types.h>
17 #include <VP_Os/vp_os_thread.h>
18 #include <VP_Os/vp_os_malloc.h>
19 #include <VP_Os/vp_os_signal.h>
25 // All following macros MUST be defined !
26 // To activate, define to (1)
27 // To deactivate, define to (0)
29 #ifdef DEBUG // Debug options
30 #define _FTP_DEBUG (1) // Common debug informations
31 #define _FTP_VERBOSE (0) // Extended debug information (many outputs on ftpList)
32 #define _FTP_ERRORS_PRINT (1) // Display of error messages
33 #else // Release options
34 #define _FTP_DEBUG (0)
35 #define _FTP_VERBOSE (0)
36 #define _FTP_ERRORS_PRINT (1)
39 #define FTP_PREFIX "FTP : "
41 /* LOCAL PRINT MACROS */
44 #define FTP_ERROR(...) \
47 fprintf (stderr, "Error in function %s at line %d : ", __FUNCTION__, __LINE__); \
48 fprintf (stderr, __VA_ARGS__); \
49 char errorBuffer [512] = {0}; \
50 snprintf (errorBuffer, sizeof (errorBuffer)-1, __VA_ARGS__); \
51 FTPlastErrorMessageSize = strlen (errorBuffer) + 1; \
52 FTPlastErrorMessage = vp_os_realloc (FTPlastErrorMessage, FTPlastErrorMessageSize); \
53 if (NULL != FTPlastErrorMessage) \
55 strncpy (FTPlastErrorMessage, errorBuffer, FTPlastErrorMessageSize); \
59 #define FTP_ERROR(...) \
62 char errorBuffer [512] = {0}; \
63 snprintf (errorBuffer, sizeof (errorBuffer)-1, __VA_ARGS__); \
64 FTPlastErrorMessageSize = strlen (errorBuffer) + 1; \
65 FTPlastErrorMessage = vp_os_realloc (FTPlastErrorMessage, FTPlastErrorMessageSize); \
66 if (NULL != FTPlastErrorMessage) \
68 strncpy (FTPlastErrorMessage, errorBuffer, FTPlastErrorMessageSize); \
74 #define FTP_DEBUG(...) \
77 printf ("Debug from function %s at line %d : ", __FUNCTION__, __LINE__); \
78 printf (__VA_ARGS__); \
81 #define FTP_DEBUG(...)
85 #define FTP_PRINT(...) \
88 printf (FTP_PREFIX); \
89 printf (__VA_ARGS__); \
92 #define FTP_PRINT(...)
98 #define MAX_SIZE_MSG 32768
100 #define IP_STRING_SIZE 16 // IP strings goes from 8 ("w.x.y.z\0") to 16 ("www.xxx.yyy.zzz\0") chars
101 #define LIST_BUFFER_BLOCKSIZE 1024
102 #define FILE_NAME_MAX_SIZE 512
106 /* Total socket timeout : SOCK_TO_SEC + SOCK_TO_USEC */
107 #define SOCK_TO_SEC 1 // Socket timeout (seconds)
108 #define SOCK_TO_USEC 0 // Socket timeout (useconds)
110 /* GLOBAL ERROR MESSAGE STRING */
111 char *FTPlastErrorMessage = NULL;
112 int FTPlastErrorMessageSize = 0;
114 /* THREAD STRUCTURES */
116 typedef struct _ftp_list_param_s _ftp_list_param;
117 typedef struct _ftp_get_param_s _ftp_get_param;
118 typedef struct _ftp_put_param_s _ftp_put_param;
120 struct _ftp_put_param_s
123 char localName [FILE_NAME_MAX_SIZE];
124 char remoteName [FILE_NAME_MAX_SIZE];
126 ftp_callback callback;
130 struct _ftp_get_param_s
133 char localName [FILE_NAME_MAX_SIZE];
134 char remoteName [FILE_NAME_MAX_SIZE];
136 ftp_callback callback;
140 struct _ftp_list_param_s
145 ftp_callback callback;
148 /* LOCAL FUNCTIONS PROTOTYPES */
149 void emptyCallback (_ftp_status status, void *arg, _ftp_t *callingFtp);
150 _ftp_status waitFor226Answer (_ftp_t *ftp);
151 int setSockTimeout (int socket, int timeoutSec, int timeoutUsec);
152 _ftp_status goToBinaryMode (_ftp_t *ftp);
153 void flushFtp (_ftp_t *ftp);
154 int getFileSize (_ftp_t *ftp, const char *distPath);
155 int getLocalFileSize (const char *localPath);
156 int getResponseCode (const char *response);
157 _ftp_status getPassiveIpAndPort (const char *response, char *ip, int *port, int ipLen);
158 _ftp_status ftpTransfert (_ftp_t *ftp, const char *message, char *answer, int answSize);
159 _ftp_status ftpSend (_ftp_t *ftp, const char *message);
160 _ftp_status ftpRecv (_ftp_t *ftp, char *answer, int answSize);
161 DEFINE_THREAD_ROUTINE (ftpGet, param);
162 DEFINE_THREAD_ROUTINE (ftpPut, param);
163 DEFINE_THREAD_ROUTINE (ftpList, param);
165 /* GLOBAL CALLBACK RESULT */
166 _ftp_status lastStatusFromEmptyCallback = FTP_FAIL;
167 char *lastFileListFromEmptyCallback = NULL;
169 /* FUNCTIONS IMPLEMENTATION */
172 emptyCallback (_ftp_status status, void *arg, _ftp_t *callingFtp)
174 FTP_PRINT ("Called with status %d\n", status);
176 if (FTP_PROGRESS == status)
178 FTP_PRINT ("Trying float arg : %f\n", (NULL != arg) ? *(float *)arg : -1.0);
181 lastStatusFromEmptyCallback = status;
182 if(FTP_SUCCESS == status && NULL != arg)
184 lastFileListFromEmptyCallback = (char *)arg;
188 #define FTP_MAX_NUM_RETRIES 5
190 waitFor226Answer (_ftp_t *ftp)
192 char srvMsg[MAX_SIZE_MSG] = {0};
194 int numretries = FTP_MAX_NUM_RETRIES;
196 _ftp_status ftp_result = FTP_SUCCESS;
197 while (226 != repCode && 0 < numretries)
199 ftp_result = ftpRecv (ftp, srvMsg, MAX_SIZE_MSG-1);
200 if (FTP_FAILED (ftp_result))
204 repCode = getResponseCode (srvMsg);
210 setSockTimeout (int socket, int timeoutSec, int timeoutUsec)
213 int winTO = (1000 * timeoutSec) + (timeoutUsec / 1000);
215 struct timeval posixTO;
216 posixTO.tv_sec = timeoutSec;
217 posixTO.tv_usec = timeoutUsec;
220 if (0 > setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO,
222 (const char *)&winTO, sizeof (winTO)
224 (const char *)&posixTO, sizeof (posixTO)
228 FTP_ERROR ("Unable to set recv timeout\n");
232 if (0 > setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO,
234 (const char *)&winTO, sizeof (winTO)
236 (const char *)&posixTO, sizeof (posixTO)
240 FTP_ERROR ("Unable to set send timeout\n");
247 goToBinaryMode (_ftp_t *ftp)
249 char ftpAnswer[256] = {0};
250 _ftp_status ftp_result = ftpTransfert (ftp, "TYPE I\r\n\0", ftpAnswer, 255);
251 if (FTP_FAILED (ftp_result))
253 FTP_ERROR ("Unable to go to binary mode\n");
259 flushFtp (_ftp_t *ftp)
261 FTP_DEBUG ("Starting flush\n");
264 int flushedBytes = 0;
265 VP_COM_SOCKET_BLOCKING_OPTIONS oldOptions = ftp->socket->block;
266 ftp->socket->block = VP_COM_DONTWAIT;
267 C_RESULT vp_result = ftp->readSock (ftp->socket, (int8_t *)&c, &bytes);
268 while (0 < bytes && VP_SUCCEEDED (vp_result))
274 vp_result = ftp->readSock (ftp->socket, (int8_t *)&c, &bytes);
276 FTP_DEBUG ("Flushed %d bytes\n", flushedBytes);
277 ftp->socket->block = oldOptions;
281 getFileSize (_ftp_t *ftp, const char *distPath)
283 char ftpCommand[256] = {0};
284 snprintf (ftpCommand, sizeof (ftpCommand)-1, "SIZE %s\r\n", distPath);
285 char ftpAnswer[256] = {0};
286 _ftp_status ftp_result = ftpTransfert (ftp, ftpCommand, ftpAnswer, sizeof (ftpAnswer)-1);
287 if (FTP_FAILED (ftp_result))
289 FTP_ERROR ("Unable to get file size\n");
294 sscanf (ftpAnswer, "%d %d", &repCode, &size);
299 getLocalFileSize (const char *localPath)
301 FILE *localFile = fopen (localPath, "r");
302 if (NULL == localFile)
304 FTP_DEBUG ("File %s does not exist\n", localPath);
307 fseek (localFile, 0, SEEK_END);
308 int size = (int)ftell (localFile);
309 FTP_DEBUG ("Size of file %s : %d o\n", localPath, size);
315 getResponseCode (const char *response)
318 sscanf (response, "%d", &retVal);
323 getPassiveIpAndPort (const char *response, char *ip, int *port, int ipLen)
325 int ip1, ip2, ip3, ip4, port1, port2;
326 int indexOfFirstIpField = 0;
328 int maxIndex = strlen (response);
329 while (indexOfFirstIpField < maxIndex && '(' != atIndex)
331 atIndex = response[indexOfFirstIpField++];
333 int numread = sscanf (&response[indexOfFirstIpField], "%d,%d,%d,%d,%d,%d)", &ip1, &ip2, &ip3, &ip4, &port1, &port2);
334 _ftp_status result = FTP_SUCCESS;
337 snprintf (ip, ipLen-1, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
338 *port = 256 * port1 + port2;
339 FTP_DEBUG ("IP : %s | Port : %d\n", ip, *port);
349 ftpTransfert (_ftp_t *ftp, const char *message, char *answer, int answSize)
352 _ftp_status ftp_result = ftpSend (ftp, message);
353 if (FTP_FAILED (ftp_result))
357 return ftpRecv (ftp, answer, answSize);
361 ftpSend (_ftp_t *ftp, const char *message)
365 FTP_ERROR ("FTP not open\n");
368 FTP_DEBUG ("Sending %sto FTP at %s:%d\n", message, ftp->socket->serverHost, ftp->socket->port);
370 int bytes = strlen (message);
371 C_RESULT vp_result = ftp->writeSock (ftp->socket, (int8_t *)message, &bytes);
372 if (VP_FAILED (vp_result))
374 FTP_ERROR ("Error while sending data\n");
379 FTP_ERROR ("Unable to send data\n");
386 ftpRecv (_ftp_t *ftp, char *answer, int answSize)
390 FTP_ERROR ("FTP not open\n");
394 vp_os_memset (answer, 0x0, answSize);
399 C_RESULT vp_result = ftp->readSock (ftp->socket, (int8_t *)(&answer [index]), &bytes);
400 if (VP_FAILED (vp_result))
402 FTP_ERROR ("Error while reading data\n");
407 FTP_ERROR ("Recv timeout\n");
411 while (index < answSize && '\n' != answer [index++]);
413 FTP_DEBUG ("Answer:\n<---START--->\n%s\n<---END--->\n", answer);
418 ftpClose (_ftp_t **ftp)
420 FTP_DEBUG ("Closing ftp\n");
421 _ftp_status retVal = FTP_FAIL;
424 FTP_DEBUG ("Not null ftp\n");
425 if (NULL != (*ftp)->socket)
427 FTP_DEBUG ("Not null socket\n");
428 if (1 == (*ftp)->connected)
430 if (FTP_SUCCESS == ftpAbort ((*ftp))) // An operation was in progress, abort and let time to cleanup.
432 usleep (100000); // 100ms
434 ftpSend ((*ftp), "QUIT\r\n\0");
435 (*ftp)->connected = 0;
437 vp_com_close_socket ((*ftp)->socket);
438 vp_os_free ((*ftp)->socket);
439 (*ftp)->socket = NULL;
440 retVal = FTP_SUCCESS;
449 ftpConnectFromName (const char *name, int port, const char *username, const char *password, _ftp_status *status)
451 struct hostent *hostent = gethostbyname(name);
452 return ftpConnect(inet_ntoa( *( struct in_addr*)( hostent->h_addr)), port, username, password, status);
456 ftpConnect (const char *ip, int port, const char *username, const char *password, _ftp_status *status)
463 FTP_ERROR ("Must not pass NULL pointers to ftpConnect\n");
464 if (NULL != status) { *status = FTP_FAIL; }
467 int isAnonymous = ((0 == strcmp (username, "anonymous")) || (0 == strcmp (username, ""))) ? 1 : 0;
468 if (1 == isAnonymous)
470 FTP_DEBUG ("Connecting to %s:%d, anonymous\n", ip, port);
474 FTP_DEBUG ("Connecting to %s:%d, USER = %s, Password = %s\n", ip, port, username, password);
478 _ftp_t *retFtp = vp_os_malloc (sizeof (_ftp_t));
481 FTP_ERROR ("Unable to allocate a ftp structure\n");
484 retFtp->socket = vp_os_malloc (sizeof (vp_com_socket_t));
485 if (NULL == retFtp->socket)
487 FTP_ERROR ("Unable to allocate socket filed of the ftp structure\n");
492 retFtp->connected = 0;
494 retFtp->socket->type = VP_COM_CLIENT;
495 retFtp->socket->protocol = VP_COM_TCP;
496 retFtp->socket->port = port;
497 strncpy (retFtp->socket->serverHost, ip, VP_COM_NAME_MAXSIZE-1);
498 retFtp->socket->is_multicast = 0;
499 retFtp->socket->block = VP_COM_DEFAULT;
501 C_RESULT vp_result = vp_com_open_socket (retFtp->socket, &(retFtp->readSock), &(retFtp->writeSock));
502 if (VP_FAILED (vp_result))
504 FTP_ERROR ("Unable to connect\n");
509 int result = setSockTimeout ((int)retFtp->socket->priv, SOCK_TO_SEC, SOCK_TO_USEC);
512 FTP_ERROR ("Unable to set socket timeout\n");
517 char srvMsg[MAX_SIZE_MSG] = {0};
518 if (FTP_FAILED (ftpRecv (retFtp, srvMsg, MAX_SIZE_MSG-1)))
520 FTP_ERROR ("Unable to recieve data from server\n");
525 int repCode = getResponseCode (srvMsg);
528 FTP_ERROR ("Bad response from server (%d, expected 220)\n", repCode);
534 char buffer[256] = {0};
535 if (1 == isAnonymous)
537 snprintf (buffer, sizeof (buffer)-1, "USER anonymous\r\n");
541 snprintf (buffer, sizeof (buffer)-1, "USER %s\r\n", username);
543 if (FTP_FAILED (ftpTransfert (retFtp, buffer, srvMsg, MAX_SIZE_MSG-1)))
545 FTP_ERROR ("Error while sending command\n");
549 repCode = getResponseCode (srvMsg);
550 int goodRepCode = 331;
551 if (1 == isAnonymous)
555 if (goodRepCode != repCode)
557 FTP_ERROR ("Bad response from server (%d, expected %d)\n", repCode, goodRepCode);
562 if (0 == isAnonymous)
564 vp_os_memset (buffer, 0x0, sizeof (buffer));
565 snprintf (buffer, sizeof (buffer)-1, "PASS %s\r\n", password);
566 if (FTP_FAILED (ftpTransfert (retFtp, buffer, srvMsg, MAX_SIZE_MSG-1)))
568 FTP_ERROR ("Error while sending command\n");
572 repCode = getResponseCode (srvMsg);
575 FTP_ERROR ("Bad response from server (%d, expected 230)\n", repCode);
581 *status = FTP_SUCCESS;
582 retFtp->connected = 1;
583 retFtp->opInProgress = 0;
584 retFtp->abortCurrentOp = 0;
590 #define CLEAN_PARAMS(status) CLEAN_PARAMS_WITH_ARG(status,NULL)
591 #undef CLEAN_PARAMS_WITH_ARG
592 #define CLEAN_PARAMS_WITH_ARG(status,arg) \
595 params->ftp->opInProgress = 0; \
596 CLEAN_PARAMS_ABORT (status,arg); \
598 #undef CLEAN_PARAMS_ABORT
599 #define CLEAN_PARAMS_ABORT(status,arg) \
602 _ftp_status locStat = (status); \
603 if (NULL != localFile) fclose (localFile); \
604 if (NULL != dataSocket) \
606 vp_com_close_socket (dataSocket); \
607 vp_os_free (dataSocket); \
610 params->callback (locStat, arg, params->ftp); \
611 if (FTP_SUCCESS != status && NULL != params->fileList) \
613 vp_os_free (params->fileList); \
614 params->fileList = NULL; \
616 vp_os_free (param); \
617 FTP_DEBUG ("Returning from thread %s with status %d\n", __FUNCTION__, locStat); \
618 THREAD_RETURN (locStat); \
622 #define CHECK_ABORT \
625 if (1 <= params->ftp->abortCurrentOp) \
627 vp_os_memset (srvMsg, 0x0, MAX_SIZE_MSG); \
628 if (NULL != dataSocket) \
630 vp_com_close_socket (dataSocket); \
631 vp_os_free (dataSocket); \
634 ftpTransfert (params->ftp, "ABOR\r\n\0", srvMsg, MAX_SIZE_MSG-1); \
635 flushFtp (params->ftp); \
636 params->ftp->abortCurrentOp = 0; \
637 params->ftp->opInProgress = 0; \
638 CLEAN_PARAMS_ABORT (FTP_ABORT, NULL); \
642 DEFINE_THREAD_ROUTINE (ftpList, param)
644 FILE *localFile = NULL; // Compatibilty with macros
645 vp_com_socket_t *dataSocket = NULL;
646 Read dataRead = NULL;
647 Write dataWrite = NULL;
648 _ftp_list_param *params = (_ftp_list_param *)param;
649 if (NULL == params->ftp)
651 FTP_ERROR ("FTP not open\n");
652 CLEAN_PARAMS (FTP_FAIL);
654 flushFtp (params->ftp);
656 char srvMsg [MAX_SIZE_MSG] = {0};
657 _ftp_status ftp_result = ftpTransfert (params->ftp, "PASV\r\n\0", srvMsg, MAX_SIZE_MSG-1);
658 if (FTP_FAILED (ftp_result))
660 FTP_ERROR ("Error while sending command\n");
661 CLEAN_PARAMS (ftp_result);
663 int repCode = getResponseCode (srvMsg);
666 FTP_ERROR ("Bad response from server (%d, expected 227)\n", repCode);
667 CLEAN_PARAMS (FTP_FAIL);
670 char dataIp [IP_STRING_SIZE] = {0};
672 getPassiveIpAndPort (srvMsg, dataIp, &dataPort, IP_STRING_SIZE);
674 FTP_DEBUG ("Thread will connect to %s:%d\n", dataIp, dataPort);
675 dataSocket = vp_os_malloc (sizeof (vp_com_socket_t));
676 if (NULL == dataSocket)
678 FTP_ERROR ("Unable to allocate socket structure\n");
679 CLEAN_PARAMS (FTP_FAIL);
681 dataSocket->type = VP_COM_CLIENT;
682 dataSocket->protocol = VP_COM_TCP;
683 dataSocket->port = dataPort;
684 strncpy (dataSocket->serverHost, dataIp, VP_COM_NAME_MAXSIZE);
685 dataSocket->is_multicast = 0;
686 dataSocket->block = VP_COM_WAITALL;
688 C_RESULT vp_result = vp_com_open_socket (dataSocket, &dataRead, &dataWrite);
689 if (VP_FAILED (vp_result))
691 FTP_ERROR ("Unable to connect\n");
692 CLEAN_PARAMS (FTP_FAIL);
695 int result = setSockTimeout ((int)dataSocket->priv, SOCK_TO_SEC, SOCK_TO_USEC);
698 FTP_ERROR ("Unable to set data socket timeout\n");
699 CLEAN_PARAMS (FTP_FAIL);
704 ftp_result = ftpSend (params->ftp, "LIST\r\n\0");
705 if (FTP_FAILED (ftp_result))
707 FTP_ERROR ("Error while sending LIST command\n");
708 CLEAN_PARAMS (ftp_result);
712 char ftpData [2] = {0};
713 int bytes = 1, totalBytes;
714 vp_os_memset (params->fileList, 0x0, params->listSize);
715 vp_result = dataRead (dataSocket, (int8_t *)ftpData, &bytes);
716 if (VP_FAILED (vp_result))
718 FTP_ERROR ("Unable to receive data\n");
719 CLEAN_PARAMS (FTP_FAIL);
723 FTP_DEBUG ("Empty folder\n");
724 waitFor226Answer (params->ftp);
725 flushFtp (params->ftp);
726 CLEAN_PARAMS (FTP_SAMESIZE);
729 if (strlen (ftpData) > params->listSize - 1)
731 params->listSize += LIST_BUFFER_BLOCKSIZE;
732 params->fileList = vp_os_realloc(params->fileList, params->listSize);
733 if(NULL == params->fileList)
735 FTP_ERROR ("Not enough space in response string, can't reallocate buffer list\n");
736 CLEAN_PARAMS (FTP_FAIL);
739 snprintf (params->fileList, params->listSize-1, "%s", ftpData);
741 while (1) // Loop is killed by a return or a break statement
746 vp_result = dataRead (dataSocket, (int8_t *)ftpData, &bytes);
747 if (VP_FAILED (vp_result))
749 FTP_ERROR ("Unable to receive data\n");
750 CLEAN_PARAMS (FTP_FAIL);
752 if (0 == bytes && '\n' == params->fileList [totalBytes-1])
754 FTP_DEBUG ("Got all listing !\n");
755 // Timeouted. We got all the listing !
756 // Timeout is voluntary, so still return FTP_SUCCESS
762 FTP_ERROR ("Recv timeout\n");
763 CLEAN_PARAMS (FTP_TIMEOUT);
765 if (strlen (ftpData) > (params->listSize - 1 - strlen (params->fileList)))
767 params->listSize += LIST_BUFFER_BLOCKSIZE;
768 params->fileList = vp_os_realloc(params->fileList, params->listSize);
769 if(NULL == params->fileList)
771 FTP_ERROR ("Not enough space in response string, can't reallocate buffer list\n");
772 CLEAN_PARAMS (FTP_FAIL);
775 strcat (params->fileList, ftpData);
777 FTP_PRINT ("Progress of listing : finished ? %d : (%d->%d bytes) %s\n", (params->response [totalBytes -1] == '\n') ? 1: 0, bytes, totalBytes, params->response);
780 ftp_result = ftpRecv (params->ftp, srvMsg, MAX_SIZE_MSG-1);
781 if (FTP_FAILED (ftp_result))
783 FTP_ERROR ("Error while getting answer\n");
784 CLEAN_PARAMS (ftp_result);
786 repCode = getResponseCode (srvMsg);
789 FTP_ERROR ("Bad response from server (%d, expected 150)\n", repCode);
790 CLEAN_PARAMS (FTP_FAIL);
794 if (NULL != dataSocket)
796 vp_com_close_socket (dataSocket);
797 vp_os_free (dataSocket);
800 waitFor226Answer (params->ftp);
801 flushFtp (params->ftp);
804 CLEAN_PARAMS_WITH_ARG (FTP_SUCCESS, (void *)params->fileList);
807 DEFINE_THREAD_ROUTINE (ftpGet, param)
809 vp_com_socket_t *dataSocket = NULL;
810 Read dataRead = NULL;
811 Write dataWrite = NULL;
812 FILE *localFile = NULL;
813 _ftp_get_param *params = (_ftp_get_param *)param;
814 FTP_DEBUG ("Downloading %s to %s [resume : %c]\n", params->remoteName, params->localName, params->useResume ? 'y' : 'n');
815 if (NULL == params->ftp)
817 FTP_ERROR ("FTP not open\n");
818 CLEAN_PARAMS (FTP_FAIL);
820 flushFtp (params->ftp);
822 char buffer[512] = {0};
823 char srvMsg[MAX_SIZE_MSG] = {0};
824 snprintf (buffer, sizeof (buffer)-1, "PASV\r\n");
825 _ftp_status ftp_result = ftpTransfert (params->ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
826 if (FTP_FAILED (ftp_result))
828 FTP_ERROR ("Error while entering passive mode\n");
829 CLEAN_PARAMS (ftp_result);
831 int repCode = getResponseCode (srvMsg);
834 FTP_ERROR ("Bad response from server (%d, expected 227)\n", repCode);
835 CLEAN_PARAMS (FTP_FAIL);
838 ftp_result = goToBinaryMode (params->ftp);
839 if (FTP_FAILED (ftp_result))
841 FTP_ERROR ("Unable to go to binary mode\n");
842 CLEAN_PARAMS (ftp_result);
845 int fileSize = getFileSize (params->ftp, params->remoteName);
848 FTP_ERROR ("File %s does not exist on server\n", params->remoteName);
849 CLEAN_PARAMS (FTP_FAIL);
851 int sizeToGet = fileSize;
852 int localFileSize = getLocalFileSize (params->localName);
853 int appendToFile = params->useResume;
854 int appendOffset = 0;
855 if (-1 == localFileSize && 1 == params->useResume)
857 FTP_DEBUG ("File does not exist ... full download\n");
860 if (1 == appendToFile)
862 if (localFileSize == fileSize)
864 FTP_DEBUG ("File already downloaded\n");
865 CLEAN_PARAMS (FTP_SAMESIZE);
867 else if (localFileSize > fileSize)
869 FTP_ERROR ("Local file (%s) is greater than distant file (%s)\n", params->localName, params->remoteName);
870 CLEAN_PARAMS (FTP_BADSIZE);
872 sizeToGet = fileSize - localFileSize;
874 char buffer[50] = {0};
875 appendOffset = fileSize - sizeToGet;
876 snprintf (buffer, sizeof (buffer)-1, "REST %d\r\n", appendOffset);
877 char srvAnsw[MAX_SIZE_MSG] = {0};
878 _ftp_status ftp_result = ftpTransfert (params->ftp, buffer, srvAnsw, MAX_SIZE_MSG-1);
879 if (FTP_FAILED (ftp_result))
881 FTP_ERROR ("Unable to set server offset\n");
882 CLEAN_PARAMS (ftp_result);
886 char dataIp [IP_STRING_SIZE] = {0};
888 getPassiveIpAndPort (srvMsg, dataIp, &dataPort, IP_STRING_SIZE);
890 FTP_DEBUG ("Thread will connect to %s:%d\n", dataIp, dataPort);
891 dataSocket = vp_os_malloc (sizeof (vp_com_socket_t));
892 if (NULL == dataSocket)
894 FTP_ERROR ("Unable to allocate socket structure\n");
895 CLEAN_PARAMS (FTP_FAIL);
897 dataSocket->type = VP_COM_CLIENT;
898 dataSocket->protocol = VP_COM_TCP;
899 dataSocket->port = dataPort;
900 strncpy (dataSocket->serverHost, dataIp, VP_COM_NAME_MAXSIZE);
901 dataSocket->is_multicast = 0;
902 dataSocket->block = VP_COM_WAITALL;
904 C_RESULT vp_result = vp_com_open_socket (dataSocket, &dataRead, &dataWrite);
905 if (VP_FAILED (vp_result))
907 FTP_ERROR ("Unable to connect\n");
908 CLEAN_PARAMS (FTP_FAIL);
911 int result = setSockTimeout ((int)dataSocket->priv, SOCK_TO_SEC, SOCK_TO_USEC);
914 FTP_ERROR ("Unable to set data socket timeout\n");
915 CLEAN_PARAMS (FTP_FAIL);
920 vp_os_memset (buffer, 0x0, sizeof (buffer));
921 snprintf (buffer, sizeof (buffer)-1, "RETR %s\r\n", params->remoteName);
922 ftp_result = ftpSend (params->ftp, buffer);
923 if (FTP_FAILED (ftp_result))
925 FTP_ERROR ("Error while sending RETR command\n");
926 CLEAN_PARAMS (ftp_result);
929 int sizeGot = appendOffset;
930 float percentGot = (sizeGot * 100.0) / (fileSize *1.0);
931 params->callback (FTP_PROGRESS, (void *)&percentGot, params->ftp);
933 char filePart [MAX_SIZE_MSG] = {0};
936 if (1 == appendToFile)
938 localFile = fopen (params->localName, "ab");
942 localFile = fopen (params->localName, "wb");
944 if (NULL == localFile)
946 FTP_ERROR ("Unable to open dest file %s\n", params->localName);
947 CLEAN_PARAMS (FTP_FAIL);
949 while (sizeGot < fileSize)
952 int bytes = MAX_SIZE_MSG-1;
953 C_RESULT vp_result = dataRead (dataSocket, (int8_t *)filePart, &bytes);
954 if (VP_FAILED (vp_result))
956 FTP_ERROR ("Error while receiving data\n");
957 CLEAN_PARAMS (FTP_FAIL);
961 FTP_ERROR ("Recv timeout\n");
962 CLEAN_PARAMS (FTP_TIMEOUT);
964 if (0 > fwrite (filePart, 1, bytes, localFile))
966 FTP_ERROR ("Unable to write to file\n");
967 CLEAN_PARAMS (FTP_FAIL);
970 percentGot = (sizeGot * 100.0) / (fileSize * 1.0);
971 params->callback (FTP_PROGRESS, (void *)&percentGot, params->ftp);
973 ftp_result = ftpRecv (params->ftp, srvMsg, MAX_SIZE_MSG-1);
974 if (FTP_FAILED (ftp_result))
976 FTP_ERROR ("Error while getting answer\n");
977 CLEAN_PARAMS (ftp_result);
979 repCode = getResponseCode (srvMsg);
982 FTP_ERROR ("Bad response from server (%d, expected 150)\n", repCode);
983 CLEAN_PARAMS (FTP_FAIL);
987 if (NULL != dataSocket)
989 vp_com_close_socket (dataSocket);
990 vp_os_free (dataSocket);
993 waitFor226Answer (params->ftp);
994 flushFtp (params->ftp);
996 CLEAN_PARAMS (FTP_SUCCESS);
999 DEFINE_THREAD_ROUTINE (ftpPut, param)
1001 vp_com_socket_t *dataSocket = NULL;
1002 Read dataRead = NULL;
1003 Write dataWrite = NULL;
1004 FILE *localFile = NULL;
1005 _ftp_put_param *params = (_ftp_put_param *)param;
1006 FTP_DEBUG ("Uploading %s to %s [resume : %c]\n", params->localName, params->remoteName, params->useResume ? 'y' : 'n');
1007 if (NULL == params->ftp)
1009 FTP_ERROR ("FTP not open\n");
1010 CLEAN_PARAMS (FTP_FAIL);
1012 flushFtp (params->ftp);
1014 char buffer[512] = {0};
1015 char srvMsg[MAX_SIZE_MSG] = {0};
1016 snprintf (buffer, sizeof (buffer)-1, "PASV\r\n");
1017 _ftp_status ftp_result = ftpTransfert (params->ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1018 if (FTP_FAILED (ftp_result))
1020 FTP_ERROR ("Error while entering passive mode\n");
1021 CLEAN_PARAMS (ftp_result);
1023 int repCode = getResponseCode (srvMsg);
1026 FTP_ERROR ("Bad response from server (%d, expected 227)\n", repCode);
1027 CLEAN_PARAMS (FTP_FAIL);
1030 ftp_result = goToBinaryMode (params->ftp);
1031 if (FTP_FAILED (ftp_result))
1033 FTP_ERROR ("Unable to go to binary mode\n");
1034 CLEAN_PARAMS (ftp_result);
1037 int localFileSize = getLocalFileSize (params->localName);
1038 if (0 >= localFileSize)
1040 FTP_ERROR ("File %s does not exist on filesystem\n", params->localName);
1041 CLEAN_PARAMS (FTP_FAIL);
1043 int fileSize = getFileSize (params->ftp, params->remoteName);
1044 int sizeToPut = localFileSize;
1045 int appendToFile = params->useResume;
1046 int appendOffset = 0;
1047 if (-1 == fileSize && 1 == params->useResume)
1049 FTP_DEBUG ("File does not exist on server ... full upload\n");
1052 if (1 == appendToFile)
1054 if (localFileSize == fileSize)
1056 FTP_DEBUG ("File already uploaded\n");
1057 CLEAN_PARAMS (FTP_SAMESIZE);
1059 else if (localFileSize < fileSize)
1061 FTP_ERROR ("Distant file (%s) is greather than local file (%s)\n", params->remoteName, params->localName);
1062 CLEAN_PARAMS (FTP_BADSIZE);
1064 sizeToPut = localFileSize - fileSize;
1066 char buffer [50] = {0};
1067 appendOffset = localFileSize - sizeToPut;
1068 snprintf (buffer, sizeof (buffer)-1, "REST %d\r\n", appendOffset);
1069 char srvAnswer[MAX_SIZE_MSG] = {0};
1070 ftp_result = ftpTransfert (params->ftp, buffer, srvAnswer, MAX_SIZE_MSG-1);
1071 if (FTP_FAILED (ftp_result))
1073 FTP_ERROR ("Unable to set server offset\n");
1074 CLEAN_PARAMS (ftp_result);
1078 char dataIp [IP_STRING_SIZE] = {0};
1080 getPassiveIpAndPort (srvMsg, dataIp, &dataPort, IP_STRING_SIZE);
1082 FTP_DEBUG ("Thread will connect to %s:%d\n", dataIp, dataPort);
1083 dataSocket = vp_os_malloc (sizeof (vp_com_socket_t));
1084 if (NULL == dataSocket)
1086 FTP_ERROR ("Unable to allocate socket structure\n");
1087 CLEAN_PARAMS (FTP_FAIL);
1089 dataSocket->type = VP_COM_CLIENT;
1090 dataSocket->protocol = VP_COM_TCP;
1091 dataSocket->port = dataPort;
1092 strncpy (dataSocket->serverHost, dataIp, VP_COM_NAME_MAXSIZE);
1093 dataSocket->is_multicast = 0;
1094 dataSocket->block = VP_COM_DEFAULT;
1096 C_RESULT vp_result = vp_com_open_socket (dataSocket, &dataRead, &dataWrite);
1097 if (VP_FAILED (vp_result))
1099 FTP_ERROR ("Unable to connect\n");
1100 CLEAN_PARAMS (FTP_FAIL);
1103 int result = setSockTimeout ((int)dataSocket->priv, SOCK_TO_SEC, SOCK_TO_USEC);
1106 FTP_ERROR ("Unable to set data socket timeout\n");
1107 CLEAN_PARAMS (FTP_FAIL);
1112 vp_os_memset (buffer, 0x0, sizeof (buffer));
1113 snprintf (buffer, sizeof (buffer)-1, "STOR %s\r\n", params->remoteName);
1114 ftp_result = ftpTransfert (params->ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1115 if (FTP_FAILED (ftp_result))
1117 FTP_ERROR ("Error while sending command\n");
1118 CLEAN_PARAMS (ftp_result);
1120 repCode = getResponseCode (srvMsg);
1123 FTP_ERROR ("Bad response from server (%d, expected 150)\n", repCode);
1124 CLEAN_PARAMS (FTP_FAIL);
1127 int sizeSent = appendOffset;
1128 float percentSend = (sizeSent * 100.0) / (localFileSize *1.0);
1129 params->callback (FTP_PROGRESS, (void *)&percentSend, params->ftp);
1131 int numberOfFullSendNeeded = (sizeToPut / (MAX_SIZE_MSG-1));
1132 int partialSendNeeded = (sizeToPut % (MAX_SIZE_MSG-1)); // Zero if not needed, non-zero if needed
1133 char filePart [MAX_SIZE_MSG] = {0};
1135 localFile = fopen (params->localName, "rb");
1136 if (NULL == localFile)
1138 FTP_ERROR ("Unable to open source file %s\n", params->localName);
1139 CLEAN_PARAMS (FTP_FAIL);
1141 fseek (localFile, appendOffset, SEEK_SET);
1144 for (numSend = 0; numSend < numberOfFullSendNeeded; numSend++)
1147 int bytes = fread (filePart, 1, MAX_SIZE_MSG-1, localFile);
1150 FTP_ERROR ("Unable to read from file\n");
1151 CLEAN_PARAMS (FTP_FAIL);
1153 bytes = MAX_SIZE_MSG-1;
1154 C_RESULT vp_result = dataWrite (dataSocket, (int8_t *)filePart, &bytes);
1155 if (VP_FAILED (vp_result))
1157 FTP_ERROR ("Unable to send data\n");
1158 CLEAN_PARAMS (FTP_FAIL);
1160 if (MAX_SIZE_MSG-1 > bytes)
1162 FTP_ERROR ("Send timeout\n");
1163 CLEAN_PARAMS (FTP_TIMEOUT);
1165 sizeSent += MAX_SIZE_MSG-1;
1166 percentSend = (sizeSent * 100.0) / (localFileSize * 1.0);
1167 params->callback (FTP_PROGRESS, (void *)&percentSend, params->ftp);
1170 if (0 != partialSendNeeded)
1173 vp_os_memset (filePart, 0x0, MAX_SIZE_MSG);
1174 int bytes = fread (filePart, 1, MAX_SIZE_MSG-1, localFile);
1175 FTP_DEBUG ("Read %d bytes\n", bytes);
1178 FTP_ERROR ("Unable to read from file\n");
1179 CLEAN_PARAMS (FTP_FAIL);
1181 int sendBytes = bytes;
1182 C_RESULT vp_result = dataWrite (dataSocket, (int8_t *)filePart, &sendBytes);
1183 if (VP_FAILED (vp_result))
1185 FTP_ERROR ("Unable to send data\n");
1186 CLEAN_PARAMS (FTP_FAIL);
1188 if (bytes > sendBytes)
1190 FTP_ERROR ("Send timeout\n");
1191 CLEAN_PARAMS (FTP_TIMEOUT);
1194 percentSend = (sizeSent * 100.0) / (localFileSize * 1.0);
1195 params->callback (FTP_PROGRESS, (void *)&percentSend, params->ftp);
1199 if (NULL != dataSocket)
1201 vp_com_close_socket (dataSocket);
1202 vp_os_free (dataSocket);
1205 waitFor226Answer (params->ftp);
1206 flushFtp (params->ftp);
1208 CLEAN_PARAMS (FTP_SUCCESS);
1213 ftpPut (_ftp_t *ftp, const char *localName, const char *remoteName, int useResume, ftp_callback callback)
1215 THREAD_HANDLE putThread;
1216 ftp_callback actualCallback = (NULL != callback) ? callback : emptyCallback;
1219 actualCallback (FTP_FAIL, NULL, ftp);
1222 if (1 == ftp->opInProgress)
1224 actualCallback (FTP_BUSY, NULL, ftp);
1227 ftp->opInProgress = 1;
1229 _ftp_put_param *param = vp_os_malloc (sizeof (_ftp_put_param));
1233 FTP_ERROR ("Unable to allocate thread param\n");
1234 actualCallback (FTP_FAIL, NULL, ftp);
1235 ftp->opInProgress = 0;
1240 strncpy (param->localName, localName, FILE_NAME_MAX_SIZE);
1241 param->localName [FILE_NAME_MAX_SIZE-1] = '\0';
1242 strncpy (param->remoteName, remoteName, FILE_NAME_MAX_SIZE);
1243 param->remoteName [FILE_NAME_MAX_SIZE-1] = '\0';
1244 param->useResume = useResume;
1245 param->callback = actualCallback;
1246 param->fileList = NULL;
1247 _ftp_status threadReturn = FTP_SUCCESS;
1249 vp_os_thread_create (thread_ftpPut, (THREAD_PARAMS)param, &putThread);
1251 if (NULL == callback)
1253 vp_os_thread_join (putThread);
1254 threadReturn = lastStatusFromEmptyCallback;
1257 return threadReturn;
1261 ftpGet (_ftp_t *ftp, const char *remoteName, const char *localName, int useResume, ftp_callback callback)
1263 THREAD_HANDLE getThread;
1264 ftp_callback actualCallback = (NULL != callback) ? callback : emptyCallback;
1267 actualCallback (FTP_FAIL, NULL, ftp);
1270 if (1 == ftp->opInProgress)
1272 actualCallback (FTP_BUSY, NULL, ftp);
1275 ftp->opInProgress = 1;
1277 _ftp_get_param *param = vp_os_malloc (sizeof (_ftp_get_param));
1281 FTP_ERROR ("Unable to allocate thread param\n");
1282 actualCallback (FTP_FAIL, NULL, ftp);
1283 ftp->opInProgress = 0;
1288 strncpy (param->localName, localName, FILE_NAME_MAX_SIZE);
1289 param->localName [FILE_NAME_MAX_SIZE-1] = '\0';
1290 strncpy (param->remoteName, remoteName, FILE_NAME_MAX_SIZE);
1291 param->remoteName [FILE_NAME_MAX_SIZE-1] = '\0';
1292 param->useResume = useResume;
1293 param->callback = actualCallback;
1294 param->fileList = NULL;
1295 _ftp_status threadReturn = FTP_SUCCESS;
1297 vp_os_thread_create (thread_ftpGet, (THREAD_PARAMS)param, &getThread);
1299 if (NULL == callback)
1301 vp_os_thread_join (getThread);
1302 threadReturn = lastStatusFromEmptyCallback;
1305 return threadReturn;
1309 ftpList (_ftp_t *ftp, char **fileList, ftp_callback callback)
1311 if (NULL == fileList && NULL == callback)
1313 FTP_ERROR ("file list and callback pointer must not be both NULL\n");
1316 THREAD_HANDLE listThread;
1317 ftp_callback actualCallback = (NULL != callback) ? callback : emptyCallback;
1320 actualCallback (FTP_FAIL, NULL, ftp);
1323 if (1 == ftp->opInProgress)
1325 actualCallback (FTP_BUSY, NULL, ftp);
1328 ftp->opInProgress = 1;
1330 _ftp_list_param *param = vp_os_malloc (sizeof (_ftp_list_param));
1334 FTP_ERROR ("Unable to allocate thread param\n");
1335 actualCallback (FTP_FAIL, NULL, ftp);
1336 ftp->opInProgress = 0;
1340 param->fileList = vp_os_malloc (sizeof (char) * LIST_BUFFER_BLOCKSIZE);
1341 if (NULL == param->fileList)
1343 FTP_ERROR ("Unable to allocate list buffer\n");
1344 actualCallback (FTP_FAIL, NULL, ftp);
1345 ftp->opInProgress = 0;
1351 param->listSize = LIST_BUFFER_BLOCKSIZE;
1352 param->callback = actualCallback;
1353 _ftp_status threadReturn = FTP_SUCCESS;
1355 vp_os_thread_create (thread_ftpList, (THREAD_PARAMS)param, &listThread);
1357 if (NULL == callback)
1359 vp_os_thread_join (listThread);
1360 threadReturn = lastStatusFromEmptyCallback;
1361 if (FTP_SUCCESS == threadReturn)
1363 *fileList = lastFileListFromEmptyCallback;
1364 lastFileListFromEmptyCallback = NULL;
1368 return threadReturn;
1372 ftpRemove (_ftp_t *ftp, const char *remoteName)
1374 _ftp_status ftp_result = FTP_FAIL;
1375 char buffer [256] = {0};
1376 char srvMsg [MAX_SIZE_MSG] = {0};
1377 if (NULL == remoteName)
1379 FTP_ERROR ("remoteName must not be a NULL pointer\n");
1384 FTP_ERROR ("FTP not open\n");
1387 snprintf (buffer, sizeof (buffer)-1, "DELE %s\r\n", remoteName);
1388 ftp_result = ftpTransfert (ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1389 if (FTP_FAILED (ftp_result))
1391 FTP_ERROR ("Error while sending the delete command\n");
1394 int repCode = getResponseCode (srvMsg);
1395 if (250 != repCode && 550 != repCode)
1397 FTP_ERROR ("Bad response from server (%d, expected 250 or 550)\n", repCode);
1398 ftp_result = FTP_FAIL;
1404 ftpRename (_ftp_t *ftp, const char *origin, const char *dest)
1406 _ftp_status ftp_result = FTP_FAIL;
1407 char buffer [256] = {0};
1408 char srvMsg [MAX_SIZE_MSG] = {0};
1409 if (NULL == origin ||
1412 FTP_ERROR ("origin and dest pointers must not be NULL\n");
1417 FTP_ERROR ("FTP not open\n");
1420 snprintf (buffer, sizeof (buffer)-1, "RNFR %s\r\n", origin);
1421 ftp_result = ftpTransfert (ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1422 if (FTP_FAILED (ftp_result))
1424 FTP_ERROR ("Error while sending the RNFR command\n");
1427 int repCode = getResponseCode (srvMsg);
1430 FTP_ERROR ("Bad response from server (%d, expected 350)\n", repCode);
1431 ftp_result = FTP_FAIL;
1434 vp_os_memset (buffer, 0x0, sizeof (buffer));
1435 vp_os_memset (srvMsg, 0x0, sizeof (srvMsg));
1437 snprintf (buffer, sizeof (buffer)-1, "RNTO %s\r\n", dest);
1438 ftp_result = ftpTransfert (ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1439 if (FTP_FAILED (ftp_result))
1441 FTP_ERROR ("Error while sending the RNTO command\n");
1444 repCode = getResponseCode (srvMsg);
1445 if (250 == repCode) // Rename worked
1447 ftp_result = FTP_SUCCESS;
1449 else if (550 == repCode) // Source file don't exist
1451 FTP_DEBUG ("File %s doest not exist on FTP\n", origin);
1452 ftp_result = FTP_SAMESIZE;
1456 FTP_ERROR ("Bad response from server (%d, expected 250 or 550)\n", repCode);
1457 ftp_result = FTP_FAIL;
1463 ftpCd (_ftp_t *ftp, const char *nextDir)
1465 _ftp_status ftp_result = FTP_FAIL;
1466 char buffer [256] = {0};
1467 char srvMsg [MAX_SIZE_MSG] = {0};
1468 if (NULL == nextDir)
1470 FTP_ERROR ("nextDir must not be NULL\n");
1475 FTP_ERROR ("FTP not open\n");
1478 snprintf (buffer, sizeof (buffer)-1, "CWD %s\r\n", nextDir);
1479 ftp_result = ftpTransfert (ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1480 if (FTP_FAILED (ftp_result))
1482 FTP_ERROR ("Error while sending the CWD command\n");
1485 int repCode = getResponseCode (srvMsg);
1488 FTP_ERROR ("Bad response from server (%d, expected 250)\n", repCode);
1489 ftp_result = FTP_FAIL;
1495 ftpPwd (_ftp_t *ftp, char *workingDir, int wdLen)
1497 _ftp_status ftp_result = FTP_FAIL;
1498 char srvMsg [MAX_SIZE_MSG] = {0};
1499 if (NULL == workingDir)
1501 FTP_ERROR ("workingDir must not be NULL\n");
1506 FTP_ERROR ("FTP not open\n");
1509 ftp_result = ftpTransfert (ftp, "PWD\r\n\0", srvMsg, MAX_SIZE_MSG-1);
1510 if (FTP_FAILED (ftp_result))
1512 FTP_ERROR ("Error while sending the CWD command\n");
1515 int repCode = getResponseCode (srvMsg);
1518 FTP_ERROR ("Bad response from server (%d, expected 257)\n", repCode);
1519 ftp_result = FTP_FAIL;
1523 int pwdStartIndex = 0;
1524 int pwdEndIndex = 0;
1525 for (pwdStartIndex = 0; (pwdStartIndex < MAX_SIZE_MSG) && (srvMsg[pwdStartIndex] != '\"'); pwdStartIndex++);
1526 for (pwdEndIndex = pwdStartIndex+1; (pwdEndIndex < MAX_SIZE_MSG) && (srvMsg[pwdEndIndex] != '\"'); pwdEndIndex++);
1527 if (MAX_SIZE_MSG == pwdStartIndex ||
1528 MAX_SIZE_MSG == pwdEndIndex)
1530 FTP_ERROR ("FTP Answer does not conains PWD\n");
1531 ftp_result = FTP_FAIL;
1535 int srvLen = pwdEndIndex - (pwdStartIndex + 1);
1536 int totalLen = (srvLen < wdLen) ? srvLen : wdLen;
1537 strncpy (workingDir, &(srvMsg[pwdStartIndex+1]), totalLen);
1538 FTP_DEBUG ("PWD is %s\n", workingDir);
1545 ftpMkdir (_ftp_t *ftp, const char *dirName)
1547 _ftp_status ftp_result = FTP_FAIL;
1548 char buffer [256] = {0};
1549 char srvMsg [MAX_SIZE_MSG] = {0};
1550 if (NULL == dirName)
1552 FTP_ERROR ("dirName must not be NULL\n");
1557 FTP_ERROR ("FTP not open\n");
1560 snprintf (buffer, sizeof (buffer)-1, "MKD %s\r\n", dirName);
1561 ftp_result = ftpTransfert (ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1562 if (FTP_FAILED (ftp_result))
1564 FTP_ERROR ("Error while sending the MKD command\n");
1567 int repCode = getResponseCode (srvMsg);
1570 FTP_ERROR ("Bad response from server (%d, expected 257)\n", repCode);
1571 ftp_result = FTP_FAIL;
1577 ftpRmdir (_ftp_t *ftp, const char *dirName)
1579 _ftp_status ftp_result = FTP_FAIL;
1580 char buffer [256] = {0};
1581 char srvMsg [MAX_SIZE_MSG] = {0};
1582 if (NULL == dirName)
1584 FTP_ERROR ("dirName must not be NULL\n");
1589 FTP_ERROR ("FTP not open\n");
1592 snprintf (buffer, sizeof (buffer)-1, "RMD %s\r\n", dirName);
1593 ftp_result = ftpTransfert (ftp, buffer, srvMsg, MAX_SIZE_MSG-1);
1594 if (FTP_FAILED (ftp_result))
1596 FTP_ERROR ("Error while sending the RMD command\n");
1599 int repCode = getResponseCode (srvMsg);
1600 if (250 == repCode) // Deleted
1602 FTP_DEBUG ("Successfully deleted %s directory\n", dirName);
1603 ftp_result = FTP_SUCCESS;
1605 else if (550 == repCode) // Didn't exist / not empty
1607 FTP_DEBUG ("Did not delete directory %s : did not exist or was not empty\n", dirName);
1608 ftp_result = FTP_BADSIZE;
1612 FTP_ERROR ("Bad response from server (%d, expected 250 or 550)\n", repCode);
1613 ftp_result = FTP_FAIL;
1618 _ftp_status ftpAbort (_ftp_t *ftp)
1620 _ftp_status retVal = FTP_FAIL;
1623 FTP_ERROR ("FTP not open\n");
1627 if (1 == ftp->opInProgress)
1629 ftp->abortCurrentOp = 1;
1630 retVal = FTP_SUCCESS;
1634 retVal = FTP_SAMESIZE;