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);
Hi, Thanks for the patch! Could I ask you to create a bug on https://bugzilla.mindrot.org/ and attach it so it doesn't get lost? Thanks, Damien Miller On Thu, 2 Jun 2016, Rian Hunter wrote:> 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); > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev >
Sure, now located at https://bugzilla.mindrot.org/show_bug.cgi?id=2579 On 2016-06-01 19:45, Damien Miller wrote:> Hi, > > Thanks for the patch! Could I ask you to create a bug on > https://bugzilla.mindrot.org/ and attach it so it doesn't get lost? > > Thanks, > Damien Miller > > On Thu, 2 Jun 2016, Rian Hunter wrote: > >> 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); >> _______________________________________________ >> openssh-unix-dev mailing list >> openssh-unix-dev at mindrot.org >> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev >>
Reasonably Related Threads
- [PATCH] cleanup of global variables server/client_version_string in sshconnect.c
- Incomplete attestation data for FIDO2 SKs?
- [PATCH v2 0/2] Add openssl engine keys with provider upgrade path
- [RFC 0/2] add engine based keys
- Configure option '--with-ssh1' breaks openssh-7.3p1