Files
Work/ftp/FTP.BAK
2024-08-07 09:16:27 -04:00

443 lines
14 KiB
Plaintext

#include <stdio.h>
#include <socket/hostent.hpp>
#include <socket/servent.hpp>
#include <socket/socket.hpp>
#include <ftp/ftp.hpp>
FTPClient::FTPClient(void)
: mIsLoggedIn(FALSE), mCurrentType('A')
{
createCommands();
}
FTPClient::~FTPClient()
{
}
WORD FTPClient::open(String hostName)
{
HostEnt hostEntry;
ServEnt serverEntry;
message(String("trying ")+hostName+String("..."));
if(!mWSASystem.isInitialized()){message("WINSOCK initialization failure.");return FALSE;}
InternetAddress internetAddress(hostName);
if(!internetAddress.isZero()){if(!hostEntry.hostByAddress(internetAddress)){message(String("no DNS entry for ")+hostName);return FALSE;}}
else if(!hostEntry.hostByName(hostName)){message(String("no DNS entry for ")+hostName);return FALSE;}
message(String("connect...")+String("'")+hostEntry.hostName()+String("' (")+(String)(hostEntry.addresses())[0]+String(")"));
INETSocketAddress::internetAddress((hostEntry.addresses())[0]);
if(!serverEntry.serviceByName("ftp","tcp")){message("cannot determine port number for ftp daemon.");return FALSE;}
if(!mFTPControl.openSocket()){message("unable to create socket.");return FALSE;}
INETSocketAddress::family(PF_INET);
INETSocketAddress::port(serverEntry.port());
if(!mFTPControl.connect((INETSocketAddress&)*this)){message("unable to connect to ftp daemon");return FALSE;}
receiveStrings();
mFTPControl.getSocketName((INETSocketAddress&)*this);
return mFTPControl.isConnected();
}
WORD FTPClient::login(String userName,String password)
{
String blank(" ");
String receiveString;
if(!mFTPControl.isConnected())return FALSE;
if(isLoggedIn())logout();
putControlData(mFTPCommands[User]+blank+userName,FALSE);
if(!mFTPControl.receive(receiveString))return FALSE;
message(receiveString);
putControlData(mFTPCommands[Password]+blank+password,FALSE);
if(!mFTPControl.receive(receiveString))return FALSE;
message(receiveString);
while(mFTPControl.hasData())
{
mFTPControl.receive(receiveString);
message(receiveString);
}
if(receiveString.betweenString(0,' ')==String("530"))return FALSE;
isLoggedIn(TRUE);
return TRUE;
}
WORD FTPClient::logout(void)
{
Block<String> responseLines;
isLoggedIn(FALSE);
if(!mFTPControl.isConnected()){message("Not connected.");return FALSE;}
if(!putControlData(mFTPCommands[Logout],FALSE))return FALSE;
if(!mFTPControl.receive(responseLines))return FALSE;
message(responseLines);
mFTPControl.closeSocket();
return TRUE;
}
WORD FTPClient::port(FTPData &ftpData)
{
InternetAddress inetAddr;
String portString;
String workString;
WORD dataPort;
inetAddr=((INETSocketAddress&)*this).internetAddress();
portString=(String)inetAddr;
portString.replaceToken('.',',');
dataPort=ntohs(((INETSocketAddress&)ftpData).port());
::sprintf(workString,",%d,%d",(short)HIBYTE(dataPort),(short)LOBYTE(dataPort));
putControlData(mFTPCommands[DataPort]+String(" ")+portString+workString,FALSE);
if(!mFTPControl.receive(workString))return FALSE;
message(workString);
if(workString.betweenString(0,' ')==String("500"))return FALSE;
return TRUE;
}
WORD FTPClient::changeWorkingDirectory(String workingDirectory)
{
String responseLine;
if(!mFTPControl.isConnected()||workingDirectory.isNull())return FALSE;
if(!putControlData(mFTPCommands[ChangeWorkingDirectory]+String(" ")+workingDirectory,FALSE))return FALSE;
if(!mFTPControl.receive(responseLine))return FALSE;
message(responseLine);
return TRUE;
}
WORD FTPClient::printWorkingDirectory(void)
{
String workingDirectory;
if(!mFTPControl.isConnected())return FALSE;
if(!putControlData(mFTPCommands[PrintWorkingDirectory],FALSE))return FALSE;
if(!mFTPControl.receive(workingDirectory))return FALSE;
message(workingDirectory);
return TRUE;
}
WORD FTPClient::list(String pathName)
{
String controlData;
String responseLine;
if(!mFTPControl.isConnected())return FALSE;
if(pathName.isNull())controlData=mFTPCommands[List];
else controlData=mFTPCommands[List]+String(" ")+pathName;
if(!putControlData(controlData,FALSE))return FALSE;
if(!mFTPControl.receive(responseLine))return FALSE;
if(!(responseLine.betweenString(0,' ')==String("150")))return FALSE;
return TRUE;
}
WORD FTPClient::nameList(String pathName,WORD showResponse)
{
String controlData;
String responseLine;
if(!mFTPControl.isConnected())return FALSE;
if(pathName.isNull())controlData=mFTPCommands[NameList];
else controlData=mFTPCommands[NameList]+String(" ")+pathName;
if(!putControlData(controlData,FALSE))return FALSE;
if(!mFTPControl.receive(responseLine))return FALSE;
if(showResponse)message(responseLine);
if(!(responseLine.betweenString(0,' ')==String("150")))return FALSE;
return TRUE;
}
WORD FTPClient::type(BYTE type,BYTE storage)
{
String representationType;
String responseLine;
if(!mFTPControl.isConnected())return FALSE;
if('A'==type||'E'==type)
{
if(storage)::sprintf(representationType,"%c %c",type,storage);
else ::sprintf(representationType,"%c",type);
}
else if('I'==type)::sprintf(representationType,"%c",type);
else if('L'==type)::sprintf(representationType,"%c %d",type,(int)storage);
else return FALSE;
if(!putControlData(mFTPCommands[RepresentationType]+String(" ")+representationType,FALSE))return FALSE;
if(!mFTPControl.receive(responseLine))return FALSE;
message(responseLine);
mCurrentType=type;
return TRUE;
}
WORD FTPClient::retrieve(String pathFileName,DWORD &sizeData)
{
String responseString;
char *lpChar;
sizeData=0;
if(!mFTPControl.isConnected()||pathFileName.isNull())return FALSE;
if(!putControlData(mFTPCommands[Retrieve]+String(" ")+pathFileName,FALSE))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
message(responseString);
if(!(responseString.betweenString(0,' ')==String("150")))return FALSE;
lpChar=(char*)responseString.strstr("bytes");
if(!lpChar)return TRUE;
while(*lpChar!='(')lpChar--;
String sizeString(++lpChar);
sizeString=sizeString.betweenString(0,' ');
if(sizeString.isNull())return FALSE;
sizeData=(DWORD)((long)sizeString);
return TRUE;
}
WORD FTPClient::store(String pathFileName)
{
String responseString;
if(!mFTPControl.isConnected()||pathFileName.isNull())return FALSE;
if(!putControlData(mFTPCommands[Store]+String(" ")+pathFileName,FALSE))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
message(responseString);
return TRUE;
}
WORD FTPClient::mode(BYTE transferMode)
{
String modeString;
if(!mFTPControl.isConnected())return FALSE;
if('S'!=transferMode&&'B'!=transferMode&&'C'!=transferMode)return FALSE;
::sprintf(modeString,"%c",transferMode);
return putControlData(mFTPCommands[TransferMode]+String(" ")+modeString);
}
WORD FTPClient::renameFrom(String oldPathFileName)
{
String responseString;
if(!mFTPControl.isConnected()||oldPathFileName.isNull())return FALSE;
if(!putControlData(mFTPCommands[RenameFrom]+String(" ")+oldPathFileName,FALSE))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
if(!(responseString.betweenString(0,' ')==String("350"))){message(responseString);return FALSE;}
return TRUE;
}
WORD FTPClient::renameTo(String newPathFileName)
{
String responseString;
if(!mFTPControl.isConnected()||newPathFileName.isNull())return FALSE;
if(!putControlData(mFTPCommands[RenameTo]+String(" ")+newPathFileName,FALSE))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
message(responseString);
if(!(responseString.betweenString(0,' ')==String("250")))return FALSE;
return TRUE;
}
WORD FTPClient::account(String accountInfo)
{
if(!mFTPControl.isConnected()||accountInfo.isNull())return FALSE;
return putControlData(mFTPCommands[Account]+String(" ")+accountInfo);
}
WORD FTPClient::changeToParentDirectory(void)
{
if(!mFTPControl.isConnected())return FALSE;
return putControlData(mFTPCommands[ChangeToParentDirectory]);
}
WORD FTPClient::structureMount(String systemFileGroupDesignator)
{
if(!mFTPControl.isConnected()||systemFileGroupDesignator.isNull())return FALSE;
return putControlData(mFTPCommands[StructureMount]+String(" ")+systemFileGroupDesignator);
}
WORD FTPClient::reinitialize(void)
{
if(!mFTPControl.isConnected())return FALSE;
return putControlData(mFTPCommands[Reinitialize]);
}
WORD FTPClient::passive(void)
{
if(!mFTPControl.isConnected())return FALSE;
return putControlData(mFTPCommands[Passive]);
}
WORD FTPClient::fileStructure(BYTE structure)
{
String structureString;
if(!mFTPControl.isConnected())return FALSE;
if('F'!=structure&&'R'!=structure&&'P'!=structure)return FALSE;
::sprintf(structureString,"%c",structure);
return putControlData(mFTPCommands[FileStructure]+String(" ")+structureString);
}
WORD FTPClient::storeUnique(String pathFileName)
{
if(!mFTPControl.isConnected()||pathFileName.isNull())return FALSE;
return putControlData(mFTPCommands[StoreUnique]+String(" ")+pathFileName);
}
WORD FTPClient::append(String pathFileName)
{
if(!mFTPControl.isConnected()||pathFileName.isNull())return FALSE;
return putControlData(mFTPCommands[Append]+String(" ")+pathFileName);
}
WORD FTPClient::allocate(DWORD numBytes,DWORD maxRecord)
{
String allocationString;
if(!mFTPControl.isConnected())return FALSE;
if(maxRecord)::sprintf(allocationString,"%ld R %ld",numBytes,maxRecord);
else ::sprintf(allocationString,"%ld",numBytes);
return putControlData(mFTPCommands[Allocate]+String(" ")+allocationString);
}
WORD FTPClient::restart(String serverMarker)
{
if(!mFTPControl.isConnected()||serverMarker.isNull())return FALSE;
return putControlData(mFTPCommands[Restart]+String(" ")+serverMarker);
}
WORD FTPClient::abort(void)
{
if(!mFTPControl.isConnected())return FALSE;
return putControlData(mFTPCommands[Abort]);
}
WORD FTPClient::remove(String pathFileName)
{
String responseString;
if(!mFTPControl.isConnected()||pathFileName.isNull())return FALSE;
if(!putControlData(mFTPCommands[Delete]+String(" ")+pathFileName,FALSE))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
message(responseString);
return TRUE;
}
WORD FTPClient::removeDirectory(String pathDirectoryName)
{
String responseString;
if(!mFTPControl.isConnected()||pathDirectoryName.isNull())return FALSE;
if(!putControlData(mFTPCommands[RemoveDirectory]+String(" ")+pathDirectoryName,FALSE))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
message(responseString);
return TRUE;
}
WORD FTPClient::makeDirectory(String pathDirectoryName)
{
String responseString;
if(!mFTPControl.isConnected()||pathDirectoryName.isNull())return FALSE;
if(!putControlData(mFTPCommands[MakeDirectory]+String(" ")+pathDirectoryName,FALSE))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
message(responseString);
return TRUE;
}
WORD FTPClient::siteParameters(void)
{
String responseString;
if(!mFTPControl.isConnected())return FALSE;
if(!putControlData(mFTPCommands[SiteParameters]))return FALSE;
if(!mFTPControl.receive(responseString))return FALSE;
message(responseString);
return TRUE;
}
WORD FTPClient::system(void)
{
if(!mFTPControl.isConnected())return FALSE;
return putControlData(mFTPCommands[System]);
}
WORD FTPClient::status(String pathName)
{
if(!mFTPControl.isConnected())return FALSE;
if(!pathName.isNull())return putControlData(mFTPCommands[Status]+String(" ")+pathName);
return putControlData(mFTPCommands[Status]);
}
WORD FTPClient::help(String commandName)
{
Block<String> receiveStrings;
if(!mFTPControl.isConnected())return FALSE;
if(!commandName.isNull()){if(!putControlData(mFTPCommands[Help]+String(" ")+commandName,FALSE))return FALSE;}
else if(!putControlData(mFTPCommands[Help],FALSE))return FALSE;
mFTPControl.receive(receiveStrings);
for(short itemIndex=0;itemIndex<receiveStrings.size();itemIndex++)message(receiveStrings[itemIndex]);
return TRUE;
}
WORD FTPClient::noop(void)
{
if(!mFTPControl.isConnected())return FALSE;
return putControlData(mFTPCommands[Noop]);
}
WORD FTPClient::putControlData(String stringData,WORD waitForResponse)
{
if(!mFTPControl.isConnected())return FALSE;
if(!mFTPControl.send(stringData)){message("error sending data to ftp daemon");return FALSE;}
if(waitForResponse&&!getControlData()){message("error reading data from ftp daemon");return FALSE;}
return TRUE;
}
WORD FTPClient::getControlData(void)
{
mResponseStrings.remove();
mFTPControl.receive(mResponseStrings);
return mResponseStrings.size();
}
void FTPClient::receiveStrings(WORD displayStrings)
{
Block<String> receiveStrings;
if(!mFTPControl.isConnected())return;
if(!mFTPControl.receive(receiveStrings))return;
if(!displayStrings||!receiveStrings.size())return;
message(receiveStrings);
}
void FTPClient::createCommands(void)
{
mFTPCommands.insert(&String("USER")); // user name
mFTPCommands.insert(&String("PASS")); // password
mFTPCommands.insert(&String("ACCT")); // account
mFTPCommands.insert(&String("CWD")); // change working directory
mFTPCommands.insert(&String("CDUP")); // change to parent directory
mFTPCommands.insert(&String("SMNT")); // structure mount
mFTPCommands.insert(&String("REIN")); // reinitialize
mFTPCommands.insert(&String("QUIT")); // quit
mFTPCommands.insert(&String("PORT")); // data port
mFTPCommands.insert(&String("PASV")); // passive
mFTPCommands.insert(&String("TYPE")); // representation type
mFTPCommands.insert(&String("STRU")); // file structure
mFTPCommands.insert(&String("MODE")); // transfer mode
mFTPCommands.insert(&String("RETR")); // retrieve
mFTPCommands.insert(&String("STOR")); // store
mFTPCommands.insert(&String("STOU")); // store unique
mFTPCommands.insert(&String("APPE")); // append (with create)
mFTPCommands.insert(&String("ALLO")); // allocate
mFTPCommands.insert(&String("REST")); // restart
mFTPCommands.insert(&String("RNFR")); // rename from
mFTPCommands.insert(&String("RNTO")); // rename to
mFTPCommands.insert(&String("ABOR")); // abort
mFTPCommands.insert(&String("DELE")); // delete
mFTPCommands.insert(&String("RMD")); // remove directory
mFTPCommands.insert(&String("MKD")); // make directory
mFTPCommands.insert(&String("PWD")); // print working directory
mFTPCommands.insert(&String("LIST")); // list
mFTPCommands.insert(&String("NLST")); // name list
mFTPCommands.insert(&String("SITE")); // site parameters
mFTPCommands.insert(&String("SYST")); // system
mFTPCommands.insert(&String("STAT")); // status
mFTPCommands.insert(&String("HELP")); // help
mFTPCommands.insert(&String("NOOP")); // noop
}
// *** virtual overloads
void FTPClient::message(String /*messageString*/)
{
}
void FTPClient::message(Block<String> &/*messageStrings*/)
{
}