static void ssh_seek(BDRVSSHState *s, int64_t offset, int flags) { bool op_read = (flags & SSH_SEEK_READ) != 0; bool force = (flags & SSH_SEEK_FORCE) != 0; if (force || op_read != s->offset_op_read || offset != s->offset) { DPRINTF("seeking to offset=%" PRIi64, offset); libssh2_sftp_seek64(s->sftp_handle, offset); s->offset = offset; s->offset_op_read = op_read; } }
static int ssh_create(const char *filename, QemuOpts *opts, Error **errp) { int r, ret; int64_t total_size = 0; QDict *uri_options = NULL; BDRVSSHState s; ssize_t r2; char c[1] = { '\0' }; ssh_state_init(&s); /* Get desired file size. */ total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), BDRV_SECTOR_SIZE); DPRINTF("total_size=%" PRIi64, total_size); uri_options = qdict_new(); r = parse_uri(filename, uri_options, errp); if (r < 0) { ret = r; goto out; } r = connect_to_ssh(&s, uri_options, LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE| LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, 0644, errp); if (r < 0) { ret = r; goto out; } if (total_size > 0) { libssh2_sftp_seek64(s.sftp_handle, total_size-1); r2 = libssh2_sftp_write(s.sftp_handle, c, 1); if (r2 < 0) { sftp_error_setg(errp, &s, "truncate failed"); ret = -EINVAL; goto out; } s.attrs.filesize = total_size; } ret = 0; out: ssh_state_free(&s); if (uri_options != NULL) { QDECREF(uri_options); } return ret; }
off_t sftpfs_lseek (vfs_file_handler_t * file_handler, off_t offset, int whence, GError ** error) { sftpfs_file_handler_data_t *file_handler_data; switch (whence) { case SEEK_SET: /* Need reopen file because: "You MUST NOT seek during writing or reading a file with SFTP, as the internals use outstanding packets and changing the "file position" during transit will results in badness." */ if (file_handler->pos > offset || offset == 0) { sftpfs_reopen (file_handler, error); if (error != NULL && *error != NULL) return 0; } file_handler->pos = offset; break; case SEEK_CUR: file_handler->pos += offset; break; case SEEK_END: if (file_handler->pos > file_handler->ino->st.st_size - offset) { sftpfs_reopen (file_handler, error); if (error != NULL && *error != NULL) return 0; } file_handler->pos = file_handler->ino->st.st_size - offset; break; } file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data; libssh2_sftp_seek64 (file_handler_data->handle, file_handler->pos); file_handler->pos = (off_t) libssh2_sftp_tell64 (file_handler_data->handle); return file_handler->pos; }
gboolean sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode, GError ** error) { unsigned long sftp_open_flags = 0; int sftp_open_mode = 0; gboolean do_append = FALSE; sftpfs_file_handler_data_t *file_handler_data; sftpfs_super_data_t *super_data; char *name; (void) mode; name = vfs_s_fullpath (&sftpfs_class, file_handler->ino); if (name == NULL) return FALSE; super_data = (sftpfs_super_data_t *) file_handler->ino->super->data; file_handler_data = g_new0 (sftpfs_file_handler_data_t, 1); if ((flags & O_CREAT) != 0 || (flags & O_WRONLY) != 0) { sftp_open_flags = (flags & O_WRONLY) != 0 ? LIBSSH2_FXF_WRITE : 0; sftp_open_flags |= (flags & O_CREAT) != 0 ? LIBSSH2_FXF_CREAT : 0; if ((flags & O_APPEND) != 0) { sftp_open_flags |= LIBSSH2_FXF_APPEND; do_append = TRUE; } sftp_open_flags |= (flags & O_TRUNC) != 0 ? LIBSSH2_FXF_TRUNC : 0; sftp_open_mode = LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH; } else sftp_open_flags = LIBSSH2_FXF_READ; while (TRUE) { int libssh_errno; file_handler_data->handle = libssh2_sftp_open (super_data->sftp_session, sftpfs_fix_filename (name), sftp_open_flags, sftp_open_mode); if (file_handler_data->handle != NULL) break; libssh_errno = libssh2_session_last_errno (super_data->session); if (libssh_errno != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, libssh_errno, error); g_free (name); g_free (file_handler_data); return FALSE; } } g_free (name); file_handler_data->flags = flags; file_handler_data->mode = mode; file_handler->data = file_handler_data; if (do_append) { struct stat file_info; if (sftpfs_fstat (file_handler, &file_info, error) == 0) libssh2_sftp_seek64 (file_handler_data->handle, file_info.st_size); } 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; }