2 * Sample showing how to do SFTP non-blocking transfers.
4 * The sample code has default values for host name, user name, password
5 * and path to copy, but you can specify them on the command line like:
7 * "sftp_nonblock 192.168.0.1 user password /tmp/secrets"
10 #include "libssh2_config.h"
12 #include <libssh2_sftp.h>
14 #ifdef HAVE_WINSOCK2_H
15 # include <winsock2.h>
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
20 #ifdef HAVE_NETINET_IN_H
21 # include <netinet/in.h>
23 #ifdef HAVE_SYS_SELECT_H
24 # include <sys/select.h>
29 #ifdef HAVE_ARPA_INET_H
30 # include <arpa/inet.h>
32 #ifdef HAVE_SYS_TIME_H
33 # include <sys/time.h>
36 #include <sys/types.h>
42 #ifdef HAVE_GETTIMEOFDAY
44 static long tvdiff(struct timeval newer
, struct timeval older
)
46 return (newer
.tv_sec
-older
.tv_sec
)*1000+
47 (newer
.tv_usec
-older
.tv_usec
)/1000;
51 static int waitsocket(int socket_fd
, LIBSSH2_SESSION
*session
)
53 struct timeval timeout
;
56 fd_set
*writefd
= NULL
;
57 fd_set
*readfd
= NULL
;
65 FD_SET(socket_fd
, &fd
);
67 /* now make sure we wait in the correct direction */
68 dir
= libssh2_session_block_directions(session
);
70 if(dir
& LIBSSH2_SESSION_BLOCK_INBOUND
)
73 if(dir
& LIBSSH2_SESSION_BLOCK_OUTBOUND
)
76 rc
= select(socket_fd
+ 1, readfd
, writefd
, NULL
, &timeout
);
81 int main(int argc
, char *argv
[])
83 unsigned long hostaddr
;
84 int sock
, i
, auth_pw
= 1;
85 struct sockaddr_in sin
;
86 const char *fingerprint
;
87 LIBSSH2_SESSION
*session
;
88 const char *username
="username";
89 const char *password
="password";
90 const char *sftppath
="/tmp/TEST";
91 #ifdef HAVE_GETTIMEOFDAY
99 LIBSSH2_SFTP
*sftp_session
;
100 LIBSSH2_SFTP_HANDLE
*sftp_handle
;
106 err
= WSAStartup(MAKEWORD(2,0), &wsadata
);
108 fprintf(stderr
, "WSAStartup failed with error: %d\n", err
);
114 hostaddr
= inet_addr(argv
[1]);
116 hostaddr
= htonl(0x7F000001);
129 rc
= libssh2_init (0);
131 fprintf (stderr
, "libssh2 initialization failed (%d)\n", rc
);
136 * The application code is responsible for creating the socket
137 * and establishing the connection
139 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
141 sin
.sin_family
= AF_INET
;
142 sin
.sin_port
= htons(22);
143 sin
.sin_addr
.s_addr
= hostaddr
;
144 if (connect(sock
, (struct sockaddr
*)(&sin
),
145 sizeof(struct sockaddr_in
)) != 0) {
146 fprintf(stderr
, "failed to connect!\n");
150 /* Create a session instance */
151 session
= libssh2_session_init();
155 /* Since we have set non-blocking, tell libssh2 we are non-blocking */
156 libssh2_session_set_blocking(session
, 0);
158 #ifdef HAVE_GETTIMEOFDAY
159 gettimeofday(&start
, NULL
);
162 /* ... start it up. This will trade welcome banners, exchange keys,
163 * and setup crypto, compression, and MAC layers
165 while ((rc
= libssh2_session_handshake(session
, sock
)) ==
166 LIBSSH2_ERROR_EAGAIN
);
168 fprintf(stderr
, "Failure establishing SSH session: %d\n", rc
);
172 /* At this point we havn't yet authenticated. The first thing to do
173 * is check the hostkey's fingerprint against our known hosts Your app
174 * may have it hard coded, may go to a file, may present it to the
175 * user, that's your call
177 fingerprint
= libssh2_hostkey_hash(session
, LIBSSH2_HOSTKEY_HASH_SHA1
);
178 fprintf(stderr
, "Fingerprint: ");
179 for(i
= 0; i
< 20; i
++) {
180 fprintf(stderr
, "%02X ", (unsigned char)fingerprint
[i
]);
182 fprintf(stderr
, "\n");
185 /* We could authenticate via password */
186 while ((rc
= libssh2_userauth_password(session
, username
, password
))
187 == LIBSSH2_ERROR_EAGAIN
);
189 fprintf(stderr
, "Authentication by password failed.\n");
193 /* Or by public key */
195 libssh2_userauth_publickey_fromfile(session
, username
,
201 LIBSSH2_ERROR_EAGAIN
);
203 fprintf(stderr
, "\tAuthentication by public key failed\n");
208 libssh2_trace(session
, LIBSSH2_TRACE_CONN
);
210 fprintf(stderr
, "libssh2_sftp_init()!\n");
212 sftp_session
= libssh2_sftp_init(session
);
215 if(libssh2_session_last_errno(session
) ==
216 LIBSSH2_ERROR_EAGAIN
) {
217 fprintf(stderr
, "non-blocking init\n");
218 waitsocket(sock
, session
); /* now we wait */
221 fprintf(stderr
, "Unable to init SFTP session\n");
225 } while (!sftp_session
);
227 fprintf(stderr
, "libssh2_sftp_open()!\n");
228 /* Request a file via SFTP */
230 sftp_handle
= libssh2_sftp_open(sftp_session
, sftppath
,
231 LIBSSH2_FXF_READ
, 0);
234 if (libssh2_session_last_errno(session
) != LIBSSH2_ERROR_EAGAIN
) {
235 fprintf(stderr
, "Unable to open file with SFTP\n");
239 fprintf(stderr
, "non-blocking open\n");
240 waitsocket(sock
, session
); /* now we wait */
243 } while (!sftp_handle
);
245 fprintf(stderr
, "libssh2_sftp_open() is done, now receive data!\n");
249 /* loop until we fail */
250 while ((rc
= libssh2_sftp_read(sftp_handle
, mem
,
251 sizeof(mem
))) == LIBSSH2_ERROR_EAGAIN
) {
253 waitsocket(sock
, session
); /* now we wait */
263 #ifdef HAVE_GETTIMEOFDAY
264 gettimeofday(&end
, NULL
);
265 time_ms
= tvdiff(end
, start
);
266 fprintf(stderr
, "Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total
,
267 time_ms
, total
/(time_ms
/1000.0), spin
);
269 fprintf(stderr
, "Got %d bytes spin: %d\n", total
, spin
);
272 libssh2_sftp_close(sftp_handle
);
273 libssh2_sftp_shutdown(sftp_session
);
277 fprintf(stderr
, "libssh2_session_disconnect\n");
278 while (libssh2_session_disconnect(session
,
279 "Normal Shutdown, Thank you") ==
280 LIBSSH2_ERROR_EAGAIN
);
281 libssh2_session_free(session
);
288 fprintf(stderr
, "all done\n");