[PATCH] Link count attribute extension
Rian Hunter
rian at thelig.ht
Thu Jun 2 12:17:55 AEST 2016
Hello,
This patch adds client and server support for transmitting the st_nlink field
across SSH2_FXP_NAME and SSH2_FXP_ATTRS responses.
Please let me know if there anything I can do to improve this patch. I am
not subscribed to list so please CC me.
Index: sftp-common.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sftp-common.c,v
retrieving revision 1.28
diff -u -r1.28 sftp-common.c
--- sftp-common.c 20 Jan 2015 23:14:00 -0000 1.28
+++ sftp-common.c 2 Jun 2016 01:32:02 -0000
@@ -56,6 +56,8 @@
a->perm = 0;
a->atime = 0;
a->mtime = 0;
+ a->has_nlink = 0;
+ a->nlink = 0;
}
/* Convert from struct stat to filexfer attribs */
@@ -74,6 +76,9 @@
a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
a->atime = st->st_atime;
a->mtime = st->st_mtime;
+ a->flags |= SSH2_FILEXFER_ATTR_EXTENDED;
+ a->has_nlink = 1;
+ a->nlink = st->st_nlink;
}
/* Convert from filexfer attribs to struct stat */
@@ -94,6 +99,11 @@
st->st_atime = a->atime;
st->st_mtime = a->mtime;
}
+ if (a->flags & SSH2_FILEXFER_ATTR_EXTENDED) {
+ if (a->has_nlink) {
+ st->st_nlink = a->nlink;
+ }
+ }
}
/* Decode attributes in buffer */
@@ -138,6 +148,15 @@
return r;
debug3("Got file attribute \"%.100s\" len %zu",
type, dlen);
+ if (strcmp(type, SFTP_EXT_ATTR_LINK_COUNT) == 0) {
+ if (dlen < 8) {
+ return SSH_ERR_MESSAGE_INCOMPLETE;
+ free(type);
+ free(data);
+ }
+ a->has_nlink = 1;
+ a->nlink = PEEK_U64(data);
+ }
free(type);
free(data);
}
@@ -170,6 +189,24 @@
if ((r = sshbuf_put_u32(b, a->atime)) != 0 ||
(r = sshbuf_put_u32(b, a->mtime)) != 0)
return r;
+ }
+ if (a->flags & SSH2_FILEXFER_ATTR_EXTENDED) {
+ u_int32_t count = 0;
+ if (a->has_nlink) {
+ count += 1;
+ }
+
+ if (count) {
+ if ((r = sshbuf_put_u32(b, count)) != 0)
+ return r;
+
+ if (a->has_nlink) {
+ if ((r = sshbuf_put_cstring(b, SFTP_EXT_ATTR_LINK_COUNT)) != 0 ||
+ (r = sshbuf_put_u32(b, 8)) != 0 ||
+ (r = sshbuf_put_u64(b, a->nlink)))
+ return r;
+ }
+ }
}
return 0;
}
Index: sftp-common.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sftp-common.h,v
retrieving revision 1.12
diff -u -r1.12 sftp-common.h
--- sftp-common.h 14 Jan 2015 13:54:13 -0000 1.12
+++ sftp-common.h 2 Jun 2016 01:32:02 -0000
@@ -40,6 +40,8 @@
u_int32_t perm;
u_int32_t atime;
u_int32_t mtime;
+ u_int32_t has_nlink;
+ u_int64_t nlink;
};
void attrib_clear(Attrib *);
@@ -50,3 +52,5 @@
char *ls_file(const char *, const struct stat *, int, int);
const char *fx2txt(int);
+
+#define SFTP_EXT_ATTR_LINK_COUNT "attr-link-count at openssh.com"
Index: sftp-server.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sftp-server.c,v
retrieving revision 1.109
diff -u -r1.109 sftp-server.c
--- sftp-server.c 15 Feb 2016 09:47:49 -0000 1.109
+++ sftp-server.c 2 Jun 2016 01:32:02 -0000
@@ -659,6 +659,9 @@
(r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
/* fsync extension */
(r = sshbuf_put_cstring(msg, "fsync at openssh.com")) != 0 ||
+ (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
+ /* attr link count extension */
+ (r = sshbuf_put_cstring(msg, SFTP_EXT_ATTR_LINK_COUNT)) != 0 ||
(r = sshbuf_put_cstring(msg, "1")) != 0) /* version */
fatal("%s: buffer error: %s", __func__, ssh_err(r));
send_msg(msg);
More information about the openssh-unix-dev
mailing list