1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-08 03:42:12 +03:00

sftp: Added lsetstat extension

Signed-off-by: Abdelrahman Youssef <abdelrahmanyossef12@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Abdelrahman Youssef
2024-03-13 16:02:18 +02:00
committed by Jakub Jelen
parent 164ca9ae93
commit 19e62a78a6
2 changed files with 116 additions and 0 deletions

View File

@@ -948,6 +948,29 @@ LIBSSH_API int sftp_rename(sftp_session sftp, const char *original, const char
*/ */
LIBSSH_API int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr); LIBSSH_API int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr);
/**
* @brief This request is like setstat (excluding mode and size) but sets file
* attributes on symlinks themselves.
*
* Note, that this function can only set time values using 32 bit values due to
* the restrictions in the SFTP protocol version 3 implemented by libssh.
* The support for 64 bit time values was introduced in SFTP version 5, which is
* not implemented by libssh nor any major SFTP servers.
*
* @param sftp The sftp session handle.
*
* @param file The symbolic link which attributes should be changed.
*
* @param attr The file attributes structure with the attributes set
* which should be changed.
*
* @return 0 on success, < 0 on error with ssh and sftp error set.
*
* @see sftp_get_error()
*/
LIBSSH_API int
sftp_lsetstat(sftp_session sftp, const char *file, sftp_attributes attr);
/** /**
* @brief Change the file owner and group * @brief Change the file owner and group
* *

View File

@@ -1893,6 +1893,10 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
sftp_status_message status = NULL; sftp_status_message status = NULL;
int rc; int rc;
if (sftp == NULL || file == NULL || attr == NULL) {
return -1;
}
buffer = ssh_buffer_new(); buffer = ssh_buffer_new();
if (buffer == NULL) { if (buffer == NULL) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
@@ -1967,6 +1971,95 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
return -1; return -1;
} }
int
sftp_lsetstat(sftp_session sftp, const char *file, sftp_attributes attr)
{
uint32_t id;
ssh_buffer buffer = NULL;
sftp_message msg = NULL;
sftp_status_message status = NULL;
const char *extension_name = "lsetstat@openssh.com";
int rc;
if (sftp == NULL || file == NULL || attr == NULL) {
return -1;
}
buffer = ssh_buffer_new();
if (buffer == NULL) {
ssh_set_error_oom(sftp->session);
sftp_set_error(sftp, SSH_FX_FAILURE);
return -1;
}
id = sftp_get_new_id(sftp);
rc = ssh_buffer_pack(buffer, "dss", id, extension_name, file);
if (rc != SSH_OK) {
ssh_set_error_oom(sftp->session);
SSH_BUFFER_FREE(buffer);
sftp_set_error(sftp, SSH_FX_FAILURE);
return -1;
}
rc = buffer_add_attributes(buffer, attr);
if (rc != 0) {
ssh_set_error_oom(sftp->session);
SSH_BUFFER_FREE(buffer);
sftp_set_error(sftp, SSH_FX_FAILURE);
return -1;
}
rc = sftp_packet_write(sftp, SSH_FXP_EXTENDED, buffer);
SSH_BUFFER_FREE(buffer);
if (rc < 0) {
return -1;
}
while (msg == NULL) {
if (sftp_read_and_dispatch(sftp) < 0) {
return -1;
}
msg = sftp_dequeue(sftp, id);
}
/* By specification, this command only returns SSH_FXP_STATUS */
if (msg->packet_type == SSH_FXP_STATUS) {
status = parse_status_msg(msg);
sftp_message_free(msg);
if (status == NULL) {
return -1;
}
sftp_set_error(sftp, status->status);
switch (status->status) {
case SSH_FX_OK:
status_msg_free(status);
return 0;
default:
break;
}
/*
* The status should be SSH_FX_OK if the command was successful, if it
* didn't, then there was an error
*/
ssh_set_error(sftp->session,
SSH_REQUEST_DENIED,
"SFTP server: %s",
status->errormsg);
status_msg_free(status);
return -1;
} else {
ssh_set_error(sftp->session,
SSH_FATAL,
"Received message %d when attempting to lsetstat",
msg->packet_type);
sftp_message_free(msg);
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
}
return -1;
}
/* Change the file owner and group */ /* Change the file owner and group */
int sftp_chown(sftp_session sftp, const char *file, uid_t owner, gid_t group) { int sftp_chown(sftp_session sftp, const char *file, uid_t owner, gid_t group) {
struct sftp_attributes_struct attr; struct sftp_attributes_struct attr;