2010-05-27 7 views
3

Quelqu'un pourrait-il recommander FTP/SFTP bibliothèque C/C++ pour système embarqué Linux? Je connais la bibliothèque Curl mais j'ai besoin de quelque chose d'aussi simple que possible pour télécharger des fichiers depuis des serveurs FTP/SFTP. Y a-t-il une recommandation à rechercher? Oui, le support SFTP est essentiel. En fait, je peux même sacrifier le multi-threading parce que je n'ai besoin que d'un flux à la fois. Et j'aimerais qu'il soit capable de fonctionner à travers des mémoires tampons, mais cela ne devrait pas poser de problème.simple bon C/C++ FTP et recommandation de la bibliothèque client SFTP pour Linux embarqué

Merci d'avance. Après avoir passé du temps avec libcurl, j'ai décidé de ne pas aller de l'avant en faveur de l'utilisation directe de libssh2 pour SFTP et de réutiliser la bibliothèque FTP propriétaire de différents projets. libcurl semble trop lié à l'approche de l'outil de ligne de commande curl. Par exemple, essayez d'obtenir la taille de fichier à distance avant de commencer l'opération de téléchargement - ce n'était certainement pas prévu.

Mais en réalité, une autre des propositions sont les bienvenues surtout je ne vois pas bien très simple publique C ou bibliothèque C++ FTP du tout. Tout est soit très vieux et pas soutenu ou frais et humide.

+0

Lequel avez-vous fini par utiliser? –

Répondre

3

libssh2 est un grand lib pour SFTP - et il arrive aussi d'être le lib (lib) boucle utilise pour SFTP.

3

Avez-vous regardé libcurl's alternatives page? Quelques options peuvent fournir une solution FTP.

Je pense que si vous vous éloignez de libcurl, vous devrez peut-être utiliser deux bibliothèques différentes, une pour SFTP (ce qui est vraiment juste SSH) et un pour FTP.

Cependant, si vous ne voulez pas faire cela, vous voudrez peut-être envisager de compiler libcurl pour le lier à cyaSSL ou à PolarSSL au lieu de openssl pour rendre l'installation plus légère. Vous pouvez également essayer de le compiler avec des options minimales, car vous n'avez besoin que d'un support FTP et SFTP.

Espérons que cela aide.

+2

La solution sélectionnée était légèrement personnalisée openssl et libcurl avec seulement les protocoles FTP et SFTP activés. Assez bon pour mon cas. –

+0

.. mais après un certain temps, j'ai dû le changer en libssh2 pour SFTP et FTP personnalisé. –

2

vous pouvez utiliser libssh pour SFTP. J'ai mis du code ici pour vous qui a Pause/Resume et fonctionne sur Windows. Pour Linux, vous devez remplacer les fonctions de gestion de fichiers locales. Je ne peux pas copier la classe entière car elle dépassera cette limite de site Web. changez le nom d'utilisateur et mot de passe et le nom d'hôte aux équivalents appropriés de votre serveur sftp:

int main(array<System::String ^> ^args) 
    { 

     //Console::WriteLine(L"Hello World"); 


     pSFTPConnector sshc = new SFTPConnector(L".\\", L"127.0.0.1", 22, L"iman", L"iman"); // change the hostname , port , username, password to your sftp server, your credentials 

     //FILE *nullfile = fopen("null", "w"); 
     //sshc->setLogFile(nullfile); 
     sshc->setVerbosity(SSH_LOG_RARE);  // you can change the verbosity as appropriate for you 

     int i= sshc->InitSession(); 
     i=sshc->ConnectSession(); 
     i = sshc->InitSFTP(); 


     //i = sshc->SFTPrename("renamed_myfile.txt", "myfile.txt"); //change these file names 
     //i = sshc->Makedir("sftpdir"); 
     //i = sshc->testUploadFile("myfile2.txt", "1234567890testfile"); 


     // change these file names to whatever appropriate 
     //i = sshc->SFTPget("c:\\testdir\\Got_CAR_HIRE_FINAL_test.jpg", "CAR_HIRE_FINAL_test.jpg", 64*1024); 
     i = sshc->SFTPget("c:\\testdir\\get_downloaded_CAR_HIRE_FINAL.jpg", "CAR_HIRE_FINAL.jpg", 64 *1024); 
     i = sshc->SFTPreget("c:\\testdir\\reget_downloaded_CAR_HIRE_FINAL.jpg", "CAR_HIRE_FINAL.jpg", 64 * 1024); 
     i = sshc->SFTPput("c:\\testdir\\CAR_HIRE_FINAL.jpg", "put_CAR_HIRE_FINAL.jpg", 64 * 1024); 
     i = sshc->SFTPreput("c:\\testdir\\CAR_HIRE_FINAL.jpg", "reput_CAR_HIRE_FINAL.jpg", 64 * 1024); 

     delete sshc; 
     return 0; 
    } 


