From efbcb3860d3e98292de6fb529db6551787e97d3e Mon Sep 17 00:00:00 2001
From: Christian Kandeler <christian.kandeler@nokia.com>
Date: Fri, 24 Jun 2011 14:57:03 +0200
Subject: [PATCH] SSH: set correct attributes when uploading a file.

Change-Id: I59484d5e66491e8941992abdd2a478364ec258a7
Reviewed-on: http://codereview.qt.nokia.com/710
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
---
 src/libs/utils/ssh/sftpincomingpacket.cpp |  8 -------
 src/libs/utils/ssh/sftpoperation.cpp      | 26 ++++++++++++++++++++---
 src/libs/utils/ssh/sftpoutgoingpacket.cpp | 25 ++++++++++++++++------
 src/libs/utils/ssh/sftpoutgoingpacket_p.h |  6 ++++--
 src/libs/utils/ssh/sftppacket.cpp         |  1 -
 src/libs/utils/ssh/sftppacket_p.h         |  8 +++++++
 6 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/src/libs/utils/ssh/sftpincomingpacket.cpp b/src/libs/utils/ssh/sftpincomingpacket.cpp
index 77a887607b5..fb6adf070a1 100644
--- a/src/libs/utils/ssh/sftpincomingpacket.cpp
+++ b/src/libs/utils/ssh/sftpincomingpacket.cpp
@@ -38,14 +38,6 @@
 namespace Utils {
 namespace Internal {
 
-namespace {
-    const int SSH_FILEXFER_ATTR_SIZE = 0x00000001;
-    const int SSH_FILEXFER_ATTR_UIDGID = 0x00000002;
-    const int SSH_FILEXFER_ATTR_PERMISSIONS = 0x00000004;
-    const int SSH_FILEXFER_ATTR_ACMODTIME = 0x00000008;
-    const int SSH_FILEXFER_ATTR_EXTENDED = 0x80000000;
-} // anonymous namespace
-
 SftpIncomingPacket::SftpIncomingPacket() : m_length(0)
 {
 }
diff --git a/src/libs/utils/ssh/sftpoperation.cpp b/src/libs/utils/ssh/sftpoperation.cpp
index c70d4b331a6..6688e964cc2 100644
--- a/src/libs/utils/ssh/sftpoperation.cpp
+++ b/src/libs/utils/ssh/sftpoperation.cpp
@@ -121,7 +121,8 @@ SftpCreateFile::SftpCreateFile(SftpJobId jobId, const QString &path,
 SftpOutgoingPacket & SftpCreateFile::initialPacket(SftpOutgoingPacket &packet)
 {
     state = OpenRequested;
-    return packet.generateOpenFileForWriting(remotePath, mode, jobId);
+    return packet.generateOpenFileForWriting(remotePath, mode,
+        SftpOutgoingPacket::DefaultPermissions, jobId);
 }
 
 
@@ -176,10 +177,29 @@ SftpUploadFile::SftpUploadFile(SftpJobId jobId, const QString &remotePath,
 SftpOutgoingPacket &SftpUploadFile::initialPacket(SftpOutgoingPacket &packet)
 {
     state = OpenRequested;
-    return packet.generateOpenFileForWriting(remotePath, mode, jobId);
+    quint32 permissions = 0;
+    const QFile::Permissions &qtPermissions = localFile->permissions();
+    if (qtPermissions & QFile::ExeOther)
+        permissions |= 1 << 0;
+    if (qtPermissions & QFile::WriteOther)
+        permissions |= 1 << 1;
+    if (qtPermissions & QFile::ReadOther)
+        permissions |= 1 << 2;
+    if (qtPermissions & QFile::ExeGroup)
+        permissions |= 1<< 3;
+    if (qtPermissions & QFile::WriteGroup)
+        permissions |= 1<< 4;
+    if (qtPermissions & QFile::ReadGroup)
+        permissions |= 1<< 5;
+    if (qtPermissions & QFile::ExeOwner)
+        permissions |= 1<< 6;
+    if (qtPermissions & QFile::WriteOwner)
+        permissions |= 1<< 7;
+    if (qtPermissions & QFile::ReadOwner)
+        permissions |= 1<< 8;
+    return packet.generateOpenFileForWriting(remotePath, mode, permissions, jobId);
 }
 
-
 SftpUploadDir::~SftpUploadDir() {}
 
 } // namespace Internal
diff --git a/src/libs/utils/ssh/sftpoutgoingpacket.cpp b/src/libs/utils/ssh/sftpoutgoingpacket.cpp
index 4e5112e2cc7..732ca78b6d9 100644
--- a/src/libs/utils/ssh/sftpoutgoingpacket.cpp
+++ b/src/libs/utils/ssh/sftpoutgoingpacket.cpp
@@ -36,6 +36,8 @@
 
 #include <QtCore/QtEndian>
 
+#include <limits>
+
 namespace Utils {
 namespace Internal {
 
@@ -103,16 +105,22 @@ SftpOutgoingPacket &SftpOutgoingPacket::generateRename(const QString &oldPath,
 }
 
 SftpOutgoingPacket &SftpOutgoingPacket::generateOpenFileForWriting(const QString &path,
-    SftpOverwriteMode mode, quint32 requestId)
+    SftpOverwriteMode mode, quint32 permissions, quint32 requestId)
 {
-    return generateOpenFile(path, Write, mode, requestId);
+    QList<quint32> attributes;
+    if (permissions != DefaultPermissions)
+        attributes << SSH_FILEXFER_ATTR_PERMISSIONS << permissions;
+    else
+        attributes << DefaultAttributes;
+    return generateOpenFile(path, Write, mode, attributes, requestId);
 }
 
 SftpOutgoingPacket &SftpOutgoingPacket::generateOpenFileForReading(const QString &path,
     quint32 requestId)
 {
     // Note: Overwrite mode is irrelevant and will be ignored.
-    return generateOpenFile(path, Read, SftpSkipExisting, requestId);
+    return generateOpenFile(path, Read, SftpSkipExisting, QList<quint32>() << DefaultAttributes,
+        requestId);
 }
 
 SftpOutgoingPacket &SftpOutgoingPacket::generateReadFile(const QByteArray &handle,
@@ -136,7 +144,7 @@ SftpOutgoingPacket &SftpOutgoingPacket::generateWriteFile(const QByteArray &hand
 }
 
 SftpOutgoingPacket &SftpOutgoingPacket::generateOpenFile(const QString &path,
-    OpenType openType, SftpOverwriteMode mode, quint32 requestId)
+    OpenType openType, SftpOverwriteMode mode, const QList<quint32> &attributes, quint32 requestId)
 {
     quint32 pFlags;
     switch (openType) {
@@ -152,8 +160,11 @@ SftpOutgoingPacket &SftpOutgoingPacket::generateOpenFile(const QString &path,
         }
         break;
     }
-    return init(SSH_FXP_OPEN, requestId).appendString(path).appendInt(pFlags)
-        .appendInt(DefaultAttributes).finalize();
+
+    init(SSH_FXP_OPEN, requestId).appendString(path).appendInt(pFlags);
+    foreach (const quint32 attribute, attributes)
+        appendInt(attribute);
+    return finalize();
 }
 
 SftpOutgoingPacket &SftpOutgoingPacket::init(SftpPacketType type,
@@ -201,5 +212,7 @@ SftpOutgoingPacket &SftpOutgoingPacket::finalize()
     return *this;
 }
 
+const quint32 SftpOutgoingPacket::DefaultPermissions = std::numeric_limits<quint32>::max();
+
 } // namespace Internal
 } // namespace Utils
diff --git a/src/libs/utils/ssh/sftpoutgoingpacket_p.h b/src/libs/utils/ssh/sftpoutgoingpacket_p.h
index 552296c3df4..3522b38e366 100644
--- a/src/libs/utils/ssh/sftpoutgoingpacket_p.h
+++ b/src/libs/utils/ssh/sftpoutgoingpacket_p.h
@@ -55,7 +55,7 @@ public:
     SftpOutgoingPacket &generateRename(const QString &oldPath,
         const QString &newPath, quint32 requestId);
     SftpOutgoingPacket &generateOpenFileForWriting(const QString &path,
-         SftpOverwriteMode mode, quint32 requestId);
+         SftpOverwriteMode mode, quint32 permissions, quint32 requestId);
     SftpOutgoingPacket &generateOpenFileForReading(const QString &path,
         quint32 requestId);
     SftpOutgoingPacket &generateReadFile(const QByteArray &handle,
@@ -65,12 +65,14 @@ public:
     SftpOutgoingPacket &generateWriteFile(const QByteArray &handle,
         quint64 offset, const QByteArray &data, quint32 requestId);
 
+    static const quint32 DefaultPermissions;
+
 private:
     static QByteArray encodeString(const QString &string);
 
     enum OpenType { Read, Write };
     SftpOutgoingPacket &generateOpenFile(const QString &path, OpenType openType,
-        SftpOverwriteMode mode, quint32 requestId);
+        SftpOverwriteMode mode, const QList<quint32> &attributes, quint32 requestId);
 
     SftpOutgoingPacket &init(SftpPacketType type, quint32 requestId);
     SftpOutgoingPacket &appendInt(quint32 value);
diff --git a/src/libs/utils/ssh/sftppacket.cpp b/src/libs/utils/ssh/sftppacket.cpp
index cb6e704eee0..566494f997d 100644
--- a/src/libs/utils/ssh/sftppacket.cpp
+++ b/src/libs/utils/ssh/sftppacket.cpp
@@ -43,7 +43,6 @@ const int AbstractSftpPacket::TypeOffset = 4;
 const int AbstractSftpPacket::RequestIdOffset = TypeOffset + 1;
 const int AbstractSftpPacket::PayloadOffset = RequestIdOffset + 4;
 
-
 AbstractSftpPacket::AbstractSftpPacket()
 {
 }
diff --git a/src/libs/utils/ssh/sftppacket_p.h b/src/libs/utils/ssh/sftppacket_p.h
index ea7c31acf24..227232b7264 100644
--- a/src/libs/utils/ssh/sftppacket_p.h
+++ b/src/libs/utils/ssh/sftppacket_p.h
@@ -84,6 +84,14 @@ enum SftpStatusCode {
     SSH_FX_OP_UNSUPPORTED = 8
 };
 
+enum SftpAttributeType {
+    SSH_FILEXFER_ATTR_SIZE = 0x00000001,
+    SSH_FILEXFER_ATTR_UIDGID = 0x00000002,
+    SSH_FILEXFER_ATTR_PERMISSIONS = 0x00000004,
+    SSH_FILEXFER_ATTR_ACMODTIME = 0x00000008,
+    SSH_FILEXFER_ATTR_EXTENDED = 0x80000000
+};
+
 class AbstractSftpPacket
 {
 public:
-- 
GitLab