summaryrefslogtreecommitdiffstats
path: root/0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch
diff options
context:
space:
mode:
authorRemi Collet <fedora@famillecollet.com>2014-12-20 07:14:27 +0100
committerRemi Collet <fedora@famillecollet.com>2014-12-20 07:14:27 +0100
commitb19d09aa2aea5acd142de597e1fa77cb4462254f (patch)
treec8cd020fc7c529c73a564d38c6283a05dc7ef338 /0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch
parent6d60df25b515671f7e99c1b39dd8422ddc366d5e (diff)
libssh2: 1.4.3 for EL-5 (sync with EL-7)
Diffstat (limited to '0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch')
-rw-r--r--0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch223
1 files changed, 223 insertions, 0 deletions
diff --git a/0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch b/0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch
new file mode 100644
index 0000000..cc1cbb4
--- /dev/null
+++ b/0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch
@@ -0,0 +1,223 @@
+From 6e0d757f24a45252c4cae9ea09732eda2562c767 Mon Sep 17 00:00:00 2001
+From: "Richard W.M. Jones" <rjones@redhat.com>
+Date: Tue, 9 Apr 2013 11:42:09 +0200
+Subject: [PATCH 3/3] sftp: Add support for fsync (OpenSSH extension).
+
+The new libssh2_sftp_fsync API causes data and metadata in the
+currently open file to be committed to disk at the server.
+
+This is an OpenSSH extension to the SFTP protocol. See:
+
+https://bugzilla.mindrot.org/show_bug.cgi?id=1798
+---
+ docs/Makefile.am | 1 +
+ docs/libssh2_sftp_fsync.3 | 39 +++++++++++++++++++
+ include/libssh2_sftp.h | 1 +
+ src/sftp.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++
+ src/sftp.h | 5 +++
+ 5 files changed, 143 insertions(+)
+ create mode 100644 docs/libssh2_sftp_fsync.3
+
+diff --git a/docs/Makefile.am b/docs/Makefile.am
+index e4cf487..e6ab394 100644
+--- a/docs/Makefile.am
++++ b/docs/Makefile.am
+@@ -120,6 +120,7 @@ dist_man_MANS = \
+ libssh2_sftp_fstat.3 \
+ libssh2_sftp_fstat_ex.3 \
+ libssh2_sftp_fstatvfs.3 \
++ libssh2_sftp_fsync.3 \
+ libssh2_sftp_get_channel.3 \
+ libssh2_sftp_init.3 \
+ libssh2_sftp_last_error.3 \
+diff --git a/docs/libssh2_sftp_fsync.3 b/docs/libssh2_sftp_fsync.3
+new file mode 100644
+index 0000000..646760a
+--- /dev/null
++++ b/docs/libssh2_sftp_fsync.3
+@@ -0,0 +1,39 @@
++.TH libssh2_sftp_fsync 3 "8 Apr 2013" "libssh2 1.4.4" "libssh2 manual"
++.SH NAME
++libssh2_sftp_fsync - synchronize file to disk
++.SH SYNOPSIS
++.nf
++#include <libssh2.h>
++#include <libssh2_sftp.h>
++
++int
++libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
++.fi
++.SH DESCRIPTION
++This function causes the remote server to synchronize the file
++data and metadata to disk (like fsync(2)).
++
++For this to work requires fsync@openssh.com support on the server.
++
++\fIhandle\fP - SFTP File Handle as returned by
++.BR libssh2_sftp_open_ex(3)
++
++.SH RETURN VALUE
++Returns 0 on success or negative on failure. If used in non-blocking mode, it
++returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
++LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
++.SH ERRORS
++\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
++
++\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
++
++\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response
++was received on the socket, or an SFTP operation caused an errorcode
++to be returned by the server. In particular, this can be returned if
++the SSH server does not support the fsync operation: the SFTP subcode
++\fILIBSSH2_FX_OP_UNSUPPORTED\fP will be returned in this case.
++
++.SH AVAILABILITY
++Added in libssh2 1.4.4 and OpenSSH 6.3.
++.SH SEE ALSO
++.BR fsync(2)
+diff --git a/include/libssh2_sftp.h b/include/libssh2_sftp.h
+index 74884fb..677faf2 100644
+--- a/include/libssh2_sftp.h
++++ b/include/libssh2_sftp.h
+@@ -247,6 +247,7 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
+
+ LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
+ const char *buffer, size_t count);
++LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle);
+
+ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
+ #define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
+diff --git a/src/sftp.c b/src/sftp.c
+index 65fa77a..01017fd 100644
+--- a/src/sftp.c
++++ b/src/sftp.c
+@@ -986,6 +986,10 @@ sftp_shutdown(LIBSSH2_SFTP *sftp)
+ LIBSSH2_FREE(session, sftp->symlink_packet);
+ sftp->symlink_packet = NULL;
+ }
++ if (sftp->fsync_packet) {
++ LIBSSH2_FREE(session, sftp->fsync_packet);
++ sftp->fsync_packet = NULL;
++ }
+
+ sftp_packet_flush(sftp);
+
+@@ -2014,6 +2018,99 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer,
+
+ }
+
++static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
++{
++ LIBSSH2_SFTP *sftp = handle->sftp;
++ LIBSSH2_CHANNEL *channel = sftp->channel;
++ LIBSSH2_SESSION *session = channel->session;
++ /* 34 = packet_len(4) + packet_type(1) + request_id(4) +
++ string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */
++ uint32_t packet_len = handle->handle_len + 34;
++ size_t data_len;
++ unsigned char *packet, *s, *data;
++ ssize_t rc;
++ uint32_t retcode;
++
++ if (sftp->fsync_state == libssh2_NB_state_idle) {
++ _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
++ "Issuing fsync command");
++ s = packet = LIBSSH2_ALLOC(session, packet_len);
++ if (!packet) {
++ return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
++ "Unable to allocate memory for FXP_EXTENDED "
++ "packet");
++ }
++
++ _libssh2_store_u32(&s, packet_len - 4);
++ *(s++) = SSH_FXP_EXTENDED;
++ sftp->fsync_request_id = sftp->request_id++;
++ _libssh2_store_u32(&s, sftp->fsync_request_id);
++ _libssh2_store_str(&s, "fsync@openssh.com", 17);
++ _libssh2_store_str(&s, handle->handle, handle->handle_len);
++
++ sftp->fsync_state = libssh2_NB_state_created;
++ } else {
++ packet = sftp->fsync_packet;
++ }
++
++ if (sftp->fsync_state == libssh2_NB_state_created) {
++ rc = _libssh2_channel_write(channel, 0, packet, packet_len);
++ if (rc == LIBSSH2_ERROR_EAGAIN ||
++ (0 <= rc && rc < (ssize_t)packet_len)) {
++ sftp->fsync_packet = packet;
++ return LIBSSH2_ERROR_EAGAIN;
++ }
++
++ LIBSSH2_FREE(session, packet);
++ sftp->fsync_packet = NULL;
++
++ if (rc < 0) {
++ sftp->fsync_state = libssh2_NB_state_idle;
++ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
++ "_libssh2_channel_write() failed");
++ }
++ sftp->fsync_state = libssh2_NB_state_sent;
++ }
++
++ rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
++ sftp->fsync_request_id, &data, &data_len);
++ if (rc == LIBSSH2_ERROR_EAGAIN) {
++ return rc;
++ } else if (rc) {
++ sftp->fsync_state = libssh2_NB_state_idle;
++ return _libssh2_error(session, rc,
++ "Error waiting for FXP EXTENDED REPLY");
++ }
++
++ sftp->fsync_state = libssh2_NB_state_idle;
++
++ retcode = _libssh2_ntohu32(data + 5);
++ LIBSSH2_FREE(session, data);
++
++ if (retcode != LIBSSH2_FX_OK) {
++ sftp->last_errno = retcode;
++ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
++ "fsync failed");
++ }
++
++ return 0;
++}
++
++/* libssh2_sftp_fsync
++ * Commit data on the handle to disk.
++ */
++LIBSSH2_API int
++libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd)
++{
++ int rc;
++ if(!hnd)
++ return LIBSSH2_ERROR_BAD_USE;
++ BLOCK_ADJUST(rc, hnd->sftp->channel->session,
++ sftp_fsync(hnd));
++ return rc;
++}
++
++
+ /*
+ * sftp_fstat
+ *
+diff --git a/src/sftp.h b/src/sftp.h
+index 55bdb46..63e8139 100644
+--- a/src/sftp.h
++++ b/src/sftp.h
+@@ -175,6 +175,11 @@ struct _LIBSSH2_SFTP
+ /* State variable used in sftp_write() */
+ libssh2_nonblocking_states write_state;
+
++ /* State variables used in sftp_fsync() */
++ libssh2_nonblocking_states fsync_state;
++ unsigned char *fsync_packet;
++ uint32_t fsync_request_id;
++
+ /* State variables used in libssh2_sftp_readdir() */
+ libssh2_nonblocking_states readdir_state;
+ unsigned char *readdir_packet;
+--
+1.8.1.4
+