typedef enum sshconerr{ 
    E_OK = 1, E_SESSION_ALOC = -1, E_SSH_CONNECT_ERR = -2, E_SFTP_ALLOC = -3, E_INIT_SFTP = -4, E_CREATE_DIR = -5, E_FILEOPEN_WRITE = -6, E_WRITE_ERR = -7 
    , E_FILE_CLOSE = -8, E_FILE_OPEN_READ = -9, E_INVALID_PARAMS = -10, E_SFTP_ERR = -11, E_SFTP_READ_ERR = -12, E_SFTP_READBYTES_ERR = -13, E_GET_FILEINF = -14 
    , E_LOCAL_FILE_NOTFOUND = -15, E_RENAME_ERR = -16, E_MEM_ALLOC = -17, E_LOCAL_FILE_READ = -18, E_LOCAL_FILE_RDWR = -19, E_REMOTEFILE_SEEK = -20 
    , E_REMOTE_FILE_OPEN = -21, E_DELETE_ERR = -22, E_RENAME_LOCAL_FILE = -23, E_LOCAL_DELETE_FILE = -24, E_FILEOPEN_RDONLY = -25, E_SFTP_READ_EOF=-26 
         ,E_UNKNOWN=-999 } ESSHERR; 


// status of transfers; 
typedef enum sftpstat{ ES_DONE=0 , ES_INPROGRESS , ES_FAILED, ES_STARTING, ES_PAUSED, ES_RESUMING, ES_CANCELLED, ES_NONE } ESFTPSTAT; 

using namespace std; 


// statistics about the transfer; 
typedef struct transferstatstruct { 
    string remote_file_name; 
    string local_file_name; 
    __int64 total_size; 
    __int64 transferred; 
    __int64 averagebps; 
    long long seconds_elapsed; 
    long long  seconds_remained; 
    int percent; 
    ESFTPSTAT transferstate; 
} TTransStat; 


#define E_SESSION_NEW -1 



// these libraries are required 
#pragma comment(lib, "ssh.lib") 





// this is the main class that does the majority of the work 

