From b4b6cfdb1cdbac5fe0db690d4a3248f94dcb8446 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 11 Jul 2008 04:38:11 +0000 Subject: Changed slightly the SFTP quote commands chmod, chown and chgrp to only set the attribute that has changed instead of all possible ones. Hopefully, this will solve the "Permission denied" problem that Nagarajan Sreenivasan reported when setting some modes, but regardless, it saves a protocol round trip in the chmod case. --- CHANGES | 7 +++++++ lib/ssh.c | 41 +++++++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index 258c4b248..ef250ba33 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,13 @@ Changelog +Daniel Fandrich (10 Jul 2008) +- Changed slightly the SFTP quote commands chmod, chown and chgrp to only + set the attribute that has changed instead of all possible ones. Hopefully, + this will solve the "Permission denied" problem that Nagarajan Sreenivasan + reported when setting some modes, but regardless, it saves a protocol + round trip in the chmod case. + Yang Tse (10 Jul 2008) - Peter Lamberg filed bug report #2015126: "poll gives WSAEINVAL when POLLPRI is set in fdset.events" (http://curl.haxx.se/bug/view.cgi?id=2015126) which diff --git a/lib/ssh.c b/lib/ssh.c index 6f2392d6d..cb6e96c78 100644 --- a/lib/ssh.c +++ b/lib/ssh.c @@ -997,27 +997,34 @@ static CURLcode ssh_statemach_act(struct connectdata *conn) break; case SSH_SFTP_QUOTE_STAT: - rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2, - &sshc->quote_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0) { /* get those attributes */ - err = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; - Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; - failf(data, "Attempt to get SFTP stats failed: %s", - sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_QUOTE_ERROR; - break; + if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) { + /* Since chown and chgrp only set owner OR group but libssh2 wants to + * set them both at once, we need to obtain the current ownership first. + * This takes an extra protocol round trip. + */ + rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2, + &sshc->quote_attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + else if(rc != 0) { /* get those attributes */ + err = libssh2_sftp_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + sshc->quote_path1 = NULL; + Curl_safefree(sshc->quote_path2); + sshc->quote_path2 = NULL; + failf(data, "Attempt to get SFTP stats failed: %s", + sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } } /* Now set the new attributes... */ if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) { sshc->quote_attrs.gid = strtol(sshc->quote_path1, NULL, 10); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) { Curl_safefree(sshc->quote_path1); sshc->quote_path1 = NULL; @@ -1031,6 +1038,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn) } else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) { sshc->quote_attrs.permissions = strtol(sshc->quote_path1, NULL, 8); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; /* permissions are octal */ if(sshc->quote_attrs.permissions == 0 && !ISDIGIT(sshc->quote_path1[0])) { @@ -1046,6 +1054,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn) } else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) { sshc->quote_attrs.uid = strtol(sshc->quote_path1, NULL, 10); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) { Curl_safefree(sshc->quote_path1); sshc->quote_path1 = NULL; -- cgit v1.2.3