libssh2实现上传下载文件

xingyun86 1月前 266

libssh2实现上传下载文件

EXTERN_C_START
#include <libssh2.h>
#include <libssh2_sftp.h>
EXTERN_C_END
#ifdef WIN32
#define write(f, b, c)  write((f), (b), (unsigned int)(c))
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <stdio.h>
static const char* pubkey = "/home/username/.ssh/id_rsa.pub";
static const char* privkey = "/home/username/.ssh/id_rsa";
static const char* username = "username";
static const char* password = "password";
static const char* sftppath = "/tmp/TEST"; /* source path */
static const char* dest = "/tmp/TEST2";    /* destination path */
static const char* storage = "/tmp/sftp-storage"; /* local file name to store
                                                     the downloaded file in */
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION* session)
{
    struct timeval timeout;
    int rc;
    fd_set fd;
    fd_set* writefd = NULL;
    fd_set* readfd = NULL;
    int dir;
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    FD_ZERO(&fd);
    FD_SET(socket_fd, &fd);
    /* now make sure we wait in the correct direction */
    dir = libssh2_session_block_directions(session);
    if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
        readfd = &fd;
    if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
        writefd = &fd;
    rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
    return rc;
}
int sftp_rw_main(int argc, char* argv[])
{
    libssh2_socket_t sock;
    int i, auth_pw = 1;
    struct sockaddr_in sin;
    const char* fingerprint;
    int rc;
    LIBSSH2_SESSION* session = NULL;
    LIBSSH2_SFTP* sftp_session;
    LIBSSH2_SFTP_HANDLE* sftp_handle;
    FILE* tempstorage = NULL;
    char mem[1024*100];
    struct timeval timeout;
    fd_set fd;
    fd_set fd2;
#ifdef WIN32
    WSADATA wsadata;
    rc = WSAStartup(MAKEWORD(2, 2), &wsadata);
    if (rc) {
        fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
        return 1;
    }
#endif
    if (argc > 1) {
        username = argv[1];
    }
    if (argc > 2) {
        password = argv[2];
    }
    if (argc > 3) {
        sftppath = argv[3];
    }
    if (argc > 4) {
        dest = argv[4];
    }
    if (argc > 5) {
        storage = argv[5];
    }
    rc = libssh2_init(0);
    if (rc) {
        fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
        return 1;
    }
    /* Ultra basic "connect to port 22 on localhost".  Your code is
     * responsible for creating the socket establishing the connection
     */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == LIBSSH2_INVALID_SOCKET) {
        fprintf(stderr, "failed to create socket!\n");
        goto shutdown;
    }
    sin.sin_family = AF_INET;
    sin.sin_port = htons(22);
    sin.sin_addr.s_addr = htonl(0x7F000001);
    if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
        fprintf(stderr, "failed to connect!\n");
        goto shutdown;
    }
    /* Create a session instance */
    session = libssh2_session_init();
    if (!session) {
        fprintf(stderr, "Could not initialize SSH session!\n");
        goto shutdown;
    }
    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */
    rc = libssh2_session_handshake(session, sock);
    if (rc) {
        fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
        goto shutdown;
    }
    libssh2_session_set_blocking(session, 0);
    /* At this point we have not yet authenticated.  The first thing to do
     * is check the hostkey's fingerprint against our known hosts Your app
     * may have it hard coded, may go to a file, may present it to the
     * user, that's your call
     */
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
    fprintf(stderr, "Fingerprint: ");
    for (i = 0; i < 20; i++) {
        fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stderr, "\n");
    if (auth_pw) {
        /* We could authenticate via password */
        while ((rc = libssh2_userauth_password(session, username, password)) ==
            LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "Authentication by password failed!\n");
            goto shutdown;
        }
    }
    else {
        /* Or by public key */
        while ((rc =
            libssh2_userauth_publickey_fromfile(session, username,
                pubkey, privkey,
                password)) ==
            LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "Authentication by public key failed!\n");
            goto shutdown;
        }
    }
    do {
        sftp_session = libssh2_sftp_init(session);
        if (!sftp_session) {
            if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
                fprintf(stderr, "non-blocking init\n");
                waitsocket(sock, session); /* now we wait */
            }
            else {
                fprintf(stderr, "Unable to init SFTP session\n");
                goto shutdown;
            }
        }
    } while (!sftp_session);
    tempstorage = fopen(storage, "wb");
    if (!tempstorage) {
        fprintf(stderr, "Cannot open temp storage file %s\n", storage);
        goto shutdown;
    }
    /* Request a file via SFTP */
    do {
        sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
            LIBSSH2_FXF_READ, 0);
        if (!sftp_handle) {
            if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
                fprintf(stderr, "Unable to open file with SFTP: %ld\n",
                    libssh2_sftp_last_error(sftp_session));
                goto shutdown;
            }
            else {
                fprintf(stderr, "non-blocking open\n");
                waitsocket(sock, session); /* now we wait */
            }
        }
    } while (!sftp_handle);
    fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
    if (sftp_handle) {
        ssize_t nread;
        libssh2_struct_stat_size total = 0;
        do {
            /* loop until we fail */
            while ((nread = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) ==
                LIBSSH2_ERROR_EAGAIN) {
                waitsocket(sock, session); /* now we wait */
            }
            if (nread > 0) {
                total += nread;
                /* write to temporary storage area */
                fwrite(mem, nread, 1, tempstorage);
            }
            else {
                break;
            }
        } while (1);
    }
    else {
        fprintf(stderr, "SFTP failed to open sftp source path: %s\n",
            dest);
    }
    libssh2_sftp_close(sftp_handle);
    fclose(tempstorage);
    tempstorage = fopen(storage, "rb");
    if (!tempstorage) {
        /* weird, we cannot read the file we just wrote to... */
        fprintf(stderr, "Cannot open %s for reading\n", storage);
        goto shutdown;
    }
    /* we're done downloading, now reverse the process and upload the
       temporarily stored data to the destination path */
    do {
        sftp_handle = libssh2_sftp_open(sftp_session, dest,
            LIBSSH2_FXF_WRITE |
            LIBSSH2_FXF_CREAT |
            LIBSSH2_FXF_TRUNC,
            LIBSSH2_SFTP_S_IRUSR |
            LIBSSH2_SFTP_S_IWUSR |
            LIBSSH2_SFTP_S_IRGRP |
            LIBSSH2_SFTP_S_IROTH);
        if (!sftp_handle) {
            if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
                fprintf(stderr, "Unable to open file with SFTP: %ld\n",
                    libssh2_sftp_last_error(sftp_session));
                goto shutdown;
            }
            else {
                fprintf(stderr, "non-blocking open\n");
                waitsocket(sock, session); /* now we wait */
            }
        }
    } while (!sftp_handle);
    fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
    if (sftp_handle) {
        char* ptr;
        size_t nread;
        ssize_t nwritten;
        libssh2_struct_stat_size total = 0;
        do {
            nread = fread(mem, 1, sizeof(mem), tempstorage);
            if (nread <= 0) {
                /* end of file */
                break;
            }
            ptr = mem;
            total += nread;
            do {
                /* write data in a loop until we block */
                while ((nwritten = libssh2_sftp_write(sftp_handle, ptr, nread)) ==
                    LIBSSH2_ERROR_EAGAIN) {
                    waitsocket(sock, session);
                }
                if (nwritten < 0)
                {
                    break;
                }
                ptr += nwritten;
                nread -= nwritten;
            } while (nread);
        } while (nwritten > 0);
        fprintf(stderr, "SFTP upload done!\n");
    }
    else {
        fprintf(stderr, "SFTP failed to open destination path: %s\n",
            dest);
    }
    libssh2_sftp_shutdown(sftp_session);
shutdown:
    if (session) {
        libssh2_session_disconnect(session, "Normal Shutdown");
        libssh2_session_free(session);
    }
    if (sock != LIBSSH2_INVALID_SOCKET) {
        shutdown(sock, 2);
#ifdef WIN32
        closesocket(sock);
#else
        close(sock);
#endif
    }
    if (tempstorage)
        fclose(tempstorage);
    fprintf(stderr, "all done\n");
    libssh2_exit();
    return 0;
}
int main(int argc, char ** argv)
{
    char* cArgv[] = {(char*)"",/*(char*)"192.168.1.211",*/(char*)"headquarters\\ddd",(char*)"123456", (char*)"D:/output1.png",(char*)"d:/output-1.png",(char*)"D:/output2.png", };
    int nArgc = sizeof(cArgv) / sizeof(*cArgv);
    sftp_rw_main(nArgc, cArgv);
    return(0);
}


×
打赏作者
最新回复 (0)
查看全部
全部楼主
返回