1 /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
4 * Redistribution and use in source and binary forms,
5 * with or without modification, are permitted provided
6 * that the following conditions are met:
8 * Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the
10 * following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * Neither the name of the copyright holder nor the names
18 * of any other contributors may be used to endorse or
19 * promote products derived from this software without
20 * specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
38 #include "libssh2_priv.h"
42 /* {{{ libssh2_scp_recv
43 * Open a channel and request a remote file via SCP
45 * NOTE: Will block in a busy loop on error. This has to be done,
46 * otherwise the blocking error code would erase the true
49 LIBSSH2_API LIBSSH2_CHANNEL
*
50 libssh2_scp_recv(LIBSSH2_SESSION
* session
, const char *path
, struct stat
* sb
)
52 int path_len
= strlen(path
);
55 if (session
->scpRecv_state
== libssh2_NB_state_idle
) {
56 session
->scpRecv_mode
= 0;
57 session
->scpRecv_size
= 0;
58 session
->scpRecv_mtime
= 0;
59 session
->scpRecv_atime
= 0;
61 session
->scpRecv_command_len
= path_len
+ sizeof("scp -f ");
64 session
->scpRecv_command_len
++;
67 session
->scpRecv_command
=
68 LIBSSH2_ALLOC(session
, session
->scpRecv_command_len
);
69 if (!session
->scpRecv_command
) {
70 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
71 "Unable to allocate a command buffer for SCP session",
76 memcpy(session
->scpRecv_command
, "scp -pf ",
77 sizeof("scp -pf ") - 1);
78 memcpy(session
->scpRecv_command
+ sizeof("scp -pf ") - 1, path
,
81 memcpy(session
->scpRecv_command
, "scp -f ", sizeof("scp -f ") - 1);
82 memcpy(session
->scpRecv_command
+ sizeof("scp -f ") - 1, path
,
85 session
->scpRecv_command
[session
->scpRecv_command_len
- 1] = '\0';
87 _libssh2_debug(session
, LIBSSH2_DBG_SCP
,
88 "Opening channel for SCP receive");
90 session
->scpRecv_state
= libssh2_NB_state_created
;
93 if (session
->scpRecv_state
== libssh2_NB_state_created
) {
94 /* Allocate a channel */
96 session
->scpRecv_channel
=
97 libssh2_channel_open_ex(session
, "session",
98 sizeof("session") - 1,
99 LIBSSH2_CHANNEL_WINDOW_DEFAULT
,
100 LIBSSH2_CHANNEL_PACKET_DEFAULT
, NULL
,
102 if (!session
->scpRecv_channel
) {
103 if (libssh2_session_last_errno(session
) !=
104 LIBSSH2_ERROR_EAGAIN
) {
105 LIBSSH2_FREE(session
, session
->scpRecv_command
);
106 session
->scpRecv_command
= NULL
;
107 session
->scpRecv_state
= libssh2_NB_state_idle
;
109 } else if (libssh2_session_last_errno(session
) ==
110 LIBSSH2_ERROR_EAGAIN
) {
111 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
112 "Would block starting up channel", 0);
116 } while (!session
->scpRecv_channel
);
118 session
->scpRecv_state
= libssh2_NB_state_sent
;
121 if (session
->scpRecv_state
== libssh2_NB_state_sent
) {
122 /* Request SCP for the desired file */
123 rc
= libssh2_channel_process_startup(session
->scpRecv_channel
, "exec",
125 (char *) session
->scpRecv_command
,
126 session
->scpRecv_command_len
);
127 if (rc
== PACKET_EAGAIN
) {
128 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
129 "Would block requesting SCP startup", 0);
132 LIBSSH2_FREE(session
, session
->scpRecv_command
);
133 session
->scpRecv_command
= NULL
;
136 LIBSSH2_FREE(session
, session
->scpRecv_command
);
137 session
->scpRecv_command
= NULL
;
139 _libssh2_debug(session
, LIBSSH2_DBG_SCP
, "Sending initial wakeup");
141 session
->scpRecv_response
[0] = '\0';
143 session
->scpRecv_state
= libssh2_NB_state_sent1
;
146 if (session
->scpRecv_state
== libssh2_NB_state_sent1
) {
147 rc
= libssh2_channel_write_ex(session
->scpRecv_channel
, 0,
148 (char *) session
->scpRecv_response
, 1);
149 if (rc
== PACKET_EAGAIN
) {
150 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
151 "Would block sending initial wakeup", 0);
153 } else if (rc
!= 1) {
157 /* Parse SCP response */
158 session
->scpRecv_response_len
= 0;
160 session
->scpRecv_state
= libssh2_NB_state_sent2
;
163 if ((session
->scpRecv_state
== libssh2_NB_state_sent2
)
164 || (session
->scpRecv_state
== libssh2_NB_state_sent3
)) {
166 && (session
->scpRecv_response_len
<
167 LIBSSH2_SCP_RESPONSE_BUFLEN
)) {
168 unsigned char *s
, *p
;
170 if (session
->scpRecv_state
== libssh2_NB_state_sent2
) {
171 rc
= libssh2_channel_read_ex(session
->scpRecv_channel
, 0,
174 session
->scpRecv_response_len
, 1);
175 if (rc
== PACKET_EAGAIN
) {
176 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
177 "Would block waiting for SCP response", 0);
179 } else if (rc
<= 0) {
180 /* Timeout, give up */
181 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
182 "Timed out waiting for SCP response", 0);
185 session
->scpRecv_response_len
++;
187 if (session
->scpRecv_response
[0] != 'T') {
189 * Set this as the default error for here, if
190 * we are successful it will be replaced
192 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
193 "Invalid data in SCP response, missing Time data",
196 session
->scpRecv_err_len
=
197 libssh2_channel_packet_data_len(session
->
199 session
->scpRecv_err_msg
=
200 LIBSSH2_ALLOC(session
, session
->scpRecv_err_len
+ 1);
201 if (!session
->scpRecv_err_msg
) {
204 memset(session
->scpRecv_err_msg
, 0,
205 session
->scpRecv_err_len
+ 1);
207 /* Read the remote error message */
208 rc
= libssh2_channel_read_ex(session
->scpRecv_channel
, 0,
209 session
->scpRecv_err_msg
,
210 session
->scpRecv_err_len
);
213 * Since we have alread started reading this packet, it is
214 * already in the systems so it can't return PACKET_EAGAIN
216 LIBSSH2_FREE(session
, session
->scpRecv_err_msg
);
217 session
->scpRecv_err_msg
= NULL
;
218 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
219 "Unknown error while getting error string",
224 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
225 session
->scpRecv_err_msg
, 1);
226 session
->scpRecv_err_msg
= NULL
;
230 if ((session
->scpRecv_response_len
> 1) &&
232 scpRecv_response
[session
->scpRecv_response_len
- 1] <
235 scpRecv_response
[session
->scpRecv_response_len
- 1] >
238 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
241 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
244 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
246 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
247 "Invalid data in SCP response", 0);
251 if ((session
->scpRecv_response_len
< 9)
253 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
255 if (session
->scpRecv_response_len
==
256 LIBSSH2_SCP_RESPONSE_BUFLEN
) {
257 /* You had your chance */
258 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
259 "Unterminated response from SCP server",
263 /* Way too short to be an SCP response, or not done yet, short circuit */
267 /* We're guaranteed not to go under response_len == 0 by the logic above */
269 scpRecv_response
[session
->scpRecv_response_len
- 1] ==
272 scpRecv_response
[session
->scpRecv_response_len
-
274 session
->scpRecv_response_len
--;
275 session
->scpRecv_response
[session
->scpRecv_response_len
] =
278 if (session
->scpRecv_response_len
< 8) {
279 /* EOL came too soon */
280 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
281 "Invalid response from SCP server, too short",
286 s
= session
->scpRecv_response
+ 1;
288 p
= (unsigned char *) strchr((char *) s
, ' ');
289 if (!p
|| ((p
- s
) <= 0)) {
290 /* No spaces or space in the wrong spot */
291 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
292 "Invalid response from SCP server, malformed mtime",
298 /* Make sure we don't get fooled by leftover values */
300 session
->scpRecv_mtime
= strtol((char *) s
, NULL
, 10);
302 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
303 "Invalid response from SCP server, invalid mtime",
307 s
= (unsigned char *) strchr((char *) p
, ' ');
308 if (!s
|| ((s
- p
) <= 0)) {
309 /* No spaces or space in the wrong spot */
310 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
311 "Invalid response from SCP server, malformed mtime.usec",
316 /* Ignore mtime.usec */
318 p
= (unsigned char *) strchr((char *) s
, ' ');
319 if (!p
|| ((p
- s
) <= 0)) {
320 /* No spaces or space in the wrong spot */
321 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
322 "Invalid response from SCP server, too short or malformed",
328 /* Make sure we don't get fooled by leftover values */
330 session
->scpRecv_atime
= strtol((char *) s
, NULL
, 10);
332 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
333 "Invalid response from SCP server, invalid atime",
339 session
->scpRecv_response
[0] = '\0';
341 session
->scpRecv_state
= libssh2_NB_state_sent3
;
344 if (session
->scpRecv_state
== libssh2_NB_state_sent3
) {
345 rc
= libssh2_channel_write_ex(session
->scpRecv_channel
, 0,
347 scpRecv_response
, 1);
348 if (rc
== PACKET_EAGAIN
) {
349 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
350 "Would block waiting to send SCP ACK", 0);
352 } else if (rc
!= 1) {
356 _libssh2_debug(session
, LIBSSH2_DBG_SCP
,
357 "mtime = %ld, atime = %ld",
358 session
->scpRecv_mtime
, session
->scpRecv_atime
);
360 /* We *should* check that atime.usec is valid, but why let that stop use? */
365 session
->scpRecv_state
= libssh2_NB_state_sent4
;
368 if (session
->scpRecv_state
== libssh2_NB_state_sent4
) {
369 session
->scpRecv_response_len
= 0;
371 session
->scpRecv_state
= libssh2_NB_state_sent5
;
374 if ((session
->scpRecv_state
== libssh2_NB_state_sent5
)
375 || (session
->scpRecv_state
== libssh2_NB_state_sent6
)) {
376 while (session
->scpRecv_response_len
< LIBSSH2_SCP_RESPONSE_BUFLEN
) {
377 char *s
, *p
, *e
= NULL
;
379 if (session
->scpRecv_state
== libssh2_NB_state_sent5
) {
380 rc
= libssh2_channel_read_ex(session
->scpRecv_channel
, 0,
383 session
->scpRecv_response_len
, 1);
384 if (rc
== PACKET_EAGAIN
) {
385 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
386 "Would block waiting for SCP response", 0);
388 } else if (rc
<= 0) {
389 /* Timeout, give up */
390 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
391 "Timed out waiting for SCP response", 0);
394 session
->scpRecv_response_len
++;
396 if (session
->scpRecv_response
[0] != 'C') {
397 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
398 "Invalid response from SCP server", 0);
402 if ((session
->scpRecv_response_len
> 1) &&
404 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
407 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
411 scpRecv_response
[session
->scpRecv_response_len
- 1] < 32)
413 scpRecv_response
[session
->scpRecv_response_len
- 1] >
415 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
416 "Invalid data in SCP response", 0);
420 if ((session
->scpRecv_response_len
< 7)
422 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
424 if (session
->scpRecv_response_len
==
425 LIBSSH2_SCP_RESPONSE_BUFLEN
) {
426 /* You had your chance */
427 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
428 "Unterminated response from SCP server",
432 /* Way too short to be an SCP response, or not done yet, short circuit */
436 /* We're guaranteed not to go under response_len == 0 by the logic above */
438 scpRecv_response
[session
->scpRecv_response_len
- 1] ==
441 scpRecv_response
[session
->scpRecv_response_len
-
443 session
->scpRecv_response_len
--;
445 session
->scpRecv_response
[session
->scpRecv_response_len
] =
448 if (session
->scpRecv_response_len
< 6) {
449 /* EOL came too soon */
450 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
451 "Invalid response from SCP server, too short",
456 s
= (char *) session
->scpRecv_response
+ 1;
459 if (!p
|| ((p
- s
) <= 0)) {
460 /* No spaces or space in the wrong spot */
461 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
462 "Invalid response from SCP server, malformed mode",
468 /* Make sure we don't get fooled by leftover values */
470 session
->scpRecv_mode
= strtol(s
, &e
, 8);
471 if ((e
&& *e
) || errno
) {
472 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
473 "Invalid response from SCP server, invalid mode",
479 if (!s
|| ((s
- p
) <= 0)) {
480 /* No spaces or space in the wrong spot */
481 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
482 "Invalid response from SCP server, too short or malformed",
488 /* Make sure we don't get fooled by leftover values */
490 session
->scpRecv_size
= strtol(p
, &e
, 10);
491 if ((e
&& *e
) || errno
) {
492 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
493 "Invalid response from SCP server, invalid size",
499 session
->scpRecv_response
[0] = '\0';
501 session
->scpRecv_state
= libssh2_NB_state_sent6
;
504 if (session
->scpRecv_state
== libssh2_NB_state_sent6
) {
505 rc
= libssh2_channel_write_ex(session
->scpRecv_channel
, 0,
507 scpRecv_response
, 1);
508 if (rc
== PACKET_EAGAIN
) {
509 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
510 "Would block sending SCP ACK", 0);
512 } else if (rc
!= 1) {
515 _libssh2_debug(session
, LIBSSH2_DBG_SCP
,
516 "mode = 0%lo size = %ld", session
->scpRecv_mode
,
517 session
->scpRecv_size
);
519 /* We *should* check that basename is valid, but why let that stop us? */
524 session
->scpRecv_state
= libssh2_NB_state_sent7
;
528 memset(sb
, 0, sizeof(struct stat
));
530 sb
->st_mtime
= session
->scpRecv_mtime
;
531 sb
->st_atime
= session
->scpRecv_atime
;
532 sb
->st_size
= session
->scpRecv_size
;
533 sb
->st_mode
= session
->scpRecv_mode
;
536 session
->scpRecv_state
= libssh2_NB_state_idle
;
537 return session
->scpRecv_channel
;
540 while (libssh2_channel_free(session
->scpRecv_channel
) == PACKET_EAGAIN
);
541 session
->scpRecv_channel
= NULL
;
542 session
->scpRecv_state
= libssh2_NB_state_idle
;
548 /* {{{ libssh2_scp_send_ex
549 * Send a file using SCP
551 * NOTE: Will block in a busy loop on error. This has to be done,
552 * otherwise the blocking error code would erase the true
553 * cause of the error.
555 LIBSSH2_API LIBSSH2_CHANNEL
*
556 libssh2_scp_send_ex(LIBSSH2_SESSION
* session
, const char *path
, int mode
,
557 size_t size
, long mtime
, long atime
)
559 int path_len
= strlen(path
);
560 unsigned const char *base
;
563 if (session
->scpSend_state
== libssh2_NB_state_idle
) {
564 session
->scpSend_command_len
= path_len
+ sizeof("scp -t ");
566 if (mtime
|| atime
) {
567 session
->scpSend_command_len
++;
570 session
->scpSend_command
=
571 LIBSSH2_ALLOC(session
, session
->scpSend_command_len
);
572 if (!session
->scpSend_command
) {
573 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
574 "Unable to allocate a command buffer for scp session",
579 if (mtime
|| atime
) {
580 memcpy(session
->scpSend_command
, "scp -pt ",
581 sizeof("scp -pt ") - 1);
582 memcpy(session
->scpSend_command
+ sizeof("scp -pt ") - 1, path
,
585 memcpy(session
->scpSend_command
, "scp -t ", sizeof("scp -t ") - 1);
586 memcpy(session
->scpSend_command
+ sizeof("scp -t ") - 1, path
,
589 session
->scpSend_command
[session
->scpSend_command_len
- 1] = '\0';
591 _libssh2_debug(session
, LIBSSH2_DBG_SCP
,
592 "Opening channel for SCP send");
593 /* Allocate a channel */
595 session
->scpSend_state
= libssh2_NB_state_created
;
598 if (session
->scpSend_state
== libssh2_NB_state_created
) {
599 session
->scpSend_channel
=
600 libssh2_channel_open_ex(session
, "session", sizeof("session") - 1,
601 LIBSSH2_CHANNEL_WINDOW_DEFAULT
,
602 LIBSSH2_CHANNEL_PACKET_DEFAULT
, NULL
, 0);
603 if (!session
->scpSend_channel
) {
604 if (libssh2_session_last_errno(session
) != LIBSSH2_ERROR_EAGAIN
) {
605 /* previous call set libssh2_session_last_error(), pass it through */
606 LIBSSH2_FREE(session
, session
->scpSend_command
);
607 session
->scpSend_command
= NULL
;
608 session
->scpSend_state
= libssh2_NB_state_idle
;
610 } else if (libssh2_session_last_errno(session
) ==
611 LIBSSH2_ERROR_EAGAIN
) {
612 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
613 "Would block starting up channel", 0);
618 session
->scpSend_state
= libssh2_NB_state_sent
;
621 if (session
->scpSend_state
== libssh2_NB_state_sent
) {
622 /* Request SCP for the desired file */
623 rc
= libssh2_channel_process_startup(session
->scpSend_channel
, "exec",
625 (char *) session
->scpSend_command
,
626 session
->scpSend_command_len
);
627 if (rc
== PACKET_EAGAIN
) {
628 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
629 "Would block requesting SCP startup", 0);
632 /* previous call set libssh2_session_last_error(), pass it through */
633 LIBSSH2_FREE(session
, session
->scpSend_command
);
634 session
->scpSend_command
= NULL
;
635 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
636 "Unknown error while getting error string", 0);
639 LIBSSH2_FREE(session
, session
->scpSend_command
);
640 session
->scpSend_command
= NULL
;
642 session
->scpSend_state
= libssh2_NB_state_sent1
;
645 if (session
->scpSend_state
== libssh2_NB_state_sent1
) {
647 rc
= libssh2_channel_read_ex(session
->scpSend_channel
, 0,
648 (char *) session
->scpSend_response
, 1);
649 if (rc
== PACKET_EAGAIN
) {
650 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
651 "Would block waiting for response from remote", 0);
653 } else if ((rc
<= 0) || (session
->scpSend_response
[0] != 0)) {
654 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
655 "Invalid ACK response from remote", 0);
659 if (mtime
|| atime
) {
660 /* Send mtime and atime to be used for file */
661 session
->scpSend_response_len
=
662 snprintf((char *) session
->scpSend_response
,
663 LIBSSH2_SCP_RESPONSE_BUFLEN
, "T%ld 0 %ld 0\n", mtime
,
665 _libssh2_debug(session
, LIBSSH2_DBG_SCP
, "Sent %s",
666 session
->scpSend_response
);
669 session
->scpSend_state
= libssh2_NB_state_sent2
;
672 /* Send mtime and atime to be used for file */
673 if (mtime
|| atime
) {
674 if (session
->scpSend_state
== libssh2_NB_state_sent2
) {
675 rc
= libssh2_channel_write_ex(session
->scpSend_channel
, 0,
676 (char *) session
->scpSend_response
,
677 session
->scpSend_response_len
);
678 if (rc
== PACKET_EAGAIN
) {
679 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
680 "Would block sending time data for SCP file", 0);
682 } else if (rc
!= session
->scpSend_response_len
) {
683 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
684 "Unable to send time data for SCP file", 0);
688 session
->scpSend_state
= libssh2_NB_state_sent3
;
691 if (session
->scpSend_state
== libssh2_NB_state_sent3
) {
693 rc
= libssh2_channel_read_ex(session
->scpSend_channel
, 0,
694 (char *) session
->scpSend_response
,
696 if (rc
== PACKET_EAGAIN
) {
697 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
698 "Would block waiting for response", 0);
700 } else if ((rc
<= 0) || (session
->scpSend_response
[0] != 0)) {
701 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
702 "Invalid ACK response from remote", 0);
706 session
->scpSend_state
= libssh2_NB_state_sent4
;
709 if (session
->scpSend_state
== libssh2_NB_state_sent2
) {
710 session
->scpSend_state
= libssh2_NB_state_sent4
;
714 if (session
->scpSend_state
== libssh2_NB_state_sent4
) {
715 /* Send mode, size, and basename */
716 base
= (unsigned char *) strrchr(path
, '/');
720 base
= (unsigned char *) path
;
723 session
->scpSend_response_len
=
724 snprintf((char *) session
->scpSend_response
,
725 LIBSSH2_SCP_RESPONSE_BUFLEN
, "C0%o %lu %s\n", mode
,
726 (unsigned long) size
, base
);
727 _libssh2_debug(session
, LIBSSH2_DBG_SCP
, "Sent %s",
728 session
->scpSend_response
);
730 session
->scpSend_state
= libssh2_NB_state_sent5
;
733 if (session
->scpSend_state
== libssh2_NB_state_sent5
) {
734 rc
= libssh2_channel_write_ex(session
->scpSend_channel
, 0,
735 (char *) session
->scpSend_response
,
736 session
->scpSend_response_len
);
737 if (rc
== PACKET_EAGAIN
) {
738 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
739 "Would block send core file data for SCP file", 0);
741 } else if (rc
!= session
->scpSend_response_len
) {
742 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
743 "Unable to send core file data for SCP file", 0);
747 session
->scpSend_state
= libssh2_NB_state_sent6
;
750 if (session
->scpSend_state
== libssh2_NB_state_sent6
) {
752 rc
= libssh2_channel_read_ex(session
->scpSend_channel
, 0,
753 (char *) session
->scpSend_response
, 1);
754 if (rc
== PACKET_EAGAIN
) {
755 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
756 "Would block waiting for response", 0);
758 } else if (rc
<= 0) {
759 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
760 "Invalid ACK response from remote", 0);
762 } else if (session
->scpSend_response
[0] != 0) {
764 * Set this as the default error for here, if
765 * we are successful it will be replaced
767 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
768 "Invalid ACK response from remote", 0);
770 session
->scpSend_err_len
=
771 libssh2_channel_packet_data_len(session
->scpSend_channel
, 0);
772 session
->scpSend_err_msg
=
773 LIBSSH2_ALLOC(session
, session
->scpSend_err_len
+ 1);
774 if (!session
->scpSend_err_msg
) {
777 memset(session
->scpSend_err_msg
, 0, session
->scpSend_err_len
+ 1);
779 /* Read the remote error message */
780 rc
= libssh2_channel_read_ex(session
->scpSend_channel
, 0,
781 session
->scpSend_err_msg
,
782 session
->scpSend_err_len
);
785 * Since we have alread started reading this packet, it is
786 * already in the systems so it can't return PACKET_EAGAIN
788 LIBSSH2_FREE(session
, session
->scpSend_err_msg
);
789 session
->scpSend_err_msg
= NULL
;
793 libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
794 session
->scpSend_err_msg
, 1);
795 session
->scpSend_err_msg
= NULL
;
800 session
->scpSend_state
= libssh2_NB_state_idle
;
802 return session
->scpSend_channel
;
805 while (libssh2_channel_free(session
->scpSend_channel
) == PACKET_EAGAIN
);
806 session
->scpSend_channel
= NULL
;
807 session
->scpSend_state
= libssh2_NB_state_idle
;