/*
Complete FTP class
Author : sanjay Murugesan
Email : sanjay@msanjay.net
Please feel free to use this code in your own projects, however, I would appreciate email
with any suggestions or comments, or even just a note saying "hey, I just used this to
in my so and so project ".
Check out more of my codes at http://projects.msanjay.net
*/
#include "ftp.h"
// make the port command
void FTP::GetPortCommand(char *PortCommand)
{
char ipAddr[17];
char PartOfIP[4];
//char PortCommand[30];
char PartOfPort[6];
char *temp;
hostent *h;
char hostname[20];
int err;
// get the ip address
if ((err=gethostname(hostname,20))==-1)
{
cout<<"error in getting the hostname from the system"<<endl;
exit(1);
}
if ((h=gethostbyname(hostname)) == NULL) { // get the host info
cout<<"Error in finding the ip address of the host name";
exit(1);
}
strcpy(ipAddr,inet_ntoa(*((struct in_addr *)h->h_addr)));
//cout<<"The ip address is : "<<ipAddr<<endl;
strcpy(PortCommand,"PORT ");
temp=strtok(ipAddr,".");
while(temp!=NULL)
{
strcpy(PartOfIP,temp);
strcat(PortCommand,PartOfIP);
strcat(PortCommand,",");
temp=strtok(NULL,".\0");
}
itoa(ClientPort/256,PartOfPort,10);
strcat(PortCommand,PartOfPort);
strcat(PortCommand,",");
itoa(ClientPort%256,PartOfPort,10);
strcat(PortCommand,PartOfPort);
strcat(PortCommand,"\r\n");
}
// return the debug mode
bool FTP::isDebug()
{
return debug;
}
// Toggle the debug mode
void FTP::ToggleDebug()
{
if (debug)
debug = false;
else
debug = true;
}
// get the file name
bool FTP::GetFile(char file[])
{
char cmd[100],PortCommand[30],*fileContent,*RecvBuffer,*fsize;
int fileSize;
strcpy(cmd,"SIZE ");
strcat(cmd,file);
if (debug)
cout<<"<<"<<cmd<<endl;
strcat(cmd,"\r\n");
int SendBytes=SendData(cmd);
int RecvBytes=RecvData(RecvBuffer);
if (debug)
cout<<">>"<<RecvBuffer<<endl;
if (strstr(RecvBuffer,"550")!=NULL)
{
cout<<"=> Such a file name does not exist in server"<<endl<<endl;
return false;
}
fsize = strtok(RecvBuffer," ");
fsize = strtok(NULL,"\0 ");
SizeOfFile = atoi(fsize);
//cout<<"size of file"<<SizeOfFile;
strcpy(cmd,"TYPE I\r\n");
if (debug)
cout<<"<<"<<cmd;
SendBytes=SendData(cmd);
RecvBytes=RecvData(RecvBuffer);
//cout<<"BINARY VALUE SET"<<RecvBuffer<<endl;
if (debug)
cout<<">>"<<RecvBuffer<<endl;
strcpy(cmd,"RETR ");
strcat(cmd,file);
strcat(cmd,"\r\n");
// get the port command
GetPortCommand(PortCommand);
if (debug)
cout<<"<<"<<PortCommand<<endl;
SendBytes=SendData(PortCommand);
RecvBytes=RecvData(RecvBuffer);
if (debug)
cout<<">>"<<RecvBuffer<<endl;
if (debug)
cout<<"<<"<<cmd;
SendBytes=SendData(cmd);
RecvBytes=RecvData(RecvBuffer);
if (debug)
cout<<">>"<<RecvBuffer<<endl;
fileSize = GetDataFromServer(fileContent);
//delete RecvBuffer;
RecvBytes=RecvData(RecvBuffer);
if (debug)
cout<<">>"<<RecvBuffer<<endl;
if (strstr(RecvBuffer,"226")==NULL)
{
cout<<"=> Error in receiving file during Get command"<<endl<<endl;
return false;
}
ofstream fout;
fout.open(file,ios::out | ios::binary);
fout.write(fileContent,fileSize);
fout.close();
return true;
}
// open a connection to the server
bool FTP::OpenConnection(char *ip)
{
char *message;
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
cout<<"Failed to load Winsock library!\n";
return 1;
}
// cout << "Looking up address..." << flush;
u_long nRemoteAddress = LookupAddress(ip);
if (nRemoteAddress == INADDR_NONE) {
cout << endl << "Please check the IP address entered by you " <<
endl;
return false;
}
in_addr Address;
memcpy(&Address, &nRemoteAddress, sizeof(u_long));
ClientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
char yes='1';
// lose the pesky "Address already in use" error message
if (setsockopt(ClientSock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(char)) == -1) {
cout<<"error in setsockopt call"<<endl;
exit(1);
}
server.sin_family = AF_INET;
server.sin_port = htons(ServerPort);
server.sin_addr.s_addr = nRemoteAddress;
memset(&(server.sin_zero), '\0', 8); // zero the rest of the struct
if (connect(ClientSock, (struct sockaddr *)&server,
sizeof(server)) == SOCKET_ERROR)
{
cout<<"connect() failed: "<< WSAGetLastError()<<endl;
return false;
}
if (!RecvData(message))
{
cout<<"Error in receiving confirmation for OPEN command"<<endl;
return false;
}
if (debug)
cout<<">>"<<message<<endl;
if (strstr(message,"220")!=NULL)
return true;
else
{
cout<<"=> Server could not accept the connection. May be maximum limit of users reached"<<endl<<endl;
return false;
}
}
// send user name to the server
int FTP::SendUser(char user[])
{
char *RecvBuffer;
char userCmd[50];
strcpy(userCmd,"USER ");
strcat(userCmd,user);
strcat(userCmd,"\r\n");
if (debug)
cout<<"<<"<<userCmd;
int SendBytes=SendData(userCmd);
int RecvBytes=RecvData(RecvBuffer);
if (debug)
cout<<">>"<<RecvBuffer<<endl;
// if(strstr(RecvBuffer,"331")==NULL)
// {
// cout<<"=> User name cannot be validated :( "<<endl;
// return 0;
// }
return RecvBytes;
}
// send password to the server
bool FTP::SendPass(char pass[])
{
char *RecvBuffer;
char passrCmd[50];
strcpy(passrCmd,"PASS ");
strcat(passrCmd,pass);
strcat(passrCmd,"\r\n");
if (debug)
cout<<"<<"<<passrCmd;
if (SendData(passrCmd)==0)
{
cout<<"=> Error in sending the password to the server"<<endl<<endl;
return false;
}
if (RecvData(RecvBuffer)==0)
{
cout<<">>"<<RecvBuffer<<endl;
cout<<"=> Error in getting the confirmation for password to the server."<<endl<<endl;
return false;
}
if (debug)
cout<<">>"<<RecvBuffer<<endl;
if (strstr(RecvBuffer,"230")!=NULL)
return true;
else
{
cout<<"=> Server could not authenticate the user.. "<<endl<<endl;
return false;
}
}
// get the current working directory from the server
int FTP::PrintWorkingDirectory()
{
char *dir;
int RecvBytes;
char cmd[5];
strcpy(cmd,"PWD\r\n");
if (debug)
cout<<"<<"<<endl;
if(SendData(cmd)==0)
{
cout<<"=> Error in sending the CWD command to the server."<<endl<<endl;
return false;
}
if ((RecvBytes=RecvData(dir))==0)
{
cout<<">>"<<dir<<endl;
cout<<"=> Error in getting the current working directory from the server."<<endl<<endl;
return false;
}
cout<<dir<<endl;
return RecvBytes;
}
// change the current working directory of the server
int FTP::ChangeWorkingDirectory(char dir[])
{
char cmd[100];
int RecvBytes;
char *RecvBuffer;
strcpy(cmd,"CWD ");
strcat(cmd,dir);
if (debug)
cout<<"<<"<<cmd<<endl;
strcat(cmd,"\r\n");
SendData(cmd);
if ((RecvBytes=RecvData(RecvBuffer))==0)
{
cout<<RecvBuffer<<endl;
cout<<"=> Error in getting the changing the current directory of the server."<<endl<<endl;
return false;
}
if (debug)
cout<<">>"<<RecvBuffer<<endl;
return RecvBytes;
}
// delete a file from the server
int FTP::DeleteFile(char file[])
{
char cmd[100];
int RecvBytes;
char *RecvBuffer;
strcpy(cmd,"DELE ");
strcat(cmd,file);
if (debug)
cout<<"<<"<<cmd<<endl;
strcat(cmd,"\r\n");
SendData(cmd);
if ((RecvBytes=RecvData(RecvBuffer))==0)
{
cout<<RecvBuffer<<endl;
cout<<"=> Error in deleting the file \""<<file<<"\" from the server "<<endl<<endl;
return false;
}
if (debug)
cout<<">>"<<RecvBuffer<<endl;
return RecvBytes;
}
// close the connection
void FTP::quit()
{
char *RecvBuffer;
char cmd[7];
strcpy(cmd,"QUIT\r\n");
cout<<"<<"<<cmd;
SendData(cmd);
if (RecvData(RecvBuffer)==0)
{
cout<<RecvBuffer<<endl;
cout<<"=> Error in closing the connection."<<endl<<endl;
}
if (debug