]> andersk Git - gssapi-openssh.git/blobdiff - openssh/sftp-server.c
Import of OpenSSH 3.9p1
[gssapi-openssh.git] / openssh / sftp-server.c
index 1d13e97b24c2fc26c48605dcff3158c5f933dc8d..e82280057534a57a4eeb6dcba955b5d5e620bf31 100644 (file)
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: sftp-server.c,v 1.45 2004/02/19 21:15:04 markus Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.47 2004/06/25 05:38:48 dtucker Exp $");
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -31,11 +31,7 @@ RCSID("$OpenBSD: sftp-server.c,v 1.45 2004/02/19 21:15:04 markus Exp $");
 #define get_string(lenp)               buffer_get_string(&iqueue, lenp);
 #define TRACE                          debug
 
-#ifdef HAVE___PROGNAME
 extern char *__progname;
-#else
-char *__progname;
-#endif
 
 /* input and output queue */
 Buffer iqueue;
@@ -260,7 +256,7 @@ send_msg(Buffer *m)
 }
 
 static void
-send_status(u_int32_t id, u_int32_t error)
+send_status(u_int32_t id, u_int32_t status)
 {
        Buffer msg;
        const char *status_messages[] = {
@@ -276,14 +272,14 @@ send_status(u_int32_t id, u_int32_t error)
                "Unknown error"                 /* Others */
        };
 
-       TRACE("sent status id %u error %u", id, error);
+       TRACE("sent status id %u error %u", id, status);
        buffer_init(&msg);
        buffer_put_char(&msg, SSH2_FXP_STATUS);
        buffer_put_int(&msg, id);
-       buffer_put_int(&msg, error);
+       buffer_put_int(&msg, status);
        if (version >= 3) {
                buffer_put_cstring(&msg,
-                   status_messages[MIN(error,SSH2_FX_MAX)]);
+                   status_messages[MIN(status,SSH2_FX_MAX)]);
                buffer_put_cstring(&msg, "");
        }
        send_msg(&msg);
@@ -839,9 +835,29 @@ process_rename(void)
                status = errno_to_portable(errno);
        else if (S_ISREG(sb.st_mode)) {
                /* Race-free rename of regular files */
-               if (link(oldpath, newpath) == -1)
-                       status = errno_to_portable(errno);
-               else if (unlink(oldpath) == -1) {
+               if (link(oldpath, newpath) == -1) {
+                       if (errno == EOPNOTSUPP
+#ifdef LINK_OPNOTSUPP_ERRNO
+                           || errno == LINK_OPNOTSUPP_ERRNO
+#endif
+                           ) {
+                               struct stat st;
+
+                               /*
+                                * fs doesn't support links, so fall back to
+                                * stat+rename.  This is racy.
+                                */
+                               if (stat(newpath, &st) == -1) {
+                                       if (rename(oldpath, newpath) == -1)
+                                               status =
+                                                   errno_to_portable(errno);
+                                       else
+                                               status = SSH2_FX_OK;
+                               }
+                       } else {
+                               status = errno_to_portable(errno);
+                       }
+               } else if (unlink(oldpath) == -1) {
                        status = errno_to_portable(errno);
                        /* clean spare link */
                        unlink(newpath);
@@ -863,20 +879,20 @@ process_readlink(void)
 {
        u_int32_t id;
        int len;
-       char link[MAXPATHLEN];
+       char buf[MAXPATHLEN];
        char *path;
 
        id = get_int();
        path = get_string(NULL);
        TRACE("readlink id %u path %s", id, path);
-       if ((len = readlink(path, link, sizeof(link) - 1)) == -1)
+       if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
                send_status(id, errno_to_portable(errno));
        else {
                Stat s;
 
-               link[len] = '\0';
+               buf[len] = '\0';
                attrib_clear(&s.attrib);
-               s.name = s.long_name = link;
+               s.name = s.long_name = buf;
                send_names(id, 1, &s);
        }
        xfree(path);
This page took 0.148607 seconds and 4 git commands to generate.