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 >>