示例#1
0
int
sftpfs_fstat (void *data, struct stat *buf, GError ** mcerror)
{
    int res;
    LIBSSH2_SFTP_ATTRIBUTES attrs;
    vfs_file_handler_t *fh = (vfs_file_handler_t *) data;
    sftpfs_file_handler_data_t *sftpfs_fh = fh->data;
    struct vfs_s_super *super = fh->ino->super;
    sftpfs_super_data_t *super_data = (sftpfs_super_data_t *) super->data;

    mc_return_val_if_error (mcerror, -1);

    if (sftpfs_fh->handle == NULL)
        return -1;

    do
    {
        res = libssh2_sftp_fstat_ex (sftpfs_fh->handle, &attrs, 0);
        if (res >= 0)
            break;

        if (res != LIBSSH2_ERROR_EAGAIN)
        {
            sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
            return -1;
        }

        sftpfs_waitsocket (super_data, mcerror);
        mc_return_val_if_error (mcerror, -1);
    }
    while (res == LIBSSH2_ERROR_EAGAIN);

    if ((attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) != 0)
    {
        buf->st_uid = attrs.uid;
        buf->st_gid = attrs.gid;
    }

    if ((attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) != 0)
    {
        buf->st_atime = attrs.atime;
        buf->st_mtime = attrs.mtime;
        buf->st_ctime = attrs.mtime;
    }

    if ((attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) != 0)
        buf->st_size = attrs.filesize;

    if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) != 0)
        buf->st_mode = attrs.permissions;

    return 0;
}
示例#2
0
/**
 * @function SFTP.stat
 * 
 * ### Synopsis
 * 
 * var stat = SFTP.stat(handle, path);
 * 
 * Get attributes of a remote file.
 * 
 * The returned object will be of the form:
 * 
 * + size: size of file in bytes.
 * + permissions: file permissions.
 * + uid: uid of owner of file.
 * + gid: gid of owner of file.
 * + mtime: modification time (timestamp) of file.
 * + atime: access time (timestamp) of file
 * 
 * @param {object} handle - opaque handle to existing SFTP connection (already connected).
 * @param {string} path - path on remote server to directory to get status of.
 * @returns {object} stat - object of the form described above.
 */
JSVAL sftp_stat (JSARGS args) {
    HandleScope scope;
    SFTP *handle = HANDLE(args[0]);
    String::Utf8Value path(args[1]);
    LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(handle->sftp_session, *path, LIBSSH2_FXF_READ, 0);
    if (!sftp_handle) {
        return scope.Close(String::New("Could not get status for remote file"));
    }
    LIBSSH2_SFTP_ATTRIBUTES attrs;
    if (libssh2_sftp_fstat_ex(sftp_handle, &attrs, 0) < 0) {
        libssh2_sftp_close(sftp_handle);
        return scope.Close(String::New("Could not get status for remote file"));
    }

    Handle<String> _permissions = String::New("permissions");
    Handle<String> _uid = String::New("uid");
    Handle<String> _gid = String::New("gid");
    Handle<String> _size = String::New("size");
    Handle<String> _mtime = String::New("mtime");
    Handle<String> _atime = String::New("atime");

    JSOBJ o = Object::New();
    if (attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
        o->Set(_size, Integer::New(attrs.filesize));
    }
    if (attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
        o->Set(_permissions, Integer::New(attrs.permissions));
    }
    if (attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) {
        o->Set(_uid, Integer::New(attrs.uid));
        o->Set(_gid, Integer::New(attrs.gid));
    }
    if (attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
        o->Set(_mtime, Integer::New(attrs.mtime));
        o->Set(_atime, Integer::New(attrs.atime));
    }

    libssh2_sftp_close(sftp_handle);
    return scope.Close(o);
}
示例#3
0
bool SFTPChannel::updateReadFile()
{
    int rc;

    if (mRequestState == Beginning)
    {
        QByteArray path = mCurrentRequest->getPath().toUtf8();
        mOperationHandle = libssh2_sftp_open_ex(mHandle, path, path.length(), LIBSSH2_FXF_READ, 0, LIBSSH2_SFTP_OPENFILE);
        if (mOperationHandle)
            mRequestState = Sizing;
        else if ((rc = libssh2_session_last_errno(mSession->sessionHandle())) == LIBSSH2_ERROR_EAGAIN)
            return true;	// try again
        else
        {
            criticalError(tr("Failed to open remote file for reading: %1").arg(rc));
            return false;
        }
    }

    if (mRequestState == Sizing)
    {
        LIBSSH2_SFTP_ATTRIBUTES attr;
        int rc = libssh2_sftp_fstat_ex(mOperationHandle, &attr, 0);
        if (rc == LIBSSH2_ERROR_EAGAIN)
            return true;
        else if (rc < 0)
        {
            criticalError(tr("Failed to stat remote file: %1").arg(rc));
            return false;
        }

        mOperationSize = attr.filesize;
        if (mOperationSize == 0)
            mOperationSize = 1;
        mRequestState = Reading;
    }

    if (mRequestState == Reading)
    {
        char buffer[4096];

        rc = libssh2_sftp_read(mOperationHandle, buffer, sizeof(buffer));
        if (rc == LIBSSH2_ERROR_EAGAIN)
            return true;	//	Try again
        else if (rc == 0)
            mRequestState = Finishing;
        else if (rc < 0)
        {
            criticalError(tr("Error while reading file contents: %1").arg(rc));
            return false;
        }
        else	//	Got some data
        {
            mCurrentRequest->addContent(buffer, rc);
            mCurrentRequest->triggerProgress((mCurrentRequest->getContent().length() * 100) / mOperationSize);
        }
    }

    if (mRequestState == Finishing)
    {
        rc = libssh2_sftp_close_handle(mOperationHandle);
        if (rc == LIBSSH2_ERROR_EAGAIN)
            return true;
        else if (rc < 0)
        {
            criticalError(tr("Failed to cleanly close SFTP file: %1").arg(rc));
            return false;
        }

        //	Success! Send a response and finish up.
        QVariantMap finalResult;
        finalResult.insert("content", mCurrentRequest->getContent());
        mCurrentRequest->triggerSuccess(finalResult);
        return false;
    }

    return true;
}
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int sock, i, auth_pw = 1;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session;
    const char *username="******";
    const char *password="******";
    const char *loclfile="sftp_write.c";
    const char *sftppath="/tmp/TEST";
    int rc;
    FILE *local;
    LIBSSH2_SFTP *sftp_session;
    LIBSSH2_SFTP_HANDLE *sftp_handle;
    LIBSSH2_SFTP_ATTRIBUTES attrs;
    char mem[1024*100];
    size_t nread;
    char *ptr;

