5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 silc_sftp_client_start();
22 silc_sftp_client_receive_process();
32 #include "silcincludes.h"
36 SilcSchedule schedule;
37 SilcSocketConnection sock;
49 static void sftp_name(SilcSFTP sftp, SilcSFTPStatus status,
50 const SilcSFTPName name, void *context);
51 static void sftp_handle(SilcSFTP sftp, SilcSFTPStatus status,
52 SilcSFTPHandle handle, void *context);
53 static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
54 const unsigned char *data, SilcUInt32 data_len,
56 static void end_test(void);
58 static void send_packet(SilcBuffer packet, void *context)
60 Client client = (Client)context;
61 SilcSocketConnection sock = client->sock;
62 SilcPacketContext packetdata;
63 const SilcBufferStruct p;
66 memset(&packetdata, 0, sizeof(packetdata));
67 packetdata.type = SILC_PACKET_FTP;
68 packetdata.truelen = packet->len + SILC_PACKET_HEADER_LEN;
69 SILC_PACKET_PADLEN(packetdata.truelen, 0, packetdata.padlen);
70 silc_packet_assemble(&packetdata, NULL, NULL, NULL, sock,
71 packet->data, packet->len, (const SilcBuffer)&p);
72 ret = silc_packet_send(sock, TRUE);
76 silc_schedule_set_listen_fd(client->schedule, sock->sock,
77 (SILC_TASK_READ | SILC_TASK_WRITE), FALSE);
78 SILC_SET_OUTBUF_PENDING(sock);
81 static bool packet_parse(SilcPacketParserContext *parser, void *context)
83 Client client = (Client)parser->context;
84 SilcSocketConnection sock = parser->sock;
85 SilcPacketContext *packet = parser->packet;
88 ret = silc_packet_parse(packet, NULL);
89 assert(packet->type == SILC_PACKET_FTP);
91 silc_sftp_client_receive_process(client->sftp, sock, packet);
96 SILC_TASK_CALLBACK(packet_process)
98 Client client = (Client)context;
99 SilcSocketConnection sock = client->sock;
102 if (type == SILC_TASK_WRITE) {
103 if (sock->outbuf->data - sock->outbuf->head)
104 silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
106 ret = silc_packet_send(sock, TRUE);
110 silc_schedule_set_listen_fd(client->schedule, fd, SILC_TASK_READ, FALSE);
111 SILC_UNSET_OUTBUF_PENDING(sock);
112 silc_buffer_clear(sock->outbuf);
117 if (type == SILC_TASK_READ) {
118 ret = silc_packet_receive(sock);
123 silc_net_close_connection(sock->sock);
124 silc_socket_free(sock);
128 silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
129 packet_parse, client);
133 static void sftp_status(SilcSFTP sftp, SilcSFTPStatus status,
134 const char *message, const char *lang_tag,
137 fprintf(stderr, "Status %d\n", status);
138 if (status != SILC_SFTP_STATUS_OK) {
139 SILC_LOG_DEBUG(("Error status"));
149 static void sftp_attr(SilcSFTP sftp, SilcSFTPStatus status,
150 const SilcSFTPAttributes attrs, void *context)
152 SilcSFTPHandle handle = (SilcSFTPHandle)context;
153 int debug = silc_debug;
156 fprintf(stderr, "Status %d\n", status);
157 if (status != SILC_SFTP_STATUS_OK) {
158 SILC_LOG_DEBUG(("Error status"));
167 SILC_LOG_DEBUG(("Attr.flags: %d", attrs->flags));
168 SILC_LOG_DEBUG(("Attr.size: %lu", attrs->size));
169 SILC_LOG_DEBUG(("Attr.uid: %d", attrs->uid));
170 SILC_LOG_DEBUG(("Attr.gid: %d", attrs->gid));
171 SILC_LOG_DEBUG(("Attr.permissions: %d", attrs->permissions));
172 SILC_LOG_DEBUG(("Attr.atime: %d", attrs->atime));
173 SILC_LOG_DEBUG(("Attr.mtime: %d", attrs->mtime));
174 SILC_LOG_DEBUG(("Attr.extended count: %d", attrs->extended_count));
175 for (i = 0; i < attrs->extended_count; i++) {
176 SILC_LOG_HEXDUMP(("Attr.extended_type[i]:", i),
177 attrs->extended_type[i]->data,
178 attrs->extended_type[i]->len);
179 SILC_LOG_HEXDUMP(("Attr.extended_data[i]:", i),
180 attrs->extended_data[i]->data,
181 attrs->extended_data[i]->len);
187 fprintf(stderr, "Closing file\n");
188 silc_sftp_close(sftp, handle, sftp_status, context);
192 fprintf(stderr, "LStatting file %s\n", file);
193 silc_sftp_lstat(sftp, file, sftp_attr, context);
197 static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
198 const unsigned char *data, SilcUInt32 data_len,
201 SilcSFTPHandle handle = (SilcSFTPHandle)context;
202 int debug = silc_debug;
204 if (status != SILC_SFTP_STATUS_OK) {
205 SilcSFTPAttributesStruct attrs;
207 fprintf(stderr, "Status %d\n", status);
209 if (status != SILC_SFTP_STATUS_EOF) {
210 SILC_LOG_DEBUG(("Error status"));
216 if (!strcmp(file, "/sftp/sftp_server.c")) {
217 fprintf(stderr, "FStatting file handle %s\n", file);
218 silc_sftp_fstat(sftp, handle, sftp_attr, context);
222 /* Open another file */
224 memset(&attrs, 0, sizeof(attrs));
225 file = "/sftp/sftp_server.c";
226 fprintf(stderr, "Opening file %s\n", file);
228 silc_sftp_open(sftp, file, SILC_SFTP_FXF_READ,
229 &attrs, sftp_handle, gclient);
235 SILC_LOG_HEXDUMP(("data"), (unsigned char *)data, data_len);
240 /* Attempt to read more */
241 fprintf(stderr, "Reading more of file %s\n", file);
242 silc_sftp_read(sftp, handle, offset, 2048, sftp_data, handle);
245 static void sftp_name(SilcSFTP sftp, SilcSFTPStatus status,
246 const SilcSFTPName name, void *context)
248 Client client = (Client)context;
251 SILC_LOG_DEBUG(("Name"));
252 fprintf(stderr, "Status %d\n", status);
254 if (status != SILC_SFTP_STATUS_OK) {
255 SILC_LOG_DEBUG(("Error status"));
261 fprintf(stderr, "Directory: %s\n", dir);
262 for (i = 0; i < name->count; i++) {
263 fprintf(stderr, "%s\n", name->long_filename[i]);
266 if (!strcmp(dir, "sftp")) {
267 SilcSFTPAttributesStruct attrs;
271 memset(&attrs, 0, sizeof(attrs));
273 fprintf(stderr, "Opening file %s\n", file);
275 silc_sftp_open(sftp, file, SILC_SFTP_FXF_READ,
276 &attrs, sftp_handle, client);
280 if (!strcmp(dir, "/"))
283 fprintf(stderr, "Opening %s\n", dir);
287 silc_sftp_opendir(sftp, dir, sftp_handle, client);
290 static void sftp_handle(SilcSFTP sftp, SilcSFTPStatus status,
291 SilcSFTPHandle handle, void *context)
293 Client client = (Client)context;
295 SILC_LOG_DEBUG(("Handle"));
296 fprintf(stderr, "Status %d\n", status);
297 if (status != SILC_SFTP_STATUS_OK) {
298 SILC_LOG_DEBUG(("Error status"));
305 fprintf(stderr, "Reading %s\n", dir);
307 silc_sftp_readdir(sftp, handle, sftp_name, client);
309 fprintf(stderr, "Reading file %s\n", file);
312 silc_sftp_read(sftp, handle, 0, 2048, sftp_data, handle);
316 static void sftp_version(SilcSFTP sftp, SilcSFTPStatus status,
317 SilcSFTPVersion version, void *context)
319 Client client = (Client)context;
320 fprintf(stderr, "Version: %d\n", (int)version);
322 SILC_LOG_DEBUG(("Version"));
323 fprintf(stderr, "Status %d\n", status);
324 if (status != SILC_SFTP_STATUS_OK) {
325 SILC_LOG_DEBUG(("Error status"));
333 fprintf(stderr, "Opening %s\n", dir);
335 silc_sftp_opendir(sftp, dir, sftp_handle, client);
338 int main(int argc, char **argv)
340 Client client = silc_calloc(1, sizeof(*client));
345 if (argc > 1 && !strcmp(argv[1], "-d")) {
347 silc_debug_hexdump = 1;
348 silc_log_set_debug_string("*sftp*");
351 client->schedule = silc_schedule_init(100, NULL);
352 if (!client->schedule)
355 /* Connecto to server */
356 sock = silc_net_create_connection(NULL, 5000, "127.0.0.1");
359 silc_socket_alloc(sock, 0, NULL, &client->sock);
360 silc_schedule_task_add(client->schedule, sock,
361 packet_process, client, 0, 0,
362 SILC_TASK_GENERIC, SILC_TASK_PRI_NORMAL);
364 /* Start SFTP session */
365 client->sftp = silc_sftp_client_start(send_packet, client,
366 sftp_version, client);
368 silc_schedule(client->schedule);
372 static void end_test(void)
374 SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
375 fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");