summaryrefslogtreecommitdiff
path: root/sftp-server.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-15 12:14:12 +1100
committerDamien Miller <djm@mindrot.org>2013-10-15 12:14:12 +1100
commite9fc72edd6c313b670558cd5219601c38a949b67 (patch)
tree32ed93978e93622d5829a55cbc0479e00b1161bf /sftp-server.c
parent194fd904d8597a274b93e075b2047afdf5a175d4 (diff)
- djm@cvs.openbsd.org 2013/10/14 23:28:23
[canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c] refactor client config code a little: add multistate option partsing to readconf.c, similar to servconf.c's existing code. move checking of options that accept "none" as an argument to readconf.c add a lowercase() function and use it instead of explicit tolower() in loops part of a larger diff that was ok markus@
Diffstat (limited to 'sftp-server.c')
-rw-r--r--sftp-server.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/sftp-server.c b/sftp-server.c
index b62bd351..3056c454 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -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.
*
@@ -230,6 +230,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)
@@ -256,6 +258,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)
@@ -279,6 +283,7 @@ struct Handle {
int use;
DIR *dirp;
int fd;
+ int flags;
char *name;
u_int64_t bytes_read, bytes_write;
int next_unused;
@@ -302,7 +307,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;
@@ -320,6 +325,7 @@ handle_new(int use, const char *name, int fd, DIR *dirp)
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;
@@ -382,6 +388,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 0;
+}
+
static void
handle_update_read(int handle, ssize_t bytes)
{
@@ -668,7 +682,7 @@ process_open(u_int32_t id)
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 {
@@ -754,7 +768,8 @@ process_write(u_int32_t id)
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 {
@@ -971,7 +986,7 @@ process_opendir(u_int32_t id)
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 {