#include #include #include #include #include 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 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 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; 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 &/*messageStrings*/) { }