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.
20 #include "silcincludes.h"
24 SilcSchedule schedule;
25 SilcSocketConnection sock;
36 static void sftp_name(SilcSFTP sftp, SilcSFTPStatus status,
37 const SilcSFTPName name, void *context);
38 static void sftp_handle(SilcSFTP sftp, SilcSFTPStatus status,
39 SilcSFTPHandle handle, void *context);
40 static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
41 const unsigned char *data, uint32 data_len,
44 static void send_packet(SilcSocketConnection sock,
45 SilcBuffer packet, void *context)
47 Client client = (Client)context;
48 SilcPacketContext packetdata;
51 memset(&packetdata, 0, sizeof(packetdata));
52 packetdata.type = SILC_PACKET_FTP;
53 packetdata.truelen = packet->len + SILC_PACKET_HEADER_LEN;
54 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, 0);
55 silc_packet_send_prepare(sock,
56 SILC_PACKET_HEADER_LEN,
59 packetdata.buffer = sock->outbuf;
60 silc_buffer_put(sock->outbuf, packet->data, packet->len);
61 silc_packet_assemble(&packetdata, NULL);
62 ret = silc_packet_send(sock, TRUE);
66 silc_schedule_set_listen_fd(client->schedule, sock->sock,
67 (SILC_TASK_READ | SILC_TASK_WRITE));
68 SILC_SET_OUTBUF_PENDING(sock);
71 static bool packet_parse(SilcPacketParserContext *parser, void *context)
73 Client client = (Client)parser->context;
74 SilcSocketConnection sock = parser->sock;
75 SilcPacketContext *packet = parser->packet;
78 ret = silc_packet_parse(packet, NULL);
79 assert(packet->type == SILC_PACKET_FTP);
81 silc_sftp_client_receive_process(client->sftp, sock, packet);
86 SILC_TASK_CALLBACK(packet_process)
88 Client client = (Client)context;
89 SilcSocketConnection sock = client->sock;
92 if (type == SILC_TASK_WRITE) {
93 if (sock->outbuf->data - sock->outbuf->head)
94 silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
96 ret = silc_packet_send(sock, TRUE);
100 silc_schedule_set_listen_fd(client->schedule, fd, SILC_TASK_READ);
101 SILC_UNSET_OUTBUF_PENDING(sock);
102 silc_buffer_clear(sock->outbuf);
106 if (type == SILC_TASK_READ) {
107 ret = silc_packet_receive(sock);
112 silc_net_close_connection(sock->sock);
113 silc_socket_free(sock);
117 silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
118 packet_parse, client);
122 static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
123 const unsigned char *data, uint32 data_len,
126 SilcSFTPHandle handle = (SilcSFTPHandle)context;
127 int debug = silc_debug;
129 if (status != SILC_SFTP_STATUS_OK) {
130 SilcSFTPAttributesStruct attrs;
132 fprintf(stderr, "Status %d\n", status);
134 if (!strcmp(file, "/sftp/sftp_server.c"))
137 /* Open another file */
139 memset(&attrs, 0, sizeof(attrs));
140 file = "/sftp/sftp_server.c";
141 fprintf(stderr, "Opening file %s\n", file);
143 silc_sftp_open(sftp, file, SILC_SFTP_FXF_READ,
144 &attrs, sftp_handle, gclient);
150 SILC_LOG_HEXDUMP(("data"), (unsigned char *)data, data_len);
155 /* Attempt to read more */
156 fprintf(stderr, "Reading more of file %s\n", file);
157 silc_sftp_read(sftp, handle, offset, 2048, sftp_data, handle);
160 static void sftp_name(SilcSFTP sftp, SilcSFTPStatus status,
161 const SilcSFTPName name, void *context)
163 Client client = (Client)context;
166 SILC_LOG_DEBUG(("Name"));
167 fprintf(stderr, "Status %d\n", status);
169 fprintf(stderr, "Directory: %s\n", dir);
170 for (i = 0; i < name->count; i++) {
171 fprintf(stderr, "%s\n", name->long_filename[i]);
174 if (!strcmp(dir, "sftp")) {
175 SilcSFTPAttributesStruct attrs;
179 memset(&attrs, 0, sizeof(attrs));
181 fprintf(stderr, "Opening file %s\n", file);
183 silc_sftp_open(sftp, file, SILC_SFTP_FXF_READ,
184 &attrs, sftp_handle, client);
188 if (!strcmp(dir, "/"))
191 fprintf(stderr, "Opening %s\n", dir);
195 silc_sftp_opendir(sftp, dir, sftp_handle, client);
198 static void sftp_handle(SilcSFTP sftp, SilcSFTPStatus status,
199 SilcSFTPHandle handle, void *context)
201 Client client = (Client)context;
203 SILC_LOG_DEBUG(("Handle"));
204 fprintf(stderr, "Status %d\n", status);
205 if (status != SILC_SFTP_STATUS_OK)
209 fprintf(stderr, "Reading %s\n", dir);
211 silc_sftp_readdir(sftp, handle, sftp_name, client);
213 fprintf(stderr, "Reading file %s\n", file);
216 silc_sftp_read(sftp, handle, 0, 2048, sftp_data, handle);
220 static void sftp_version(SilcSFTP sftp, SilcSFTPStatus status,
221 SilcSFTPVersion version, void *context)
223 Client client = (Client)context;
224 fprintf(stderr, "Version: %d\n", (int)version);
226 SILC_LOG_DEBUG(("Version"));
227 fprintf(stderr, "Status %d\n", status);
231 fprintf(stderr, "Opening %s\n", dir);
233 silc_sftp_opendir(sftp, dir, sftp_handle, client);
236 int main(int argc, char **argv)
238 Client client = silc_calloc(1, sizeof(*client));
243 if (argc > 1 && !strcmp(argv[1], "-d")) {
245 silc_debug_hexdump = 1;
246 silc_log_set_debug_string("");
249 client->schedule = silc_schedule_init(100);
250 if (!client->schedule)
253 /* Connecto to server */
254 sock = silc_net_create_connection(NULL, 5000, "127.0.0.1");
257 silc_socket_alloc(sock, 0, NULL, &client->sock);
258 silc_schedule_task_add(client->schedule, sock,
259 packet_process, client, 0, 0,
260 SILC_TASK_GENERIC, SILC_TASK_PRI_NORMAL);
262 /* Start SFTP session */
263 client->sftp = silc_sftp_client_start(client->sock, send_packet, client,
264 sftp_version, client);
266 silc_schedule(client->schedule);