aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/sftp.h7
-rw-r--r--libssh/sftp.c53
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");