typedef class CSFTPConnector{ 

private: 

    ssh_session session;     // ssh session 
    sftp_session sftp;      // sftp session 
    sftp_file file;       // structure for a remote file 
    FILE *localfile;      // not used in windows but could be local file pointer in UNIX 
    FILE *logfile;       // the file for writing logs, default is set to stderr 
    string filename;      // file name of the transfer; 
    string localfilename;     // file name of local file; 
    string  tempfilename;    // a temporaty file name will be used during the transfer which is renamed when transfer is completed. 
    ESFTPSTAT transferstatus;    // state of the transfer which has one of the above values (ESFTPSTAT) 
    time_t transferstarttime;    // time of start of the transfer 
    wchar_t username[SHORT_BUFF_LEN]; 
    wchar_t password[SHORT_BUFF_LEN]; 
    wchar_t hostname[SHORT_BUFF_LEN];  // hostname of the sftp server 
    wchar_t basedir[SHORT_BUFF_LEN];  // this base dir is the directory of public and private key structur (NOT USED IN THIS VERSION) 
    int port;        // port of the server; 
    int verbosity;       // degree of verbosity of libssh 
    __int64 filesize;      // total number of bytes to be transfered; 
    DWORD local_file_size_hiDWORD;   // Bill Gates cannot accept the file size without twisting the programmers, so he accepts them in 2 separate words like this 
    DWORD local_file_size_lowDWORD;  // these 2 DWORDs when connected together comprise a 64 bit file size. 
    __int64 lfilesize;       // local file size 
    __int64 rfilesize;       // remote file size 
    __int64 transfered;       // number of bytes already transfered 
    bool pause;         // pause flag 
    TTransStat stats;       // statistics of the transfer 
    HANDLE localfilehandle;     // windows uses handles to manipulate files. this is the handle to local file. 

    ESSHERR CSFTPConnector::rwopen_existing_SFTPfile(char *fn);   // open a file on remote (server) read/write for upload 
    ESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn);   // open a file on remote (server) read only for download 
    ESSHERR createSFTPfile(char *fn);         // create a file on server; 
    ESSHERR writeSFTPfile(char *block, size_t blocksize);    // write a block of data to the open remote file 
    ESSHERR readSFTPfile(char *block, size_t len, size_t *bytesread); // read a block of data from the open remote file 
    ESSHERR readSFTPfile(char *block, __int64 len, DWORD *bytesread); 
    ESSHERR closeSFTPfile();  // closes the remote file; 
    ESSHERR openSFTPfile(char *fn); // opens the remote file 
    ESSHERR getSFTPfileinfo();   // gets information about the remote file 


public: 
    wstring errstring;  // the string describing last error 
    ESSHERR Err;    // error code of last error 
    CSFTPConnector();   // default constructor; 
    CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass); // constructor 
    void setVerbosity(int v);  
    int getVerbosity(); 
    ESSHERR InitSession();   // must be called befor doing any transfer 
    ESSHERR ConnectSession();  // connnects to the ssh server 
    ESSHERR InitSFTP();  // must be called befor doing any transfer 
    ESSHERR Makedir(char *newdir); 
    ESSHERR testUploadFile(char *fn, char *block);   // do not use this , only for test purposes for myself 
    ESSHERR SFTPput(char *lfn, char *rfn, size_t blocksize);   // Upload a file from start 
    ESSHERR SFTPreput(char *lfn, char *rfn, size_t blocksize);   // checks for previouse interrupted transfer, then either continues the previouse transfer (if there was any) or starts a new one (UPLOAD) 
    ESSHERR SFTPrename(char *newname, char *oldname);     // renames a remote file(must be closed) 
    ESSHERR CSFTPConnector::SFTPdelete(char *remfile);     // deletes a remote file 
    TTransStat getStatus();            // gets statistics of the transfer 
    ESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize); // Downloads a file from sftp server 
    ESSHERR CSFTPConnector::SFTPreget(char *lfn, char *rfn, size_t blocksize); // checks for previouse interrupted transfer, then either continues the previouse transfer (if there was any) or starts a new one (DOWNLOAD) 
    void CancelTransfer(); 
    void PauseTransfer(); 
    void setLogFile(FILE *logf);   // sets the log file, if not set stderr will be used. by default. 
    void CloseLocalFile(); 
    void CloseRemoteFile(); 

    ~CSFTPConnector(); 




} SFTPConnector, *pSFTPConnector ; 





void CSFTPConnector::CloseLocalFile() 
{ 
    CloseHandle(localfilehandle); 
} 


void CSFTPConnector::CloseRemoteFile() 
{ 
    sftp_close(file); 
} 



void CSFTPConnector::setLogFile(FILE *logf) 
{ 
    logfile = logf; 
} 


void CSFTPConnector::CancelTransfer() 
{ 
    transferstatus = ES_CANCELLED; 

} 
void CSFTPConnector::PauseTransfer() 
{ 
    transferstatus = ES_PAUSED; 
    pause = true; 
} 

//---------------------------------------- 


ESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize) 
{ 
    DWORD  result; 
    int rc; 
    BOOL bresult; 
    DWORD bytesread; 
    filesize = 0; 
    transfered = 0; 

    pause = false; 
    transferstatus = ES_NONE; 
    char *block; 
    struct stat st; 
    wchar_t temp[SHORT_BUFF_LEN]; 
    size_t tempsize; 
    wstring wlfn; 
    int loopcounter = 0; 

    localfilename = lfn; 

    filename = rfn; 

    tempfilename = string(lfn) + ".sftp_temp"; 
    mbstowcs_s(&tempsize, temp, tempfilename.c_str(), SHORT_BUFF_LEN); 

    localfilehandle = CreateFile(temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (localfilehandle == INVALID_HANDLE_VALUE) 
    { 
     transferstatus = ES_FAILED; 
     errstring = L"Could not open local file:" + wstring(temp) + L" for read and write"; 
     Err = E_LOCAL_FILE_RDWR; 
     return E_LOCAL_FILE_RDWR; 
    } 

    lfilesize =0; 
    transfered =0; 

    block = (char*)malloc(blocksize + 1); 
    if (block == NULL) { 
     Err = E_MEM_ALLOC; 
     transferstatus = ES_FAILED; 
     errstring = L"Could not allocate memory for file block size"; 
     CloseLocalFile(); 
     return E_MEM_ALLOC; 
    } 

    result = rdopen_existing_SFTPfile((char *)rfn); 

    if (result == E_OK){ 
     getSFTPfileinfo(); 
     filesize = rfilesize; 
    } 
    else 
    { 
     Err = E_REMOTE_FILE_OPEN; 
     transferstatus = ES_FAILED; 
     errstring = L"Could not open remote file"; 
     CloseLocalFile(); 
     delete block; 
     return E_REMOTEFILE_SEEK; 
    } 


    transferstatus = ES_STARTING; 

    sftp_file_set_blocking(file); 
    transferstarttime = time(NULL); 
    transferstatus = ES_INPROGRESS; 

    while (transferstatus != ES_FAILED && transferstatus != ES_PAUSED && transferstatus != ES_CANCELLED &&transferstatus != ES_DONE) 
    { 
     loopcounter++; 

     result = readSFTPfile(block, blocksize, (size_t *)&bytesread); 
     if (result != E_OK && result!= E_SFTP_READ_EOF) 
     { 
      errstring = L"Error reading from remote sftp server file."; 
      Err = (ESSHERR)result; 
      transferstatus = ES_FAILED; 
      CloseRemoteFile(); 
      CloseLocalFile(); 
      delete block; 
      return (ESSHERR)result; 
     } 
     if (result == E_SFTP_READ_EOF) transferstatus = ES_DONE; 
     fprintf(logfile, "Read %d bytes from input file. Number of packets: %d , %llu from %llu bytes\n", bytesread, loopcounter, transfered, filesize); 

     bresult = WriteFile(localfilehandle, (LPVOID)block, bytesread, &bytesread, NULL); 
     if (bytesread < blocksize) 
     { 
      if (bresult == FALSE) 
      { 
       errstring = L"Error writing to local file."; 
       Err = E_LOCAL_FILE_RDWR; 
       transferstatus = ES_FAILED; 
       CloseRemoteFile(); 
       CloseLocalFile(); 
       delete block; 
       return E_LOCAL_FILE_RDWR; 
      } 
      else if (bytesread == 0) 
      { 
       errstring = L"Transfer done."; 
       Err = E_OK; 
       transferstatus = ES_DONE; 
       continue; 
      } 
     } 


     Err = E_OK; 

     if (pause == true) transferstatus = ES_PAUSED; 
     if (bresult == TRUE && bytesread == 0) 
     { 
      // at the end of the file 
      transferstatus = ES_DONE; 
     } 
     Sleep(BLOCKTRANSDELAY); 
     if (loopcounter % 331 == 0)Sleep(77 * BLOCKTRANSDELAY); 
     if (loopcounter % 3331 == 0)Sleep(777 * BLOCKTRANSDELAY); 

    } 

    // closing files 
    result = closeSFTPfile(); 
    CloseHandle(localfilehandle); 

    Sleep(1000); 


    if (transferstatus == ES_DONE) 
    { 
     wchar_t temp2[SHORT_BUFF_LEN]; 
     mbstowcs_s(&tempsize, temp2, lfn, SHORT_BUFF_LEN); 
     bresult = MoveFile(temp, temp2); 
     if (bresult != TRUE) 
     { 
      Err = E_RENAME_LOCAL_FILE; 
      errstring = L"Could not rename local file: " + wstring(temp); 
      transferstatus = ES_FAILED; 
      delete block; 
      return E_RENAME_LOCAL_FILE; 
     } 
    } 

    if (transferstatus == ES_CANCELLED) 
    { 
     wchar_t temp2[SHORT_BUFF_LEN]; 
     mbstowcs_s(&tempsize, temp2, lfn, SHORT_BUFF_LEN); 
     bresult = DeleteFile(temp); 
     if (bresult != TRUE) 
     { 
      Err = E_LOCAL_DELETE_FILE; 
      errstring = L"Could not rename local file: " + wstring(temp); 
      transferstatus = ES_FAILED; 
      delete block; 
      return E_LOCAL_DELETE_FILE; 
     } 
    } 

    delete block; 
    return (ESSHERR) result; 
} 


TTransStat CSFTPConnector::getStatus() 
{ 
    stats.seconds_elapsed = time(NULL) - transferstarttime; 
    stats.averagebps = (transfered * 8)/stats.seconds_elapsed; 
    if (filesize > 0) { 
     stats.percent = (transfered *100)/ filesize; 
     stats.seconds_remained = ((filesize - transfered) * 8)/stats.averagebps; 
    } 
    else 
    { 
     stats.percent = -1; 
     stats.seconds_remained = -1; 
    } 
    stats.total_size = filesize; 
    stats.transferstate = transferstatus; 
    stats.remote_file_name = filename; 
    stats.local_file_name = localfilename; 

    return stats; 
} 


ESSHERR CSFTPConnector::SFTPrename(char *newname, char *oldname) 
{ 

    int rc=sftp_rename(sftp, oldname, newname); 
    if (rc !=SSH_OK){ 
     return E_RENAME_ERR; 
    } 

    return E_OK; 
} 



ESSHERR CSFTPConnector::SFTPdelete(char *remfile) 
{ 

    int rc = sftp_unlink(sftp,remfile); 
    if (rc != SSH_OK){ 
     return E_DELETE_ERR; 
    } 

    return E_OK; 
} 



ESSHERR CSFTPConnector::SFTPreput(char *lfn, char *rfn, size_t blocksize) 
{ 
    ESSHERR  result; 
    BOOL bresult; 
    DWORD bytesread; 
    filesize = 0; 
    transfered = 0; 

    pause = false; 
    transferstatus = ES_NONE; 
    char *block; 
    struct stat st; 
    wchar_t temp[SHORT_BUFF_LEN]; 
    size_t tempsize; 
    wstring wlfn; 
    int loopcounter = 0; 

    localfilename = lfn; 
    //wlfn = wstring(lfn); 
    //localfile = fopen(lfn, L"r"); 
    filename = rfn; 
    mbstowcs_s(&tempsize, temp, lfn, SHORT_BUFF_LEN); 

    //filesize = getFileSize(localfilename); 

    /*if(filesize < 0) { 
    transferstatus = ES_FAILED; 
    Err = E_LOCAL_FILE_NOTFOUND; 
    return E_LOCAL_FILE_NOTFOUND; 
    }*/ 

    localfilehandle = CreateFile(temp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (localfilehandle == INVALID_HANDLE_VALUE) 
    { 
     transferstatus = ES_FAILED; 
     Err = E_LOCAL_FILE_NOTFOUND; 
     return E_LOCAL_FILE_NOTFOUND; 
    } 
    local_file_size_lowDWORD = GetFileSize(localfilehandle, &local_file_size_hiDWORD); 
    filesize = (local_file_size_hiDWORD * 0x100000000) + local_file_size_lowDWORD; 

    if (filesize < 0) { 
     transferstatus = ES_FAILED; 
     Err = E_LOCAL_FILE_NOTFOUND; 
     CloseLocalFile(); 
     return E_LOCAL_FILE_NOTFOUND; 
    } 

    block = (char*)malloc(blocksize + 1); 
    if (block == NULL) { 
     Err = E_MEM_ALLOC; 
     transferstatus = ES_FAILED; 
     errstring = L"Could not allocate memory for file block size"; 
     CloseLocalFile(); 
     return E_MEM_ALLOC; 
    } 


    tempfilename = string(rfn) + ".sftp_temp"; 

    result = rwopen_existing_SFTPfile((char *)tempfilename.c_str()); 
    if (result == E_OK){ 
     getSFTPfileinfo(); 
     sftp_seek64(file, rfilesize); 
     __int64 tempi64 = rfilesize & 0x00000000FFFFFFFF; 
     DWORD dwlow = tempi64; 
     tempi64 = (rfilesize & 0x7FFFFFFF00000000); 
     tempi64 = tempi64 >> 32; 
     long dwhi = tempi64; 
     DWORD dwResult=SetFilePointer(localfilehandle, dwlow,&dwhi , FILE_BEGIN); 
     if (dwResult == INVALID_SET_FILE_POINTER) 
     { 
      transferstatus = ES_FAILED; Err = result; return result; 
     } 
     transferstatus = ES_RESUMING; 
     transfered = rfilesize; 

    } 
    else{ 
     result = createSFTPfile((char *)tempfilename.c_str()); 
     transferstatus = ES_STARTING; 
     if (result != E_OK) { 
      transferstatus = ES_FAILED; 
      Err = result; 
      CloseLocalFile(); 
      return result; 
     } 
     } 
     sftp_file_set_blocking(file); 
     transferstarttime = time(NULL); 
     transferstatus = ES_INPROGRESS; 

    while (transferstatus != ES_FAILED && transferstatus != ES_PAUSED && transferstatus != ES_DONE) 
    { 
     loopcounter++; 
     bresult = ReadFile(localfilehandle, (LPVOID)block, blocksize, &bytesread, NULL); 
     fprintf(logfile, "Read %d bytes from input file. Number of packets: %d , %llu from %llu bytes\n", bytesread, loopcounter, transfered, filesize); 
     if (bytesread < blocksize) 
     { 
      if (bresult == FALSE) 
      { 
       errstring = L"Error reading from local file."; 
       Err = E_LOCAL_FILE_READ; 
       transferstatus = ES_FAILED; 
       CloseRemoteFile(); 
       CloseLocalFile(); 
       return E_LOCAL_FILE_READ; 
      } 
      else if (bytesread == 0) 
      { 
       errstring = L"Transfer done."; 
       Err = E_OK; 
       transferstatus = ES_DONE; 
       continue; 
      } 
     } 

     result = writeSFTPfile(block, bytesread); 
     if (result != E_OK && bytesread>0) 
     { 
      errstring = L"Error transmitting to remote sftp server file."; 
      Err = result; 
      transferstatus = ES_FAILED; 
      CloseRemoteFile(); 
      CloseLocalFile(); 
      return result; 
     } 


     Err = E_OK; 
     //transfered = transfered + bytesread; 
     if (pause == true) transferstatus = ES_PAUSED; 
     if (bresult == TRUE && bytesread == 0) 
     { 
      // at the end of the file 
      transferstatus = ES_DONE; 
     } 
     Sleep(BLOCKTRANSDELAY); 
     if (loopcounter % 331 == 0)Sleep(77 * BLOCKTRANSDELAY); 
     if (loopcounter % 3331 == 0)Sleep(777 * BLOCKTRANSDELAY); 

    } 

    CloseRemoteFile(); 
    CloseLocalFile(); 
    Sleep(1000); 

    if (transferstatus == ES_CANCELLED) 
    { 
     result = SFTPdelete((char *)tempfilename.c_str()); 
     if (bresult != E_OK) 
     { 
      Err = E_DELETE_ERR; 
      errstring = L"Could not delete remote file."; 
      transferstatus = ES_FAILED; 
      return E_DELETE_ERR; 
     } 
    } 
    if (transferstatus == ES_DONE) result = SFTPrename(rfn, (char *)tempfilename.c_str()); 
    delete block; 
    return result; 
} 




ESSHERR CSFTPConnector::getSFTPfileinfo() 
{ 
    sftp_attributes fileinf = sftp_fstat(file); 

    if (fileinf == NULL){ 
     return E_GET_FILEINF; 
    } 

    rfilesize = fileinf->size; 

    sftp_attributes_free(fileinf); 
    return E_OK; 
} 

ESSHERR CSFTPConnector::closeSFTPfile() 
{ 
    int rc = sftp_close(file); 
    if (rc != SSH_OK) 
    { 
     fprintf(logfile, "Can't close the written file: %s\n", 
      ssh_get_error(session)); 
     return E_FILE_CLOSE; 
    } 
    return E_OK; 
} 


ESSHERR CSFTPConnector::writeSFTPfile(char *block, size_t blocksize) 
{ 
    size_t nwritten = sftp_write(file, block, blocksize); 
    if (nwritten != blocksize) 
    { 
     fprintf(logfile, "Can't write data to file: %s\n", 
      ssh_get_error(session)); 
     //sftp_close(file); 
     transfered = transfered + nwritten; 
     return E_WRITE_ERR; 
    } 

    transfered = transfered + nwritten; 
    return E_OK; 
} 

ESSHERR CSFTPConnector::readSFTPfile(char *block, size_t len, size_t *bytesread) 
{ 

    DWORD readbytes; 
    *bytesread = 0; 
    if (len <= 0) return E_INVALID_PARAMS; 
    if (bytesread == NULL || block == NULL) return E_INVALID_PARAMS; 

    readbytes = sftp_read(file, block, len); 
    if (readbytes < 0) 
    { 
     fprintf(logfile, "Can't read from remote file: %s %s\n", filename.c_str(), ssh_get_error(session)); 
     *bytesread = 0; 
     return E_SFTP_READ_ERR; 
    } 


    if (readbytes < len) 
    { 
     *bytesread = readbytes; 
     transfered = transfered + readbytes; 
     return E_SFTP_READ_EOF; 
    } 


    *bytesread = readbytes; 
    transfered = transfered + readbytes; 

    return E_OK; 

} 

ESSHERR CSFTPConnector::readSFTPfile(char *block, __int64 len, DWORD *bytesread) 
{ 
    DWORD readbytes; 
    *bytesread = 0; 
    if (len <= 0) return E_INVALID_PARAMS; 
    if (bytesread == NULL || block == NULL) return E_INVALID_PARAMS; 

    readbytes = sftp_read(file, block, len); 
    if (readbytes < 0) 
    { 
     fprintf(logfile, "Can't read from remote file: %s %s\n", filename.c_str(), ssh_get_error(session)); 
     *bytesread = 0; 
     return E_SFTP_READ_ERR; 
    } 


    if (readbytes < len) 
    { 
     *bytesread = readbytes; 
     return E_SFTP_READ_EOF; 
    } 


    *bytesread = readbytes; 
    transfered = transfered + readbytes; 

    return E_OK; 

} 


ESSHERR CSFTPConnector::createSFTPfile(char *fn) 
{ 

    int access_type = O_CREAT | O_RDWR; 
    int rc, nwritten; 

    filename = string(fn); 
    file = sftp_open(sftp, fn, 
     access_type, S_IWRITE); 
    if (file == NULL) 
    { 
     fprintf(logfile, "Can't open file for writing: %s\n", 
      ssh_get_error(session)); 
     return E_FILEOPEN_WRITE; 
    } 
    return E_OK; 
} 


ESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn) 
{ 

    int access_type = O_RDONLY ; 
    int rc, nwritten; 

    filename = string(fn); 
    file = sftp_open(sftp, fn, 
     access_type, S_IREAD); 
    if (file == NULL) 
    { 
     fprintf(logfile, "Can't open file for writing: %s\n", 
      ssh_get_error(session)); 
     return E_FILEOPEN_RDONLY; 
    } 
    return E_OK; 
} 




ESSHERR CSFTPConnector::openSFTPfile(char *fn) 
{ 
    int access_type = O_RDONLY; 
    int rc, nwritten; 

    filename = string(fn); 
    file = sftp_open(sftp, fn, 
     access_type, S_IWRITE); 
    if (file == NULL) 
    { 
     fprintf(logfile, "Can't open file for writing: %s\n", 
      ssh_get_error(session)); 
     return E_FILE_OPEN_READ; 
    } 
    return E_OK; 

} 

ESSHERR CSFTPConnector::Makedir(char *newdir) 
{ 
    int rc; 
    rc = sftp_mkdir(sftp, newdir, S_IFDIR); 
    if (rc != SSH_OK) 
    { 
     if (sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS) 
     { 
      fprintf(logfile, "Can't create directory: %s\n", 
       ssh_get_error(session)); 
      return E_CREATE_DIR; 
     } 
    } 

     return E_OK; 
} 




SFTPConnector::CSFTPConnector() 
{ 
    //libssh2_init(0); 
    session = ssh_new(); 
    if (session == NULL) 
    { 
     Err = E_SESSION_ALOC; 
     errstring = L"Could not allocate a session."; 

    } 
    wcscpy(hostname, L"localhost"); 
    wcscpy(username, L"User"); 
    wcscpy(password, L"Password"); 
    wcscpy(basedir, L".\\"); 
    port = 22; 
    verbosity = SSH_LOG_RARE; 
    filesize = 0; 
    transfered = 0; 

    pause = false; 
    transferstatus = ES_NONE; 
    logfile = stderr; 
} 


CSFTPConnector::CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass) 
{ 

    session = ssh_new(); 

    if (session == NULL) 
    { 
     Err = E_SESSION_ALOC; 
     errstring = L"Could not allocate a session."; 

    } 
    wcscpy(hostname, hn); 
    wcscpy(username, un); 
    wcscpy(password, pass); 
    wcscpy(basedir, dir); 
    port = hostport; 
    verbosity = SSH_LOG_RARE; 
    filesize=0; 
    transfered=0; 

    pause=false; 
    transferstatus = ES_NONE; 
    logfile = stderr; 

} 


