diff options
Diffstat (limited to 'sftp-server.c')
-rw-r--r-- | sftp-server.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/sftp-server.c b/sftp-server.c index b62bd3510..3056c454e 100644 --- a/sftp-server.c +++ b/sftp-server.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-server.c,v 1.100 2013/10/14 14:18:56 jmc Exp $ */ | 1 | /* $OpenBSD: sftp-server.c,v 1.101 2013/10/14 23:28:23 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -230,6 +230,8 @@ flags_from_portable(int pflags) | |||
230 | } else if (pflags & SSH2_FXF_WRITE) { | 230 | } else if (pflags & SSH2_FXF_WRITE) { |
231 | flags = O_WRONLY; | 231 | flags = O_WRONLY; |
232 | } | 232 | } |
233 | if (pflags & SSH2_FXF_APPEND) | ||
234 | flags |= O_APPEND; | ||
233 | if (pflags & SSH2_FXF_CREAT) | 235 | if (pflags & SSH2_FXF_CREAT) |
234 | flags |= O_CREAT; | 236 | flags |= O_CREAT; |
235 | if (pflags & SSH2_FXF_TRUNC) | 237 | if (pflags & SSH2_FXF_TRUNC) |
@@ -256,6 +258,8 @@ string_from_portable(int pflags) | |||
256 | PAPPEND("READ") | 258 | PAPPEND("READ") |
257 | if (pflags & SSH2_FXF_WRITE) | 259 | if (pflags & SSH2_FXF_WRITE) |
258 | PAPPEND("WRITE") | 260 | PAPPEND("WRITE") |
261 | if (pflags & SSH2_FXF_APPEND) | ||
262 | PAPPEND("APPEND") | ||
259 | if (pflags & SSH2_FXF_CREAT) | 263 | if (pflags & SSH2_FXF_CREAT) |
260 | PAPPEND("CREATE") | 264 | PAPPEND("CREATE") |
261 | if (pflags & SSH2_FXF_TRUNC) | 265 | if (pflags & SSH2_FXF_TRUNC) |
@@ -279,6 +283,7 @@ struct Handle { | |||
279 | int use; | 283 | int use; |
280 | DIR *dirp; | 284 | DIR *dirp; |
281 | int fd; | 285 | int fd; |
286 | int flags; | ||
282 | char *name; | 287 | char *name; |
283 | u_int64_t bytes_read, bytes_write; | 288 | u_int64_t bytes_read, bytes_write; |
284 | int next_unused; | 289 | int next_unused; |
@@ -302,7 +307,7 @@ static void handle_unused(int i) | |||
302 | } | 307 | } |
303 | 308 | ||
304 | static int | 309 | static int |
305 | handle_new(int use, const char *name, int fd, DIR *dirp) | 310 | handle_new(int use, const char *name, int fd, int flags, DIR *dirp) |
306 | { | 311 | { |
307 | int i; | 312 | int i; |
308 | 313 | ||
@@ -320,6 +325,7 @@ handle_new(int use, const char *name, int fd, DIR *dirp) | |||
320 | handles[i].use = use; | 325 | handles[i].use = use; |
321 | handles[i].dirp = dirp; | 326 | handles[i].dirp = dirp; |
322 | handles[i].fd = fd; | 327 | handles[i].fd = fd; |
328 | handles[i].flags = flags; | ||
323 | handles[i].name = xstrdup(name); | 329 | handles[i].name = xstrdup(name); |
324 | handles[i].bytes_read = handles[i].bytes_write = 0; | 330 | handles[i].bytes_read = handles[i].bytes_write = 0; |
325 | 331 | ||
@@ -382,6 +388,14 @@ handle_to_fd(int handle) | |||
382 | return -1; | 388 | return -1; |
383 | } | 389 | } |
384 | 390 | ||
391 | static int | ||
392 | handle_to_flags(int handle) | ||
393 | { | ||
394 | if (handle_is_ok(handle, HANDLE_FILE)) | ||
395 | return handles[handle].flags; | ||
396 | return 0; | ||
397 | } | ||
398 | |||
385 | static void | 399 | static void |
386 | handle_update_read(int handle, ssize_t bytes) | 400 | handle_update_read(int handle, ssize_t bytes) |
387 | { | 401 | { |
@@ -668,7 +682,7 @@ process_open(u_int32_t id) | |||
668 | if (fd < 0) { | 682 | if (fd < 0) { |
669 | status = errno_to_portable(errno); | 683 | status = errno_to_portable(errno); |
670 | } else { | 684 | } else { |
671 | handle = handle_new(HANDLE_FILE, name, fd, NULL); | 685 | handle = handle_new(HANDLE_FILE, name, fd, flags, NULL); |
672 | if (handle < 0) { | 686 | if (handle < 0) { |
673 | close(fd); | 687 | close(fd); |
674 | } else { | 688 | } else { |
@@ -754,7 +768,8 @@ process_write(u_int32_t id) | |||
754 | if (fd < 0) | 768 | if (fd < 0) |
755 | status = SSH2_FX_FAILURE; | 769 | status = SSH2_FX_FAILURE; |
756 | else { | 770 | else { |
757 | if (lseek(fd, off, SEEK_SET) < 0) { | 771 | if (!(handle_to_flags(handle) & O_APPEND) && |
772 | lseek(fd, off, SEEK_SET) < 0) { | ||
758 | status = errno_to_portable(errno); | 773 | status = errno_to_portable(errno); |
759 | error("process_write: seek failed"); | 774 | error("process_write: seek failed"); |
760 | } else { | 775 | } else { |
@@ -971,7 +986,7 @@ process_opendir(u_int32_t id) | |||
971 | if (dirp == NULL) { | 986 | if (dirp == NULL) { |
972 | status = errno_to_portable(errno); | 987 | status = errno_to_portable(errno); |
973 | } else { | 988 | } else { |
974 | handle = handle_new(HANDLE_DIR, path, 0, dirp); | 989 | handle = handle_new(HANDLE_DIR, path, 0, 0, dirp); |
975 | if (handle < 0) { | 990 | if (handle < 0) { |
976 | closedir(dirp); | 991 | closedir(dirp); |
977 | } else { | 992 | } else { |