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"
39 #include "libssh2_sftp.h"
41 /* Note: Version 6 was documented at the time of writing
42 * However it was marked as "DO NOT IMPLEMENT" due to pending changes
44 * This release of libssh2 implements Version 5 with automatic downgrade
45 * based on server's declaration
48 /* SFTP packet types */
49 #define SSH_FXP_INIT 1
50 #define SSH_FXP_VERSION 2
51 #define SSH_FXP_OPEN 3
52 #define SSH_FXP_CLOSE 4
53 #define SSH_FXP_READ 5
54 #define SSH_FXP_WRITE 6
55 #define SSH_FXP_LSTAT 7
56 #define SSH_FXP_FSTAT 8
57 #define SSH_FXP_SETSTAT 9
58 #define SSH_FXP_FSETSTAT 10
59 #define SSH_FXP_OPENDIR 11
60 #define SSH_FXP_READDIR 12
61 #define SSH_FXP_REMOVE 13
62 #define SSH_FXP_MKDIR 14
63 #define SSH_FXP_RMDIR 15
64 #define SSH_FXP_REALPATH 16
65 #define SSH_FXP_STAT 17
66 #define SSH_FXP_RENAME 18
67 #define SSH_FXP_READLINK 19
68 #define SSH_FXP_SYMLINK 20
69 #define SSH_FXP_STATUS 101
70 #define SSH_FXP_HANDLE 102
71 #define SSH_FXP_DATA 103
72 #define SSH_FXP_NAME 104
73 #define SSH_FXP_ATTRS 105
74 #define SSH_FXP_EXTENDED 200
75 #define SSH_FXP_EXTENDED_REPLY 201
77 #define LIBSSH2_SFTP_HANDLE_FILE 0
78 #define LIBSSH2_SFTP_HANDLE_DIR 1
81 #define LIBSSH2_SFTP_ATTR_PFILETYPE_FILE 0100000
83 #define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000
85 /* {{{ libssh2_sftp_packet_add
86 * Add a packet to the SFTP packet brigade
89 libssh2_sftp_packet_add(LIBSSH2_SFTP
* sftp
, unsigned char *data
,
90 unsigned long data_len
)
92 LIBSSH2_SESSION
*session
= sftp
->channel
->session
;
93 LIBSSH2_PACKET
*packet
;
95 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Received packet %d",
97 packet
= LIBSSH2_ALLOC(session
, sizeof(LIBSSH2_PACKET
));
99 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
100 "Unable to allocate datablock for SFTP packet", 0);
103 memset(packet
, 0, sizeof(LIBSSH2_PACKET
));
106 packet
->data_len
= data_len
;
107 packet
->data_head
= 5;
108 packet
->brigade
= &sftp
->packets
;
110 packet
->prev
= sftp
->packets
.tail
;
112 packet
->prev
->next
= packet
;
114 sftp
->packets
.head
= packet
;
116 sftp
->packets
.tail
= packet
;
123 /* {{{ libssh2_sftp_packet_read
124 * Frame an SFTP packet off the channel
127 libssh2_sftp_packet_read(LIBSSH2_SFTP
* sftp
, int flush
)
129 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
130 LIBSSH2_SESSION
*session
= channel
->session
;
131 unsigned char buffer
[4]; /* To store the packet length */
132 unsigned char *packet
;
133 unsigned long packet_len
, packet_received
;
134 ssize_t bytes_received
;
137 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Waiting for packet");
139 if (flush
&& sftp
->partial_packet
) {
140 /* When flushing, remove previous partial */
141 LIBSSH2_FREE(session
, sftp
->partial_packet
);
142 sftp
->partial_packet
= NULL
;
145 /* If there was a previous partial, start using it */
146 if (sftp
->partial_packet
) {
147 packet
= sftp
->partial_packet
;
148 packet_len
= sftp
->partial_len
;
149 packet_received
= sftp
->partial_received
;
150 sftp
->partial_packet
= NULL
;
152 if (flush
&& session
->socket_block
&& !libssh2_waitsocket(session
, 0)) {
153 /* While flushing in blocking mode, check before reading */
156 rc
= libssh2_channel_read_ex(channel
, 0, (char *) buffer
, 4);
157 if (flush
&& (rc
< 0)) {
158 /* When flushing, exit quickly */
160 } else if (rc
== PACKET_EAGAIN
) {
161 return PACKET_EAGAIN
;
162 } else if (4 != rc
) {
163 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
164 "Timeout waiting for FXP packet", 0);
168 packet_len
= libssh2_ntohu32(buffer
);
169 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
170 "Data begin - Packet Length: %lu", packet_len
);
171 if (packet_len
> LIBSSH2_SFTP_PACKET_MAXLEN
) {
172 libssh2_error(session
, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED
,
173 "SFTP packet too large", 0);
177 packet
= LIBSSH2_ALLOC(session
, packet_len
);
179 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
180 "Unable to allocate SFTP packet", 0);
187 /* Read as much of the packet as we can */
188 while (packet_len
> packet_received
) {
190 libssh2_channel_read_ex(channel
, 0,
191 (char *) packet
+ packet_received
,
192 packet_len
- packet_received
);
194 if (flush
&& (bytes_received
< 0)) {
196 /* When flushing, remove packet if existing */
197 LIBSSH2_FREE(session
, packet
);
199 /* When flushing, exit quickly */
201 } else if (bytes_received
== PACKET_EAGAIN
) {
203 * We received EAGAIN, save what we have and
204 * return to EAGAIN to the caller
206 sftp
->partial_packet
= packet
;
207 sftp
->partial_len
= packet_len
;
208 sftp
->partial_received
= packet_received
;
211 return PACKET_EAGAIN
;
212 } else if (bytes_received
< 0) {
213 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
214 "Receive error waiting for SFTP packet", 0);
215 LIBSSH2_FREE(session
, packet
);
218 packet_received
+= bytes_received
;
221 if (libssh2_sftp_packet_add(sftp
, packet
, packet_len
)) {
222 LIBSSH2_FREE(session
, packet
);
231 /* {{{ libssh2_sftp_packet_ask
232 * A la libssh2_packet_ask()
235 libssh2_sftp_packet_ask(LIBSSH2_SFTP
* sftp
, unsigned char packet_type
,
236 unsigned long request_id
, unsigned char **data
,
237 unsigned long *data_len
, int poll_channel
)
239 LIBSSH2_SESSION
*session
= sftp
->channel
->session
;
240 LIBSSH2_PACKET
*packet
= sftp
->packets
.head
;
241 unsigned char match_buf
[5];
244 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Asking for %d packet",
247 int ret
= libssh2_sftp_packet_read(sftp
, 0);
248 if (ret
== PACKET_EAGAIN
) {
249 return PACKET_EAGAIN
;
250 } else if (ret
< 0) {
255 match_buf
[0] = packet_type
;
256 if (packet_type
== SSH_FXP_VERSION
) {
257 /* Special consideration when matching VERSION packet */
260 libssh2_htonu32(match_buf
+ 1, request_id
);
264 if (strncmp((char *) packet
->data
, (char *) match_buf
, match_len
) == 0) {
265 *data
= packet
->data
;
266 *data_len
= packet
->data_len
;
269 packet
->prev
->next
= packet
->next
;
271 sftp
->packets
.head
= packet
->next
;
275 packet
->next
->prev
= packet
->prev
;
277 sftp
->packets
.tail
= packet
->prev
;
280 LIBSSH2_FREE(session
, packet
);
284 packet
= packet
->next
;
291 /* {{{ libssh2_sftp_packet_require
292 * A la libssh2_packet_require
295 libssh2_sftp_packet_require(LIBSSH2_SFTP
* sftp
, unsigned char packet_type
,
296 unsigned long request_id
, unsigned char **data
,
297 unsigned long *data_len
)
299 LIBSSH2_SESSION
*session
= sftp
->channel
->session
;
302 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Requiring %d packet",
305 if (libssh2_sftp_packet_ask
306 (sftp
, packet_type
, request_id
, data
, data_len
, 0) == 0) {
307 /* The right packet was available in the packet brigade */
311 while (session
->socket_state
== LIBSSH2_SOCKET_CONNECTED
) {
312 ret
= libssh2_sftp_packet_read(sftp
, 0);
313 if (ret
== PACKET_EAGAIN
) {
314 return PACKET_EAGAIN
;
315 } else if (ret
<= 0) {
319 if (packet_type
== ret
) {
320 /* Be lazy, let packet_ask pull it out of the brigade */
321 return libssh2_sftp_packet_ask(sftp
, packet_type
, request_id
, data
,
326 /* Only reached if the socket died */
332 /* {{{ libssh2_sftp_packet_requirev
333 * Requie one of N possible reponses
336 libssh2_sftp_packet_requirev(LIBSSH2_SFTP
* sftp
, int num_valid_responses
,
337 const unsigned char *valid_responses
,
338 unsigned long request_id
, unsigned char **data
,
339 unsigned long *data_len
)
345 * If no timeout is active, start a new one and flush
346 * any pending packets
348 if (sftp
->requirev_start
== 0) {
349 _libssh2_debug(sftp
->channel
->session
, LIBSSH2_DBG_SFTP
,
350 "_requirev(): Initialize timeout");
351 sftp
->requirev_start
= time(NULL
);
354 while (libssh2_sftp_packet_read(sftp
, 1) > 0);
357 while (sftp
->channel
->session
->socket_state
== LIBSSH2_SOCKET_CONNECTED
) {
358 for(i
= 0; i
< num_valid_responses
; i
++) {
359 if (libssh2_sftp_packet_ask
360 (sftp
, valid_responses
[i
], request_id
, data
, data_len
,
363 * Set to zero before all returns to say
364 * the timeout is not active
366 sftp
->requirev_start
= 0;
371 ret
= libssh2_sftp_packet_read(sftp
, 0);
372 if ((ret
< 0) && (ret
!= PACKET_EAGAIN
)) {
373 sftp
->requirev_start
= 0;
375 } else if (ret
<= 0) {
376 /* prevent busy-looping */
378 LIBSSH2_READ_TIMEOUT
- (time(NULL
) - sftp
->requirev_start
);
381 sftp
->requirev_start
= 0;
382 return PACKET_TIMEOUT
;
383 } else if (sftp
->channel
->session
->socket_block
384 && (libssh2_waitsocket(sftp
->channel
->session
, left
) <=
386 sftp
->requirev_start
= 0;
387 return PACKET_TIMEOUT
;
388 } else if (ret
== PACKET_EAGAIN
) {
389 return PACKET_EAGAIN
;
394 sftp
->requirev_start
= 0;
400 /* {{{ libssh2_sftp_attrsize
401 * Size that attr will occupy when turned into a bin struct
404 libssh2_sftp_attrsize(const LIBSSH2_SFTP_ATTRIBUTES
* attrs
)
406 int attrsize
= 4; /* flags(4) */
412 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_SIZE
)
414 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_UIDGID
)
416 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_PERMISSIONS
)
418 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_ACMODTIME
)
419 attrsize
+= 8; /* atime + mtime as u32 */
426 /* {{{ libssh2_sftp_attr2bin
427 * Populate attributes into an SFTP block
430 libssh2_sftp_attr2bin(unsigned char *p
, const LIBSSH2_SFTP_ATTRIBUTES
* attrs
)
432 unsigned char *s
= p
;
433 unsigned long flag_mask
=
434 LIBSSH2_SFTP_ATTR_SIZE
| LIBSSH2_SFTP_ATTR_UIDGID
|
435 LIBSSH2_SFTP_ATTR_PERMISSIONS
| LIBSSH2_SFTP_ATTR_ACMODTIME
;
437 /* TODO: When we add SFTP4+ functionality flag_mask can get additional bits */
440 libssh2_htonu32(s
, 0);
444 libssh2_htonu32(s
, attrs
->flags
& flag_mask
);
447 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_SIZE
) {
448 libssh2_htonu64(s
, attrs
->filesize
);
452 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_UIDGID
) {
453 libssh2_htonu32(s
, attrs
->uid
);
455 libssh2_htonu32(s
, attrs
->gid
);
459 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_PERMISSIONS
) {
460 libssh2_htonu32(s
, attrs
->permissions
);
464 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_ACMODTIME
) {
465 libssh2_htonu32(s
, attrs
->atime
);
467 libssh2_htonu32(s
, attrs
->mtime
);
476 /* {{{ libssh2_sftp_bin2attr
479 libssh2_sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES
* attrs
, const unsigned char *p
)
481 const unsigned char *s
= p
;
483 memset(attrs
, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES
));
484 attrs
->flags
= libssh2_ntohu32(s
);
487 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_SIZE
) {
488 attrs
->filesize
= libssh2_ntohu64(s
);
492 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_UIDGID
) {
493 attrs
->uid
= libssh2_ntohu32(s
);
495 attrs
->gid
= libssh2_ntohu32(s
);
499 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_PERMISSIONS
) {
500 attrs
->permissions
= libssh2_ntohu32(s
);
504 if (attrs
->flags
& LIBSSH2_SFTP_ATTR_ACMODTIME
) {
505 attrs
->atime
= libssh2_ntohu32(s
);
507 attrs
->mtime
= libssh2_ntohu32(s
);
520 LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor
);
522 /* {{{ libssh2_sftp_dtor
523 * Shutdown an SFTP stream when the channel closes
525 LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor
)
527 LIBSSH2_SFTP
*sftp
= (LIBSSH2_SFTP
*) (*channel_abstract
);
529 (void) session_abstract
;
532 /* Loop through handles closing them */
533 while (sftp
->handles
) {
534 libssh2_sftp_close_handle(sftp
->handles
);
537 /* Free the partial packet storage for libssh2_sftp_packet_read */
538 if (sftp
->partial_packet
) {
539 LIBSSH2_FREE(session
, sftp
->partial_packet
);
542 /* Free the packet storage for _libssh2_sftp_packet_readdir */
543 if (sftp
->readdir_packet
) {
544 LIBSSH2_FREE(session
, sftp
->readdir_packet
);
547 LIBSSH2_FREE(session
, sftp
);
552 /* {{{ libssh2_sftp_init
553 * Startup an SFTP session
555 * NOTE: Will block in a busy loop on error. This has to be done,
556 * otherwise the blocking error code would erase the true
557 * cause of the error.
559 LIBSSH2_API LIBSSH2_SFTP
*
560 libssh2_sftp_init(LIBSSH2_SESSION
* session
)
562 unsigned char *data
, *s
;
563 unsigned long data_len
;
566 if (session
->sftpInit_state
== libssh2_NB_state_idle
) {
567 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
568 "Initializing SFTP subsystem");
570 session
->sftpInit_sftp
= NULL
;
572 session
->sftpInit_state
= libssh2_NB_state_created
;
575 if (session
->sftpInit_state
== libssh2_NB_state_created
) {
576 session
->sftpInit_channel
=
577 libssh2_channel_open_ex(session
, "session", sizeof("session") - 1,
578 LIBSSH2_CHANNEL_WINDOW_DEFAULT
,
579 LIBSSH2_CHANNEL_PACKET_DEFAULT
, NULL
, 0);
580 if (!session
->sftpInit_channel
) {
581 if (libssh2_session_last_errno(session
) == LIBSSH2_ERROR_EAGAIN
) {
582 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
583 "Would block starting up channel", 0);
585 } else if (libssh2_session_last_errno(session
) !=
586 LIBSSH2_ERROR_EAGAIN
) {
587 libssh2_error(session
, LIBSSH2_ERROR_CHANNEL_FAILURE
,
588 "Unable to startup channel", 0);
589 session
->sftpInit_state
= libssh2_NB_state_idle
;
594 session
->sftpInit_state
= libssh2_NB_state_sent
;
597 if (session
->sftpInit_state
== libssh2_NB_state_sent
) {
598 rc
= libssh2_channel_process_startup(session
->sftpInit_channel
,
600 sizeof("subsystem") - 1, "sftp",
602 if (rc
== PACKET_EAGAIN
) {
603 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
604 "Would block to request SFTP subsystem", 0);
607 libssh2_error(session
, LIBSSH2_ERROR_CHANNEL_FAILURE
,
608 "Unable to request SFTP subsystem", 0);
609 goto sftp_init_error
;
612 session
->sftpInit_state
= libssh2_NB_state_sent1
;
615 if (session
->sftpInit_state
== libssh2_NB_state_sent1
) {
616 rc
= libssh2_channel_handle_extended_data2(session
->sftpInit_channel
,
617 LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE
);
618 if (rc
== PACKET_EAGAIN
) {
619 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
620 "Would block requesting handle extended data", 0);
624 session
->sftpInit_sftp
= LIBSSH2_ALLOC(session
, sizeof(LIBSSH2_SFTP
));
625 if (!session
->sftpInit_sftp
) {
626 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
627 "Unable to allocate a new SFTP structure", 0);
628 goto sftp_init_error
;
630 memset(session
->sftpInit_sftp
, 0, sizeof(LIBSSH2_SFTP
));
631 session
->sftpInit_sftp
->channel
= session
->sftpInit_channel
;
632 session
->sftpInit_sftp
->request_id
= 0;
634 libssh2_htonu32(session
->sftpInit_buffer
, 5);
635 session
->sftpInit_buffer
[4] = SSH_FXP_INIT
;
636 libssh2_htonu32(session
->sftpInit_buffer
+ 5, LIBSSH2_SFTP_VERSION
);
638 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
639 "Sending FXP_INIT packet advertising version %d support",
640 (int) LIBSSH2_SFTP_VERSION
);
642 session
->sftpInit_state
= libssh2_NB_state_sent2
;
645 if (session
->sftpInit_state
== libssh2_NB_state_sent2
) {
646 rc
= libssh2_channel_write_ex(session
->sftpInit_channel
, 0,
647 (char *) session
->sftpInit_buffer
, 9);
648 if (rc
== PACKET_EAGAIN
) {
649 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
650 "Would block sending SSH_FXP_INIT", 0);
652 } else if (9 != rc
) {
653 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
654 "Unable to send SSH_FXP_INIT", 0);
655 goto sftp_init_error
;
658 session
->sftpInit_state
= libssh2_NB_state_sent3
;
661 /* For initiallization we are requiring blocking, probably reasonable */
662 rc
= libssh2_sftp_packet_require(session
->sftpInit_sftp
, SSH_FXP_VERSION
,
663 0, &data
, &data_len
);
664 if (rc
== PACKET_EAGAIN
) {
665 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
666 "Would block waiting for response from SFTP subsystem",
670 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
671 "Timeout waiting for response from SFTP subsystem", 0);
672 goto sftp_init_error
;
675 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
676 "Invalid SSH_FXP_VERSION response", 0);
677 goto sftp_init_error
;
681 session
->sftpInit_sftp
->version
= libssh2_ntohu32(s
);
683 if (session
->sftpInit_sftp
->version
> LIBSSH2_SFTP_VERSION
) {
684 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
685 "Truncating remote SFTP version from %lu",
686 session
->sftpInit_sftp
->version
);
687 session
->sftpInit_sftp
->version
= LIBSSH2_SFTP_VERSION
;
689 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
690 "Enabling SFTP version %lu compatability",
691 session
->sftpInit_sftp
->version
);
692 while (s
< (data
+ data_len
)) {
693 unsigned char *extension_name
, *extension_data
;
694 unsigned long extname_len
, extdata_len
;
696 extname_len
= libssh2_ntohu32(s
);
701 extdata_len
= libssh2_ntohu32(s
);
706 /* TODO: Actually process extensions */
708 LIBSSH2_FREE(session
, data
);
710 /* Make sure that when the channel gets closed, the SFTP service is shut down too */
711 session
->sftpInit_sftp
->channel
->abstract
= session
->sftpInit_sftp
;
712 session
->sftpInit_sftp
->channel
->close_cb
= libssh2_sftp_dtor
;
714 session
->sftpInit_state
= libssh2_NB_state_idle
;
715 return session
->sftpInit_sftp
;
718 while (libssh2_channel_free(session
->sftpInit_channel
) == PACKET_EAGAIN
);
719 session
->sftpInit_channel
= NULL
;
720 if (session
->sftpInit_sftp
) {
721 LIBSSH2_FREE(session
, session
->sftpInit_sftp
);
722 session
->sftpInit_sftp
= NULL
;
724 session
->sftpInit_state
= libssh2_NB_state_idle
;
730 /* {{{ libssh2_sftp_shutdown
731 * Shutsdown the SFTP subsystem
734 libssh2_sftp_shutdown(LIBSSH2_SFTP
* sftp
)
737 * Make sure all memory used in the state variables are free
739 if (sftp
->partial_packet
) {
740 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->partial_packet
);
741 sftp
->partial_packet
= NULL
;
743 if (sftp
->open_packet
) {
744 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->open_packet
);
745 sftp
->open_packet
= NULL
;
747 if (sftp
->read_packet
) {
748 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->read_packet
);
749 sftp
->read_packet
= NULL
;
751 if (sftp
->readdir_packet
) {
752 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->readdir_packet
);
753 sftp
->readdir_packet
= NULL
;
755 if (sftp
->write_packet
) {
756 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->write_packet
);
757 sftp
->write_packet
= NULL
;
759 if (sftp
->fstat_packet
) {
760 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->fstat_packet
);
761 sftp
->fstat_packet
= NULL
;
763 if (sftp
->unlink_packet
) {
764 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->unlink_packet
);
765 sftp
->unlink_packet
= NULL
;
767 if (sftp
->rename_packet
) {
768 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->rename_packet
);
769 sftp
->rename_packet
= NULL
;
771 if (sftp
->mkdir_packet
) {
772 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->mkdir_packet
);
773 sftp
->mkdir_packet
= NULL
;
775 if (sftp
->rmdir_packet
) {
776 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->rmdir_packet
);
777 sftp
->rmdir_packet
= NULL
;
779 if (sftp
->stat_packet
) {
780 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->stat_packet
);
781 sftp
->stat_packet
= NULL
;
783 if (sftp
->symlink_packet
) {
784 LIBSSH2_FREE(sftp
->channel
->session
, sftp
->symlink_packet
);
785 sftp
->symlink_packet
= NULL
;
788 return libssh2_channel_free(sftp
->channel
);
793 /* *******************************
794 * SFTP File and Directory Ops *
795 ******************************* */
797 /* {{{ libssh2_sftp_open_ex
799 LIBSSH2_API LIBSSH2_SFTP_HANDLE
*
800 libssh2_sftp_open_ex(LIBSSH2_SFTP
* sftp
, const char *filename
,
801 unsigned int filename_len
, unsigned long flags
, long mode
,
804 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
805 LIBSSH2_SESSION
*session
= channel
->session
;
806 LIBSSH2_SFTP_HANDLE
*fp
;
807 LIBSSH2_SFTP_ATTRIBUTES attrs
= {
808 LIBSSH2_SFTP_ATTR_PERMISSIONS
, 0, 0, 0, 0, 0, 0
810 unsigned long data_len
;
811 unsigned char *data
, *s
;
812 static const unsigned char fopen_responses
[2] =
813 { SSH_FXP_HANDLE
, SSH_FXP_STATUS
};
816 if (sftp
->open_state
== libssh2_NB_state_idle
) {
817 /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + flags(4) */
818 sftp
->open_packet_len
= filename_len
+ 13 +
820 LIBSSH2_SFTP_OPENFILE
) ?
(4 +
821 libssh2_sftp_attrsize(&attrs
)) : 0);
823 s
= sftp
->open_packet
= LIBSSH2_ALLOC(session
, sftp
->open_packet_len
);
824 if (!sftp
->open_packet
) {
825 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
826 "Unable to allocate memory for FXP_OPEN or FXP_OPENDIR packet",
830 /* Filetype in SFTP 3 and earlier */
831 attrs
.permissions
= mode
|
833 LIBSSH2_SFTP_OPENFILE
) ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE
:
834 LIBSSH2_SFTP_ATTR_PFILETYPE_DIR
);
836 libssh2_htonu32(s
, sftp
->open_packet_len
- 4);
840 LIBSSH2_SFTP_OPENFILE
) ? SSH_FXP_OPEN
: SSH_FXP_OPENDIR
;
841 sftp
->open_request_id
= sftp
->request_id
++;
842 libssh2_htonu32(s
, sftp
->open_request_id
);
844 libssh2_htonu32(s
, filename_len
);
846 memcpy(s
, filename
, filename_len
);
848 if (open_type
== LIBSSH2_SFTP_OPENFILE
) {
849 libssh2_htonu32(s
, flags
);
851 s
+= libssh2_sftp_attr2bin(s
, &attrs
);
854 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Sending %s open request",
856 LIBSSH2_SFTP_OPENFILE
) ?
"file" : "directory");
858 sftp
->open_state
= libssh2_NB_state_created
;
861 if (sftp
->open_state
== libssh2_NB_state_created
) {
862 rc
= libssh2_channel_write_ex(channel
, 0, (char *) sftp
->open_packet
,
863 sftp
->open_packet_len
);
864 if (rc
== PACKET_EAGAIN
) {
865 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
866 "Would block sending FXP_OPEN or FXP_OPENDIR command",
869 } else if (sftp
->open_packet_len
!= rc
) {
870 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
871 "Unable to send FXP_OPEN or FXP_OPENDIR command", 0);
872 LIBSSH2_FREE(session
, sftp
->open_packet
);
873 sftp
->open_packet
= NULL
;
874 sftp
->open_state
= libssh2_NB_state_idle
;
877 LIBSSH2_FREE(session
, sftp
->open_packet
);
878 sftp
->open_packet
= NULL
;
880 sftp
->open_state
= libssh2_NB_state_sent
;
883 if (sftp
->open_state
== libssh2_NB_state_sent
) {
884 rc
= libssh2_sftp_packet_requirev(sftp
, 2, fopen_responses
,
885 sftp
->open_request_id
, &data
,
887 if (rc
== PACKET_EAGAIN
) {
888 libssh2_error(session
, LIBSSH2_ERROR_EAGAIN
,
889 "Would block waiting for status message", 0);
892 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
893 "Timeout waiting for status message", 0);
894 sftp
->open_state
= libssh2_NB_state_idle
;
899 sftp
->open_state
= libssh2_NB_state_idle
;
901 if (data
[0] == SSH_FXP_STATUS
) {
902 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
903 "Failed opening remote file", 0);
904 sftp
->last_errno
= libssh2_ntohu32(data
+ 5);
905 LIBSSH2_FREE(session
, data
);
909 fp
= LIBSSH2_ALLOC(session
, sizeof(LIBSSH2_SFTP_HANDLE
));
911 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
912 "Unable to allocate new SFTP handle structure", 0);
913 LIBSSH2_FREE(session
, data
);
916 memset(fp
, 0, sizeof(LIBSSH2_SFTP_HANDLE
));
919 LIBSSH2_SFTP_OPENFILE
) ? LIBSSH2_SFTP_HANDLE_FILE
:
920 LIBSSH2_SFTP_HANDLE_DIR
;
922 fp
->handle_len
= libssh2_ntohu32(data
+ 5);
923 if (fp
->handle_len
> 256) {
924 /* SFTP doesn't allow handles longer than 256 characters */
925 fp
->handle_len
= 256;
927 fp
->handle
= LIBSSH2_ALLOC(session
, fp
->handle_len
);
929 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
930 "Unable to allocate space for SFTP file/dir handle", 0);
931 LIBSSH2_FREE(session
, data
);
932 LIBSSH2_FREE(session
, fp
);
935 memcpy(fp
->handle
, data
+ 9, fp
->handle_len
);
936 LIBSSH2_FREE(session
, data
);
938 /* Link the file and the sftp session together */
939 fp
->next
= sftp
->handles
;
945 fp
->u
.file
.offset
= 0;
947 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Open command successful");
953 /* {{{ libssh2_sftp_read
954 * Read from an SFTP file handle
957 libssh2_sftp_read(LIBSSH2_SFTP_HANDLE
* handle
, char *buffer
,
958 size_t buffer_maxlen
)
960 LIBSSH2_SFTP
*sftp
= handle
->sftp
;
961 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
962 LIBSSH2_SESSION
*session
= channel
->session
;
963 unsigned long data_len
, request_id
;
964 /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + offset(8) + length(4) */
965 ssize_t packet_len
= handle
->handle_len
+ 25;
966 unsigned char *packet
, *s
, *data
;
967 static const unsigned char read_responses
[2] =
968 { SSH_FXP_DATA
, SSH_FXP_STATUS
};
969 size_t bytes_read
= 0;
970 size_t bytes_requested
= 0;
971 size_t total_read
= 0;
974 if (sftp
->read_state
== libssh2_NB_state_idle
) {
975 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
976 "Reading %lu bytes from SFTP handle",
977 (unsigned long) buffer_maxlen
);
978 packet
= LIBSSH2_ALLOC(session
, packet_len
);
980 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
981 "Unable to allocate memory for FXP_CLOSE packet", 0);
984 sftp
->read_state
= libssh2_NB_state_allocated
;
986 packet
= sftp
->read_packet
;
987 request_id
= sftp
->read_request_id
;
988 total_read
= sftp
->read_total_read
;
991 while (total_read
< buffer_maxlen
) {
994 * If buffer_maxlen bytes will be requested, server may return all
995 * with one packet. But libssh2 have packet length limit.
996 * So we request data by pieces.
998 bytes_requested
= buffer_maxlen
- total_read
;
999 /* 10 = packet_type(1)+request_id(4)+data_length(4)+end_of_line_flag(1) */
1000 if (bytes_requested
> LIBSSH2_SFTP_PACKET_MAXLEN
- 10) {
1001 bytes_requested
= LIBSSH2_SFTP_PACKET_MAXLEN
- 10;
1003 #ifdef LIBSSH2_DEBUG_SFTP
1004 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
1005 "Requesting %lu bytes from SFTP handle",
1006 (unsigned long) bytes_requested
);
1009 if (sftp
->read_state
== libssh2_NB_state_allocated
) {
1010 libssh2_htonu32(s
, packet_len
- 4);
1012 *(s
++) = SSH_FXP_READ
;
1013 request_id
= sftp
->request_id
++;
1014 libssh2_htonu32(s
, request_id
);
1016 libssh2_htonu32(s
, handle
->handle_len
);
1019 memcpy(s
, handle
->handle
, handle
->handle_len
);
1020 s
+= handle
->handle_len
;
1022 libssh2_htonu64(s
, handle
->u
.file
.offset
);
1025 libssh2_htonu32(s
, buffer_maxlen
);
1028 sftp
->read_state
= libssh2_NB_state_created
;
1031 if (sftp
->read_state
== libssh2_NB_state_created
) {
1033 libssh2_channel_write_ex(channel
, 0, (char *) packet
,
1035 if (retcode
== PACKET_EAGAIN
) {
1036 sftp
->read_packet
= packet
;
1037 sftp
->read_request_id
= request_id
;
1038 sftp
->read_total_read
= total_read
;
1039 return PACKET_EAGAIN
;
1040 } else if (packet_len
!= retcode
) {
1041 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1042 "Unable to send FXP_READ command", 0);
1043 LIBSSH2_FREE(session
, packet
);
1044 sftp
->read_packet
= NULL
;
1045 sftp
->read_state
= libssh2_NB_state_idle
;
1048 sftp
->read_packet
= packet
;
1049 sftp
->read_request_id
= request_id
;
1050 sftp
->read_total_read
= total_read
;
1051 sftp
->read_state
= libssh2_NB_state_sent
;
1054 if (sftp
->read_state
== libssh2_NB_state_sent
) {
1056 libssh2_sftp_packet_requirev(sftp
, 2, read_responses
,
1057 request_id
, &data
, &data_len
);
1058 if (retcode
== PACKET_EAGAIN
) {
1059 return PACKET_EAGAIN
;
1060 } else if (retcode
) {
1061 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1062 "Timeout waiting for status message", 0);
1063 LIBSSH2_FREE(session
, packet
);
1064 sftp
->read_packet
= NULL
;
1065 sftp
->read_state
= libssh2_NB_state_idle
;
1069 sftp
->read_state
= libssh2_NB_state_sent1
;
1073 case SSH_FXP_STATUS
:
1074 retcode
= libssh2_ntohu32(data
+ 5);
1075 LIBSSH2_FREE(session
, packet
);
1076 LIBSSH2_FREE(session
, data
);
1077 sftp
->read_packet
= NULL
;
1078 sftp
->read_state
= libssh2_NB_state_idle
;
1080 if (retcode
== LIBSSH2_FX_EOF
) {
1083 sftp
->last_errno
= retcode
;
1084 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1085 "SFTP Protocol Error", 0);
1090 bytes_read
= libssh2_ntohu32(data
+ 5);
1091 if (bytes_read
> (data_len
- 9)) {
1092 LIBSSH2_FREE(session
, packet
);
1093 sftp
->read_packet
= NULL
;
1094 sftp
->read_state
= libssh2_NB_state_idle
;
1097 #ifdef LIBSSH2_DEBUG_SFTP
1098 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "%lu bytes returned",
1099 (unsigned long) bytes_read
);
1101 memcpy(buffer
+ total_read
, data
+ 9, bytes_read
);
1102 handle
->u
.file
.offset
+= bytes_read
;
1103 total_read
+= bytes_read
;
1104 LIBSSH2_FREE(session
, data
);
1106 * Set the state back to allocated, so a new one will be
1107 * created to either request more data or get EOF
1109 sftp
->read_state
= libssh2_NB_state_allocated
;
1113 LIBSSH2_FREE(session
, packet
);
1114 sftp
->read_packet
= NULL
;
1115 sftp
->read_state
= libssh2_NB_state_idle
;
1121 /* {{{ libssh2_sftp_readdir
1122 * Read from an SFTP directory handle
1125 libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE
* handle
, char *buffer
,
1126 size_t buffer_maxlen
, char *longentry
,
1127 size_t longentry_maxlen
,
1128 LIBSSH2_SFTP_ATTRIBUTES
* attrs
)
1130 LIBSSH2_SFTP
*sftp
= handle
->sftp
;
1131 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1132 LIBSSH2_SESSION
*session
= channel
->session
;
1133 LIBSSH2_SFTP_ATTRIBUTES attrs_dummy
;
1134 unsigned long data_len
, filename_len
, longentry_len
, num_names
;
1135 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
1136 ssize_t packet_len
= handle
->handle_len
+ 13;
1137 unsigned char *s
, *data
;
1138 unsigned char read_responses
[2] = { SSH_FXP_NAME
, SSH_FXP_STATUS
};
1141 if (sftp
->readdir_state
== libssh2_NB_state_idle
) {
1142 if (handle
->u
.dir
.names_left
) {
1144 * A prior request returned more than one directory entry,
1145 * feed it back from the buffer
1147 unsigned char *s
= (unsigned char *) handle
->u
.dir
.next_name
;
1148 unsigned long real_filename_len
= libssh2_ntohu32(s
);
1150 filename_len
= real_filename_len
;
1152 if (filename_len
> buffer_maxlen
) {
1153 filename_len
= buffer_maxlen
;
1155 memcpy(buffer
, s
, filename_len
);
1156 s
+= real_filename_len
;
1158 /* The filename is not null terminated, make it so if possible */
1159 if (filename_len
< buffer_maxlen
) {
1160 buffer
[filename_len
] = '\0';
1163 if ((longentry
== NULL
) || (longentry_maxlen
== 0)) {
1165 s
+= 4 + libssh2_ntohu32(s
);
1167 unsigned long real_longentry_len
= libssh2_ntohu32(s
);
1169 longentry_len
= real_longentry_len
;
1171 if (longentry_len
> longentry_maxlen
) {
1172 longentry_len
= longentry_maxlen
;
1174 memcpy(longentry
, s
, longentry_len
);
1175 s
+= real_longentry_len
;
1177 /* The longentry is not null terminated, make it so if possible */
1178 if (longentry_len
< longentry_maxlen
) {
1179 longentry
[longentry_len
] = '\0';
1184 memset(attrs
, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES
));
1186 s
+= libssh2_sftp_bin2attr(attrs ? attrs
: &attrs_dummy
, s
);
1188 handle
->u
.dir
.next_name
= (char *) s
;
1189 if ((--handle
->u
.dir
.names_left
) == 0) {
1190 LIBSSH2_FREE(session
, handle
->u
.dir
.names_packet
);
1193 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
1194 "libssh2_sftp_readdir_ex() return %d",
1196 return filename_len
;
1199 /* Request another entry(entries?) */
1201 s
= sftp
->readdir_packet
= LIBSSH2_ALLOC(session
, packet_len
);
1202 if (!sftp
->readdir_packet
) {
1203 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1204 "Unable to allocate memory for FXP_READDIR packet",
1209 libssh2_htonu32(s
, packet_len
- 4);
1211 *(s
++) = SSH_FXP_READDIR
;
1212 sftp
->readdir_request_id
= sftp
->request_id
++;
1213 libssh2_htonu32(s
, sftp
->readdir_request_id
);
1215 libssh2_htonu32(s
, handle
->handle_len
);
1217 memcpy(s
, handle
->handle
, handle
->handle_len
);
1218 s
+= handle
->handle_len
;
1220 sftp
->readdir_state
= libssh2_NB_state_created
;
1223 if (sftp
->readdir_state
== libssh2_NB_state_created
) {
1224 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
1225 "Reading entries from directory handle");
1227 libssh2_channel_write_ex(channel
, 0,
1228 (char *) sftp
->readdir_packet
,
1229 packet_len
)) == PACKET_EAGAIN
) {
1230 return PACKET_EAGAIN
;
1231 } else if (packet_len
!= retcode
) {
1232 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1233 "Unable to send FXP_READ command", 0);
1234 LIBSSH2_FREE(session
, sftp
->readdir_packet
);
1235 sftp
->readdir_packet
= NULL
;
1236 sftp
->readdir_state
= libssh2_NB_state_idle
;
1240 LIBSSH2_FREE(session
, sftp
->readdir_packet
);
1241 sftp
->readdir_packet
= NULL
;
1243 sftp
->readdir_state
= libssh2_NB_state_sent
;
1247 libssh2_sftp_packet_requirev(sftp
, 2, read_responses
,
1248 sftp
->readdir_request_id
, &data
,
1250 if (retcode
== PACKET_EAGAIN
) {
1251 return PACKET_EAGAIN
;
1252 } else if (retcode
) {
1253 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1254 "Timeout waiting for status message", 0);
1255 sftp
->readdir_state
= libssh2_NB_state_idle
;
1259 if (data
[0] == SSH_FXP_STATUS
) {
1260 retcode
= libssh2_ntohu32(data
+ 5);
1261 LIBSSH2_FREE(session
, data
);
1262 if (retcode
== LIBSSH2_FX_EOF
) {
1263 sftp
->readdir_state
= libssh2_NB_state_idle
;
1266 sftp
->last_errno
= retcode
;
1267 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1268 "SFTP Protocol Error", 0);
1269 sftp
->readdir_state
= libssh2_NB_state_idle
;
1274 num_names
= libssh2_ntohu32(data
+ 5);
1275 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "%lu entries returned",
1277 if (num_names
<= 0) {
1278 LIBSSH2_FREE(session
, data
);
1279 sftp
->readdir_state
= libssh2_NB_state_idle
;
1280 return (num_names
== 0) ?
0 : -1;
1283 if (num_names
== 1) {
1284 unsigned long real_filename_len
= libssh2_ntohu32(data
+ 9);
1286 filename_len
= real_filename_len
;
1287 if (filename_len
> buffer_maxlen
) {
1288 filename_len
= buffer_maxlen
;
1290 memcpy(buffer
, data
+ 13, filename_len
);
1292 /* The filename is not null terminated, make it so if possible */
1293 if (filename_len
< buffer_maxlen
) {
1294 buffer
[filename_len
] = '\0';
1298 memset(attrs
, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES
));
1299 libssh2_sftp_bin2attr(attrs
, data
+ 13 + real_filename_len
+
1301 libssh2_ntohu32(data
+ 13 +
1302 real_filename_len
)));
1304 LIBSSH2_FREE(session
, data
);
1306 sftp
->readdir_state
= libssh2_NB_state_idle
;
1307 return filename_len
;
1310 handle
->u
.dir
.names_left
= num_names
;
1311 handle
->u
.dir
.names_packet
= data
;
1312 handle
->u
.dir
.next_name
= (char *) data
+ 9;
1314 sftp
->readdir_state
= libssh2_NB_state_idle
;
1316 /* Be lazy, just use the name popping mechanism from the start of the function */
1317 return libssh2_sftp_readdir_ex(handle
, buffer
, buffer_maxlen
, longentry
,
1318 longentry_maxlen
, attrs
);
1323 /* {{{ libssh2_sftp_write
1324 * Write data to a file handle
1327 libssh2_sftp_write(LIBSSH2_SFTP_HANDLE
* handle
, const char *buffer
,
1330 LIBSSH2_SFTP
*sftp
= handle
->sftp
;
1331 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1332 LIBSSH2_SESSION
*session
= channel
->session
;
1333 unsigned long data_len
, retcode
;
1334 /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + offset(8) + count(4) */
1335 ssize_t packet_len
= handle
->handle_len
+ count
+ 25;
1336 unsigned char *s
, *data
;
1339 if (sftp
->write_state
== libssh2_NB_state_idle
) {
1340 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Writing %lu bytes",
1341 (unsigned long) count
);
1342 s
= sftp
->write_packet
= LIBSSH2_ALLOC(session
, packet_len
);
1343 if (!sftp
->write_packet
) {
1344 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1345 "Unable to allocate memory for FXP_WRITE packet", 0);
1349 libssh2_htonu32(s
, packet_len
- 4);
1351 *(s
++) = SSH_FXP_WRITE
;
1352 sftp
->write_request_id
= sftp
->request_id
++;
1353 libssh2_htonu32(s
, sftp
->write_request_id
);
1355 libssh2_htonu32(s
, handle
->handle_len
);
1357 memcpy(s
, handle
->handle
, handle
->handle_len
);
1358 s
+= handle
->handle_len
;
1359 libssh2_htonu64(s
, handle
->u
.file
.offset
);
1361 libssh2_htonu32(s
, count
);
1363 memcpy(s
, buffer
, count
);
1366 sftp
->write_state
= libssh2_NB_state_created
;
1369 if (sftp
->write_state
== libssh2_NB_state_created
) {
1371 libssh2_channel_write_ex(channel
, 0, (char *) sftp
->write_packet
,
1372 packet_len
)) == PACKET_EAGAIN
) {
1373 return PACKET_EAGAIN
;
1375 if (packet_len
!= rc
) {
1376 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1377 "Unable to send FXP_READ command", 0);
1378 LIBSSH2_FREE(session
, sftp
->write_packet
);
1379 sftp
->write_packet
= NULL
;
1380 sftp
->write_state
= libssh2_NB_state_idle
;
1383 LIBSSH2_FREE(session
, sftp
->write_packet
);
1384 sftp
->write_packet
= NULL
;
1385 sftp
->write_state
= libssh2_NB_state_sent
;
1388 rc
= libssh2_sftp_packet_require(sftp
, SSH_FXP_STATUS
,
1389 sftp
->write_request_id
, &data
, &data_len
);
1390 if (rc
== PACKET_EAGAIN
) {
1391 return PACKET_EAGAIN
;
1393 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1394 "Timeout waiting for status message", 0);
1395 sftp
->write_state
= libssh2_NB_state_idle
;
1399 sftp
->write_state
= libssh2_NB_state_idle
;
1401 retcode
= libssh2_ntohu32(data
+ 5);
1402 LIBSSH2_FREE(session
, data
);
1404 if (retcode
== LIBSSH2_FX_OK
) {
1405 handle
->u
.file
.offset
+= count
;
1408 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
, "SFTP Protocol Error",
1410 sftp
->last_errno
= retcode
;
1417 /* {{{ libssh2_sftp_fstat_ex
1418 * Get or Set stat on a file
1421 libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE
* handle
,
1422 LIBSSH2_SFTP_ATTRIBUTES
* attrs
, int setstat
)
1424 LIBSSH2_SFTP
*sftp
= handle
->sftp
;
1425 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1426 LIBSSH2_SESSION
*session
= channel
->session
;
1427 unsigned long data_len
;
1428 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
1429 ssize_t packet_len
=
1430 handle
->handle_len
+ 13 + (setstat ?
libssh2_sftp_attrsize(attrs
) : 0);
1431 unsigned char *s
, *data
;
1432 static const unsigned char fstat_responses
[2] =
1433 { SSH_FXP_ATTRS
, SSH_FXP_STATUS
};
1436 if (sftp
->fstat_state
== libssh2_NB_state_idle
) {
1437 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Issuing %s command",
1438 setstat ?
"set-stat" : "stat");
1439 s
= sftp
->fstat_packet
= LIBSSH2_ALLOC(session
, packet_len
);
1440 if (!sftp
->fstat_packet
) {
1441 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1442 "Unable to allocate memory for FSTAT/FSETSTAT packet",
1447 libssh2_htonu32(s
, packet_len
- 4);
1449 *(s
++) = setstat ? SSH_FXP_FSETSTAT
: SSH_FXP_FSTAT
;
1450 sftp
->fstat_request_id
= sftp
->request_id
++;
1451 libssh2_htonu32(s
, sftp
->fstat_request_id
);
1453 libssh2_htonu32(s
, handle
->handle_len
);
1455 memcpy(s
, handle
->handle
, handle
->handle_len
);
1456 s
+= handle
->handle_len
;
1458 s
+= libssh2_sftp_attr2bin(s
, attrs
);
1461 sftp
->fstat_state
= libssh2_NB_state_created
;
1464 if (sftp
->fstat_state
== libssh2_NB_state_created
) {
1465 rc
= libssh2_channel_write_ex(channel
, 0, (char *) sftp
->fstat_packet
,
1467 if (rc
== PACKET_EAGAIN
) {
1468 return PACKET_EAGAIN
;
1469 } else if (packet_len
!= rc
) {
1470 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1471 setstat ?
(char *) "Unable to send FXP_FSETSTAT"
1472 : (char *) "Unable to send FXP_FSTAT command", 0);
1473 LIBSSH2_FREE(session
, sftp
->fstat_packet
);
1474 sftp
->fstat_packet
= NULL
;
1475 sftp
->fstat_state
= libssh2_NB_state_idle
;
1478 LIBSSH2_FREE(session
, sftp
->fstat_packet
);
1479 sftp
->fstat_packet
= NULL
;
1481 sftp
->fstat_state
= libssh2_NB_state_sent
;
1484 rc
= libssh2_sftp_packet_requirev(sftp
, 2, fstat_responses
,
1485 sftp
->fstat_request_id
, &data
,
1487 if (rc
== PACKET_EAGAIN
) {
1488 return PACKET_EAGAIN
;
1490 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1491 "Timeout waiting for status message", 0);
1492 sftp
->fstat_state
= libssh2_NB_state_idle
;
1496 sftp
->fstat_state
= libssh2_NB_state_idle
;
1498 if (data
[0] == SSH_FXP_STATUS
) {
1501 retcode
= libssh2_ntohu32(data
+ 5);
1502 LIBSSH2_FREE(session
, data
);
1503 if (retcode
== LIBSSH2_FX_OK
) {
1506 sftp
->last_errno
= retcode
;
1507 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1508 "SFTP Protocol Error", 0);
1513 libssh2_sftp_bin2attr(attrs
, data
+ 5);
1520 /* {{{ libssh2_sftp_seek
1521 * Set the read/write pointer to an arbitrary position within the file
1524 libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE
* handle
, size_t offset
)
1526 handle
->u
.file
.offset
= offset
;
1531 /* {{{ libssh2_sftp_tell
1532 * Return the current read/write pointer's offset
1535 libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE
* handle
)
1537 return handle
->u
.file
.offset
;
1543 /* {{{ libssh2_sftp_close_handle
1544 * Close a file or directory handle
1545 * Also frees handle resource and unlinks it from the SFTP structure
1548 libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE
* handle
)
1550 LIBSSH2_SFTP
*sftp
= handle
->sftp
;
1551 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1552 LIBSSH2_SESSION
*session
= channel
->session
;
1553 unsigned long data_len
, retcode
;
1554 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
1555 ssize_t packet_len
= handle
->handle_len
+ 13;
1556 unsigned char *s
, *data
;
1559 if (handle
->close_state
== libssh2_NB_state_idle
) {
1560 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Closing handle");
1561 s
= handle
->close_packet
= LIBSSH2_ALLOC(session
, packet_len
);
1562 if (!handle
->close_packet
) {
1563 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1564 "Unable to allocate memory for FXP_CLOSE packet", 0);
1568 libssh2_htonu32(s
, packet_len
- 4);
1570 *(s
++) = SSH_FXP_CLOSE
;
1571 handle
->close_request_id
= sftp
->request_id
++;
1572 libssh2_htonu32(s
, handle
->close_request_id
);
1574 libssh2_htonu32(s
, handle
->handle_len
);
1576 memcpy(s
, handle
->handle
, handle
->handle_len
);
1577 s
+= handle
->handle_len
;
1579 handle
->close_state
= libssh2_NB_state_created
;
1582 if (handle
->close_state
== libssh2_NB_state_created
) {
1583 rc
= libssh2_channel_write_ex(channel
, 0,
1584 (char *) handle
->close_packet
,
1586 if (rc
== PACKET_EAGAIN
) {
1587 return PACKET_EAGAIN
;
1588 } else if (packet_len
!= rc
) {
1589 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1590 "Unable to send FXP_CLOSE command", 0);
1591 LIBSSH2_FREE(session
, handle
->close_packet
);
1592 handle
->close_packet
= NULL
;
1593 handle
->close_state
= libssh2_NB_state_idle
;
1596 LIBSSH2_FREE(session
, handle
->close_packet
);
1597 handle
->close_packet
= NULL
;
1599 handle
->close_state
= libssh2_NB_state_sent
;
1602 if (handle
->close_state
== libssh2_NB_state_sent
) {
1603 rc
= libssh2_sftp_packet_require(sftp
, SSH_FXP_STATUS
,
1604 handle
->close_request_id
, &data
,
1606 if (rc
== PACKET_EAGAIN
) {
1607 return PACKET_EAGAIN
;
1609 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1610 "Timeout waiting for status message", 0);
1611 handle
->close_state
= libssh2_NB_state_idle
;
1615 handle
->close_state
= libssh2_NB_state_sent1
;
1618 retcode
= libssh2_ntohu32(data
+ 5);
1619 LIBSSH2_FREE(session
, data
);
1621 if (retcode
!= LIBSSH2_FX_OK
) {
1622 sftp
->last_errno
= retcode
;
1623 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1624 "SFTP Protocol Error", 0);
1625 handle
->close_state
= libssh2_NB_state_idle
;
1629 if (handle
== sftp
->handles
) {
1630 sftp
->handles
= handle
->next
;
1633 handle
->next
->prev
= NULL
;
1636 if ((handle
->handle_type
== LIBSSH2_SFTP_HANDLE_DIR
)
1637 && handle
->u
.dir
.names_left
) {
1638 LIBSSH2_FREE(session
, handle
->u
.dir
.names_packet
);
1641 handle
->close_state
= libssh2_NB_state_idle
;
1643 LIBSSH2_FREE(session
, handle
->handle
);
1644 LIBSSH2_FREE(session
, handle
);
1651 /* **********************
1652 * SFTP Miscellaneous *
1653 ********************** */
1655 /* {{{ libssh2_sftp_unlink_ex
1656 * Delete a file from the remote server
1658 /* libssh2_sftp_unlink_ex - NB-UNSAFE?? */
1660 libssh2_sftp_unlink_ex(LIBSSH2_SFTP
* sftp
, const char *filename
,
1661 unsigned int filename_len
)
1663 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1664 LIBSSH2_SESSION
*session
= channel
->session
;
1665 unsigned long data_len
, retcode
;
1666 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */
1667 ssize_t packet_len
= filename_len
+ 13;
1668 unsigned char *s
, *data
;
1671 if (sftp
->unlink_state
== libssh2_NB_state_idle
) {
1672 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Unlinking %s", filename
);
1673 s
= sftp
->unlink_packet
= LIBSSH2_ALLOC(session
, packet_len
);
1674 if (!sftp
->unlink_packet
) {
1675 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1676 "Unable to allocate memory for FXP_REMOVE packet",
1681 libssh2_htonu32(s
, packet_len
- 4);
1683 *(s
++) = SSH_FXP_REMOVE
;
1684 sftp
->unlink_request_id
= sftp
->request_id
++;
1685 libssh2_htonu32(s
, sftp
->unlink_request_id
);
1687 libssh2_htonu32(s
, filename_len
);
1689 memcpy(s
, filename
, filename_len
);
1692 sftp
->unlink_state
= libssh2_NB_state_created
;
1695 if (sftp
->unlink_state
== libssh2_NB_state_created
) {
1696 rc
= libssh2_channel_write_ex(channel
, 0, (char *) sftp
->unlink_packet
,
1698 if (rc
== PACKET_EAGAIN
) {
1699 return PACKET_EAGAIN
;
1700 } else if (packet_len
!= rc
) {
1701 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1702 "Unable to send FXP_REMOVE command", 0);
1703 LIBSSH2_FREE(session
, sftp
->unlink_packet
);
1704 sftp
->unlink_packet
= NULL
;
1705 sftp
->unlink_state
= libssh2_NB_state_idle
;
1708 LIBSSH2_FREE(session
, sftp
->unlink_packet
);
1709 sftp
->unlink_packet
= NULL
;
1711 sftp
->unlink_state
= libssh2_NB_state_sent
;
1714 rc
= libssh2_sftp_packet_require(sftp
, SSH_FXP_STATUS
,
1715 sftp
->unlink_request_id
, &data
,
1717 if (rc
== PACKET_EAGAIN
) {
1718 return PACKET_EAGAIN
;
1720 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1721 "Timeout waiting for status message", 0);
1722 sftp
->unlink_state
= libssh2_NB_state_idle
;
1726 sftp
->unlink_state
= libssh2_NB_state_idle
;
1728 retcode
= libssh2_ntohu32(data
+ 5);
1729 LIBSSH2_FREE(session
, data
);
1731 if (retcode
== LIBSSH2_FX_OK
) {
1734 sftp
->last_errno
= retcode
;
1735 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1736 "SFTP Protocol Error", 0);
1743 /* {{{ libssh2_sftp_rename_ex
1744 * Rename a file on the remote server
1747 libssh2_sftp_rename_ex(LIBSSH2_SFTP
* sftp
, const char *source_filename
,
1748 unsigned int source_filename_len
,
1749 const char *dest_filename
,
1750 unsigned int dest_filename_len
, long flags
)
1752 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1753 LIBSSH2_SESSION
*session
= channel
->session
;
1754 unsigned long data_len
, retcode
;
1755 ssize_t packet_len
=
1756 source_filename_len
+ dest_filename_len
+ 17 + (sftp
->version
>=
1758 /* packet_len(4) + packet_type(1) + request_id(4) +
1759 source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */
1760 unsigned char *data
;
1763 if (sftp
->version
< 2) {
1764 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1765 "Server does not support RENAME", 0);
1769 if (sftp
->rename_state
== libssh2_NB_state_idle
) {
1770 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Renaming %s to %s",
1771 source_filename
, dest_filename
);
1772 sftp
->rename_s
= sftp
->rename_packet
=
1773 LIBSSH2_ALLOC(session
, packet_len
);
1774 if (!sftp
->rename_packet
) {
1775 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1776 "Unable to allocate memory for FXP_RENAME packet",
1781 libssh2_htonu32(sftp
->rename_s
, packet_len
- 4);
1782 sftp
->rename_s
+= 4;
1783 *(sftp
->rename_s
++) = SSH_FXP_RENAME
;
1784 sftp
->rename_request_id
= sftp
->request_id
++;
1785 libssh2_htonu32(sftp
->rename_s
, sftp
->rename_request_id
);
1786 sftp
->rename_s
+= 4;
1787 libssh2_htonu32(sftp
->rename_s
, source_filename_len
);
1788 sftp
->rename_s
+= 4;
1789 memcpy(sftp
->rename_s
, source_filename
, source_filename_len
);
1790 sftp
->rename_s
+= source_filename_len
;
1791 libssh2_htonu32(sftp
->rename_s
, dest_filename_len
);
1792 sftp
->rename_s
+= 4;
1793 memcpy(sftp
->rename_s
, dest_filename
, dest_filename_len
);
1794 sftp
->rename_s
+= dest_filename_len
;
1796 if (sftp
->version
>= 5) {
1797 libssh2_htonu32(sftp
->rename_s
, flags
);
1798 sftp
->rename_s
+= 4;
1801 sftp
->rename_state
= libssh2_NB_state_created
;
1804 if (sftp
->rename_state
== libssh2_NB_state_created
) {
1805 rc
= libssh2_channel_write_ex(channel
, 0, (char *) sftp
->rename_packet
,
1806 sftp
->rename_s
- sftp
->rename_packet
);
1807 if (rc
== PACKET_EAGAIN
) {
1808 return PACKET_EAGAIN
;
1809 } else if (packet_len
!= rc
) {
1810 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1811 "Unable to send FXP_RENAME command", 0);
1812 LIBSSH2_FREE(session
, sftp
->rename_packet
);
1813 sftp
->rename_packet
= NULL
;
1814 sftp
->rename_state
= libssh2_NB_state_idle
;
1817 LIBSSH2_FREE(session
, sftp
->rename_packet
);
1818 sftp
->rename_packet
= NULL
;
1820 sftp
->rename_state
= libssh2_NB_state_sent
;
1823 rc
= libssh2_sftp_packet_require(sftp
, SSH_FXP_STATUS
,
1824 sftp
->rename_request_id
, &data
,
1826 if (rc
== PACKET_EAGAIN
) {
1827 return PACKET_EAGAIN
;
1829 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1830 "Timeout waiting for status message", 0);
1831 sftp
->rename_state
= libssh2_NB_state_idle
;
1835 sftp
->rename_state
= libssh2_NB_state_idle
;
1837 retcode
= libssh2_ntohu32(data
+ 5);
1838 LIBSSH2_FREE(session
, data
);
1845 case LIBSSH2_FX_FILE_ALREADY_EXISTS
:
1846 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1847 "File already exists and SSH_FXP_RENAME_OVERWRITE not specified",
1849 sftp
->last_errno
= retcode
;
1853 case LIBSSH2_FX_OP_UNSUPPORTED
:
1854 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1855 "Operation Not Supported", 0);
1856 sftp
->last_errno
= retcode
;
1861 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1862 "SFTP Protocol Error", 0);
1863 sftp
->last_errno
= retcode
;
1872 /* {{{ libssh2_sftp_mkdir_ex
1873 * Create an SFTP directory
1876 libssh2_sftp_mkdir_ex(LIBSSH2_SFTP
* sftp
, const char *path
,
1877 unsigned int path_len
, long mode
)
1879 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1880 LIBSSH2_SESSION
*session
= channel
->session
;
1881 LIBSSH2_SFTP_ATTRIBUTES attrs
= {
1882 LIBSSH2_SFTP_ATTR_PERMISSIONS
, 0, 0, 0, 0, 0, 0
1884 unsigned long data_len
, retcode
, request_id
;
1885 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
1886 ssize_t packet_len
= path_len
+ 13 + libssh2_sftp_attrsize(&attrs
);
1887 unsigned char *packet
, *s
, *data
;
1890 if (sftp
->mkdir_state
== libssh2_NB_state_idle
) {
1891 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
,
1892 "Creating directory %s with mode 0%lo", path
, mode
);
1893 s
= packet
= LIBSSH2_ALLOC(session
, packet_len
);
1895 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1896 "Unable to allocate memory for FXP_MKDIR packet", 0);
1899 /* Filetype in SFTP 3 and earlier */
1900 attrs
.permissions
= mode
| LIBSSH2_SFTP_ATTR_PFILETYPE_DIR
;
1902 libssh2_htonu32(s
, packet_len
- 4);
1904 *(s
++) = SSH_FXP_MKDIR
;
1905 request_id
= sftp
->request_id
++;
1906 libssh2_htonu32(s
, request_id
);
1908 libssh2_htonu32(s
, path_len
);
1910 memcpy(s
, path
, path_len
);
1912 s
+= libssh2_sftp_attr2bin(s
, &attrs
);
1914 sftp
->mkdir_state
= libssh2_NB_state_created
;
1916 packet
= sftp
->mkdir_packet
;
1917 request_id
= sftp
->mkdir_request_id
;
1920 if (sftp
->mkdir_state
== libssh2_NB_state_created
) {
1921 rc
= libssh2_channel_write_ex(channel
, 0, (char *) packet
, packet_len
);
1922 if (rc
== PACKET_EAGAIN
) {
1923 sftp
->mkdir_packet
= packet
;
1924 sftp
->mkdir_request_id
= request_id
;
1925 return PACKET_EAGAIN
;
1927 if (packet_len
!= rc
) {
1928 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1929 "Unable to send FXP_READ command", 0);
1930 LIBSSH2_FREE(session
, packet
);
1931 sftp
->mkdir_state
= libssh2_NB_state_idle
;
1934 LIBSSH2_FREE(session
, packet
);
1935 sftp
->mkdir_state
= libssh2_NB_state_sent
;
1936 sftp
->mkdir_packet
= NULL
;
1939 rc
= libssh2_sftp_packet_require(sftp
, SSH_FXP_STATUS
, request_id
, &data
,
1941 if (rc
== PACKET_EAGAIN
) {
1942 return PACKET_EAGAIN
;
1944 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
1945 "Timeout waiting for status message", 0);
1946 sftp
->mkdir_state
= libssh2_NB_state_idle
;
1950 sftp
->mkdir_state
= libssh2_NB_state_idle
;
1952 retcode
= libssh2_ntohu32(data
+ 5);
1953 LIBSSH2_FREE(session
, data
);
1955 if (retcode
== LIBSSH2_FX_OK
) {
1958 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
1959 "SFTP Protocol Error", 0);
1960 sftp
->last_errno
= retcode
;
1967 /* {{{ libssh2_sftp_rmdir_ex
1968 * Remove a directory
1970 /* libssh2_sftp_rmdir_ex - NB-UNSAFE?? */
1972 libssh2_sftp_rmdir_ex(LIBSSH2_SFTP
* sftp
, const char *path
,
1973 unsigned int path_len
)
1975 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
1976 LIBSSH2_SESSION
*session
= channel
->session
;
1977 unsigned long data_len
, retcode
;
1978 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
1979 ssize_t packet_len
= path_len
+ 13;
1980 unsigned char *s
, *data
;
1983 if (sftp
->rmdir_state
== libssh2_NB_state_idle
) {
1984 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "Removing directory: %s",
1986 s
= sftp
->rmdir_packet
= LIBSSH2_ALLOC(session
, packet_len
);
1987 if (!sftp
->rmdir_packet
) {
1988 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1989 "Unable to allocate memory for FXP_MKDIR packet", 0);
1993 libssh2_htonu32(s
, packet_len
- 4);
1995 *(s
++) = SSH_FXP_RMDIR
;
1996 sftp
->rmdir_request_id
= sftp
->request_id
++;
1997 libssh2_htonu32(s
, sftp
->rmdir_request_id
);
1999 libssh2_htonu32(s
, path_len
);
2001 memcpy(s
, path
, path_len
);
2004 sftp
->rmdir_state
= libssh2_NB_state_created
;
2007 if (sftp
->rmdir_state
== libssh2_NB_state_created
) {
2008 rc
= libssh2_channel_write_ex(channel
, 0, (char *) sftp
->rmdir_packet
,
2010 if (rc
== PACKET_EAGAIN
) {
2011 return PACKET_EAGAIN
;
2012 } else if (packet_len
!= rc
) {
2013 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
2014 "Unable to send FXP_MKDIR command", 0);
2015 LIBSSH2_FREE(session
, sftp
->rmdir_packet
);
2016 sftp
->rmdir_packet
= NULL
;
2017 sftp
->rmdir_state
= libssh2_NB_state_idle
;
2020 LIBSSH2_FREE(session
, sftp
->rmdir_packet
);
2021 sftp
->rmdir_packet
= NULL
;
2023 sftp
->rmdir_state
= libssh2_NB_state_sent
;
2026 rc
= libssh2_sftp_packet_require(sftp
, SSH_FXP_STATUS
,
2027 sftp
->rmdir_request_id
, &data
, &data_len
);
2028 if (rc
== PACKET_EAGAIN
) {
2029 return PACKET_EAGAIN
;
2031 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
2032 "Timeout waiting for status message", 0);
2033 sftp
->rmdir_state
= libssh2_NB_state_idle
;
2037 sftp
->rmdir_state
= libssh2_NB_state_idle
;
2039 retcode
= libssh2_ntohu32(data
+ 5);
2040 LIBSSH2_FREE(session
, data
);
2042 if (retcode
== LIBSSH2_FX_OK
) {
2045 sftp
->last_errno
= retcode
;
2046 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
2047 "SFTP Protocol Error", 0);
2054 /* {{{ libssh2_sftp_stat_ex
2055 * Stat a file or symbolic link
2057 /* libssh2_sftp_stat_ex - NB-UNSAFE?? */
2059 libssh2_sftp_stat_ex(LIBSSH2_SFTP
* sftp
, const char *path
,
2060 unsigned int path_len
, int stat_type
,
2061 LIBSSH2_SFTP_ATTRIBUTES
* attrs
)
2063 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
2064 LIBSSH2_SESSION
*session
= channel
->session
;
2065 unsigned long data_len
;
2066 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
2067 ssize_t packet_len
=
2070 LIBSSH2_SFTP_SETSTAT
) ?
libssh2_sftp_attrsize(attrs
) : 0);
2071 unsigned char *s
, *data
;
2072 static const unsigned char stat_responses
[2] =
2073 { SSH_FXP_ATTRS
, SSH_FXP_STATUS
};
2076 if (sftp
->stat_state
== libssh2_NB_state_idle
) {
2077 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "%s %s",
2078 (stat_type
== LIBSSH2_SFTP_SETSTAT
) ?
"Set-statting" :
2080 LIBSSH2_SFTP_LSTAT ?
"LStatting" : "Statting"), path
);
2081 s
= sftp
->stat_packet
= LIBSSH2_ALLOC(session
, packet_len
);
2082 if (!sftp
->stat_packet
) {
2083 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
2084 "Unable to allocate memory for FXP_MKDIR packet", 0);
2088 libssh2_htonu32(s
, packet_len
- 4);
2090 switch (stat_type
) {
2091 case LIBSSH2_SFTP_SETSTAT
:
2092 *(s
++) = SSH_FXP_SETSTAT
;
2095 case LIBSSH2_SFTP_LSTAT
:
2096 *(s
++) = SSH_FXP_LSTAT
;
2099 case LIBSSH2_SFTP_STAT
:
2101 *(s
++) = SSH_FXP_STAT
;
2103 sftp
->stat_request_id
= sftp
->request_id
++;
2104 libssh2_htonu32(s
, sftp
->stat_request_id
);
2106 libssh2_htonu32(s
, path_len
);
2108 memcpy(s
, path
, path_len
);
2110 if (stat_type
== LIBSSH2_SFTP_SETSTAT
) {
2111 s
+= libssh2_sftp_attr2bin(s
, attrs
);
2114 sftp
->stat_state
= libssh2_NB_state_created
;
2117 if (sftp
->stat_state
== libssh2_NB_state_created
) {
2118 rc
= libssh2_channel_write_ex(channel
, 0, (char *) sftp
->stat_packet
,
2120 if (rc
== PACKET_EAGAIN
) {
2121 return PACKET_EAGAIN
;
2122 } else if (packet_len
!= rc
) {
2123 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
2124 "Unable to send STAT/LSTAT/SETSTAT command", 0);
2125 LIBSSH2_FREE(session
, sftp
->stat_packet
);
2126 sftp
->stat_packet
= NULL
;
2127 sftp
->stat_state
= libssh2_NB_state_idle
;
2130 LIBSSH2_FREE(session
, sftp
->stat_packet
);
2131 sftp
->stat_packet
= NULL
;
2133 sftp
->stat_state
= libssh2_NB_state_sent
;
2136 rc
= libssh2_sftp_packet_requirev(sftp
, 2, stat_responses
,
2137 sftp
->stat_request_id
, &data
, &data_len
);
2138 if (rc
== PACKET_EAGAIN
) {
2139 return PACKET_EAGAIN
;
2141 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
2142 "Timeout waiting for status message", 0);
2143 sftp
->stat_state
= libssh2_NB_state_idle
;
2147 sftp
->stat_state
= libssh2_NB_state_idle
;
2149 if (data
[0] == SSH_FXP_STATUS
) {
2152 retcode
= libssh2_ntohu32(data
+ 5);
2153 LIBSSH2_FREE(session
, data
);
2154 if (retcode
== LIBSSH2_FX_OK
) {
2157 sftp
->last_errno
= retcode
;
2158 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
2159 "SFTP Protocol Error", 0);
2164 memset(attrs
, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES
));
2165 libssh2_sftp_bin2attr(attrs
, data
+ 5);
2166 LIBSSH2_FREE(session
, data
);
2173 /* {{{ libssh2_sftp_symlink_ex
2174 * Read or set a symlink
2177 libssh2_sftp_symlink_ex(LIBSSH2_SFTP
* sftp
, const char *path
,
2178 unsigned int path_len
, char *target
,
2179 unsigned int target_len
, int link_type
)
2181 LIBSSH2_CHANNEL
*channel
= sftp
->channel
;
2182 LIBSSH2_SESSION
*session
= channel
->session
;
2183 unsigned long data_len
, link_len
;
2184 /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
2185 ssize_t packet_len
=
2187 ((link_type
== LIBSSH2_SFTP_SYMLINK
) ?
(4 + target_len
) : 0);
2188 unsigned char *s
, *data
;
2189 static const unsigned char link_responses
[2] =
2190 { SSH_FXP_NAME
, SSH_FXP_STATUS
};
2193 if ((sftp
->version
< 3) && (link_type
!= LIBSSH2_SFTP_REALPATH
)) {
2194 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
2195 "Server does not support SYMLINK or READLINK", 0);
2199 if (sftp
->symlink_state
== libssh2_NB_state_idle
) {
2200 s
= sftp
->symlink_packet
= LIBSSH2_ALLOC(session
, packet_len
);
2201 if (!sftp
->symlink_packet
) {
2202 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
2203 "Unable to allocate memory for SYMLINK/READLINK/REALPATH packet",
2208 _libssh2_debug(session
, LIBSSH2_DBG_SFTP
, "%s %s on %s",
2210 LIBSSH2_SFTP_SYMLINK
) ?
"Creating" : "Reading",
2212 LIBSSH2_SFTP_REALPATH
) ?
"realpath" : "symlink", path
);
2214 libssh2_htonu32(s
, packet_len
- 4);
2216 switch (link_type
) {
2217 case LIBSSH2_SFTP_REALPATH
:
2218 *(s
++) = SSH_FXP_REALPATH
;
2221 case LIBSSH2_SFTP_SYMLINK
:
2222 *(s
++) = SSH_FXP_SYMLINK
;
2225 case LIBSSH2_SFTP_READLINK
:
2227 *(s
++) = SSH_FXP_READLINK
;
2229 sftp
->symlink_request_id
= sftp
->request_id
++;
2230 libssh2_htonu32(s
, sftp
->symlink_request_id
);
2232 libssh2_htonu32(s
, path_len
);
2234 memcpy(s
, path
, path_len
);
2236 if (link_type
== LIBSSH2_SFTP_SYMLINK
) {
2237 libssh2_htonu32(s
, target_len
);
2239 memcpy(s
, target
, target_len
);
2243 sftp
->symlink_state
= libssh2_NB_state_created
;
2246 if (sftp
->symlink_state
== libssh2_NB_state_created
) {
2247 rc
= libssh2_channel_write_ex(channel
, 0,
2248 (char *) sftp
->symlink_packet
,
2250 if (rc
== PACKET_EAGAIN
) {
2251 return PACKET_EAGAIN
;
2252 } else if (packet_len
!= rc
) {
2253 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
2254 "Unable to send SYMLINK/READLINK command", 0);
2255 LIBSSH2_FREE(session
, sftp
->symlink_packet
);
2256 sftp
->symlink_packet
= NULL
;
2257 sftp
->symlink_state
= libssh2_NB_state_idle
;
2260 LIBSSH2_FREE(session
, sftp
->symlink_packet
);
2261 sftp
->symlink_packet
= NULL
;
2263 sftp
->symlink_state
= libssh2_NB_state_sent
;
2266 rc
= libssh2_sftp_packet_requirev(sftp
, 2, link_responses
,
2267 sftp
->symlink_request_id
, &data
,
2269 if (rc
== PACKET_EAGAIN
) {
2270 return PACKET_EAGAIN
;
2272 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_TIMEOUT
,
2273 "Timeout waiting for status message", 0);
2274 sftp
->symlink_state
= libssh2_NB_state_idle
;
2278 sftp
->symlink_state
= libssh2_NB_state_idle
;
2280 if (data
[0] == SSH_FXP_STATUS
) {
2283 retcode
= libssh2_ntohu32(data
+ 5);
2284 LIBSSH2_FREE(session
, data
);
2285 if (retcode
== LIBSSH2_FX_OK
) {
2288 sftp
->last_errno
= retcode
;
2289 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
2290 "SFTP Protocol Error", 0);
2295 if (libssh2_ntohu32(data
+ 5) < 1) {
2296 libssh2_error(session
, LIBSSH2_ERROR_SFTP_PROTOCOL
,
2297 "Invalid READLINK/REALPATH response, no name entries",
2299 LIBSSH2_FREE(session
, data
);
2303 link_len
= libssh2_ntohu32(data
+ 9);
2304 if (link_len
>= target_len
) {
2305 link_len
= target_len
- 1;
2307 memcpy(target
, data
+ 13, link_len
);
2308 target
[link_len
] = 0;
2309 LIBSSH2_FREE(session
, data
);
2316 /* {{{ libssh2_sftp_last_error
2317 * Returns the last error code reported by SFTP
2319 LIBSSH2_API
unsigned long
2320 libssh2_sftp_last_error(LIBSSH2_SFTP
* sftp
)
2322 return sftp
->last_errno
;