summaryrefslogtreecommitdiff
path: root/sftp-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'sftp-server.c')
-rw-r--r--sftp-server.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/sftp-server.c b/sftp-server.c
index 1d13e97b2..e82280057 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: sftp-server.c,v 1.45 2004/02/19 21:15:04 markus Exp $"); 17RCSID("$OpenBSD: sftp-server.c,v 1.47 2004/06/25 05:38:48 dtucker Exp $");
18 18
19#include "buffer.h" 19#include "buffer.h"
20#include "bufaux.h" 20#include "bufaux.h"
@@ -31,11 +31,7 @@ RCSID("$OpenBSD: sftp-server.c,v 1.45 2004/02/19 21:15:04 markus Exp $");
31#define get_string(lenp) buffer_get_string(&iqueue, lenp); 31#define get_string(lenp) buffer_get_string(&iqueue, lenp);
32#define TRACE debug 32#define TRACE debug
33 33
34#ifdef HAVE___PROGNAME
35extern char *__progname; 34extern char *__progname;
36#else
37char *__progname;
38#endif
39 35
40/* input and output queue */ 36/* input and output queue */
41Buffer iqueue; 37Buffer iqueue;
@@ -260,7 +256,7 @@ send_msg(Buffer *m)
260} 256}
261 257
262static void 258static void
263send_status(u_int32_t id, u_int32_t error) 259send_status(u_int32_t id, u_int32_t status)
264{ 260{
265 Buffer msg; 261 Buffer msg;
266 const char *status_messages[] = { 262 const char *status_messages[] = {
@@ -276,14 +272,14 @@ send_status(u_int32_t id, u_int32_t error)
276 "Unknown error" /* Others */ 272 "Unknown error" /* Others */
277 }; 273 };
278 274
279 TRACE("sent status id %u error %u", id, error); 275 TRACE("sent status id %u error %u", id, status);
280 buffer_init(&msg); 276 buffer_init(&msg);
281 buffer_put_char(&msg, SSH2_FXP_STATUS); 277 buffer_put_char(&msg, SSH2_FXP_STATUS);
282 buffer_put_int(&msg, id); 278 buffer_put_int(&msg, id);
283 buffer_put_int(&msg, error); 279 buffer_put_int(&msg, status);
284 if (version >= 3) { 280 if (version >= 3) {
285 buffer_put_cstring(&msg, 281 buffer_put_cstring(&msg,
286 status_messages[MIN(error,SSH2_FX_MAX)]); 282 status_messages[MIN(status,SSH2_FX_MAX)]);
287 buffer_put_cstring(&msg, ""); 283 buffer_put_cstring(&msg, "");
288 } 284 }
289 send_msg(&msg); 285 send_msg(&msg);
@@ -839,9 +835,29 @@ process_rename(void)
839 status = errno_to_portable(errno); 835 status = errno_to_portable(errno);
840 else if (S_ISREG(sb.st_mode)) { 836 else if (S_ISREG(sb.st_mode)) {
841 /* Race-free rename of regular files */ 837 /* Race-free rename of regular files */
842 if (link(oldpath, newpath) == -1) 838 if (link(oldpath, newpath) == -1) {
843 status = errno_to_portable(errno); 839 if (errno == EOPNOTSUPP
844 else if (unlink(oldpath) == -1) { 840#ifdef LINK_OPNOTSUPP_ERRNO
841 || errno == LINK_OPNOTSUPP_ERRNO
842#endif
843 ) {
844 struct stat st;
845
846 /*
847 * fs doesn't support links, so fall back to
848 * stat+rename. This is racy.
849 */
850 if (stat(newpath, &st) == -1) {
851 if (rename(oldpath, newpath) == -1)
852 status =
853 errno_to_portable(errno);
854 else
855 status = SSH2_FX_OK;
856 }
857 } else {
858 status = errno_to_portable(errno);
859 }
860 } else if (unlink(oldpath) == -1) {
845 status = errno_to_portable(errno); 861 status = errno_to_portable(errno);
846 /* clean spare link */ 862 /* clean spare link */
847 unlink(newpath); 863 unlink(newpath);
@@ -863,20 +879,20 @@ process_readlink(void)
863{ 879{
864 u_int32_t id; 880 u_int32_t id;
865 int len; 881 int len;
866 char link[MAXPATHLEN]; 882 char buf[MAXPATHLEN];
867 char *path; 883 char *path;
868 884
869 id = get_int(); 885 id = get_int();
870 path = get_string(NULL); 886 path = get_string(NULL);
871 TRACE("readlink id %u path %s", id, path); 887 TRACE("readlink id %u path %s", id, path);
872 if ((len = readlink(path, link, sizeof(link) - 1)) == -1) 888 if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
873 send_status(id, errno_to_portable(errno)); 889 send_status(id, errno_to_portable(errno));
874 else { 890 else {
875 Stat s; 891 Stat s;
876 892
877 link[len] = '\0'; 893 buf[len] = '\0';
878 attrib_clear(&s.attrib); 894 attrib_clear(&s.attrib);
879 s.name = s.long_name = link; 895 s.name = s.long_name = buf;
880 send_names(id, 1, &s); 896 send_names(id, 1, &s);
881 } 897 }
882 xfree(path); 898 xfree(path);