Thread: C++ FTP class won't work

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    29

    C++ FTP class won't work

    I've the following C++ code that is a FTP class test.
    Code:
    #if defined(_WIN32)
       #include <windows.h>
       #include <winsock.h>
     
       #define socket_receive(Socket,buffer,len, flags) recv(Socket, (char*)buffer, len , flags)
       #define socket_send(Socket,buffer,len, flags) send(Socket, (char*)buffer, len , flags)
       #define socket_close closesocket
    #else
       #include <sys/socket.h>
       #include <netinet/in.h>
       #include <netdb.h>
       #include <arpa/inet.h>
     
       #define socket_receive(Socket,buffer,len, flags) recv(Socket, (char*)buffer, len , flags)
       #define socket_send(Socket,buffer,len, flags) send(Socket, (char*)buffer, len , flags)
       #define socket_close close
    #endif
     
    #include <string>
    #include <vector>
    #include <fstream>
    #include <iostream>
    using namespace std;
    #include <boost/algorithm/string.hpp>
    #include <boost/lexical_cast.hpp>
    using namespace boost;
     
          class FTPUploader
          {
          public:
             string Host, Username, Password, Path;
             bool Logined, Initialized;
     
             SOCKET wSOCKET;
             int bytes, retValue;
             string mes, reply;
     
             const static int BLOCK_SIZE = 512;
             char buffer[BLOCK_SIZE];
     
          public:
             FTPUploader(string _Host, string _Username, string _Password, string _Path)
             {
                this->Host = _Host;
                this->Username = _Username;
                this->Password = _Password;
                this->Path = _Path;
     
                this->Initialized = false;
                this->Logined = false;
             }
     
             /* methods for gettings and setting properties */
          public:
             void set_Host(string _Host)
             {
                this->Host = _Host;
             }
             string get_Host(void)
             {
                return this->Host;
             }
     
             void set_Username(string _Username)
             {
                this->Username = _Username;
             }
             string get_Username(void)
             {
                return this->Username;
             }
     
             void set_Password(string _Password)
             {
                this->Password = _Password;
             }
             string get_Password(void)
             {
                return this->Password;
             }
     
             void set_Path(string _Path)
             {
                this->Path = _Path;
             }
             string get_Path(void)
             {
                return this->Path;
             }
     
             /* Connection handlig methods */
          private:
             bool Initialize(void)
             {
                if(this->Initialized)
                   return true;
     
                #if defined(_WIN32)
                   WSADATA wsa;
                   if(WSAStartup(MAKEWORD(1, 1), &wsa))
                   {
                      WSACleanup();
                      return false;
                   }
                #endif
     
                this->Initialized = true;
                return true;
             }
     
          public:
             bool Login(void)
             {
                if(this->Logined)
                   return true;
     
                if(!this->Initialized)
                   this->Initialize();
     
                this->wSOCKET = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
                if( this->wSOCKET == INVALID_SOCKET )
                {
                   #if defined (_WIN32)
                      WSACleanup();
                   #endif
                   return false;
                }
     
                hostent *he;
                if( (he = gethostbyname( this->Host.c_str() )) == NULL )
                   return false;
     
                sockaddr_in clientService;
                clientService.sin_family = AF_INET;
                clientService.sin_addr.s_addr = inet_addr( inet_ntoa( (**(in_addr**)he->h_addr_list ) ) );
                clientService.sin_port = htons( 21 );
     
                if( connect( this->wSOCKET, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR )
                {
                   WSACleanup();
                   return false;
                }
     
                this->readReply();
     
                if(this->retValue != 220)
                {
                   this->Close();
                   return false;
                }
     
                this->sendCommand("USER " + this->Username);
     
                if( !(this->retValue == 331 || this->retValue == 230) )
                {
                   this->Cleanup();
                   return false;
                }
     
                if(this->retValue != 230)
                {
                   this->sendCommand("PASS " + this->Password);
     
                   if( !(this->retValue == 230 || this->retValue == 202) )
                   {
                      this->Cleanup();
                      return false;
                   }
                }
     
                this->Logined = true;
     
                this->changeDirectory(this->Path);
                return true;
             }
     
             void Close(void)
             {
                if( this->wSOCKET != 0 )
                {
                   this->sendCommand("QUIT");
                }
     
                this->Cleanup();
                #if defined(_WIN32)
                   WSACleanup();
                #endif
             }
     
             void Cleanup(void)
             {
                if(this->wSOCKET != 0)
                {
                   socket_close(this->wSOCKET);
                   this->wSOCKET = 0;
                }
                this->Initialized = false;
                this->Logined = false;
             }
             /* End Connection handler methods */
          public:
             long getFileSize(string fileName)
             {
                if(!this->Logined)
                   this->Login();
                this->sendCommand("SIZE " + fileName);
     
                long size = 0;
     
                if(this->retValue == 213)
                {
                   size = atol(this->reply.substr(4).c_str());
                }
                else return 0;
     
                return size;
             }
     
          public:
             bool setBinaryMode(bool _mode)
             {
                if(_mode)
                   this->sendCommand("TYPE I");
                else
                   this->sendCommand("TYPE A");
     
                if(this->retValue != 200)
                   return false;
                return true;
             }
     
             bool changeDirectory(string _Path)
             {
                if(_Path == ".")
                   return false;
     
                if(!this->Logined)
                   this->Login();
     
                this->sendCommand("CWD " + _Path);
     
                if(this->retValue != 250)
                   return false;
     
                this->Path = _Path;
     
                return true;
             }
     
             bool makeDirectory(string _DirName)
             {
                if(!this->Logined)
                   this->Login();
     
                this->sendCommand("MKD " + _DirName);
     
                if(this->retValue != 250)
                   return false;
                return true;
             }
     
          public:
             bool upload(string fileName)
             {
                return this->upload(fileName,false);
             }
     
          public:
             bool upload(string fileName,bool resume)
             {
                if(!this->Logined)
                   this->Login();
     
                SOCKET cSocket = this->createDataSocket();
                long offset = 0;
     
                if(resume)
                {
                   try
                   {
                      this->setBinaryMode(true);
                      offset = this->getFileSize(fileName);
                   }
                   catch(bool)
                   {
                      offset = 0;
                   }
                }
     
                if(offset > 0)
                {
                   this->sendCommand("REST " + offset);
                   if(this->retValue != 350)
                      offset = 0;
                }
     
                this->sendCommand("STOR " + fileName);
     
                if( !(this->retValue == 125 || this->retValue == 150) )
                   return false;
     
                /* SECTION = get and send the file */
                ifstream input;
                input.open( fileName.c_str() , ios::binary );
     
                // get length of file:
                int length;
                input.seekg (0, ios::end);
                length = input.tellg();
                input.seekg (0, ios::beg);
     
                // allocate memory:
                char *filebuf;
                filebuf = new char [length];
     
                // read data as a block:
                input.read(filebuf,length);
     
                input.close();
                socket_send(cSocket,filebuf, length ,0);
                /* end SECTION */
     
                if(getpeername(cSocket,0,0))
                   socket_close(cSocket);
     
                this->readReply();
                if( !(this->retValue == 226 || this->retValue == 250) )
                {
                   return false;
                }
                return true;
             }
     
             /* Actor Helpers */
             void readReply(void)
             {
                this->mes = "";
     
                this->reply = this->readLine();
     
                this->retValue = lexical_cast<int>( this->reply.substr(0,3) );
             }
     
             string readLine(void)
             {
                while(true)
                {
                   this->bytes = socket_receive(this->wSOCKET,this->buffer, BLOCK_SIZE ,0);
                   cout << "bytes recived : " << this->bytes << endl;
                   cout << "strlen buffer : " <<(int)strlen(this->buffer) << endl;
                   cout << "Buffer :\n" << this->buffer << endl;
                   this->mes += this->buffer;
                   cout << "Buffer2 :\n" << this->mes << endl;
                   this->mes = this->mes.substr(0,this->bytes);
                   cout << "Buffer3 :\n" << this->mes << endl;
     
                   if(this->bytes < (int)strlen(this->buffer) )
                      break;
                }
     
                vector<string> mess;
     
                split(mess,this->mes,is_any_of("\n"));
     
                if(this->mes.length() > 2)
                {
                   this->mes = mess[mess.size() - 2];
                }
                else
                {
                   this->mes = mess[0];
                }
     
                if(!(this->mes.substr(3,1) == " "))
                {
                   return this->readLine();
                }
     
                return this->mes;
             }
          private:
             void sendCommand(string command)
             {
                command += "\r\n";
                const char *cmdBytes = command.c_str();
                socket_send(this->wSOCKET,cmdBytes, (int)strlen(cmdBytes),0);
                this->readReply();
             }
     
          private:
             SOCKET createDataSocket(void)
             {
                this->sendCommand("PASV");
     
                if(this->retValue != 227)
                   return NULL;
     
                int index1 = (int)( this->reply.find_first_of('(', 0) );
                int index2 = (int)( this->reply.find_first_of(')', 0) );
                string ipData = this->reply.substr(index1 + 1,index2 - index1 - 1);
                int parts[6];
     
                int len = (int)ipData.length();
                int partCount = 0;
                string buf = "";
     
                for(int i = 0; i < len && partCount <= 6; i++)
                {
                   string ch = ipData.substr(i,1);
                   if( isdigit( lexical_cast<char>(ch) ) ) buf += ch;
                   else if(ch != ",")
                   {
                      return NULL;
                   }
     
                   if(ch == "," || i + 1 == len)
                   {
                      try
                      {
                         parts[partCount++] = lexical_cast<int>(buf);
                         buf = "";
                      }
                      catch(bad_lexical_cast &)
                      {
                         return NULL;
                      }
                   }
                }
     
                string ipAddress = lexical_cast<string>( parts[0] ) + "." + lexical_cast<string>( parts[1] ) + "." + lexical_cast<string>( parts[2] ) + "." + lexical_cast<string>( parts[3] );
     
                int port = (parts[4] << 8) + parts[5];
     
                SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
                if( s == INVALID_SOCKET )
                   return NULL;
     
                sockaddr_in clientService;
                clientService.sin_family = AF_INET;
                clientService.sin_addr.s_addr = inet_addr( ipAddress.c_str() );
                clientService.sin_port = htons( port );
     
                if( connect( s, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR )
                   return NULL;
                return s;
             }
             /* End Actor helpers */
          };
     
    int main()
    {
       FTPUploader ftp("ftp.magicasoft.net","usr","pass",".");
       ftp.Login();
       ftp.changeDirectory("httpdocs");
       cin.get();
       return 0;
    }
    it gives the output:
    Code:
    bytes recived : 59
    strlen buffer : 519
    Buffer :
    220 ProFTPD 1.2.9 Server (ProFTPD) [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer2 :
    220 ProFTPD 1.2.9 Server (ProFTPD) [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer3 :
    220 ProFTPD 1.2.9 Server (ProFTPD) [galapagos.globat.com]
     
    bytes recived : 35
    strlen buffer : 519
    Buffer :
    331 Password required for mazdak.
    [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer2 :
    331 Password required for mazdak.
    [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer3 :
    331 Password required for mazdak.
     
    bytes recived : 28
    strlen buffer : 519
    Buffer :
    230 User mazdak logged in.
    zdak.
    [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer2 :
    230 User mazdak logged in.
    zdak.
    [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer3 :
    230 User mazdak logged in.
     
    bytes recived : 29
    strlen buffer : 519
    Buffer :
    250 CWD command successful.
    dak.
    [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer2 :
    250 CWD command successful.
    dak.
    [galapagos.globat.com]
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
    ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░ ↕
    Buffer3 :
    250 CWD command successful.
    I've tried to port it so that it uses a socket class I've made.

    socket.hpp:
    Code:
    #if defined(_WIN32)
       #include <windows.h>
       #include <winsock.h>
     
       #define socket_connect ::connect
       #define socket_close ::closesocket
       #define socket_ioctl ::ioctlsocket
       #define socket_recive(Socket,buffer,len, flags) recv(Socket, (char*)buffer, len , flags)
    #else
       #include <sys/socket.h>
       #include <netinet/in.h>
       #include <netdb.h>
       #include <arpa/inet.h>
       #include <sys/ioctl>
     
       typedef SOCKET int
       #define INVALID_SOCKET -1
       #define socket_close ::close
       #define socket_ioctl ::ioctl
       #define socket_connect(SOCKET s, sockaddr_in* name, namelen) ::connect(s, (const sockaddr*) name, sizeof(sockaddr) )
    #endif
     
    #include <string>
     
    class Socket
    {
    public:
       SOCKET m_socket;
       bool m_isOpen;
     
    private:
       void setSocket(SOCKET s)
       {
          this->m_socket = s;
       }
     
       SOCKET getSocket(void)
       {
          return this->m_socket;
       }
     
       void setIsOpen(bool bVal)
       {
          this->m_isOpen = bVal;
       }
     
    public:
       bool isOpen(void)
       {
          return this->m_isOpen;
       }
     
       Socket(void)
       {
          this->setIsOpen(false);
       }
     
       virtual ~Socket(void)
       {
          this->close();
       }
     
       bool open(int af, int type, int protocol)
       {
          if(this->isOpen())
             return true;
     
          SOCKET tempSocket = ::socket(af, type, protocol);
     
          if(tempSocket == INVALID_SOCKET)
             return false;
          else
          {
             this->setIsOpen(true);
             this->setSocket(tempSocket);
             return true;
          }
       }
     
       bool open(SOCKET tempSocket)
       {
          if(this->isOpen())
             return true;
     
          if(tempSocket == INVALID_SOCKET)
             return false;
          else
          {
             this->setIsOpen(true);
             this->setSocket(tempSocket);
             return true;
          }
       }
     
       bool close(void)
       {
          this->shutdown(0x02);
     
          if( socket_close(this->getSocket()) == 0 ? true : false )
          {
             this->setSocket(0);
             this->setIsOpen(false);
             return true;
          }
          else return false;
       }
     
       bool bind(const sockaddr* name, int namelen)
       {
          return ::bind(this->getSocket(), name, namelen) == 0 ? true : false;
       }
     
       bool connect(const sockaddr* name, int namelen)
       {
          return socket_connect(this->getSocket(), name, namelen) == 0 ? true : false;
       }
     
       bool connect(const char* host, int port, int af)
       {
          hostent* he;
          if( (he = ::gethostbyname(host)) == 0 )
             return false;
     
          sockaddr_in clientService;
          clientService.sin_family = af;
          clientService.sin_addr.s_addr = ::inet_addr( ::inet_ntoa( (**(in_addr**)he->h_addr_list ) ) );
          clientService.sin_port = htons(port);
     
          return socket_connect(this->getSocket(), (SOCKADDR*) &clientService, sizeof(clientService) ) == 0 ? true : false;
       }
     
       bool connect(std::string host, int port, int af)
       {
          return this->connect(host.c_str(), port, af);
       }
     
       bool shutdown(int how)
       {
          return ::shutdown(this->getSocket(), how) == 0 ? true : false;
       }
     
       int receive(char* buffer, int length, int flags)
       {
          return ::socket_recive(this->getSocket(), (char*)buffer, length, flags);
       }
     
       int send(char* buffer, int length, int flags)
       {
          return ::send(this->getSocket(), (char*)buffer, length, flags);
       }
     
       int send(std::string buffer, int length, int flags)
       {
          char* cBuffer = (char*)buffer.c_str();
          return ::send(this->getSocket(), cBuffer, length, flags);
       }
     
       bool listen(int backlog)
       {
          return ::listen(this->getSocket(), backlog) == 0 ? true : false;
       }
     
       Socket* accept(sockaddr* addr, int* addrlen)
       {
          Socket* tempSocket = new Socket();
          tempSocket->open( ::accept(this->getSocket(), addr, addrlen) );
          return tempSocket;
       }
     
       bool getPeerName(sockaddr* name, int* namelen)
       {
          return ::getpeername(this->getSocket(), name, namelen) == 0 ? true : false;
       }
     
       bool getName(sockaddr* name, int* namelen)
       {
          return ::getsockname(this->getSocket(), name, namelen) == 0 ? true : false;
       }
     
       bool getOption(int level, int optionName, char* optionValue)
       {
          return ::getsockopt(this->getSocket(), level, optionName, optionValue, (int*)::strlen(optionValue) ) == 0 ? true : false;
       }
     
       bool setOption(int level, int optionName, const char* optionValue)
       {
          return ::setsockopt(this->getSocket(), level, optionName, optionValue, (int)::strlen(optionValue) ) == 0 ? true : false;
       }
     
       bool ioctl(long cmd, unsigned long* argp)
       {
          socket_ioctl(this->getSocket(), cmd, argp);
       }
    };
    main.cpp:
    Code:
    #include <string>
    #include <vector>
    #include <fstream>
    #include <iostream>
    using namespace std;
    #include <boost/algorithm/string.hpp>
    #include <boost/lexical_cast.hpp>
    using namespace boost;
     
    #include "Socket.hpp"
     
          class FTPUploader
          {
          public:
             string Host, Username, Password, Path;
             bool Logined, Initialized;
     
             Socket* socket;
             int bytes, retValue;
             string mes, reply;
     
             const static int BLOCK_SIZE = 512;
             char buffer[BLOCK_SIZE];
     
             /* methods for gettings and setting properties */
          public:
             void set_Host(string _Host)
             {
                this->Host = _Host;
             }
             string get_Host(void)
             {
                return this->Host;
             }
     
             void set_Username(string _Username)
             {
                this->Username = _Username;
             }
             string get_Username(void)
             {
                return this->Username;
             }
     
             void set_Password(string _Password)
             {
                this->Password = _Password;
             }
             string get_Password(void)
             {
                return this->Password;
             }
     
             void set_Path(string _Path)
             {
                this->Path = _Path;
             }
             string get_Path(void)
             {
                return this->Path;
             }
     
          public:
             FTPUploader(string _Host, string _Username, string _Password, string _Path)
             {
                this->socket = new Socket();
     
                this->Host = _Host;
                this->Username = _Username;
                this->Password = _Password;
                this->Path = _Path;
     
                this->Initialized = false;
                this->Logined = false;
             }
     
             /* Connection handlig methods */
          private:
             bool Initialize(void)
             {
                if(this->Initialized)
                   return true;
     
                #if defined(_WIN32)
                   WSADATA wsa;
                   if(WSAStartup(MAKEWORD(1, 1), &wsa))
                   {
                      WSACleanup();
                      return false;
                   }
                #endif
     
                this->Initialized = true;
                return true;
             }
     
          public:
             bool Login(void)
             {
                if(this->Logined)
                   return true;
     
                if(!this->Initialized)
                   this->Initialize();
     
                if( !this->socket->open(AF_INET, SOCK_STREAM, IPPROTO_TCP) )
                {
                   #if defined (_WIN32)
                      WSACleanup();
                   #endif
                   return false;
                }
     
                if( !this->socket->connect(this->Host, 21, AF_INET) )
                {
                   WSACleanup();
                   return false;
                }
     
                this->readReply();
     
                if(this->retValue != 220)
                {
                   this->Close();
                   return false;
                }
     
                this->sendCommand("USER " + this->Username);
     
                if( !(this->retValue == 331 || this->retValue == 230) )
                {
                   this->Cleanup();
                   return false;
                }
     
                if(this->retValue != 230)
                {
                   this->sendCommand("PASS " + this->Password);
     
                   if( !(this->retValue == 230 || this->retValue == 202) )
                   {
                      this->Cleanup();
                      return false;
                   }
                }
     
                this->Logined = true;
     
                this->changeDirectory(this->Path);
                return true;
             }
     
             void Close(void)
             {
                if( !this->socket->isOpen() )
                {
                   this->sendCommand("QUIT");
                }
     
                this->Cleanup();
                #if defined(_WIN32)
                   WSACleanup();
                #endif
             }
     
             void Cleanup(void)
             {
                if( !this->socket->isOpen() )
                {
                   this->socket->close();
                }
                this->Initialized = false;
                this->Logined = false;
             }
             /* End Connection handler methods */
          public:
             long getFileSize(string fileName)
             {
                if(!this->Logined)
                   this->Login();
                this->sendCommand("SIZE " + fileName);
     
                long size = 0;
     
                if(this->retValue == 213)
                {
                   size = atol(this->reply.substr(4).c_str());
                }
                else return 0;
     
                return size;
             }
     
          public:
             bool setBinaryMode(bool _mode)
             {
                if(_mode)
                   this->sendCommand("TYPE I");
                else
                   this->sendCommand("TYPE A");
     
                if(this->retValue != 200)
                   return false;
                return true;
             }
     
             bool changeDirectory(string _Path)
             {
                if(_Path == ".")
                   return false;
     
                if(!this->Logined)
                   this->Login();
     
                this->sendCommand("CWD " + _Path);
     
                if(this->retValue != 250)
                   return false;
     
                this->Path = _Path;
     
                return true;
             }
     
             bool makeDirectory(string _DirName)
             {
                if(!this->Logined)
                   this->Login();
     
                this->sendCommand("MKD " + _DirName);
     
                if(this->retValue != 250)
                   return false;
                return true;
             }
     
          public:
             bool upload(string fileName)
             {
                return this->upload(fileName,false);
             }
     
          public:
             bool upload(string fileName,bool resume)
             {
                if(!this->Logined)
                   this->Login();
     
                Socket* cSocket = this->createDataSocket();
                long offset = 0;
     
                if(resume)
                {
                   try
                   {
                      this->setBinaryMode(true);
                      offset = this->getFileSize(fileName);
                   }
                   catch(bool)
                   {
                      offset = 0;
                   }
                }
     
                if(offset > 0)
                {
                   this->sendCommand("REST " + offset);
                   if(this->retValue != 350)
                      offset = 0;
                }
     
                this->sendCommand("STOR " + fileName);
     
                if( !(this->retValue == 125 || this->retValue == 150) )
                   return false;
     
                /* SECTION = get and send the file */
                ifstream input;
                input.open( fileName.c_str() , ios::binary );
     
                // get length of file:
                int length;
                input.seekg (0, ios::end);
                length = input.tellg();
                input.seekg (0, ios::beg);
     
                // allocate memory:
                char *filebuf;
                filebuf = new char [length];
     
                // read data as a block:
                input.read(filebuf,length);
     
                input.close();
                cSocket->send(filebuf, length, 0);
                /* end SECTION */
     
                if(cSocket->getPeerName(0,0))
                   cSocket->close();
     
                this->readReply();
                if( !(this->retValue == 226 || this->retValue == 250) )
                {
                   return false;
                }
                return true;
             }
     
             /* Actor Helpers */
             void readReply(void)
             {
                this->mes = "";
     
                this->reply = this->readLine();
     
                this->retValue = lexical_cast<int>( this->reply.substr(0,3) );
             }
     
             string readLine(void)
             {
                while(true)
                {
                   this->bytes = this->socket->receive(this->buffer, BLOCK_SIZE, 0);
                   cout << "bytes recived : " << this->bytes << endl;
                   cout << "strlen buffer : " <<(int)strlen(this->buffer) << endl;
                   cout << "Buffer :\n" << this->buffer << endl;
                   this->mes += this->buffer;
                   cout << "Buffer2 :\n" << this->mes << endl;
                   this->mes = this->mes.substr(0,this->bytes);
                   cout << "Buffer3 :\n" << this->mes << endl;
     
                   if(this->bytes < (int)strlen(this->buffer) )
                      break;
                }
     
                vector<string> mess;
     
                split(mess,this->mes,is_any_of("\n"));
     
                if(this->mes.length() > 2)
                {
                   this->mes = mess[mess.size() - 2];
                }
                else
                {
                   this->mes = mess[0];
                }
     
                if(!(this->mes.substr(3,1) == " "))
                {
                   return this->readLine();
                }
     
                return this->mes;
             }
          private:
             void sendCommand(string command)
             {
                command += "\r\n";
                this->socket->send(command, (int)command.length(), 0);
                this->readReply();
             }
     
          private:
             Socket* createDataSocket(void)
             {
                this->sendCommand("PASV");
     
                if(this->retValue != 227)
                   return NULL;
     
                int index1 = (int)( this->reply.find_first_of('(', 0) );
                int index2 = (int)( this->reply.find_first_of(')', 0) );
                string ipData = this->reply.substr(index1 + 1,index2 - index1 - 1);
                int parts[6];
     
                int len = (int)ipData.length();
                int partCount = 0;
                string buf = "";
     
                for(int i = 0; i < len && partCount <= 6; i++)
                {
                   string ch = ipData.substr(i,1);
                   if( isdigit( lexical_cast<char>(ch) ) ) buf += ch;
                   else if(ch != ",")
                   {
                      return NULL;
                   }
     
                   if(ch == "," || i + 1 == len)
                   {
                      try
                      {
                         parts[partCount++] = lexical_cast<int>(buf);
                         buf = "";
                      }
                      catch(bad_lexical_cast &)
                      {
                         return NULL;
                      }
                   }
                }
     
                string ipAddress = lexical_cast<string>( parts[0] ) + "." + lexical_cast<string>( parts[1] ) + "." + lexical_cast<string>( parts[2] ) + "." + lexical_cast<string>( parts[3] );
     
                int port = (parts[4] << 8) + parts[5];
     
                Socket* s = new Socket();
                if( !s->open(AF_INET,SOCK_STREAM,IPPROTO_TCP) )
                   return NULL;
     
                if( !s->connect(ipAddress, port, AF_INET) )
                   return NULL;
                return s;
             }
             /* End Actor helpers */
          };
     
    int main()
    {
       FTPUploader ftp("ftp.magicasoft.net","usr","pass",".");
       ftp.Login();
       ftp.changeDirectory("httpdocs");
       cin.get();
       return 0;
    }
    but this gives... output:

    Code:
    bytes recived : 59
    strlen buffer : 59
    Buffer :
    220 ProFTPD 1.2.9 Server (ProFTPD) [galapagos.globat.com]
     
    Buffer2 :
    220 ProFTPD 1.2.9 Server (ProFTPD) [galapagos.globat.com]
     
    Buffer3 :
    220 ProFTPD 1.2.9 Server (ProFTPD) [galapagos.globat.com]
    I've checked the most of it but I can't see a difference for the first receive ( readline() )
    And I can't see why the exact same strlens give different length :
    strlen buffer : 59
    strlen buffer : 519

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Well you're still assuming that recv() terminates any message with a \0, to make it a proper 'C' string.
    This is NOT true.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    29
    so how do I make sure that it ends with a null string?

    pseudo code :

    check buffer end character
    if not\0 -> buffer += \0

    ?

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    with your code you can only receive text.
    If you want to keep it this way you could just do something lihe this

    Code:
     sz_rec= recv( .... ) 
       buffer[sz_rec]=0;
    If you want to reveive binary data as well you cannot use any string-functions like strlen(), strcat() etc.
    You have to assemble your reveived data in memory with raw memory functions like memmove() or memcpy().
    Kurt

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Don't forget if you do this
    char buff[100];
    n = recv( sock, buff, sizeof buff, 0 );
    buff[n] = '\0';

    You will write past the end of the array if recv() actually succeeds in filling the buffer.
    So if you're expecting characters and you want to leave room to append a \0, then do
    n = recv( sock, buff, sizeof buff - 1, 0 );

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    29
    so if i use:
    if(this->bytes) < sizeof(this->buffer) )
    break;
    will it work?

    And how do i use raw memory functions with my code to make it work?

    If we examine the who code chunks there is really no difference so why do they show a difference and why does strlen() give 519 on one when it should be 59?
    Code:
                while(true)
                {
                   this->bytes = this->socket->receive(this->buffer, BLOCK_SIZE, 0);
                   cout << "bytes recived : " << this->bytes << endl;
                   cout << "strlen buffer : " <<(int)strlen(this->buffer) << endl;
                   cout << "Buffer :\n" << this->buffer << endl;
                   this->mes += this->buffer;
                   cout << "Buffer2 :\n" << this->mes << endl;
                   this->mes = this->mes.substr(0,this->bytes);
                   cout << "Buffer3 :\n" << this->mes << endl;
     
                   if(this->bytes < (int)strlen(this->buffer) )
                      break;
                }
    Code:
                while(true)
                {
                   this->bytes = socket_receive(this->wSOCKET,this->buffer, BLOCK_SIZE ,0);
                   cout << "bytes recived : " << this->bytes << endl;
                   cout << "strlen buffer : " <<(int)strlen(this->buffer) << endl;
                   cout << "Buffer :\n" << this->buffer << endl;
                   this->mes += this->buffer;
                   cout << "Buffer2 :\n" << this->mes << endl;
                   this->mes = this->mes.substr(0,this->bytes);
                   cout << "Buffer3 :\n" << this->mes << endl;
     
                   if(this->bytes < (int)strlen(this->buffer) )
                      break;
                }

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > why does strlen() give 519 on one when it should be 59?
    Because there is no \0, did you even read the replies?
    Well there is, it just roams through memory until it finds one, or it steps on something which it shouldn't and the OS kills your program.

  8. #8
    Registered User
    Join Date
    Oct 2005
    Posts
    29
    hmm then this ?
    Code:
    				while(true)
    				{
    					this->bytes = this->socket->receive(this->buffer, sizeof(this->buffer) - 1, 0);
    					this->buffer[this->bytes] = '\0';
    
    					this->mes += this->buffer;
    					this->mes = this->mes.substr(0,this->bytes);
    
    					if(this->bytes < sizeof(this->buffer) )
    						break;
    				}
    it actualy works , on the first recv, 59 bytes are received and sizeof buffer is 512 so it passes the while(true) loop.
    But is this code chunk 100% error free?

    And oh , can you show me an example of how to do it with the memcpy... ?

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > But is this code chunk 100% error free?
    1. You don't account for recv() returning end of data or error.
    2. The if() condition for your break makes no sense. IIRC, single FTP command sequences end with \r (check the RFC) and I guess you should be returning when you find a return.

    But then there's no particular reason why you would not receive say "cmd1\rcm" in a single recv() call (ie, the \r is not the last character), so you would need to store the tail of the message somewhere else so that it can be added to the result of your next command.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. CEdit::OnChar() won't work for derived class!
    By LuckY in forum Windows Programming
    Replies: 0
    Last Post: 02-28-2003, 01:01 AM
  4. Font class, why won't it work?
    By fusikon in forum Game Programming
    Replies: 2
    Last Post: 02-09-2003, 09:07 PM