mirror of
https://github.com/libssh2/libssh2.git
synced 2025-07-31 00:03:08 +03:00
sftp: add open functions with custom attribute support
Before this patch, libssh2 sent hardcoded `LIBSSH2_SFTP_ATTRIBUTES` struct on handle open. This can be problematic on some special OS, where the file size should be known on new file creation. I added two new functions to resolve this issue. Patch-by: @vajdaakos on github via #506 Changes compared to #506: - drop attr size fixup in favour of #946. - move `memcpy()` under the state where we need it. - bump filename length type to `size_t`. - fix filenames in documentation and other nits. Closes #506 Closes #947
This commit is contained in:
@ -138,6 +138,8 @@ dist_man_MANS = \
|
||||
libssh2_sftp_mkdir_ex.3 \
|
||||
libssh2_sftp_open.3 \
|
||||
libssh2_sftp_open_ex.3 \
|
||||
libssh2_sftp_open_ex_r.3 \
|
||||
libssh2_sftp_open_r.3 \
|
||||
libssh2_sftp_opendir.3 \
|
||||
libssh2_sftp_read.3 \
|
||||
libssh2_sftp_readdir.3 \
|
||||
|
73
docs/libssh2_sftp_open_ex_r.3
Normal file
73
docs/libssh2_sftp_open_ex_r.3
Normal file
@ -0,0 +1,73 @@
|
||||
.TH libssh2_sftp_open_ex_r 3 "10 Apr 2023" "libssh2 1.11.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_open_ex_r - open filehandle for file on SFTP.
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
LIBSSH2_SFTP_HANDLE *
|
||||
libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
size_t filename_len,
|
||||
unsigned long flags,
|
||||
long mode,
|
||||
int open_type,
|
||||
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
\fIsftp\fP - SFTP instance as returned by \fIlibssh2_sftp_init(3)\fP
|
||||
|
||||
\fIfilename\fP - Remote file/directory resource to open
|
||||
|
||||
\fIfilename_len\fP - Length of filename
|
||||
|
||||
\fIflags\fP - Any reasonable combination of the LIBSSH2_FXF_* constants:
|
||||
.RS
|
||||
.IP LIBSSH2_FXF_READ
|
||||
Open the file for reading.
|
||||
.IP LIBSSH2_FXF_WRITE
|
||||
Open the file for writing. If both this and LIBSSH2_FXF_READ are specified,
|
||||
the file is opened for both reading and writing.
|
||||
.IP LIBSSH2_FXF_APPEND
|
||||
Force all writes to append data at the end of the file.
|
||||
.IP LIBSSH2_FXF_CREAT,
|
||||
If this flag is specified, then a new file will be created if one does not
|
||||
already exist (if LIBSSH2_FXF_TRUNC is specified, the new file will be
|
||||
truncated to zero length if it previously exists)
|
||||
.IP LIBSSH2_FXF_TRUNC
|
||||
Forces an existing file with the same name to be truncated to zero length when
|
||||
creating a file by specifying LIBSSH2_FXF_CREAT. LIBSSH2_FXF_CREAT MUST also
|
||||
be specified if this flag is used.
|
||||
.IP LIBSSH2_FXF_EXCL
|
||||
Causes the request to fail if the named file already exists.
|
||||
LIBSSH2_FXF_CREAT MUST also be specified if this flag is used.
|
||||
|
||||
.RE
|
||||
\fImode\fP - POSIX file permissions to assign if the file is being newly
|
||||
created. See the LIBSSH2_SFTP_S_* convenience defines in <libssh2_sftp.h>
|
||||
|
||||
\fIopen_type\fP - Either of LIBSSH2_SFTP_OPENFILE (to open a file) or
|
||||
LIBSSH2_SFTP_OPENDIR (to open a directory).
|
||||
|
||||
\fIattrs\fP - Pointer to LIBSSH2_SFTP_ATTRIBUTES struct. See
|
||||
libssh2_sftp_fstat_ex for detailed usage.
|
||||
|
||||
.SH RETURN VALUE
|
||||
A pointer to the newly created LIBSSH2_SFTP_HANDLE instance or NULL on
|
||||
failure.
|
||||
.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_SOCKET_TIMEOUT\fP -
|
||||
|
||||
\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.
|
||||
|
||||
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would
|
||||
block.
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_sftp_close_handle(3)
|
||||
.BR libssh2_sftp_fstat_ex(3)
|
23
docs/libssh2_sftp_open_r.3
Normal file
23
docs/libssh2_sftp_open_r.3
Normal file
@ -0,0 +1,23 @@
|
||||
.TH libssh2_sftp_open_r 3 "10 Apr 2023" "libssh2 1.11.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_open_r - convenience macro for \fIlibssh2_sftp_open_ex_r(3)\fP calls
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
LIBSSH2_SFTP_HANDLE *
|
||||
libssh2_sftp_open_r(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
unsigned long flags,
|
||||
long mode,
|
||||
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
underlying function \fIlibssh2_sftp_open_ex_r(3)\fP.
|
||||
.SH RETURN VALUE
|
||||
See \fIlibssh2_sftp_open_ex_r(3)\fP
|
||||
.SH ERRORS
|
||||
See \fIlibssh2_sftp_open_ex_r(3)\fP
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_sftp_open_ex_r(3)
|
@ -238,6 +238,17 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
|
||||
libssh2_sftp_open_ex((sftp), \
|
||||
(path), (unsigned int)strlen(path), \
|
||||
0, 0, LIBSSH2_SFTP_OPENDIR)
|
||||
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
|
||||
libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp,
|
||||
const char *filename,
|
||||
size_t filename_len,
|
||||
unsigned long flags,
|
||||
long mode, int open_type,
|
||||
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||
#define libssh2_sftp_open_r(sftp, filename, flags, mode, attrs) \
|
||||
libssh2_sftp_open_ex_r((sftp), (filename), strlen(filename), \
|
||||
(flags), (mode), LIBSSH2_SFTP_OPENFILE, \
|
||||
(attrs))
|
||||
|
||||
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
|
||||
char *buffer, size_t buffer_maxlen);
|
||||
|
26
src/sftp.c
26
src/sftp.c
@ -1107,7 +1107,7 @@ libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp)
|
||||
static LIBSSH2_SFTP_HANDLE *
|
||||
sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
size_t filename_len, uint32_t flags, long mode,
|
||||
int open_type)
|
||||
int open_type, LIBSSH2_SFTP_ATTRIBUTES *attrs_in)
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
@ -1122,6 +1122,10 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
if(sftp->open_state == libssh2_NB_state_idle) {
|
||||
sftp->last_errno = LIBSSH2_FX_OK;
|
||||
|
||||
if(attrs_in) {
|
||||
memcpy(&attrs, attrs_in, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
|
||||
}
|
||||
|
||||
/* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) +
|
||||
flags(4) */
|
||||
sftp->open_packet_len = (uint32_t)(filename_len + 13 +
|
||||
@ -1331,7 +1335,25 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
|
||||
BLOCK_ADJUST_ERRNO(hnd, sftp->channel->session,
|
||||
sftp_open(sftp, filename, filename_len, (uint32_t)flags,
|
||||
mode, open_type));
|
||||
mode, open_type, NULL));
|
||||
return hnd;
|
||||
}
|
||||
|
||||
/* libssh2_sftp_open_ex_r
|
||||
*/
|
||||
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
|
||||
libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
size_t filename_len, unsigned long flags, long mode,
|
||||
int open_type, LIBSSH2_SFTP_ATTRIBUTES *attrs)
|
||||
{
|
||||
LIBSSH2_SFTP_HANDLE *hnd;
|
||||
|
||||
if(!sftp)
|
||||
return NULL;
|
||||
|
||||
BLOCK_ADJUST_ERRNO(hnd, sftp->channel->session,
|
||||
sftp_open(sftp, filename, filename_len, (uint32_t)flags,
|
||||
mode, open_type, attrs));
|
||||
return hnd;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user