diff --git a/docs/Makefile.am b/docs/Makefile.am index 235e77c5..8e998638 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -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 \ diff --git a/docs/libssh2_sftp_open_ex_r.3 b/docs/libssh2_sftp_open_ex_r.3 new file mode 100644 index 00000000..a7326718 --- /dev/null +++ b/docs/libssh2_sftp_open_ex_r.3 @@ -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 +#include + +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 + +\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) diff --git a/docs/libssh2_sftp_open_r.3 b/docs/libssh2_sftp_open_r.3 new file mode 100644 index 00000000..bccc0df3 --- /dev/null +++ b/docs/libssh2_sftp_open_r.3 @@ -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 +#include + +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) diff --git a/include/libssh2_sftp.h b/include/libssh2_sftp.h index e406127f..74f619fc 100644 --- a/include/libssh2_sftp.h +++ b/include/libssh2_sftp.h @@ -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); diff --git a/src/sftp.c b/src/sftp.c index 8eea6c88..a3862a73 100644 --- a/src/sftp.c +++ b/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; }