unix 如何使用C语言编程SCP一个文件?

oiopk7p5  于 2022-11-04  发布在  Unix
关注(0)|答案(5)|浏览(187)

在Unix环境中使用C语言执行scpsftp复制的最佳方法是什么?
我很想知道最好使用的库,如果可能的话,我想知道一个例子。我正在一个安装了 *Sun工具 * 的Solaris服务器上工作。

b5lpy0ml

b5lpy0ml1#

尝试Libcurl
libcurl是一个免费和易于使用的客户端URL传输库,支持DICT,文件,〉FTP,FTPS,Gopher,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,POP3,POP 3S,RTMP,RTSP,SCP,SFTP,SMTP,SMTPS,Telnet和TFTP。libcurl支持SSL证书,HTTP POST,HTTP PUT,FTP上传,基于HTTP表单的上传,代理,Cookie,用户+密码验证(基本、摘要、NTLM、协商、Kerberos)、文件传输恢复、http代理隧道等!
libcurl是高度可移植的,它构建和工作在许多平台上,包括Solaris,NetBSD,FreeBSD,OpenBSD,达尔文,HPUX,IRIX,AIX,Tru 64,Linux,UnixWare,HURD,Windows,Amiga,OS/2,BeOs,Mac OS X,Ultrix,QNX,OpenVMS,RISC操作系统,Novell NetWare,DOS和更多...

wkftcu5l

wkftcu5l2#

我不是一个真正的CMaven,但我认为你可以使用system()来运行操作系统命令。这假设你实际上不想重新实现scp,只是使用它。

ca1c2owp

ca1c2owp3#

我一直使用 system() 命令。当然,这样做需要在客户端和目标机器之间正确安装SSH密钥,这样就不会提示输入密码。

q8l4jmvw

q8l4jmvw4#

您可以使用libssh来进行sftp。我在这里为您提供了一些代码,这些代码具有Pause/Resume功能,并且可以在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 on Windows, but it 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 temporary 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 directory is the directory of the public and private key structure (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 transferred;
    DWORD  local_file_size_hiDWORD;   // Bill Gates cannot accept the file size
                                      // without twisting the programmers, so
                                      // he accepts them in two separate words
                                      // like this
    DWORD  local_file_size_lowDWORD;  // These two DWORDs when connected together comprise a 64 bit file size.
    __int64 lfilesize;                // Local file size
    __int64 rfilesize;                // Remote file size
    __int64 transferred;              // Number of bytes already transferred
    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 before doing any transfer
    ESSHERR ConnectSession(); // Connects to the SSH server
    ESSHERR InitSFTP();       // Must be called before 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 previous 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 the SFTP server
    ESSHERR CSFTPConnector::SFTPreget(char *lfn, char *rfn, size_t blocksize);  // Checks for a previous interrupted transfer,
                                                                                // then either continues the previous 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, standard
                                 // error 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;
    transferred = 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;
    transferred = 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, transferred, 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 = (transferred * 8) / stats.seconds_elapsed;
    if (filesize > 0) {
        stats.percent = (transferred *100)/ filesize;
        stats.seconds_remained = ((filesize - transferred) * 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;
    transferred = 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;
        transferred = 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, transferred, 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;
        //transferred = transferred + 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);
        transferred = transferred + nwritten;
        return E_WRITE_ERR;
    }

    transferred = transferred + 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;
        transferred = transferred + readbytes;
        return E_SFTP_READ_EOF;
    }

    *bytesread = readbytes;
    transferred = transferred + 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;
    transferred = transferred + 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;
    transferred = 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;
    transferred = 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;
}
kgsdhlau

kgsdhlau5#

在过去,我只是调用了一个包含文件传输代码的shell脚本。

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

如果传输命令成功返回,则返回1。

相关问题