File kdump-sftp-file-create.patch of Package kdump
From: Petr Tesarik <ptesarik@suse.cz>
Date: Wed, 15 Apr 2015 11:48:24 +0200
Subject: Implement file create and close for SFTP
References: FATE#318874, bsc#917747
Patch-mainline: v0.8.16
Git-commit: a0facf10ce187afa2b0c52a2af891018b0c9a320
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
---
kdumptool/sshtransfer.cc | 74 +++++++++++++++++++++++++++++++++++++++++++++++
kdumptool/sshtransfer.h | 17 ++++++++++
2 files changed, 91 insertions(+)
--- a/kdumptool/sshtransfer.cc
+++ b/kdumptool/sshtransfer.cc
@@ -412,6 +412,24 @@ void SFTPTransfer::perform(DataProvider
Debug::debug()->trace("SFTPTransfer::perform(%p, [ \"%s\"%s ])",
dataprovider, target_files.front().c_str(),
target_files.size() > 1 ? ", ..." : "");
+
+ if (directSave)
+ *directSave = false;
+
+ RootDirURLVector &urlv = getURLVector();
+ const RootDirURL &target = urlv.front();
+
+ FilePath fp = target.getPath();
+ fp.appendPath(getSubDir()).appendPath(target_files.front());
+
+ string handle = createfile(fp);
+ try {
+ } catch (...) {
+ closefile(handle);
+ throw;
+ }
+
+ closefile(handle);
}
/* -------------------------------------------------------------------------- */
@@ -483,6 +501,62 @@ void SFTPTransfer::mkpath(const std::str
}
/* -------------------------------------------------------------------------- */
+std::string SFTPTransfer::createfile(const std::string &file)
+{
+ Debug::debug()->trace("SFTPTransfer::createfile(%s)", file.c_str());
+
+ SFTPPacket pkt;
+ pkt.addByte(SSH_FXP_OPEN);
+ pkt.addInt32(nextId());
+ pkt.addString(file);
+ pkt.addInt32(SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC);
+ pkt.addInt32(0UL); // no attrs
+ sendPacket(pkt);
+
+ recvPacket(pkt);
+ unsigned char type = pkt.getByte();
+ unsigned long id = pkt.getInt32();
+ if (id != m_lastid)
+ throw KError("SFTP request/reply id mismatch");
+
+ if (type == SSH_FXP_HANDLE)
+ return pkt.getString();
+
+ if (type != SSH_FXP_STATUS)
+ throw KError("Invalid response to SSH_FXP_OPEN: type " +
+ Stringutil::number2string(unsigned(type)));
+
+ unsigned long errcode = pkt.getInt32();
+ throw KSFTPError("open failed on " + file, errcode);
+}
+
+/* -------------------------------------------------------------------------- */
+void SFTPTransfer::closefile(const std::string &handle)
+{
+ Debug::debug()->trace("SFTPTransfer::closefile(%s)", handle.c_str());
+
+ SFTPPacket pkt;
+ pkt.addByte(SSH_FXP_CLOSE);
+ pkt.addInt32(nextId());
+ pkt.addString(handle);
+ sendPacket(pkt);
+
+ recvPacket(pkt);
+ unsigned char type = pkt.getByte();
+ unsigned long id = pkt.getInt32();
+ if (id != m_lastid)
+ throw KError("SFTP request/reply id mismatch");
+
+ if (type != SSH_FXP_STATUS)
+ throw KError("Invalid response to SSH_FXP_OPEN: type " +
+ Stringutil::number2string(unsigned(type)));
+
+ unsigned long errcode = pkt.getInt32();
+ if (errcode != SSH_FX_OK)
+ throw KSFTPError("close failed on " + handle, errcode);
+}
+
+/* -------------------------------------------------------------------------- */
StringVector SFTPTransfer::makeArgs(void)
{
const RootDirURL &target = getURLVector().front();
--- a/kdumptool/sshtransfer.h
+++ b/kdumptool/sshtransfer.h
@@ -122,13 +122,28 @@ typedef KCodeError<KSFTPErrorCode> KSFTP
enum {
SSH_FXP_INIT = 1,
SSH_FXP_VERSION = 2,
+ SSH_FXP_OPEN = 3,
+ SSH_FXP_CLOSE = 4,
SSH_FXP_MKDIR = 14,
SSH_FXP_STAT = 17,
SSH_FXP_STATUS = 101,
+ SSH_FXP_HANDLE = 102,
SSH_FXP_ATTRS = 105,
};
/**
+ * Open flags
+ */
+enum {
+ SSH_FXF_READ = 0x00000001,
+ SSH_FXF_WRITE = 0x00000002,
+ SSH_FXF_APPEND = 0x00000004,
+ SSH_FXF_CREAT = 0x00000008,
+ SSH_FXF_TRUNC = 0x00000010,
+ SSH_FXF_EXCL = 0x00000020,
+};
+
+/**
* Encode/decode an SFTP packet.
*/
class SFTPPacket {
@@ -213,6 +228,8 @@ class SFTPTransfer : public URLTransfer
bool exists(const std::string &file);
void mkpath(const std::string &path);
+ std::string createfile(const std::string &file);
+ void closefile(const std::string &handle);
private:
SubProcess m_process;