#ifdef WIN32
    WSADATA wsadata;

    WSAStartup(MAKEWORD(2,0), &wsadata);
#endif

    if (argc > 1) {
        hostaddr = inet_addr(argv[1]);
    } else {
        hostaddr = htonl(0x7F000001);
    }

    if(argc > 2) {
        username = argv[2];
    }
    if(argc > 3) {
        password = argv[3];
    }
    if(argc > 4) {
        loclfile = argv[4];
    }
    if(argc > 5) {
        sftppath = argv[5];
    }

    rc = libssh2_init (0);
    if (rc != 0) {
        fprintf (stderr, "libssh2 initialization failed (%d)\n", rc);
        return 1;
    }

    local = fopen(loclfile, "rb");
    if (!local) {
        printf("Can't local file %s\n", loclfile);
        return -1;
    }

    /*
     * The application code is responsible for creating the socket
     * and establishing the connection
     */
    sock = socket(AF_INET, SOCK_STREAM, 0);

    sin.sin_family = AF_INET;
    sin.sin_port = htons(22);
    sin.sin_addr.s_addr = hostaddr;
    if (connect(sock, (struct sockaddr*)(&sin),
            sizeof(struct sockaddr_in)) != 0) {
        fprintf(stderr, "failed to connect!\n");
        return -1;
    }

    /* Create a session instance
     */
    session = libssh2_session_init();
    if(!session)
        return -1;

    /* Since we have set non-blocking, tell libssh2 we are blocking */
    libssh2_session_set_blocking(session, 1);

    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */
    rc = libssh2_session_startup(session, sock);
    if(rc) {
        fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
        return -1;
    }

    /* At this point we havn't 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);
    printf("Fingerprint: ");
    for(i = 0; i < 20; i++) {
        printf("%02X ", (unsigned char)fingerprint[i]);
    }
    printf("\n");

    if (auth_pw) {
        /* We could authenticate via password */
        if (libssh2_userauth_password(session, username, password)) {
            printf("Authentication by password failed.\n");
            goto shutdown;
        }
    } else {
        /* Or by public key */
        if (libssh2_userauth_publickey_fromfile(session, username,
                            "/home/username/.ssh/id_rsa.pub",
                            "/home/username/.ssh/id_rsa",
                            password)) {
            printf("\tAuthentication by public key failed\n");
            goto shutdown;
        }
    }

    fprintf(stderr, "libssh2_sftp_init()!\n");
    sftp_session = libssh2_sftp_init(session);

    if (!sftp_session) {
        fprintf(stderr, "Unable to init SFTP session\n");
        goto shutdown;
    }

    fprintf(stderr, "libssh2_sftp_open() for READ and WRITE!\n");
    /* Request a file via SFTP */

    sftp_handle =
        libssh2_sftp_open(sftp_session, sftppath,
                          LIBSSH2_FXF_WRITE|LIBSSH2_FXF_READ,
                          LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
                          LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
    if (!sftp_handle) {
        fprintf(stderr, "Unable to open file with SFTP\n");
        goto shutdown;
    }

    if(libssh2_sftp_fstat_ex(sftp_handle, &attrs, 0) < 0) {
        printf("libssh2_sftp_fstat_ex failed\n");
        goto shutdown;
    }
    else
        libssh2_sftp_seek64(sftp_handle, attrs.filesize);
    printf("Did a seek to position %ld\n", (long) attrs.filesize);

    fprintf(stderr, "libssh2_sftp_open() a handle for APPEND\n");

    if (!sftp_handle) {
        fprintf(stderr, "Unable to open file with SFTP\n");
        goto shutdown;
    }
    fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
    do {
        nread = fread(mem, 1, sizeof(mem), local);
        if (nread <= 0) {
            /* end of file */
            break;
        }
        ptr = mem;

        do {
            /* write data in a loop until we block */
            rc = libssh2_sftp_write(sftp_handle, ptr, nread);
            if(rc < 0)
                break;
            ptr += rc;
            nread -= rc;
        } while (nread);

    } while (rc > 0);

    libssh2_sftp_close(sftp_handle);
    libssh2_sftp_shutdown(sftp_session);

shutdown:
    libssh2_session_disconnect(session,
                               "Normal Shutdown, Thank you for playing");
    libssh2_session_free(session);

#ifdef WIN32
    closesocket(sock);
#else
    close(sock);
#endif
    if (local)
        fclose(local);
    printf("all done\n");

    libssh2_exit();

    return 0;
}