[PATCH-resend] Implement SSH2_FXF_APPEND
Ross Lagerwall
rosslagerwall at gmail.com
Tue Oct 15 07:52:42 EST 2013
Hi,
I submitted this a few weeks ago but here it is again since I got no
response. If there is somewhere else I should send this, please tell
me.
This patch implements SSH2_FXF_APPEND in the sftp server. It is a
fairly trivial patch and applies against the proper OpenSSH and the
Portable edition. I would argue that it is important for OpenSSH to
implement SSH2_FXF_APPEND since it is in the spec and clients who expect
it to work find that their files are overwritten rather than appended
to.
I opened a bug for it:
https://bugzilla.mindrot.org/show_bug.cgi?id=2159
Some relevant links:
http://marc.info/?l=openssh-unix-dev&m=138053388830753&w=2
http://marc.info/?l=openssh-unix-dev&m=123798287811788
http://marc.info/?l=openssh-unix-dev&m=111093206900604
https://bugzilla.gnome.org/show_bug.cgi?id=608910
Thanks
--
Ross Lagerwall
-------------- next part --------------
Index: sftp-server.c
===================================================================
RCS file: /cvs/openssh/sftp-server.c,v
retrieving revision 1.114
diff -u -p -r1.114 sftp-server.c
--- sftp-server.c 1 Jun 2013 21:31:19 -0000 1.114
+++ sftp-server.c 30 Sep 2013 08:16:57 -0000
@@ -130,6 +130,8 @@ flags_from_portable(int pflags)
} else if (pflags & SSH2_FXF_WRITE) {
flags = O_WRONLY;
}
+ if (pflags & SSH2_FXF_APPEND)
+ flags |= O_APPEND;
if (pflags & SSH2_FXF_CREAT)
flags |= O_CREAT;
if (pflags & SSH2_FXF_TRUNC)
@@ -156,6 +158,8 @@ string_from_portable(int pflags)
PAPPEND("READ")
if (pflags & SSH2_FXF_WRITE)
PAPPEND("WRITE")
+ if (pflags & SSH2_FXF_APPEND)
+ PAPPEND("APPEND")
if (pflags & SSH2_FXF_CREAT)
PAPPEND("CREATE")
if (pflags & SSH2_FXF_TRUNC)
@@ -179,6 +183,7 @@ struct Handle {
int use;
DIR *dirp;
int fd;
+ int flags;
char *name;
u_int64_t bytes_read, bytes_write;
int next_unused;
@@ -202,7 +207,7 @@ static void handle_unused(int i)
}
static int
-handle_new(int use, const char *name, int fd, DIR *dirp)
+handle_new(int use, const char *name, int fd, int flags, DIR *dirp)
{
int i;
@@ -220,6 +225,7 @@ handle_new(int use, const char *name, in
handles[i].use = use;
handles[i].dirp = dirp;
handles[i].fd = fd;
+ handles[i].flags = flags;
handles[i].name = xstrdup(name);
handles[i].bytes_read = handles[i].bytes_write = 0;
@@ -282,6 +288,14 @@ handle_to_fd(int handle)
return -1;
}
+static int
+handle_to_flags(int handle)
+{
+ if (handle_is_ok(handle, HANDLE_FILE))
+ return handles[handle].flags;
+ return -1;
+}
+
static void
handle_update_read(int handle, ssize_t bytes)
{
@@ -567,7 +581,7 @@ process_open(void)
if (fd < 0) {
status = errno_to_portable(errno);
} else {
- handle = handle_new(HANDLE_FILE, name, fd, NULL);
+ handle = handle_new(HANDLE_FILE, name, fd, flags, NULL);
if (handle < 0) {
close(fd);
} else {
@@ -660,7 +674,8 @@ process_write(void)
else if (readonly)
status = SSH2_FX_PERMISSION_DENIED;
else {
- if (lseek(fd, off, SEEK_SET) < 0) {
+ if (!(handle_to_flags(handle) & O_APPEND) &&
+ lseek(fd, off, SEEK_SET) < 0) {
status = errno_to_portable(errno);
error("process_write: seek failed");
} else {
@@ -893,7 +908,7 @@ process_opendir(void)
if (dirp == NULL) {
status = errno_to_portable(errno);
} else {
- handle = handle_new(HANDLE_DIR, path, 0, dirp);
+ handle = handle_new(HANDLE_DIR, path, 0, 0, dirp);
if (handle < 0) {
closedir(dirp);
} else {
More information about the openssh-unix-dev
mailing list