diff options
author | Andreas Schneider <mail@cynapses.org> | 2009-07-25 11:54:21 +0200 |
---|---|---|
committer | Andreas Schneider <mail@cynapses.org> | 2009-07-25 12:34:25 +0200 |
commit | a1c7dd99bedf7a55484e7ed226af386f6f005a0b (patch) | |
tree | 198ae74e9411f80a5ba74403ce1db0c413998adb /libssh/sftp.c | |
parent | 11a6ed907d7d54a388ee1eb148803a326cee54f6 (diff) | |
download | libssh-a1c7dd99bedf7a55484e7ed226af386f6f005a0b.tar.gz libssh-a1c7dd99bedf7a55484e7ed226af386f6f005a0b.tar.xz libssh-a1c7dd99bedf7a55484e7ed226af386f6f005a0b.zip |
Add sftp_readlink function.
Diffstat (limited to 'libssh/sftp.c')
-rw-r--r-- | libssh/sftp.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/libssh/sftp.c b/libssh/sftp.c index f0007d8c..e86a262b 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; + STRING *path_s = NULL; + STRING *link_s = NULL; + 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; |