From 7b4afdff6c8d993ee1d503537fa2bc88282edcb4 Mon Sep 17 00:00:00 2001 From: MarkRivers Date: Wed, 6 Dec 2006 21:50:38 +0000 Subject: [PATCH] New file for FTP to XPS controller --- motorApp/NewportSrc/xps_ftp.c | 395 ++++++++++++++++++++++++++++++++++ motorApp/NewportSrc/xps_ftp.h | 65 ++++++ 2 files changed, 460 insertions(+) create mode 100644 motorApp/NewportSrc/xps_ftp.c create mode 100644 motorApp/NewportSrc/xps_ftp.h diff --git a/motorApp/NewportSrc/xps_ftp.c b/motorApp/NewportSrc/xps_ftp.c new file mode 100644 index 00000000..8bad7259 --- /dev/null +++ b/motorApp/NewportSrc/xps_ftp.c @@ -0,0 +1,395 @@ +/******************************************************************** + * ftp.c : source file for FTP functions for XPS motion Controller * + * * + * Authors : Max Lekeux * + * * + * Modifications history : * + * - 23aug06,ML : creation * + * * + * Warning : These functions were created to work with the XPS FTP * + * server. They prove the possibility to use standard * + * FTP functions. They are developped to be * + * cross-platform (Linux, Unix, Windows, VxWorks) * + * * + * Warning for Visual C++ : don't forget to add wsock32.lib to the * + * link. To do so add it in Menu Project->Settings * + * Tab Link -> Objects/Library modules * + ********************************************************************/ + + +/******[ includes ]**************************************************/ +#include "xps_ftp.h" + + +/******[ ftpConnect ]************************************************/ +int ftpConnect (char* ip, char* login, char* password, int* socketFD) +{ + char command[COMMAND_SIZE]; + char returnString[RETURN_SIZE]; + struct sockaddr_in sockAddr; + int sockFD, receivedBytes; + +#ifdef WIN32 + memset(&sockAddr, 0, sizeof(sockAddr)); +#else + #ifdef vxWorks + bzero((char*)&sockAddr, sizeof(sockAddr)); + #else + bzero(&sockAddr, sizeof(sockAddr)); + #endif +#endif + + sockFD = socket(AF_INET, SOCK_STREAM, 0); + + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(21); + sockAddr.sin_addr.s_addr = inet_addr(ip); + + if (connect(sockFD, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) + return -1; + + + receivedBytes = recv(sockFD, returnString, RETURN_SIZE, 0); + + /* login */ + sprintf(command, "USER %s", login); + if (-1 == sendFtpCommandAndReceive (sockFD, command, returnString)) + return -2; + + sprintf(command, "PASS %s", password); + if (-1 == sendFtpCommandAndReceive (sockFD, command, returnString)) + return -3; + + sprintf(command, "PASV"); + sendFtpCommandAndReceive (sockFD, command, returnString); + sprintf(command, "TYPE I"); + sendFtpCommandAndReceive (sockFD, command, returnString); + + *socketFD = sockFD; + + return 0; +} + + +/******[ ftpDisconnect ]*********************************************/ +int ftpDisconnect (int socketFD) +{ +#ifdef WIN32 + return closesocket(socketFD); +#else + return close(socketFD); +#endif +} + + +/******[ ftpChangeDir ]**********************************************/ +int ftpChangeDir (int socketFD, char* destination) +{ + char command[COMMAND_SIZE]; + char returnString[RETURN_SIZE]; + + sprintf(command, "CWD %s", destination); + if (-1 == sendFtpCommandAndReceive (socketFD, command, returnString)) + return -1; + + return 0; +} + + +/******[ ftpRetreaveFile ]*******************************************/ +int ftpRetreaveFile(int socketFD, char *filename) +{ + int port_rcv, socketFDReceive, i; + struct sockaddr_in adr_rcv; + char ip[IP_SIZE]; + char command[COMMAND_SIZE]; + char returnString[RETURN_SIZE]; + FILE *file; + +#ifdef WIN32 + memset(&adr_rcv, 0, sizeof(adr_rcv)); +#else + #ifdef vxWorks + bzero((char*)&adr_rcv, sizeof(adr_rcv)); + #else + bzero(&adr_rcv, sizeof(adr_rcv)); + #endif +#endif + + port_rcv = getPort(socketFD, ip); + + socketFDReceive = socket (AF_INET, SOCK_STREAM, 0); + + adr_rcv.sin_family = AF_INET; + adr_rcv.sin_addr.s_addr = inet_addr(ip); +#ifdef WIN32 + adr_rcv.sin_port = htons((u_short)port_rcv); +#else + adr_rcv.sin_port = htons(port_rcv); +#endif + + if (0 > connect (socketFDReceive, (struct sockaddr *) &adr_rcv, sizeof(adr_rcv))) + { + fprintf(stderr,"Cound not connect to FTP server to retrieve file %s\n", filename); + return -1; + + } + + /* send command */ + sprintf(command, "RETR %s", filename); + if (-1 == sendFtpCommandAndReceive (socketFD, command, returnString)) + return -1; + + /* Check there is no problem with file */ + if (code(returnString) == 550) + return -1; + + /* open file on localhost */ + if (NULL == (file = fopen(filename, "wb"))) + { + fprintf(stderr,"Cound not open file \"%s\" for writing on local host\n", filename); + return -1; + } + + do + { + i = recv(socketFDReceive,returnString, RETURN_SIZE,0); + fwrite(returnString, sizeof(char), i, file); + } + while(i!=0); + +#ifdef WIN32 + closesocket(socketFDReceive); +#else + close(socketFDReceive); +#endif + + fclose(file); + + i = recv(socketFD, returnString, RETURN_SIZE, 0); /* read "226 Transfer complete." */ + +#ifdef DEBUG + printf(" -> "); + printRecv(returnString, i); +#endif + + return 0; +} + + +/******[ ftpStoreFile ]**********************************************/ +int ftpStoreFile(int socketFD, char *filename) +{ + int port_snd, socketFDSend, i; + struct sockaddr_in adr_snd; + char ip[IP_SIZE]; + char command[COMMAND_SIZE]; + char returnString[RETURN_SIZE]; + FILE *file; + +#ifdef WIN32 + memset(&adr_snd, 0, sizeof(adr_snd)); +#else + #ifdef vxWorks + bzero((char*)&adr_snd, sizeof(adr_snd)); + #else + bzero(&adr_snd, sizeof(adr_snd)); + #endif +#endif + + port_snd = getPort(socketFD, ip); + + socketFDSend = socket (AF_INET, SOCK_STREAM, 0); + + adr_snd.sin_family = AF_INET; + adr_snd.sin_addr.s_addr = inet_addr(ip); +#ifdef WIN32 + adr_snd.sin_port = htons((u_short)port_snd); +#else + adr_snd.sin_port = htons(port_snd); +#endif + + if (0 > connect (socketFDSend, (struct sockaddr *) &adr_snd, sizeof(adr_snd))) + { + fprintf(stderr,"Cound not connect to FTP server to retrieve file %s\n", filename); + return -1; + + } + + /* send command */ + sprintf(command, "STOR %s", filename); + if (-1 == sendFtpCommandAndReceive (socketFD, command, returnString)) + return -1; + + /* open file on localhost */ + if (NULL == (file = fopen(filename, "rb"))) + { + fprintf(stderr,"Cound not open file \"%s\" for reading on local host\n", filename); + return -1; + } + + do + { + i = fread(returnString, sizeof(char), RETURN_SIZE, file); + send(socketFDSend,returnString, i, 0); + } + while(i != 0); + +#ifdef WIN32 + closesocket(socketFDSend); +#else + close(socketFDSend); +#endif + + fclose(file); + + i = recv(socketFD, returnString, RETURN_SIZE, 0); /* read "226 Transfer complete." */ + +#ifdef DEBUG + printf(" -> "); + printRecv(returnString, i); +#endif + + return 0; +} + + +/******[ code ]******************************************************/ +int code (char *str) +{ + char tmp[3]; + strncpy(tmp, str, 3); + return atoi(tmp); +} + + +/******[ sendFtpCommandAndReceive ]**********************************/ +int sendFtpCommandAndReceive (int socketFD, char* command, char* returnString) +{ + int receivedBytes; + char str_rec[RETURN_SIZE]; + +#ifdef DEBUG + printf("%s\n", command); +#endif + + sprintf(command, "%s\n", command); + + send (socketFD, command, strlen(command), 0); + receivedBytes = recv(socketFD, str_rec, RETURN_SIZE, 0); + +#ifdef DEBUG + printf(" -> "); + printRecv (str_rec, receivedBytes); +#endif + + str_rec[receivedBytes] = '\0'; + + switch (code(str_rec)) + { + case 530: + fprintf(stderr, "Connection error\n"); return -1; + case 421: + fprintf(stderr, "Connection time out\n"); return -1; + default: + break; + } + + if (str_rec[3] == '-') /* Reading a "-" in third position means that */ + { /* the server wants to informations with one packet */ + /* for each line. */ + char tmp_code[3]; + int i, j, found_end = 0; + + strncpy(tmp_code, str_rec, 3); + while (!found_end) /* It is the end if we receive the code followed by a space */ + { + j = 0; + while ((j+4) < strlen(str_rec)) + { + if (tmp_code[0] == str_rec[j]) /* search the first letter of the code */ + { + if ((tmp_code[1] == str_rec[j+1]) + && (tmp_code[2] == str_rec[j+2]) + && (str_rec[j+3] == ' ')) + { /* compare the rest + space */ + found_end = 1; + break; + } + else + j++; + } + else + j++; + } + + if ((j+4) >= strlen(str_rec)) { /* Last line not found yet, keep going */ + i = recv(socketFD, str_rec, RETURN_SIZE, 0); + str_rec[i] = '\0'; + } + } + } + + strncpy(returnString, str_rec, RETURN_SIZE); + return 1; +} + + +/******[ getPort ]***************************************************/ +int getPort (int socketFD, char* ip) +{ + char command[COMMAND_SIZE], returnString[RETURN_SIZE], tmp[RETURN_SIZE]; + int count, i, j, port; + + strcpy(command, "PASV"); + sendFtpCommandAndReceive (socketFD, command, returnString); + + i = 27; + count = 0; + while (count < 4) + { + if (returnString[i] == ',') + { + count++; + if (count < 4) + ip[i++-27] = '.'; + } + else + { + ip[i-27] = returnString[i]; + i++; + } + } + ip[i-27] = '\0'; + + j = ++i; + while (returnString[i] != ',') + { + tmp[i-j] = returnString[i]; + i++; + } + + tmp[i-j] = '\0'; + port = (atoi (tmp) * 256); + + j = ++i; + while (returnString[i] != ')') + { + tmp[i-j] = returnString[i]; + i++; + } + + tmp[i-j] = '\0'; + port += atoi (tmp); + + return port; +} + + +/******[ printRecv ]**************************************************/ +void printRecv (char *str, int i) +{ + int j; + for (j = 0; j < i; j++) + printf("%c", str[j]); +} diff --git a/motorApp/NewportSrc/xps_ftp.h b/motorApp/NewportSrc/xps_ftp.h new file mode 100644 index 00000000..f9abcd3d --- /dev/null +++ b/motorApp/NewportSrc/xps_ftp.h @@ -0,0 +1,65 @@ +/******************************************************************** + * ftp.h : header file for FTP functions * + * * + * Authors : Max Lekeux * + * * + * Modifications : * + * - 23aug06,ML : creation * + * * + * Warning : These functions were created to work with the XPS FTP * + * server. They prove the possibility to use standard * + * FTP functions. They are developped to be * + * cross-platform (Linux, Unix, Windows, VxWorks) * + * * + * Warning for Visual C++ : don't forget to add wsock32.lib to the * + * link. To do so add it in Menu Project->Settings * + * Tab Link -> Objects/Library modules * + ********************************************************************/ + +/* #define VXWORKS */ + +/******[ includes ]**************************************************/ +#ifdef _WIN32 +#include +#include +#else +#include +#include +#ifdef vxWorks +#include +#include "inetLib.h" +#endif +#endif + +#include +#include +#include + + +/******[ defines ]***************************************************/ +/* #define DEBUG */ + +#define IP_SIZE 16 /* size of an IP address */ +#define NAME_SIZE 128 /* size for login, password */ +#define COMMAND_SIZE 256 /* size of a FTP command string */ +#define RETURN_SIZE 1500 /* size of a return (size of standard IP package) */ +#define PATH_SIZE 256 /* size of path */ + + +/******[ global variables ]******************************************/ + +int ftpChangeDir (int, char*); + +/******[ prototypes ]************************************************/ +/* FTP commands */ +int ftpConnect (char*, char*, char*, int*); +int ftpDisconnect (int); +int ftpChangeDir (int, char*); +int ftpRetreaveFile (int, char*); +int ftpStoreFile(int, char*); + +/* localy used functions */ +int code(char*); +int sendFtpCommandAndReceive (int, char*, char*); +int getPort (int, char*); +void printRecv (char*, int);