aboutsummaryrefslogtreecommitdiff
path: root/libssh/sftp.c
diff options
context:
space:
mode:
authorAndreas Schneider <mail@cynapses.org>2009-07-25 11:54:21 +0200
committerAndreas Schneider <mail@cynapses.org>2009-07-25 11:55:42 +0200
commit8ce6bd3459ed379337a709fa5d32b05021c7280f (patch)
treec14c8e621eceda4b7b3e26da820312c8a70e7ea9 /libssh/sftp.c
parent5b8338d115f1839be12b0670a221d7c02a4c0e73 (diff)
downloadlibssh-8ce6bd3459ed379337a709fa5d32b05021c7280f.tar.gz
libssh-8ce6bd3459ed379337a709fa5d32b05021c7280f.tar.xz
libssh-8ce6bd3459ed379337a709fa5d32b05021c7280f.zip
Add sftp_readlink function.
Diffstat (limited to 'libssh/sftp.c')
-rw-r--r--libssh/sftp.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/libssh/sftp.c b/libssh/sftp.c
index a115fecd..c9653baf 100644
--- a/libssh/sftp.c
+++ b/libssh/sftp.c
@@ -2295,6 +2295,80 @@ int sftp_symlink(SFTP_SESSION *sftp, const char *target, const char *dest) {
return -1;
}
+char *sftp_readlink(SFTP_SESSION *sftp, const char *path) {
+ STATUS_MESSAGE *status = NULL;
+ SFTP_MESSAGE *msg = NULL;
+ ssh_string path_s = NULL;
+ ssh_string link_s = NULL;
+ ssh_buffer buffer;
+ char *link;
+ u32 ignored;
+ u32 id;
+
+ if (sftp == NULL || path == NULL) {
+ return NULL;
+ }
+
+ buffer = buffer_new();
+ if (buffer == NULL) {
+ return NULL;
+ }
+
+ path_s = string_from_char(path);
+ if (path_s == NULL) {
+ buffer_free(buffer);
+ return NULL;
+ }
+
+ id = sftp_get_new_id(sftp);
+ if (buffer_add_u32(buffer, id) < 0 ||
+ buffer_add_ssh_string(buffer, path_s) < 0 ||
+ sftp_packet_write(sftp, SSH_FXP_READLINK, buffer) < 0) {
+ buffer_free(buffer);
+ string_free(path_s);
+ return NULL;
+ }
+ buffer_free(buffer);
+ string_free(path_s);
+
+ while (msg == NULL) {
+ if (sftp_read_and_dispatch(sftp) < 0) {
+ return NULL;
+ }
+ msg = sftp_dequeue(sftp, id);
+ }
+
+ if (msg->packet_type == SSH_FXP_NAME) {
+ /* we don't care about "count" */
+ buffer_get_u32(msg->payload, &ignored);
+ /* we only care about the file name string */
+ link_s = buffer_get_ssh_string(msg->payload);
+ sftp_message_free(msg);
+ if (link_s == NULL) {
+ return NULL;
+ }
+ link = string_to_char(link_s);
+ string_free(link_s);
+
+ return link;
+ } else if (msg->packet_type == SSH_FXP_STATUS) { /* bad response (error) */
+ status = parse_status_msg(msg);
+ sftp_message_free(msg);
+ if (status == NULL) {
+ return NULL;
+ }
+ ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
+ "SFTP server: %s", status->errormsg);
+ status_msg_free(status);
+ } else { /* this shouldn't happen */
+ ssh_set_error(sftp->session, SSH_FATAL,
+ "Received message %d when attempting to set stats", msg->packet_type);
+ sftp_message_free(msg);
+ }
+
+ return NULL;
+}
+
/* another code written by Nick */
char *sftp_canonicalize_path(SFTP_SESSION *sftp, const char *path) {
STATUS_MESSAGE *status = NULL;