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; }
/** * @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); }
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; }