=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sftp-server.c,v retrieving revision 1.100 retrieving revision 1.101 diff -u -r1.100 -r1.101 --- src/usr.bin/ssh/sftp-server.c 2013/10/14 14:18:56 1.100 +++ src/usr.bin/ssh/sftp-server.c 2013/10/14 23:28:23 1.101 @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.100 2013/10/14 14:18:56 jmc Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.101 2013/10/14 23:28:23 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -221,6 +221,8 @@ } 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) @@ -247,6 +249,8 @@ 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) @@ -270,6 +274,7 @@ int use; DIR *dirp; int fd; + int flags; char *name; u_int64_t bytes_read, bytes_write; int next_unused; @@ -293,7 +298,7 @@ } 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; @@ -311,6 +316,7 @@ 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; @@ -373,6 +379,14 @@ return -1; } +static int +handle_to_flags(int handle) +{ + if (handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].flags; + return 0; +} + static void handle_update_read(int handle, ssize_t bytes) { @@ -659,7 +673,7 @@ 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 { @@ -745,7 +759,8 @@ if (fd < 0) status = SSH2_FX_FAILURE; 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 { @@ -950,7 +965,7 @@ 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 {