ESSHERR CSFTPConnector::InitSFTP() 
{ 
    int rc; 
    sftp= sftp_new(session); 
    if (session == NULL) 
    { 
     Err = E_SFTP_ALLOC; 
     errstring = L"Could not allocate a sftp session."; 

    } 

    rc = sftp_init(sftp); 
    if (rc != SSH_OK) 
    { 
     fprintf(logfile, "Error initializing SFTP session: %s.\n", 
      sftp_get_error(sftp)); 
     sftp_free(sftp); 
     return E_INIT_SFTP; 
    } 


    return E_OK; 
} 


ESSHERR CSFTPConnector::ConnectSession() 
{ 
    char temp[SHORT_BUFF_LEN]; 
    size_t n_of_chars; 
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)password, SHORT_BUFF_LEN); 
    int ir; 

    ir=ssh_connect(session); 
    if (ir != SSH_OK){ 
     errstring = L"Could not connect the ssh session."; 
     return E_SSH_CONNECT_ERR; 
    } 

    ir=ssh_userauth_password(session, NULL, temp); 
    if (ir != SSH_OK){ 
     errstring = L"Could not connect the ssh session."; 
     return E_SSH_CONNECT_ERR; 
    } 
    return E_OK; 
} 


ESSHERR CSFTPConnector::InitSession() 
{ 
    char temp[SHORT_BUFF_LEN]; 
    size_t n_of_chars; 
    wcstombs_s(&n_of_chars, temp,SHORT_BUFF_LEN, (const wchar_t *) hostname, SHORT_BUFF_LEN); 
    ssh_options_set(session, SSH_OPTIONS_HOST,temp); 
    ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); 
    ssh_options_set(session, SSH_OPTIONS_PORT, &port); 
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)username, SHORT_BUFF_LEN); 
    ssh_options_set(session, SSH_OPTIONS_USER,temp); 
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)basedir, SHORT_BUFF_LEN); 
    ssh_options_set(session, SSH_OPTIONS_SSH_DIR, temp); 

    return E_OK; 
} 


CSFTPConnector::~CSFTPConnector() 
{ 


    sftp_free(sftp); 
    ssh_disconnect(session); 
    ssh_free(session); 

    return; 
} 
+1

Cette approche (avec libssh2) a été utilisée pour SFTP. –