Как программно SCP файл с помощью C

Как лучше всего сделать копию scp или sftp в среде unix с использованием C. Мне интересно знать, какую библиотеку лучше всего использовать, и пример, если это вообще возможно. Я работаю над solaris server с установленным sun tools.

Как на это нет принятого ответа ??

Christian Stewart 04.07.2013 02:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
4 572
5

Ответы 5

Раньше я просто вызывал сценарий оболочки, содержащий код передачи файлов.

int transferFile()
{
  //declare the transfer command
  char transferCommand[50] = "/home/tyler/transferFile.shl";
  //execute the command
  return system(transferCommand);
}

Это вернет 1, если команда передачи завершится успешно.

Я не совсем специалист по C, но думаю, что вы можете использовать system () для запуска команд ОС. Это предполагает, что вы на самом деле не хотите повторно реализовывать scp, просто используйте его.

Я всегда просто использовал команду system (). Конечно, для этого необходимо, чтобы у вас были правильно установлены ключи ssh между клиентом и целевой машиной, чтобы пароль не запрашивался.

Попробуйте Libcurl

libcurl is a free and easy-to-use client-side URL transfer library, supporting DICT, FILE, > FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. libcurl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, Kerberos), file transfer resume, http proxy tunneling and more!

libcurl is highly portable, it builds and works identically on numerous platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS and more...

вы можете использовать libssh для sftp. Я поместил здесь для вас код, который имеет паузу / возобновление и работает в Windows. для Linux вам необходимо заменить локальные функции обработки файлов. Я не могу скопировать весь класс, потому что он превышает этот лимит веб-сайта. измените имя пользователя, пароль и имя хоста на соответствующие эквиваленты вашего 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;
}

Другие вопросы по теме