diff options
-rw-r--r-- | include/libssh/sftp.h | 7 | ||||
-rw-r--r-- | libssh/sftp.c | 53 |
2 files changed, 56 insertions, 4 deletions
diff --git a/include/libssh/sftp.h b/include/libssh/sftp.h index 5d53f861..a42c76e1 100644 --- a/include/libssh/sftp.h +++ b/include/libssh/sftp.h @@ -149,17 +149,16 @@ struct sftp_status_message_struct { char *langmsg; }; -/* don't worry much of these aren't really used */ struct sftp_attributes_struct { char *name; - char *longname; /* some weird stuff */ + char *longname; /* ls -l output on openssh, not reliable else */ uint32_t flags; uint8_t type; uint64_t size; uint32_t uid; uint32_t gid; - char *owner; - char *group; + char *owner; /* set if openssh and version 4 */ + char *group; /* set if openssh and version 4 */ uint32_t permissions; uint64_t atime64; uint32_t atime; diff --git a/libssh/sftp.c b/libssh/sftp.c index 31b5ceee..4f2f4eb3 100644 --- a/libssh/sftp.c +++ b/libssh/sftp.c @@ -25,6 +25,7 @@ /* This file contains code written by Nick Zitzmann */ #include <errno.h> +#include <ctype.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> @@ -1111,6 +1112,44 @@ static sftp_attributes sftp_parse_attr_4(sftp_session sftp, ssh_buffer buf, return attr; } +enum sftp_longname_field_e { + SFTP_LONGNAME_PERM = 0, + SFTP_LONGNAME_FIXME, + SFTP_LONGNAME_OWNER, + SFTP_LONGNAME_GROUP, + SFTP_LONGNAME_SIZE, + SFTP_LONGNAME_DATE, + SFTP_LONGNAME_TIME, + SFTP_LONGNAME_NAME, +}; + +static char *sftp_parse_longname(const char *longname, + enum sftp_longname_field_e longname_field) { + const char *p, *q; + size_t field = 0; + + p = longname; + /* Find the beginning of the field which is specified by sftp_longanme_field_e. */ + while(field != longname_field) { + if(isspace(*p)) { + field++; + p++; + while(*p && isspace(*p)) { + p++; + } + } else { + p++; + } + } + + q = p; + while (! isspace(*q)) { + q++; + } + + return strndup(p, q - p); +} + /* sftp version 0-3 code. It is different from the v4 */ /* maybe a paste of the draft is better than the code */ /* @@ -1186,6 +1225,18 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf, } attr->uid = ntohl(attr->uid); attr->gid = ntohl(attr->gid); + + if (ssh_get_openssh_version(sftp->session)) { + attr->owner = sftp_parse_longname(attr->longname, SFTP_LONGNAME_OWNER); + if (attr->owner == NULL) { + break; + } + + attr->group = sftp_parse_longname(attr->longname, SFTP_LONGNAME_GROUP); + if (attr->group == NULL) { + break; + } + } } if (flags & SSH_FILEXFER_ATTR_PERMISSIONS) { @@ -1254,6 +1305,8 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf, string_free(attr->extended_data); SAFE_FREE(attr->name); SAFE_FREE(attr->longname); + SAFE_FREE(attr->owner); + SAFE_FREE(attr->group); SAFE_FREE(attr); ssh_set_error(sftp->session, SSH_FATAL, "Invalid ATTR structure"); |