<p>What would be the best way to do an <code>scp</code> or <code>sftp</code> copy in a Unix environment using C?</p>
<p>I'm interested in knowing the best library to use and an example if at all possible. I'm working on a <a href="https://en.wikipedia.org/wiki/Solaris_%28operating_system%29" rel="nofollow noreferrer">Solaris</a> server with the <em><a href="https://en.wikipedia.org/wiki/Sun_Microsystems" rel="nofollow noreferrer">Sun</a> tools</em> installed.</p>

[{'answer_id': 42705, 'author': 'Tyler Gooch', 'author_id': 1372, 'author_profile': 'https://Stackoverflow.com/users/1372', 'pm_score': 0, 'selected': False, 'text': "<p>In the past, I've simply called a shell script that contained the file transfer code.</p>\n<pre><code>int transferFile()\n{\n  // Declare the transfer command\n  char transferCommand[50] = &quot;/home/tyler/transferFile.shl&quot;;\n  // Execute the command\n  return system(transferCommand);\n}\n</code></pre>\n<p>This will return 1 if the transfer command returns successfully.</p>\n"}, {'answer_id': 42712, 'author': 'mk.', 'author_id': 1797, 'author_profile': 'https://Stackoverflow.com/users/1797', 'pm_score': 0, 'selected': False, 'text': "<p>I'm not really a C expert, but I think you can use system() to run OS commands. This would assume that you don't actually want to re-implement scp, just use it. </p>\n"}, {'answer_id': 42754, 'author': 'dagorym', 'author_id': 171, 'author_profile': 'https://Stackoverflow.com/users/171', 'pm_score': 0, 'selected': False, 'text': "<p>I've always just used the <em>system()</em> command.  Of course doing this requires that you have SSH keys properly installed between the client and target machine so that it doesn't prompt for the password.</p>\n"}, {'answer_id': 17459534, 'author': 'LogicG8', 'author_id': 973745, 'author_profile': 'https://Stackoverflow.com/users/973745', 'pm_score': 2, 'selected': False, 'text': '<p>Try <a href="http://curl.haxx.se/libcurl/" rel="nofollow noreferrer">Libcurl</a></p>\n<blockquote>\n<p>libcurl is a free and easy-to-use client-side URL transfer library, supporting DICT, FILE, &gt; 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!</p>\n<p>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...</p>\n</blockquote>\n'}, {'answer_id': 24989730, 'author': 'Desphilboy', 'author_id': 2023625, 'author_profile': 'https://Stackoverflow.com/users/2023625', 'pm_score': 0, 'selected': False, 'text': "<p>You can use libssh for sftp. I put some code here for you which has Pause/Resume and works on Windows. For Linux, you need to replace local file handling functions. I cannot copy the entire class because it will exceed this website limit. Change username and password and hostname to proper equivalents of your SFTP server:</p>\n<pre><code>int main(array&lt;System::String ^&gt; ^args)\n{\n    //Console::WriteLine(L&quot;Hello World&quot;);\n\n    pSFTPConnector  sshc = new  SFTPConnector(L&quot;.\\\\&quot;, L&quot;127.0.0.1&quot;, 22, L&quot;iman&quot;, L&quot;iman&quot;);  // Change the hostname, port, username, password to your SFTP server, your credentials\n\n    //FILE *nullfile = fopen(&quot;null&quot;, &quot;w&quot;);\n    //sshc-&gt;setLogFile(nullfile);\n    sshc-&gt;setVerbosity(SSH_LOG_RARE);        // You can change the verbosity as appropriate for you\n\n    int i = sshc-&gt;InitSession();\n    i = sshc-&gt;ConnectSession();\n    i = sshc-&gt;InitSFTP();\n\n    //i = sshc-&gt;SFTPrename(&quot;renamed_myfile.txt&quot;, &quot;myfile.txt&quot;);  // Change these file names\n    //i = sshc-&gt;Makedir(&quot;sftpdir&quot;);\n    //i = sshc-&gt;testUploadFile(&quot;myfile2.txt&quot;, &quot;1234567890testfile&quot;);\n\n    // Change these file names to whatever appropriate\n    //i = sshc-&gt;SFTPget(&quot;c:\\\\testdir\\\\Got_CAR_HIRE_FINAL_test.jpg&quot;, &quot;CAR_HIRE_FINAL_test.jpg&quot;, 64*1024);\n    i = sshc-&gt;SFTPget(&quot;c:\\\\testdir\\\\get_downloaded_CAR_HIRE_FINAL.jpg&quot;, &quot;CAR_HIRE_FINAL.jpg&quot;, 64 *1024);\n    i = sshc-&gt;SFTPreget(&quot;c:\\\\testdir\\\\reget_downloaded_CAR_HIRE_FINAL.jpg&quot;, &quot;CAR_HIRE_FINAL.jpg&quot;, 64 * 1024);\n    i = sshc-&gt;SFTPput(&quot;c:\\\\testdir\\\\CAR_HIRE_FINAL.jpg&quot;, &quot;put_CAR_HIRE_FINAL.jpg&quot;, 64 * 1024);\n    i = sshc-&gt;SFTPreput(&quot;c:\\\\testdir\\\\CAR_HIRE_FINAL.jpg&quot;, &quot;reput_CAR_HIRE_FINAL.jpg&quot;, 64 * 1024);\n\n    delete sshc;\n    return 0;\n}\n\ntypedef enum sshconerr {\n    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,\n    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,\n    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,\n    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,\n    E_UNKNOWN = -999\n} ESSHERR;\n\n\n// Status of transfers;\ntypedef enum sftpstat{ES_DONE=0, ES_INPROGRESS, ES_FAILED, ES_STARTING, ES_PAUSED, ES_RESUMING, ES_CANCELLED,  ES_NONE  } ESFTPSTAT;\n\nusing namespace std;\n\n\n// Statistics about the transfer;\ntypedef struct transferstatstruct {\n    string remote_file_name;\n    string local_file_name;\n    __int64 total_size;\n    __int64 transferred;\n    __int64 averagebps;\n    long long seconds_elapsed;\n    long long seconds_remained;\n    int percent;\n    ESFTPSTAT transferstate;\n} TTransStat;\n\n\n#define E_SESSION_NEW -1\n\n// These libraries are required\n#pragma comment(lib, &quot;ssh.lib&quot;)\n\n// This is the main class that does the majority of the work\n\ntypedef class CSFTPConnector {\n\n    private:\n    ssh_session  session;             // SSH session\n    sftp_session sftp;                // SFTP session\n    sftp_file file;                   // Structure for a remote file\n    FILE *localfile;                  // Not used on Windows, but it could be local file pointer in Unix\n    FILE *logfile;                    // The file for writing logs, default is set to stderr\n    string filename;                  // File name of the transfer;\n    string localfilename;             // File name of local file;\n    string tempfilename;              // A temporary file name will be used during the transfer which is renamed when transfer is completed.\n    ESFTPSTAT transferstatus;         // State of the transfer which has one of the above values (ESFTPSTAT)\n    time_t transferstarttime;         // Time of start of the transfer\n    wchar_t username[SHORT_BUFF_LEN];\n    wchar_t password[SHORT_BUFF_LEN];\n    wchar_t hostname[SHORT_BUFF_LEN]; // Hostname of the SFTP server\n    wchar_t basedir[SHORT_BUFF_LEN];  // This base directory is the directory of the public and private key structure (NOT USED IN THIS VERSION)\n    int port;                         // Port of the server;\n    int verbosity;                    // Degree of verbosity of libssh\n    __int64  filesize;                // Total number of bytes to be transferred;\n    DWORD  local_file_size_hiDWORD;   // Bill Gates cannot accept the file size\n                                      // without twisting the programmers, so\n                                      // he accepts them in two separate words\n                                      // like this\n    DWORD  local_file_size_lowDWORD;  // These two DWORDs when connected together comprise a 64 bit file size.\n    __int64 lfilesize;                // Local file size\n    __int64 rfilesize;                // Remote file size\n    __int64 transferred;              // Number of bytes already transferred\n    bool pause;                       // Pause flag\n    TTransStat stats;                 // Statistics of the transfer\n    HANDLE    localfilehandle;        // Windows uses handles to manipulate files. this is the handle to local file.\n\n    ESSHERR CSFTPConnector::rwopen_existing_SFTPfile(char *fn);       // Open a file on remote (server) read/write for upload\n    ESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn);       // Open a file on remote (server) read only for download\n    ESSHERR createSFTPfile(char *fn);                                 // Create a file on server;\n    ESSHERR writeSFTPfile(char *block, size_t blocksize);             // Write a block of data to the  open remote file\n    ESSHERR readSFTPfile(char *block, size_t len, size_t *bytesread); // Read a block of data from the  open remote file\n    ESSHERR readSFTPfile(char *block, __int64 len, DWORD *bytesread);\n    ESSHERR closeSFTPfile();         // Closes the remote file;\n    ESSHERR openSFTPfile(char *fn);  // Opens the remote file\n    ESSHERR getSFTPfileinfo();       // Gets information about the remote file\n\n    public:\n    wstring errstring;        // The string describing last error\n    ESSHERR Err;              // Error code of last error\n    CSFTPConnector();         // Default constructor;\n    CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass);  // Constructor\n    void setVerbosity(int v);\n    int  getVerbosity();\n    ESSHERR InitSession();    // Must be called before doing any transfer\n    ESSHERR ConnectSession(); // Connects to the SSH server\n    ESSHERR InitSFTP();       // Must be called before doing any transfer\n    ESSHERR Makedir(char *newdir);\n    ESSHERR testUploadFile(char *fn, char *block);             // Do not use this, only for test purposes for myself\n    ESSHERR SFTPput(char *lfn, char *rfn, size_t blocksize);   // Upload a file from start\n    ESSHERR SFTPreput(char *lfn, char *rfn, size_t blocksize); // Checks for previouse interrupted transfer, then\n                                                               // either continues the previous transfer (if\n                                                               // there was any) or starts a new one (UPLOAD)\n    ESSHERR SFTPrename(char *newname, char *oldname);          // Renames a remote file( must be closed)\n    ESSHERR CSFTPConnector::SFTPdelete(char *remfile);         // Deletes a remote file\n    TTransStat getStatus();                                    // Gets statistics of the transfer\n    ESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize);    // Downloads a file from the SFTP server\n    ESSHERR CSFTPConnector::SFTPreget(char *lfn, char *rfn, size_t blocksize);  // Checks for a previous interrupted transfer,\n                                                                                // then either continues the previous transfer\n                                                                                // (if there was any) or starts a new one (DOWNLOAD).\n    void CancelTransfer();\n    void PauseTransfer();\n    void setLogFile(FILE *logf); // Sets the log file. If not set, standard\n                                 // error will be used. By default.\n    void CloseLocalFile();\n    void CloseRemoteFile();\n\n    ~CSFTPConnector();\n} SFTPConnector, *pSFTPConnector;\n\nvoid CSFTPConnector::CloseLocalFile()\n{\n    CloseHandle(localfilehandle);\n}\n\n\nvoid CSFTPConnector::CloseRemoteFile()\n{\n    sftp_close(file);\n}\n\nvoid CSFTPConnector::setLogFile(FILE *logf)\n{\n    logfile = logf;\n}\n\nvoid CSFTPConnector::CancelTransfer()\n{\n    transferstatus = ES_CANCELLED;\n}\n\nvoid CSFTPConnector::PauseTransfer()\n{\n    transferstatus = ES_PAUSED;\n    pause = true;\n}\n\n//----------------------------------------\n\nESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize)\n{\n    DWORD result;\n    int rc;\n    BOOL bresult;\n    DWORD bytesread;\n    filesize = 0;\n    transferred = 0;\n\n    pause = false;\n    transferstatus = ES_NONE;\n    char *block;\n    struct stat st;\n    wchar_t temp[SHORT_BUFF_LEN];\n    size_t tempsize;\n    wstring wlfn;\n    int loopcounter = 0;\n\n    localfilename = lfn;\n\n    filename = rfn;\n\n    tempfilename = string(lfn) + &quot;.sftp_temp&quot;;\n    mbstowcs_s(&amp;tempsize, temp, tempfilename.c_str(), SHORT_BUFF_LEN);\n\n    localfilehandle = CreateFile(temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);\n    if (localfilehandle == INVALID_HANDLE_VALUE)\n    {\n        transferstatus = ES_FAILED;\n        errstring = L&quot;Could not open local file:&quot; + wstring(temp) + L&quot; for read and write&quot;;\n        Err = E_LOCAL_FILE_RDWR;\n        return E_LOCAL_FILE_RDWR;\n    }\n\n    lfilesize = 0;\n    transferred = 0;\n\n    block = (char*)malloc(blocksize + 1);\n    if (block == NULL) {\n        Err = E_MEM_ALLOC;\n        transferstatus = ES_FAILED;\n        errstring = L&quot;Could not allocate memory for file block size&quot;;\n        CloseLocalFile();\n        return E_MEM_ALLOC;\n    }\n\n    result = rdopen_existing_SFTPfile((char *)rfn);\n\n    if (result == E_OK) {\n        getSFTPfileinfo();\n        filesize = rfilesize;\n    }\n    else\n    {\n        Err = E_REMOTE_FILE_OPEN;\n        transferstatus = ES_FAILED;\n        errstring = L&quot;Could not open remote file&quot;;\n        CloseLocalFile();\n        delete block;\n        return E_REMOTEFILE_SEEK;\n    }\n\n    transferstatus = ES_STARTING;\n\n    sftp_file_set_blocking(file);\n    transferstarttime = time(NULL);\n    transferstatus = ES_INPROGRESS;\n\n    while (transferstatus != ES_FAILED &amp;&amp;\n           transferstatus != ES_PAUSED &amp;&amp;\n           transferstatus != ES_CANCELLED &amp;&amp;\n           transferstatus != ES_DONE)\n    {\n        loopcounter++;\n\n        result = readSFTPfile(block, blocksize, (size_t *)&amp;bytesread);\n        if (result != E_OK &amp;&amp; result!= E_SFTP_READ_EOF)\n        {\n            errstring = L&quot;Error reading from remote SFTP server file.&quot;;\n            Err = (ESSHERR)result;\n            transferstatus = ES_FAILED;\n            CloseRemoteFile();\n            CloseLocalFile();\n            delete block;\n            return (ESSHERR)result;\n        }\n        if (result == E_SFTP_READ_EOF)\n            transferstatus = ES_DONE;\n        fprintf(logfile, &quot;Read %d bytes from input file. Number of packets: %d, %llu from %llu bytes\\n&quot;, bytesread, loopcounter, transferred, filesize);\n\n        bresult = WriteFile(localfilehandle, (LPVOID)block, bytesread, &amp;bytesread, NULL);\n        if (bytesread &lt; blocksize)\n        {\n            if (bresult == FALSE)\n            {\n                errstring = L&quot;Error writing to local file.&quot;;\n                Err = E_LOCAL_FILE_RDWR;\n                transferstatus = ES_FAILED;\n                CloseRemoteFile();\n                CloseLocalFile();\n                delete block;\n                return E_LOCAL_FILE_RDWR;\n            }\n            else if (bytesread == 0)\n            {\n                errstring = L&quot;Transfer done.&quot;;\n                Err = E_OK;\n                transferstatus = ES_DONE;\n                continue;\n            }\n        }\n\n        Err = E_OK;\n\n        if (pause == true)\n            transferstatus = ES_PAUSED;\n        if (bresult == TRUE &amp;&amp;  bytesread == 0)\n        {\n            // At the end of the file\n            transferstatus = ES_DONE;\n        }\n        Sleep(BLOCKTRANSDELAY);\n        if (loopcounter % 331 == 0)\n            Sleep(77 * BLOCKTRANSDELAY);\n        if (loopcounter % 3331 == 0)\n            Sleep(777 * BLOCKTRANSDELAY);\n    }\n\n    // Closing files\n    result = closeSFTPfile();\n    CloseHandle(localfilehandle);\n\n    Sleep(1000);\n\n    if (transferstatus == ES_DONE)\n    {\n        wchar_t temp2[SHORT_BUFF_LEN];\n        mbstowcs_s(&amp;tempsize, temp2, lfn, SHORT_BUFF_LEN);\n        bresult = MoveFile(temp, temp2);\n        if (bresult != TRUE)\n        {\n            Err = E_RENAME_LOCAL_FILE;\n            errstring = L&quot;Could not rename local file: &quot; + wstring(temp);\n            transferstatus = ES_FAILED;\n            delete block;\n            return E_RENAME_LOCAL_FILE;\n        }\n    }\n\n    if (transferstatus == ES_CANCELLED)\n    {\n        wchar_t temp2[SHORT_BUFF_LEN];\n        mbstowcs_s(&amp;tempsize, temp2, lfn, SHORT_BUFF_LEN);\n        bresult = DeleteFile(temp);\n        if (bresult != TRUE)\n        {\n            Err = E_LOCAL_DELETE_FILE;\n            errstring = L&quot;Could not rename local file: &quot; + wstring(temp);\n            transferstatus = ES_FAILED;\n            delete block;\n            return E_LOCAL_DELETE_FILE;\n        }\n    }\n    delete block;\n    return (ESSHERR) result;\n}\n\nTTransStat CSFTPConnector::getStatus()\n{\n    stats.seconds_elapsed = time(NULL) - transferstarttime;\n    stats.averagebps = (transferred * 8) / stats.seconds_elapsed;\n    if (filesize &gt; 0) {\n        stats.percent = (transferred *100)/ filesize;\n        stats.seconds_remained = ((filesize - transferred) * 8) / stats.averagebps;\n    }\n    else\n    {\n        stats.percent = -1;\n        stats.seconds_remained = -1;\n    }\n    stats.total_size = filesize;\n    stats.transferstate = transferstatus;\n    stats.remote_file_name = filename;\n    stats.local_file_name = localfilename;\n\n    return stats;\n}\n\nESSHERR CSFTPConnector::SFTPrename(char *newname, char *oldname)\n{\n    int rc = sftp_rename(sftp, oldname, newname);\n    if (rc != SSH_OK) {\n        return E_RENAME_ERR;\n    }\n\n    return E_OK;\n}\n\n\nESSHERR CSFTPConnector::SFTPdelete(char *remfile)\n{\n    int rc = sftp_unlink(sftp, remfile);\n    if (rc != SSH_OK) {\n        return E_DELETE_ERR;\n    }\n    return E_OK;\n}\n\n\nESSHERR CSFTPConnector::SFTPreput(char *lfn, char *rfn, size_t blocksize)\n{\n    ESSHERR result;\n    BOOL  bresult;\n    DWORD bytesread;\n    filesize = 0;\n    transferred = 0;\n\n    pause = false;\n    transferstatus = ES_NONE;\n    char *block;\n    struct stat st;\n    wchar_t temp[SHORT_BUFF_LEN];\n    size_t tempsize;\n    wstring wlfn;\n    int loopcounter = 0;\n\n    localfilename = lfn;\n    //wlfn = wstring(lfn);\n    //localfile = fopen(lfn, L&quot;r&quot;);\n    filename = rfn;\n    mbstowcs_s(&amp;tempsize, temp, lfn, SHORT_BUFF_LEN);\n\n    //filesize = getFileSize(localfilename);\n\n    /*if (filesize &lt; 0) {\n        transferstatus = ES_FAILED;\n        Err = E_LOCAL_FILE_NOTFOUND;\n        return E_LOCAL_FILE_NOTFOUND;\n    }*/\n\n    localfilehandle = CreateFile(temp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n    if (localfilehandle == INVALID_HANDLE_VALUE)\n    {\n        transferstatus = ES_FAILED;\n        Err = E_LOCAL_FILE_NOTFOUND;\n        return E_LOCAL_FILE_NOTFOUND;\n    }\n    local_file_size_lowDWORD = GetFileSize(localfilehandle, &amp;local_file_size_hiDWORD);\n    filesize = (local_file_size_hiDWORD * 0x100000000) + local_file_size_lowDWORD;\n\n    if (filesize &lt; 0) {\n        transferstatus = ES_FAILED;\n        Err = E_LOCAL_FILE_NOTFOUND;\n        CloseLocalFile();\n        return E_LOCAL_FILE_NOTFOUND;\n    }\n\n    block = (char*)malloc(blocksize + 1);\n    if (block == NULL) {\n        Err = E_MEM_ALLOC;\n        transferstatus = ES_FAILED;\n        errstring = L&quot;Could not allocate memory for file block size&quot;;\n        CloseLocalFile();\n        return E_MEM_ALLOC;\n    }\n\n    tempfilename = string(rfn) + &quot;.sftp_temp&quot;;\n\n    result = rwopen_existing_SFTPfile((char *)tempfilename.c_str());\n    if (result == E_OK) {\n        getSFTPfileinfo();\n        sftp_seek64(file, rfilesize);\n        __int64 tempi64 = rfilesize &amp; 0x00000000FFFFFFFF;\n        DWORD dwlow = tempi64;\n        tempi64 = (rfilesize &amp; 0x7FFFFFFF00000000);\n        tempi64 = tempi64 &gt;&gt; 32;\n        long  dwhi = tempi64;\n        DWORD dwResult = SetFilePointer(localfilehandle, dwlow, &amp;dwhi, FILE_BEGIN);\n        if (dwResult == INVALID_SET_FILE_POINTER)\n        {\n            transferstatus = ES_FAILED; Err = result;  return result;\n        }\n        transferstatus = ES_RESUMING;\n        transferred = rfilesize;\n    }\n    else{\n        result = createSFTPfile((char *)tempfilename.c_str());\n        transferstatus = ES_STARTING;\n        if (result != E_OK) {\n            transferstatus = ES_FAILED;\n            Err = result;\n            CloseLocalFile();\n            return result;\n        }\n    }\n    sftp_file_set_blocking(file);\n    transferstarttime = time(NULL);\n    transferstatus = ES_INPROGRESS;\n\n    while (transferstatus != ES_FAILED &amp;&amp;\n           transferstatus != ES_PAUSED &amp;&amp;\n           transferstatus != ES_DONE)\n    {\n        loopcounter++;\n        bresult = ReadFile(localfilehandle, (LPVOID)block, blocksize, &amp;bytesread, NULL);\n        fprintf(logfile, &quot;Read %d bytes from input file. Number of packets: %d, %llu from %llu bytes\\n&quot;, bytesread, loopcounter, transferred, filesize);\n        if (bytesread &lt; blocksize)\n        {\n            if (bresult == FALSE)\n            {\n                errstring = L&quot;Error reading from local file.&quot;;\n                Err = E_LOCAL_FILE_READ;\n                transferstatus = ES_FAILED;\n                CloseRemoteFile();\n                CloseLocalFile();\n                return E_LOCAL_FILE_READ;\n            }\n            else if (bytesread == 0)\n            {\n                errstring = L&quot;Transfer done.&quot;;\n                Err = E_OK;\n                transferstatus = ES_DONE;\n                continue;\n            }\n        }\n\n        result = writeSFTPfile(block, bytesread);\n        if (result != E_OK &amp;&amp; bytesread&gt;0)\n        {\n            errstring = L&quot;Error transmitting to remote SFTP server file.&quot;;\n            Err = result;\n            transferstatus = ES_FAILED;\n            CloseRemoteFile();\n            CloseLocalFile();\n            return result;\n        }\n\n        Err = E_OK;\n        //transferred = transferred + bytesread;\n        if (pause == true)\n            transferstatus = ES_PAUSED;\n        if (bresult == TRUE &amp;&amp;  bytesread == 0)\n        {\n            // At the end of the file\n            transferstatus = ES_DONE;\n        }\n        Sleep(BLOCKTRANSDELAY);\n        if (loopcounter % 331 == 0)\n            Sleep(77 * BLOCKTRANSDELAY);\n        if (loopcounter % 3331 == 0)\n            Sleep(777 * BLOCKTRANSDELAY);\n    }\n\n    CloseRemoteFile();\n    CloseLocalFile();\n    Sleep(1000);\n\n    if (transferstatus == ES_CANCELLED)\n    {\n        result = SFTPdelete((char *)tempfilename.c_str());\n        if (bresult != E_OK)\n        {\n            Err = E_DELETE_ERR;\n            errstring = L&quot;Could not delete remote file.&quot;;\n            transferstatus = ES_FAILED;\n            return E_DELETE_ERR;\n        }\n    }\n    if (transferstatus == ES_DONE)\n        result = SFTPrename(rfn, (char *)tempfilename.c_str());\n    delete block;\n    return result;\n}\n\n\nESSHERR CSFTPConnector::getSFTPfileinfo()\n{\n    sftp_attributes fileinf = sftp_fstat(file);\n\n    if (fileinf == NULL) {\n        return E_GET_FILEINF;\n    }\n\n    rfilesize = fileinf-&gt;size;\n\n    sftp_attributes_free(fileinf);\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::closeSFTPfile()\n{\n    int rc = sftp_close(file);\n    if (rc != SSH_OK)\n    {\n        fprintf(logfile, &quot;Can't close the written file: %s\\n&quot;,\n                ssh_get_error(session));\n        return E_FILE_CLOSE;\n    }\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::writeSFTPfile(char *block, size_t blocksize)\n{\n    size_t nwritten = sftp_write(file, block, blocksize);\n    if (nwritten != blocksize)\n    {\n        fprintf(logfile, &quot;Can't write data to file: %s\\n&quot;,\n            ssh_get_error(session));\n        //sftp_close(file);\n        transferred = transferred + nwritten;\n        return E_WRITE_ERR;\n    }\n\n    transferred = transferred + nwritten;\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::readSFTPfile(char *block, size_t len, size_t *bytesread)\n{\n    DWORD readbytes;\n    *bytesread = 0;\n    if (len &lt;= 0)\n        return E_INVALID_PARAMS;\n    if (bytesread == NULL || block == NULL)\n        return E_INVALID_PARAMS;\n\n    readbytes = sftp_read(file, block, len);\n    if (readbytes &lt; 0)\n    {\n        fprintf(logfile, &quot;Can't read  from  remote file: %s  %s\\n&quot;, filename.c_str(), ssh_get_error(session));\n        *bytesread = 0;\n        return E_SFTP_READ_ERR;\n    }\n\n    if (readbytes &lt;  len)\n    {\n        *bytesread = readbytes;\n        transferred = transferred + readbytes;\n        return E_SFTP_READ_EOF;\n    }\n\n    *bytesread = readbytes;\n    transferred = transferred + readbytes;\n\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::readSFTPfile(char *block, __int64 len, DWORD *bytesread)\n{\n    DWORD readbytes;\n    *bytesread = 0;\n    if (len &lt;= 0)\n        return E_INVALID_PARAMS;\n    if (bytesread == NULL || block == NULL)\n        return E_INVALID_PARAMS;\n\n    readbytes = sftp_read(file, block, len);\n    if (readbytes &lt; 0)\n    {\n        fprintf(logfile, &quot;Can't read  from  remote file: %s  %s\\n&quot;, filename.c_str(), ssh_get_error(session));\n        *bytesread = 0;\n        return E_SFTP_READ_ERR;\n    }\n\n    if (readbytes &lt;  len)\n    {\n        *bytesread = readbytes;\n        return E_SFTP_READ_EOF;\n    }\n\n    *bytesread = readbytes;\n    transferred = transferred + readbytes;\n\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::createSFTPfile(char *fn)\n{\n    int access_type = O_CREAT | O_RDWR;\n    int rc, nwritten;\n\n    filename = string(fn);\n    file = sftp_open(sftp, fn,\n        access_type, S_IWRITE);\n    if (file == NULL)\n    {\n        fprintf(logfile, &quot;Can't open file for writing: %s\\n&quot;,\n                ssh_get_error(session));\n        return E_FILEOPEN_WRITE;\n    }\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn)\n{\n    int access_type = O_RDONLY;\n    int rc, nwritten;\n\n    filename = string(fn);\n    file = sftp_open(sftp, fn,\n        access_type, S_IREAD);\n    if (file == NULL)\n    {\n        fprintf(logfile, &quot;Can't open file for writing: %s\\n&quot;,\n                ssh_get_error(session));\n        return E_FILEOPEN_RDONLY;\n    }\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::openSFTPfile(char *fn)\n{\n    int access_type = O_RDONLY;\n    int rc, nwritten;\n\n    filename = string(fn);\n    file = sftp_open(sftp, fn,\n        access_type, S_IWRITE);\n    if (file == NULL)\n    {\n        fprintf(logfile, &quot;Can't open file for writing: %s\\n&quot;,\n            ssh_get_error(session));\n        return E_FILE_OPEN_READ;\n    }\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::Makedir(char *newdir)\n{\n    int rc;\n    rc = sftp_mkdir(sftp, newdir, S_IFDIR);\n    if (rc != SSH_OK)\n    {\n        if (sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS)\n        {\n            fprintf(logfile, &quot;Can't create directory: %s\\n&quot;,\n                ssh_get_error(session));\n            return E_CREATE_DIR;\n        }\n    }\n    return E_OK;\n}\n\nSFTPConnector::CSFTPConnector()\n{\n    //libssh2_init(0);\n    session = ssh_new();\n    if (session == NULL)\n    {\n        Err = E_SESSION_ALOC;\n        errstring = L&quot;Could not allocate a session.&quot;;\n\n    }\n    wcscpy(hostname, L&quot;localhost&quot;);\n    wcscpy(username, L&quot;User&quot;);\n    wcscpy(password, L&quot;Password&quot;);\n    wcscpy(basedir, L&quot;.\\\\&quot;);\n    port = 22;\n    verbosity = SSH_LOG_RARE;\n    filesize = 0;\n    transferred = 0;\n\n    pause = false;\n    transferstatus = ES_NONE;\n    logfile = stderr;\n}\n\n\nCSFTPConnector::CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass)\n{\n    session = ssh_new();\n\n    if (session == NULL)\n    {\n        Err = E_SESSION_ALOC;\n        errstring = L&quot;Could not allocate a session.&quot;;\n    }\n    wcscpy(hostname, hn);\n    wcscpy(username, un);\n    wcscpy(password, pass);\n    wcscpy(basedir, dir);\n    port = hostport;\n    verbosity = SSH_LOG_RARE;\n    filesize = 0;\n    transferred = 0;\n\n    pause = false;\n    transferstatus = ES_NONE;\n    logfile = stderr;\n}\n\nESSHERR CSFTPConnector::InitSFTP()\n{\n    int rc;\n    sftp = sftp_new(session);\n    if (session == NULL)\n    {\n        Err = E_SFTP_ALLOC;\n        errstring = L&quot;Could not allocate a sftp session.&quot;;\n    }\n\n    rc = sftp_init(sftp);\n    if (rc != SSH_OK)\n    {\n        fprintf(logfile, &quot;Error initializing SFTP session: %s.\\n&quot;,\n            sftp_get_error(sftp));\n        sftp_free(sftp);\n        return E_INIT_SFTP;\n    }\n\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::ConnectSession()\n{\n    char temp[SHORT_BUFF_LEN];\n    size_t n_of_chars;\n    wcstombs_s(&amp;n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)password, SHORT_BUFF_LEN);\n    int ir;\n\n    ir = ssh_connect(session);\n    if (ir != SSH_OK) {\n        errstring = L&quot;Could not connect the ssh session.&quot;;\n        return E_SSH_CONNECT_ERR;\n    }\n\n    ir = ssh_userauth_password(session, NULL, temp);\n    if (ir != SSH_OK) {\n        errstring = L&quot;Could not connect the ssh session.&quot;;\n        return E_SSH_CONNECT_ERR;\n    }\n    return E_OK;\n}\n\nESSHERR CSFTPConnector::InitSession()\n{\n    char temp[SHORT_BUFF_LEN];\n    size_t n_of_chars;\n    wcstombs_s(&amp;n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *) hostname, SHORT_BUFF_LEN);\n    ssh_options_set(session, SSH_OPTIONS_HOST, temp);\n    ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &amp;verbosity);\n    ssh_options_set(session, SSH_OPTIONS_PORT, &amp;port);\n    wcstombs_s(&amp;n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)username, SHORT_BUFF_LEN);\n    ssh_options_set(session, SSH_OPTIONS_USER, temp);\n    wcstombs_s(&amp;n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)basedir, SHORT_BUFF_LEN);\n    ssh_options_set(session, SSH_OPTIONS_SSH_DIR, temp);\n\n    return E_OK;\n}\n\nCSFTPConnector::~CSFTPConnector()\n{\n    sftp_free(sftp);\n    ssh_disconnect(session);\n    ssh_free(session);\n\n    return;\n}\n</code></pre>\n"}]
['https://Stackoverflow.com/questions/42672', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4491/']