1 /* Copyright (c) 2009-2010 by Daniel Stenberg
2 * Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
5 * Redistribution and use in source and binary forms,
6 * with or without modification, are permitted provided
7 * that the following conditions are met:
9 * Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
13 * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
18 * Neither the name of the copyright holder nor the names
19 * of any other contributors may be used to endorse or
20 * promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
39 #include "libssh2_priv.h"
47 /* Max. length of a quoted string after libssh2_shell_quotearg() processing */
48 #define _libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
51 This function quotes a string in a way suitable to be used with a
52 shell, e.g. the file name
57 The resulting output string is crafted in a way that makes it usable
58 with the two most common shell types: Bourne Shell derived shells
59 (sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh).
61 The following special cases are handled:
62 o If the string contains an apostrophy itself, the apostrophy
63 character is written in quotation marks, e.g. "'".
64 The shell cannot handle the syntax 'doesn\'t', so we close the
65 current argument word, add the apostrophe in quotation marks "",
66 and open a new argument word instead (_ indicate the input
71 Sequences of apostrophes are combined in one pair of quotation marks:
77 o If the string contains an exclamation mark (!), the C-Shell
78 interprets it as an event number. Using \! (not within quotation
79 marks or single quotation marks) is a mechanism understood by
80 both Bourne Shell and C-Shell.
82 If a quotation was already started, the argument word is closed
90 The result buffer must be large enough for the expanded result. A
91 bad case regarding expansion is alternating characters and
94 a'b'c'd' (length 8) gets converted to
95 'a'"'"'b'"'"'c'"'"'d'"'" (length 24)
97 This is the worst case.
99 Maximum length of the result:
100 1 + 6 * (length(input) + 1) / 2) + 1
102 => 3 * length(input) + 2
106 o one character / apostrophe pair (two characters) can get
107 represented as 6 characters: a' -> a'"'"'
108 o String terminator (+1)
110 A result buffer three times the size of the input buffer + 2
111 characters should be safe.
114 o csh-compatible quotation (special handling for '!' etc.), see
115 http://www.grymoire.com/Unix/Csh.html#toc-uh-10
118 Length of the resulting string (not counting the terminating '\0'),
119 or 0 in case of errors, e.g. result buffer too small
121 Note: this function could possible be used elsewhere within libssh2, but
122 until then it is kept static and in this source file.
126 shell_quotearg(const char *path
, unsigned char *buf
,
130 unsigned char *dst
, *endp
;
134 * UQSTRING: unquoted string: ... -- used for quoting exclamation
135 * marks. This is the initial state
136 * SQSTRING: single-quoted-string: '... -- any character may follow
137 * QSTRING: quoted string: "... -- only apostrophes may follow
139 enum { UQSTRING
, SQSTRING
, QSTRING
} state
= UQSTRING
;
141 endp
= &buf
[bufsize
];
144 while (*src
&& dst
< endp
- 1) {
148 * Special handling for apostrophe.
149 * An apostrophe is always written in quotation marks, e.g.
155 case UQSTRING
: /* Unquoted string */
160 case QSTRING
: /* Continue quoted string */
162 case SQSTRING
: /* Close single quoted string */
175 * Special handling for exclamation marks. CSH interprets
176 * exclamation marks even when quoted with apostrophes. We convert
177 * it to the plain string \!, because both Bourne Shell and CSH
178 * interpret that as a verbatim exclamation mark.
191 *dst
++ = '"'; /* Closing quotation mark */
194 case SQSTRING
: /* Close single quoted string */
207 * Ordinary character: prefer single-quoted string
220 *dst
++ = '"'; /* Closing quotation mark */
223 case SQSTRING
: /* Continue single quoted string */
228 state
= SQSTRING
; /* Start single-quoted string */
240 case QSTRING
: /* Close quoted string */
245 case SQSTRING
: /* Close single quoted string */
258 /* The result cannot be larger than 3 * strlen(path) + 2 */
259 /* assert((dst - buf) <= (3 * (src - path) + 2)); */
267 * Open a channel and request a remote file via SCP
270 static LIBSSH2_CHANNEL
*
271 scp_recv(LIBSSH2_SESSION
* session
, const char *path
, libssh2_struct_stat
* sb
)
276 const char *tmp_err_msg
;
278 if (session
->scpRecv_state
== libssh2_NB_state_idle
) {
279 session
->scpRecv_mode
= 0;
280 session
->scpRecv_size
= 0;
281 session
->scpRecv_mtime
= 0;
282 session
->scpRecv_atime
= 0;
284 session
->scpRecv_command_len
=
285 _libssh2_shell_quotedsize(path
) + sizeof("scp -f ") + (sb
?1:0);
287 session
->scpRecv_command
=
288 LIBSSH2_ALLOC(session
, session
->scpRecv_command_len
);
290 if (!session
->scpRecv_command
) {
291 _libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
292 "Unable to allocate a command buffer for "
297 snprintf((char *)session
->scpRecv_command
,
298 session
->scpRecv_command_len
,
299 "scp -%sf ", sb
?"p":"");
301 cmd_len
= strlen((char *)session
->scpRecv_command
);
302 cmd_len
+= shell_quotearg(path
,
303 &session
->scpRecv_command
[cmd_len
],
304 session
->scpRecv_command_len
- cmd_len
);
306 session
->scpRecv_command
[cmd_len
] = '\0';
307 session
->scpRecv_command_len
= cmd_len
+ 1;
309 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
,
310 "Opening channel for SCP receive");
312 session
->scpRecv_state
= libssh2_NB_state_created
;
315 if (session
->scpRecv_state
== libssh2_NB_state_created
) {
316 /* Allocate a channel */
317 session
->scpRecv_channel
=
318 _libssh2_channel_open(session
, "session",
319 sizeof("session") - 1,
320 LIBSSH2_CHANNEL_WINDOW_DEFAULT
,
321 LIBSSH2_CHANNEL_PACKET_DEFAULT
, NULL
,
323 if (!session
->scpRecv_channel
) {
324 if (libssh2_session_last_errno(session
) !=
325 LIBSSH2_ERROR_EAGAIN
) {
326 LIBSSH2_FREE(session
, session
->scpRecv_command
);
327 session
->scpRecv_command
= NULL
;
328 session
->scpRecv_state
= libssh2_NB_state_idle
;
331 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
332 "Would block starting up channel");
337 session
->scpRecv_state
= libssh2_NB_state_sent
;
340 if (session
->scpRecv_state
== libssh2_NB_state_sent
) {
341 /* Request SCP for the desired file */
342 rc
= _libssh2_channel_process_startup(session
->scpRecv_channel
, "exec",
344 (char *) session
->scpRecv_command
,
345 session
->scpRecv_command_len
);
346 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
347 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
348 "Would block requesting SCP startup");
351 LIBSSH2_FREE(session
, session
->scpRecv_command
);
352 session
->scpRecv_command
= NULL
;
355 LIBSSH2_FREE(session
, session
->scpRecv_command
);
356 session
->scpRecv_command
= NULL
;
358 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
, "Sending initial wakeup");
360 session
->scpRecv_response
[0] = '\0';
362 session
->scpRecv_state
= libssh2_NB_state_sent1
;
365 if (session
->scpRecv_state
== libssh2_NB_state_sent1
) {
366 rc
= _libssh2_channel_write(session
->scpRecv_channel
, 0,
367 session
->scpRecv_response
, 1);
368 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
369 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
370 "Would block sending initial wakeup");
372 } else if (rc
!= 1) {
376 /* Parse SCP response */
377 session
->scpRecv_response_len
= 0;
379 session
->scpRecv_state
= libssh2_NB_state_sent2
;
382 if ((session
->scpRecv_state
== libssh2_NB_state_sent2
)
383 || (session
->scpRecv_state
== libssh2_NB_state_sent3
)) {
384 while (sb
&& (session
->scpRecv_response_len
<
385 LIBSSH2_SCP_RESPONSE_BUFLEN
)) {
386 unsigned char *s
, *p
;
388 if (session
->scpRecv_state
== libssh2_NB_state_sent2
) {
389 rc
= _libssh2_channel_read(session
->scpRecv_channel
, 0,
392 session
->scpRecv_response_len
, 1);
393 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
394 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
395 "Would block waiting for SCP response");
400 _libssh2_error(session
, rc
, "Failed reading SCP response");
404 goto scp_recv_empty_channel
;
406 session
->scpRecv_response_len
++;
408 if (session
->scpRecv_response
[0] != 'T') {
416 The following string MUST be newline terminated
419 _libssh2_channel_packet_data_len(session
->
421 err_msg
= LIBSSH2_ALLOC(session
, err_len
+ 1);
423 _libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
424 "Failed to get memory ");
428 /* Read the remote error message */
429 (void)_libssh2_channel_read(session
->scpRecv_channel
, 0,
431 /* If it failed for any reason, we ignore it anyway. */
433 /* zero terminate the error */
436 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
,
437 "got %02x %s", session
->scpRecv_response
[0],
440 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
441 "Failed to recv file");
443 LIBSSH2_FREE(session
, err_msg
);
447 if ((session
->scpRecv_response_len
> 1) &&
449 scpRecv_response
[session
->scpRecv_response_len
- 1] <
452 scpRecv_response
[session
->scpRecv_response_len
- 1] >
455 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
458 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
461 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
463 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
464 "Invalid data in SCP response");
468 if ((session
->scpRecv_response_len
< 9)
470 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
472 if (session
->scpRecv_response_len
==
473 LIBSSH2_SCP_RESPONSE_BUFLEN
) {
474 /* You had your chance */
475 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
476 "Unterminated response from SCP server");
479 /* Way too short to be an SCP response, or not done yet,
484 /* We're guaranteed not to go under response_len == 0 by the
487 scpRecv_response
[session
->scpRecv_response_len
- 1] ==
490 scpRecv_response
[session
->scpRecv_response_len
-
492 session
->scpRecv_response_len
--;
493 session
->scpRecv_response
[session
->scpRecv_response_len
] =
496 if (session
->scpRecv_response_len
< 8) {
497 /* EOL came too soon */
498 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
499 "Invalid response from SCP server, "
504 s
= session
->scpRecv_response
+ 1;
506 p
= (unsigned char *) strchr((char *) s
, ' ');
507 if (!p
|| ((p
- s
) <= 0)) {
508 /* No spaces or space in the wrong spot */
509 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
510 "Invalid response from SCP server, "
516 /* Make sure we don't get fooled by leftover values */
517 session
->scpRecv_mtime
= strtol((char *) s
, NULL
, 10);
519 s
= (unsigned char *) strchr((char *) p
, ' ');
520 if (!s
|| ((s
- p
) <= 0)) {
521 /* No spaces or space in the wrong spot */
522 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
523 "Invalid response from SCP server, malformed mtime.usec");
527 /* Ignore mtime.usec */
529 p
= (unsigned char *) strchr((char *) s
, ' ');
530 if (!p
|| ((p
- s
) <= 0)) {
531 /* No spaces or space in the wrong spot */
532 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
533 "Invalid response from SCP server, too short or malformed");
538 /* Make sure we don't get fooled by leftover values */
539 session
->scpRecv_atime
= strtol((char *) s
, NULL
, 10);
542 session
->scpRecv_response
[0] = '\0';
544 session
->scpRecv_state
= libssh2_NB_state_sent3
;
547 if (session
->scpRecv_state
== libssh2_NB_state_sent3
) {
548 rc
= _libssh2_channel_write(session
->scpRecv_channel
, 0,
549 session
->scpRecv_response
, 1);
550 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
551 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
552 "Would block waiting to send SCP ACK");
554 } else if (rc
!= 1) {
558 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
,
559 "mtime = %ld, atime = %ld",
560 session
->scpRecv_mtime
, session
->scpRecv_atime
);
562 /* We *should* check that atime.usec is valid, but why let
568 session
->scpRecv_state
= libssh2_NB_state_sent4
;
571 if (session
->scpRecv_state
== libssh2_NB_state_sent4
) {
572 session
->scpRecv_response_len
= 0;
574 session
->scpRecv_state
= libssh2_NB_state_sent5
;
577 if ((session
->scpRecv_state
== libssh2_NB_state_sent5
)
578 || (session
->scpRecv_state
== libssh2_NB_state_sent6
)) {
579 while (session
->scpRecv_response_len
< LIBSSH2_SCP_RESPONSE_BUFLEN
) {
580 char *s
, *p
, *e
= NULL
;
582 if (session
->scpRecv_state
== libssh2_NB_state_sent5
) {
583 rc
= _libssh2_channel_read(session
->scpRecv_channel
, 0,
586 session
->scpRecv_response_len
, 1);
587 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
588 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
589 "Would block waiting for SCP response");
594 _libssh2_error(session
, rc
, "Failed reading SCP response");
598 goto scp_recv_empty_channel
;
600 session
->scpRecv_response_len
++;
602 if (session
->scpRecv_response
[0] != 'C') {
603 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
604 "Invalid response from SCP server");
608 if ((session
->scpRecv_response_len
> 1) &&
610 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
613 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
617 scpRecv_response
[session
->scpRecv_response_len
- 1]
619 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
620 "Invalid data in SCP response");
624 if ((session
->scpRecv_response_len
< 7)
626 scpRecv_response
[session
->scpRecv_response_len
- 1] !=
628 if (session
->scpRecv_response_len
==
629 LIBSSH2_SCP_RESPONSE_BUFLEN
) {
630 /* You had your chance */
631 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
632 "Unterminated response from SCP server");
635 /* Way too short to be an SCP response, or not done yet,
640 /* We're guaranteed not to go under response_len == 0 by the
643 scpRecv_response
[session
->scpRecv_response_len
- 1] ==
646 scpRecv_response
[session
->scpRecv_response_len
-
648 session
->scpRecv_response_len
--;
650 session
->scpRecv_response
[session
->scpRecv_response_len
] =
653 if (session
->scpRecv_response_len
< 6) {
654 /* EOL came too soon */
655 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
656 "Invalid response from SCP server, too short");
660 s
= (char *) session
->scpRecv_response
+ 1;
663 if (!p
|| ((p
- s
) <= 0)) {
664 /* No spaces or space in the wrong spot */
665 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
666 "Invalid response from SCP server, malformed mode");
671 /* Make sure we don't get fooled by leftover values */
673 session
->scpRecv_mode
= strtol(s
, &e
, 8);
675 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
676 "Invalid response from SCP server, invalid mode");
681 if (!s
|| ((s
- p
) <= 0)) {
682 /* No spaces or space in the wrong spot */
683 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
684 "Invalid response from SCP server, too short or malformed");
689 /* Make sure we don't get fooled by leftover values */
690 session
->scpRecv_size
= scpsize_strtol(p
, &e
, 10);
692 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
693 "Invalid response from SCP server, invalid size");
698 session
->scpRecv_response
[0] = '\0';
700 session
->scpRecv_state
= libssh2_NB_state_sent6
;
703 if (session
->scpRecv_state
== libssh2_NB_state_sent6
) {
704 rc
= _libssh2_channel_write(session
->scpRecv_channel
, 0,
705 session
->scpRecv_response
, 1);
706 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
707 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
708 "Would block sending SCP ACK");
710 } else if (rc
!= 1) {
713 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
,
714 "mode = 0%lo size = %ld", session
->scpRecv_mode
,
715 session
->scpRecv_size
);
717 /* We *should* check that basename is valid, but why let that
723 session
->scpRecv_state
= libssh2_NB_state_sent7
;
727 memset(sb
, 0, sizeof(libssh2_struct_stat
));
729 sb
->st_mtime
= session
->scpRecv_mtime
;
730 sb
->st_atime
= session
->scpRecv_atime
;
731 sb
->st_size
= session
->scpRecv_size
;
732 sb
->st_mode
= (unsigned short)session
->scpRecv_mode
;
735 session
->scpRecv_state
= libssh2_NB_state_idle
;
736 return session
->scpRecv_channel
;
738 scp_recv_empty_channel
:
739 /* the code only jumps here as a result of a zero read from channel_read()
740 so we check EOF status to avoid getting stuck in a loop */
741 if(libssh2_channel_eof(session
->scpRecv_channel
))
742 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
743 "Unexpected channel close");
745 return session
->scpRecv_channel
;
748 tmp_err_code
= session
->err_code
;
749 tmp_err_msg
= session
->err_msg
;
750 while (libssh2_channel_free(session
->scpRecv_channel
) ==
751 LIBSSH2_ERROR_EAGAIN
);
752 session
->err_code
= tmp_err_code
;
753 session
->err_msg
= tmp_err_msg
;
754 session
->scpRecv_channel
= NULL
;
755 session
->scpRecv_state
= libssh2_NB_state_idle
;
764 * Open a channel and request a remote file via SCP. This receives files larger
765 * than 2 GB, but is unable to report the proper size on platforms where the
766 * st_size member of struct stat is limited to 2 GB (e.g. windows).
769 LIBSSH2_API LIBSSH2_CHANNEL
*
770 libssh2_scp_recv(LIBSSH2_SESSION
*session
, const char *path
, struct stat
* sb
)
772 LIBSSH2_CHANNEL
*ptr
;
774 /* scp_recv uses libssh2_struct_stat, so pass one if the caller gave us a struct to populate... */
775 libssh2_struct_stat sb_intl
;
776 libssh2_struct_stat
*sb_ptr
;
777 sb_ptr
= sb
? &sb_intl
: NULL
;
779 BLOCK_ADJUST_ERRNO(ptr
, session
, scp_recv(session
, path
, sb_ptr
));
781 /* ...and populate the caller's with as much info as fits. */
783 memset(sb
, 0, sizeof(struct stat
));
785 sb
->st_mtime
= sb_intl
.st_mtime
;
786 sb
->st_atime
= sb_intl
.st_atime
;
787 sb
->st_size
= (off_t
)sb_intl
.st_size
;
788 sb
->st_mode
= sb_intl
.st_mode
;
797 * Open a channel and request a remote file via SCP. This supports files > 2GB
798 * on platforms that support it.
801 LIBSSH2_API LIBSSH2_CHANNEL
*
802 libssh2_scp_recv2(LIBSSH2_SESSION
*session
, const char *path
, libssh2_struct_stat
* sb
)
804 LIBSSH2_CHANNEL
*ptr
;
805 BLOCK_ADJUST_ERRNO(ptr
, session
, scp_recv(session
, path
, sb
));
812 * Send a file using SCP
815 static LIBSSH2_CHANNEL
*
816 scp_send(LIBSSH2_SESSION
* session
, const char *path
, int mode
,
817 libssh2_int64_t size
, time_t mtime
, time_t atime
)
822 const char *tmp_err_msg
;
824 if (session
->scpSend_state
== libssh2_NB_state_idle
) {
825 session
->scpSend_command_len
=
826 _libssh2_shell_quotedsize(path
) + sizeof("scp -t ") +
827 ((mtime
|| atime
)?1:0);
829 session
->scpSend_command
=
830 LIBSSH2_ALLOC(session
, session
->scpSend_command_len
);
832 if (!session
->scpSend_command
) {
833 _libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
834 "Unable to allocate a command buffer for "
839 snprintf((char *)session
->scpSend_command
,
840 session
->scpSend_command_len
,
841 "scp -%st ", (mtime
|| atime
)?"p":"");
843 cmd_len
= strlen((char *)session
->scpSend_command
);
844 cmd_len
+= shell_quotearg(path
,
845 &session
->scpSend_command
[cmd_len
],
846 session
->scpSend_command_len
- cmd_len
);
848 session
->scpSend_command
[cmd_len
] = '\0';
849 session
->scpSend_command_len
= cmd_len
+ 1;
851 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
,
852 "Opening channel for SCP send");
853 /* Allocate a channel */
855 session
->scpSend_state
= libssh2_NB_state_created
;
858 if (session
->scpSend_state
== libssh2_NB_state_created
) {
859 session
->scpSend_channel
=
860 _libssh2_channel_open(session
, "session", sizeof("session") - 1,
861 LIBSSH2_CHANNEL_WINDOW_DEFAULT
,
862 LIBSSH2_CHANNEL_PACKET_DEFAULT
, NULL
, 0);
863 if (!session
->scpSend_channel
) {
864 if (libssh2_session_last_errno(session
) != LIBSSH2_ERROR_EAGAIN
) {
865 /* previous call set libssh2_session_last_error(), pass it
867 LIBSSH2_FREE(session
, session
->scpSend_command
);
868 session
->scpSend_command
= NULL
;
869 session
->scpSend_state
= libssh2_NB_state_idle
;
872 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
873 "Would block starting up channel");
878 session
->scpSend_state
= libssh2_NB_state_sent
;
881 if (session
->scpSend_state
== libssh2_NB_state_sent
) {
882 /* Request SCP for the desired file */
883 rc
= _libssh2_channel_process_startup(session
->scpSend_channel
, "exec",
885 (char *) session
->scpSend_command
,
886 session
->scpSend_command_len
);
887 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
888 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
889 "Would block requesting SCP startup");
893 /* previous call set libssh2_session_last_error(), pass it
895 LIBSSH2_FREE(session
, session
->scpSend_command
);
896 session
->scpSend_command
= NULL
;
897 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
898 "Unknown error while getting error string");
901 LIBSSH2_FREE(session
, session
->scpSend_command
);
902 session
->scpSend_command
= NULL
;
904 session
->scpSend_state
= libssh2_NB_state_sent1
;
907 if (session
->scpSend_state
== libssh2_NB_state_sent1
) {
909 rc
= _libssh2_channel_read(session
->scpSend_channel
, 0,
910 (char *) session
->scpSend_response
, 1);
911 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
912 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
913 "Would block waiting for response from remote");
917 _libssh2_error(session
, rc
, "SCP failure");
921 /* remain in the same state */
922 goto scp_send_empty_channel
;
923 else if (session
->scpSend_response
[0] != 0) {
924 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
925 "Invalid ACK response from remote");
928 if (mtime
|| atime
) {
929 /* Send mtime and atime to be used for file */
930 session
->scpSend_response_len
=
931 snprintf((char *) session
->scpSend_response
,
932 LIBSSH2_SCP_RESPONSE_BUFLEN
, "T%ld 0 %ld 0\n",
933 (long)mtime
, (long)atime
);
934 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
, "Sent %s",
935 session
->scpSend_response
);
938 session
->scpSend_state
= libssh2_NB_state_sent2
;
941 /* Send mtime and atime to be used for file */
942 if (mtime
|| atime
) {
943 if (session
->scpSend_state
== libssh2_NB_state_sent2
) {
944 rc
= _libssh2_channel_write(session
->scpSend_channel
, 0,
945 session
->scpSend_response
,
946 session
->scpSend_response_len
);
947 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
948 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
949 "Would block sending time data for SCP file");
951 } else if (rc
!= (int)session
->scpSend_response_len
) {
952 _libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
953 "Unable to send time data for SCP file");
957 session
->scpSend_state
= libssh2_NB_state_sent3
;
960 if (session
->scpSend_state
== libssh2_NB_state_sent3
) {
962 rc
= _libssh2_channel_read(session
->scpSend_channel
, 0,
963 (char *) session
->scpSend_response
, 1);
964 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
965 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
966 "Would block waiting for response");
970 _libssh2_error(session
, rc
, "SCP failure");
974 /* remain in the same state */
975 goto scp_send_empty_channel
;
976 else if (session
->scpSend_response
[0] != 0) {
977 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
978 "Invalid SCP ACK response");
982 session
->scpSend_state
= libssh2_NB_state_sent4
;
985 if (session
->scpSend_state
== libssh2_NB_state_sent2
) {
986 session
->scpSend_state
= libssh2_NB_state_sent4
;
990 if (session
->scpSend_state
== libssh2_NB_state_sent4
) {
991 /* Send mode, size, and basename */
992 const char *base
= strrchr(path
, '/');
998 session
->scpSend_response_len
=
999 snprintf((char *) session
->scpSend_response
,
1000 LIBSSH2_SCP_RESPONSE_BUFLEN
, "C0%o %"
1001 LIBSSH2_INT64_T_FORMAT
" %s\n", mode
,
1003 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
, "Sent %s",
1004 session
->scpSend_response
);
1006 session
->scpSend_state
= libssh2_NB_state_sent5
;
1009 if (session
->scpSend_state
== libssh2_NB_state_sent5
) {
1010 rc
= _libssh2_channel_write(session
->scpSend_channel
, 0,
1011 session
->scpSend_response
,
1012 session
->scpSend_response_len
);
1013 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
1014 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
1015 "Would block send core file data for SCP file");
1017 } else if (rc
!= (int)session
->scpSend_response_len
) {
1018 _libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1019 "Unable to send core file data for SCP file");
1020 goto scp_send_error
;
1023 session
->scpSend_state
= libssh2_NB_state_sent6
;
1026 if (session
->scpSend_state
== libssh2_NB_state_sent6
) {
1028 rc
= _libssh2_channel_read(session
->scpSend_channel
, 0,
1029 (char *) session
->scpSend_response
, 1);
1030 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
1031 _libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
1032 "Would block waiting for response");
1036 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
1037 "Invalid ACK response from remote");
1038 goto scp_send_error
;
1041 goto scp_send_empty_channel
;
1043 else if (session
->scpSend_response
[0] != 0) {
1048 _libssh2_channel_packet_data_len(session
->scpSend_channel
, 0);
1049 err_msg
= LIBSSH2_ALLOC(session
, err_len
+ 1);
1051 _libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1052 "failed to get memory");
1053 goto scp_send_error
;
1056 /* Read the remote error message */
1057 rc
= _libssh2_channel_read(session
->scpSend_channel
, 0,
1061 _libssh2_debug(session
, LIBSSH2_TRACE_SCP
,
1062 "got %02x %s", session
->scpSend_response
[0],
1065 LIBSSH2_FREE(session
, err_msg
);
1066 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
1067 "failed to send file");
1068 goto scp_send_error
;
1072 session
->scpSend_state
= libssh2_NB_state_idle
;
1073 return session
->scpSend_channel
;
1075 scp_send_empty_channel
:
1076 /* the code only jumps here as a result of a zero read from channel_read()
1077 so we check EOF status to avoid getting stuck in a loop */
1078 if(libssh2_channel_eof(session
->scpSend_channel
)) {
1079 _libssh2_error(session
, LIBSSH2_ERROR_SCP_PROTOCOL
,
1080 "Unexpected channel close");
1083 return session
->scpSend_channel
;
1086 tmp_err_code
= session
->err_code
;
1087 tmp_err_msg
= session
->err_msg
;
1088 while (libssh2_channel_free(session
->scpSend_channel
) ==
1089 LIBSSH2_ERROR_EAGAIN
);
1090 session
->err_code
= tmp_err_code
;
1091 session
->err_msg
= tmp_err_msg
;
1092 session
->scpSend_channel
= NULL
;
1093 session
->scpSend_state
= libssh2_NB_state_idle
;
1098 * libssh2_scp_send_ex
1100 * Send a file using SCP. Old API.
1102 LIBSSH2_API LIBSSH2_CHANNEL
*
1103 libssh2_scp_send_ex(LIBSSH2_SESSION
*session
, const char *path
, int mode
,
1104 size_t size
, long mtime
, long atime
)
1106 LIBSSH2_CHANNEL
*ptr
;
1107 BLOCK_ADJUST_ERRNO(ptr
, session
,
1108 scp_send(session
, path
, mode
, size
,
1109 (time_t)mtime
, (time_t)atime
));
1114 * libssh2_scp_send64
1116 * Send a file using SCP
1118 LIBSSH2_API LIBSSH2_CHANNEL
*
1119 libssh2_scp_send64(LIBSSH2_SESSION
*session
, const char *path
, int mode
,
1120 libssh2_int64_t size
, time_t mtime
, time_t atime
)
1122 LIBSSH2_CHANNEL
*ptr
;
1123 BLOCK_ADJUST_ERRNO(ptr
, session
,
1124 scp_send(session
, path
, mode
, size
, mtime
, atime
));