summaryrefslogtreecommitdiff
path: root/patch/libssh-0.10.4.patch
blob: bd6dc0ec41620cd1e7147a6228f8c6fa1af05c60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
diff --git a/DefineOptions.cmake b/DefineOptions.cmake
index 068db988..7f42c2f3 100644
--- a/DefineOptions.cmake
+++ b/DefineOptions.cmake
@@ -25,6 +25,7 @@ option(WITH_GEX "Enable DH Group exchange mechanisms" ON)
 option(WITH_INSECURE_NONE "Enable insecure none cipher and MAC algorithms (not suitable for production!)" OFF)
 option(FUZZ_TESTING "Build with fuzzer for the server and client (automatically enables none cipher!)" OFF)
 option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
+option(WITH_STATIC_LIB "Build static library" ON)
 
 if (WITH_ZLIB)
     set(WITH_LIBZ ON)
@@ -60,3 +61,7 @@ endif (NOT GLOBAL_CLIENT_CONFIG)
 if (FUZZ_TESTING)
   set(WITH_INSECURE_NONE ON)
 endif (FUZZ_TESTING)
+
+if (WITH_STATIC_LIB)
+  set(BUILD_STATIC_LIB ON)
+endif()
diff --git a/include/libssh/sftp.h b/include/libssh/sftp.h
index c855df8a..1fd1710a 100644
--- a/include/libssh/sftp.h
+++ b/include/libssh/sftp.h
@@ -565,6 +565,9 @@ LIBSSH_API int sftp_async_read(sftp_file file, void *data, uint32_t len, uint32_
  */
 LIBSSH_API ssize_t sftp_write(sftp_file file, const void *buf, size_t count);
 
+LIBSSH_API int sftp_async_write(sftp_file file, const void *buf, size_t count, uint32_t* id);
+LIBSSH_API int sftp_async_write_end(sftp_file file, uint32_t id, int blocking);
+
 /**
  * @brief Seek to a specific location in a file.
  *
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c090fef7..e2f86309 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -435,6 +435,11 @@ if (BUILD_STATIC_LIB)
   if (WIN32)
     target_compile_definitions(ssh-static PUBLIC "LIBSSH_STATIC")
   endif (WIN32)
+
+  install(TARGETS ssh-static
+	  EXPORT libssh-config
+	  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+	  COMPONENT libraries)
 endif (BUILD_STATIC_LIB)
 
 message(STATUS "Threads_FOUND=${Threads_FOUND}")
diff --git a/src/sftp.c b/src/sftp.c
index e01012a8..7b5dc249 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -2228,6 +2228,102 @@ ssize_t sftp_write(sftp_file file, const void *buf, size_t count) {
   return -1; /* not reached */
 }
 
+/*
+ * sftp_async_write and sftp_async_write_end are copied from
+ * https://github.com/limes-datentechnik-gmbh/libssh
+ */
+int sftp_async_write(sftp_file file, const void *buf, size_t count, uint32_t* id) {
+  sftp_session sftp = file->sftp;
+  ssh_buffer buffer;
+  int len;
+  int packetlen;
+  int rc;
+
+  buffer = ssh_buffer_new();
+  if (buffer == NULL) {
+    ssh_set_error_oom(sftp->session);
+    return -1;
+  }
+
+  *id = sftp_get_new_id(file->sftp);
+
+  rc = ssh_buffer_pack(buffer,
+                       "dSqdP",
+                       *id,
+                       file->handle,
+                       file->offset,
+                       count, /* len of datastring */
+                       (size_t)count, buf);
+  if (rc != SSH_OK){
+    ssh_set_error_oom(sftp->session);
+    ssh_buffer_free(buffer);
+    return SSH_ERROR;
+  }
+  packetlen=ssh_buffer_get_len(buffer)+5;
+  len = sftp_packet_write(file->sftp, SSH_FXP_WRITE, buffer);
+  ssh_buffer_free(buffer);
+  if (len < 0) {
+    return SSH_ERROR;
+  } else  if (len != packetlen) {
+    ssh_set_error(sftp->session, SSH_FATAL,
+      "Could only send %d of %d bytes to remote host!", len, packetlen);
+    SSH_LOG(SSH_LOG_PACKET,
+        "Could not write as much data as expected");
+    return SSH_ERROR;
+  }
+
+  file->offset += count;
+
+  return SSH_OK;
+}
+
+int sftp_async_write_end(sftp_file file, uint32_t id, int blocking) {
+  sftp_session sftp = file->sftp;
+  sftp_message msg = NULL;
+  sftp_status_message status;
+
+  msg = sftp_dequeue(sftp, id);
+  while (msg == NULL) {
+    if (!blocking && ssh_channel_poll(sftp->channel, 0) == 0) {
+      /* we cannot block */
+      return SSH_AGAIN;
+    }
+    if (sftp_read_and_dispatch(sftp) < 0) {
+      /* something nasty has happened */
+      return SSH_ERROR;
+    }
+    msg = sftp_dequeue(sftp, id);
+  }
+
+  switch (msg->packet_type) {
+    case SSH_FXP_STATUS:
+      status = parse_status_msg(msg);
+      sftp_message_free(msg);
+      if (status == NULL) {
+        return SSH_ERROR;
+      }
+      sftp_set_error(sftp, status->status);
+      switch (status->status) {
+        case SSH_FX_OK:
+          status_msg_free(status);
+          return SSH_OK;
+        default:
+          break;
+      }
+      ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
+          "SFTP server: %s", status->errormsg);
+      status_msg_free(status);
+      return SSH_ERROR;
+    default:
+      ssh_set_error(sftp->session, SSH_FATAL,
+          "Received message %d during write!", msg->packet_type);
+      sftp_message_free(msg);
+      return SSH_ERROR;
+  }
+
+  return SSH_ERROR; /* not reached */
+}
+
 /* Seek to a specific location in a file. */
 int sftp_seek(sftp_file file, uint32_t new_offset) {
   if (file == NULL) {