#include "stFtpClient.h"
int stFtp_init(ST_Ftp **stFtp)
{
*stFtp = (ST_Ftp *)malloc(sizeof(ST_Ftp));
if(stFtp == NULL)
{
//printf("alloc ST_Ftp faile!\n");
return -1;
}
(*stFtp)->control_stream = 0;
memset(&((*stFtp)->s_in),0,sizeof(struct sockaddr_in));
memset(&((*stFtp)->reply),'\0',64);
memset(&((*stFtp)->error),'\0',64);
return 1;
}
int stFtp_free(ST_Ftp *stFtp)
{
pclose(stFtp->control_stream);
free(stFtp);
return 1;
}
static int stConnect(const struct sockaddr_in *s_in)
{
int sockcmd = socket(AF_INET,SOCK_STREAM,0);
if(connect(sockcmd,(const struct sockaddr*)s_in,sizeof(struct sockaddr_in)) < 0){
printf("Unable to connect to remote host(%s)",inet_ntoa(s_in->sin_addr));
}
return sockcmd;
}
int stFtpCmd(ST_Ftp *stFtp,const char *str1,const char *str2,char *buf)
{
if(verbose_flag && str1 && str2){
fprintf(stdout,"cmd %s %s\n",str1,str2);
}
else if(verbose_flag && str1){
fprintf(stdout,"cmd %s\n",str1);
}
if(str1){
if(str2){
fprintf(stFtp->control_stream,"%s%s\n",str1,str2);
}else{
fprintf(stFtp->control_stream,"%s\n",str1);
}
}
do{
char *buf_ptr;
if(fgets(buf,510,stFtp->control_stream) == NULL){
}
buf_ptr = strstr(buf,"\r\n");
if(buf_ptr){
*buf_ptr = '\0';
}
}while(!isdigit(buf[0]) || buf[3] != ' ' );
if(verbose_flag){
fprintf(stdout,"%s\n",buf);
}
return atoi(buf);
}
int stConnectToServer(ST_Ftp *stFtp,char *user,char *pass,char *host,int port)
{
struct hostent *hent;
char buf[512];
stFtp->s_in.sin_family = AF_INET;
hent = gethostbyname(host);
memcpy(&(stFtp->s_in.sin_addr),hent->h_addr_list[0],hent->h_length);
stFtp->s_in.sin_port = htons(port);
stFtp->control_stream = fdopen(stConnect(&(stFtp->s_in)),"r+");
if(stFtp->control_stream == NULL){
printf("Could not open control stream!\n");
return 0;
}
if(stFtpCmd(stFtp,NULL,NULL,buf) != 220){ //server ready for new user
printf("%s\n",buf);
return 0;
}
switch(stFtpCmd(stFtp,"USER",user,buf)){
case 230: //user login,continue
break;
case 331: //right user,need pass
if(stFtpCmd(stFtp,"PASS",pass,buf) != 230){
printf("PASS ERROR:%s",buf + 4);
return 0;
}
break;
default:
{
printf("USER error:%s",buf+4);
return 0;
}
}
stFtpCmd(stFtp,"TYPE I",NULL,buf);
return 1;
}
int stDisConnectToServer(ST_Ftp *stFtp)
{
char buf[64];
stFtpCmd(stFtp,"QUIT",NULL,buf);
return 1;
}
int stTransfer_Bin(ST_Ftp *stFtp)
{
char buf[64];
return (stFtpCmd(stFtp,"TYPE I",NULL,buf) == 200);
}
int stTransfer_Ascii(ST_Ftp *stFtp)
{
char buf[64];
return (stFtpCmd(stFtp,"TYPE A",NULL,buf) == 200);
}
int stCwd(ST_Ftp *stFtp,char *dir) //change work dir
{
char buf[64];
return (stFtpCmd(stFtp,"CWD ",dir,buf) == 250);
}
char *stPwd(ST_Ftp *stFtp) //show current dir
{
char buf[128];
if(stFtpCmd(stFtp,"PWD",NULL,buf) == 257)
{
char *start = buf+5;
char *end = strrchr(start,'\"');
int len = end -start;
char *path = (char *)malloc(len+1);
strncpy(path,start,len);
path[len]='\0';
return path;
}
else
return NULL;
}
int stTrasferMode_PASV(ST_Ftp *stFtp) //show current transfer mode
{
char buf[64];
return (stFtpCmd(stFtp,"PASV",NULL,buf) == 227);
}
static int stConnect_ftpdata(ST_Ftp *stFtp,char *buf)
{
unsigned short port;
char *str_ptr;
str_ptr = strrchr(buf,',');
*str_ptr = '\0';
port = atoi(str_ptr +1);
str_ptr = strrchr(buf,',');
*str_ptr = '\0';
port += atoi(str_ptr + 1) *256;
stFtp->s_in.sin_port = htons(port);
return (stConnect(&(stFtp->s_in)));
}
int stListDir(ST_Ftp *stFtp)
{
char buf[512];
char *path = 0;
char dataBuf[DATABUFSIZE];
int fd_data;
int ret = 0;
printf("List current's file!\n");
if(stFtpCmd(stFtp,"PASV ",NULL,buf) != 227){
printf("PASV error:%s\n",buf);
return FALSE;
}
fd_data = stConnect_ftpdata(stFtp,buf);
if(fd_data < 0){
printf("stListDir: connect ftpdata faile!\n");
close(fd_data);
return FALSE;
}
path = stPwd(stFtp);
ret = stFtpCmd(stFtp,"LIST ",path,buf);
switch(ret){
case 150:
while((ret = recv(fd_data,dataBuf,DATABUFSIZE,0)) > 0){
dataBuf[ret] = '\0';
printf("List dir:\n%s\n",dataBuf);
}
break;
default:
close(fd_data);
}
free(path);
close(fd_data);
stFtpCmd(stFtp,NULL,NULL,buf);
return ret;
}
int stPutFile(ST_Ftp *stFtp,char *localFile)
{
char buf[512];
char dataBuf[DATABUFSIZE];
int fd_data;
int ret;
int pfile;
int exist = access(localFile,0);
FILE *file = 0;
if(exist != 0){
printf("File is not exist!\n");
return 0;
}
if(stFtpCmd(stFtp,"PASV",NULL,buf) != 227){
printf("PASV error: %s",buf+4);
}
fd_data = stConnect_ftpdata(stFtp,buf);
if(fd_data < 0){
printf("connect ftpdata faile!\n");
close(fd_data);
return 0;
}
ret = stFtpCmd(stFtp,"STOR ",localFile,buf);
switch(ret){
case 125:
case 150:
file = fopen(localFile,"r");
pfile = fileno(file);
while((ret = read(pfile,dataBuf,DATABUFSIZE)) > 0){
printf("ret = %d\n",ret);
write(fd_data,dataBuf,ret);
}
fclose(file);
break;
default:
close(fd_data);
}
close(fd_data);
if(stFtpCmd(stFtp,NULL,NULL,buf) != 226){
printf("error: %s\n",buf);
}
return 1;
}
int stGetFile(ST_Ftp *stFtp,char *saveFile)
{
char buf[512];
char dataBuf[DATABUFSIZE];
int fd_data;
int ret;
int pfile = 0;
FILE *file = 0;
if(stFtpCmd(stFtp,"PASV",NULL,buf) != 227){
printf("PASV error: %s",buf);
}
fd_data = stConnect_ftpdata(stFtp,buf);
if(fd_data < 0){
printf("connect to server(ftpdata port) fail!\n");
close(fd_data);
return FALSE;
}
ret = stFtpCmd(stFtp,"RETR ",saveFile,buf);
switch(ret){
case 125:
case 150:
printf("yes!\n");
file = fopen(saveFile,"a");
if(file == NULL){
printf("open file error!\n");
return 0;
}
pfile = fileno(file);
while((ret = read(fd_data,dataBuf,DATABUFSIZE)) > 0){
printf("file's size is:%d\n",ret);
write(pfile,dataBuf,ret);
}
fclose(file);
break;
default:
close(fd_data);
break;
}
close(fd_data);
if(stFtpCmd(stFtp,NULL,NULL,buf) != 226){
printf("error:%s\n",buf);
}
return 1;
}
int stRmDir(char *path) //remove all files and dir in the path
{
struct dirent* ent = NULL;
DIR *dir;
static char subdir[1024] = "";
if(!strcmp(subdir, ""))
strcpy(subdir, path);
dir = opendir(path);
if(dir == NULL){
printf("file not exist!\n");
return FALSE;
}
while((ent = readdir(dir))!= NULL){
if(ent->d_type == 8||ent->d_type == 10){
char file[1024] = "";
strcpy(file, subdir);
strcat(file, "/");
strcat(file, ent->d_name);
printf("List file %s\n", ent->d_name);
remove(file);
}
else {
if(!strcmp(ent->d_name, "..") ||!strcmp(ent->d_name, "."))
continue;
strcat(subdir, "/");
strcat(subdir, ent->d_name);
printf("Sub dir %s %d dirpath = %s type = %d\n", ent->d_name, ent->d_reclen, subdir, ent->d_type);
stRmDir(subdir);
remove(subdir);
subdir[(int)(strlen(subdir)- strlen(ent->d_name)- 1)] = '\0';
printf("Return %s\n", ent->d_name, ent->d_reclen);
}
}
closedir(dir);
return TRUE;
}