forked from epics_driver_modules/motorBase
New file for FTP to XPS controller
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
@@ -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 <winsock.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef vxWorks
|
||||
#include <sockLib.h>
|
||||
#include "inetLib.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/******[ 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);
|
||||
Reference in New Issue
Block a user