* Fixed %p formatting from silc_snprintf. Affected file is
lib/silcutil/silcsnprintf.c.
+ * Ported SFTP library to new utility library. Ported also
+ the SFTP testers. Affected files in lib/silcsftp/.
+
Tue Jan 2 17:18:46 EET 2007 Pekka Riikonen <priikone@silcnet.org>
* Added lib/silcutil/silcsnprintf.[ch]. Added in addition
o All packet waiting timeout tests and error condition tests.
-lib/silcsftp
+lib/silcsftp ****DONE****
============
- o Porting to use the new util library.
+ o Porting to use the new util library. (***DONE)
lib/silccore/silcpacket.[ch] ****DONE****
AC_SUBST(SILC_SIZEOF_CHAR, $ac_cv_sizeof_char)
AC_CHECK_SIZEOF(void *, 0)
AC_SUBST(SILC_SIZEOF_VOID_P, $ac_cv_sizeof_void_p)
+AC_CHECK_TYPES(long long)
+AC_CHECK_TYPES(long double)
# Function to check if compiler flag works
# Usage: SILC_ADD_CFLAGS(FLAGS, [ACTION-IF-FAILED])
define SILC_DIST_CLIENT
define SILC_DIST_CLIENTLIB
-# XXX
-undef SILC_DIST_SFTP
-
pre-hook distdir/pre-run
post-process-dist-hook distdir/post-process-dist
post-dist-hook distdir/post-dist
AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
-#ifdef SILC_DIST_SFTP
-# silcsftp
-#endif SILC_DIST_SFTP
-
# SILC Library dirs
SILCLIB_DIRS = \
contrib \
#ifdef SILC_DIST_HTTP
silchttp \
#endif SILC_DIST_HTTP
+#ifdef SILC_DIST_SFTP
+ silcsftp
+#endif SILC_DIST_SFTP
#ifdef SILC_DIST_IDCACHE
silcvcard \
#endif SILC_DIST_IDCACHE
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2005 Pekka Riikonen
+ Copyright (C) 2001 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* Request context. Every request will allocate this context and set
the correct callback function according the `type' field. */
typedef struct SilcSFTPRequestStruct {
- SilcUInt32 id;
- SilcSFTPPacket type;
+ struct SilcSFTPRequestStruct *next;
SilcSFTPStatusCallback status;
SilcSFTPHandleCallback handle;
SilcSFTPDataCallback data;
SilcSFTPAttrCallback attr;
SilcSFTPExtendedCallback extended;
void *context;
- struct SilcSFTPRequestStruct *next;
+ SilcUInt32 id;
+ SilcSFTPPacket type;
} *SilcSFTPRequest;
/* SFTP client context */
typedef struct {
SilcStream stream;
SilcSFTPVersionCallback version;
- void *version_context;
- SilcUInt32 id;
+ SilcSFTPErrorCallback error;
+ void *context;
SilcList requests;
SilcBuffer packet;
+ SilcUInt32 id;
} *SilcSFTPClient;
/* File handle */
};
static void silc_sftp_client_receive_process(SilcSFTP context,
- SilcBuffer buffer)
+ SilcBuffer buffer);
/* Creates SilcSFTPHandle and returns pointer to it. The caller must free
the context. */
*data_len = handle->data_len;
}
-/* General routine to send SFTP packet to the SFTP server. */
+/* Generic routine to send SFTP packet to the SFTP server. */
static void silc_sftp_send_packet(SilcSFTPClient sftp,
SilcSFTPPacket type,
{
SilcBuffer tmp;
va_list vp;
+ int ret;
va_start(vp, len);
tmp = silc_sftp_packet_encode_vp(type, sftp->packet, len, vp);
silc_buffer_len(sftp->packet));
/* Send the packet */
- silc_stream_write(sftp->stream, sftp->packet->data,
- silc_buffer_len(sftp->packet));
+ while (silc_buffer_len(sftp->packet) > 0) {
+ ret = silc_stream_write(sftp->stream, silc_buffer_data(sftp->packet),
+ silc_buffer_len(sftp->packet));
+ if (ret == -2) {
+ SILC_LOG_ERROR(("Error sending SFTP packet type %d", type));
+ break;
+ }
+ if (ret <= 0)
+ break;
+ silc_buffer_pull(sftp->packet, ret);
+ }
/* Clear packet */
silc_buffer_reset(sftp->packet);
return req;
}
- SILC_LOG_DEBUG(("Unknown request ID"));
+ SILC_LOG_DEBUG(("Unknown request ID %d", id));
return NULL;
}
va_end(vp);
}
-/* Handles stream IO */
+/* Handles stream I/O */
static void silc_sftp_client_io(SilcStream stream, SilcStreamStatus status,
void *context)
{
SilcSFTPClient sftp = context;
+ unsigned char inbuf[30720];
+ SilcBufferStruct packet;
+ int ret;
switch (status) {
+ case SILC_STREAM_CAN_READ:
+ SILC_LOG_DEBUG(("Reading data from stream"));
+
+ /* Read data from stream */
+ ret = silc_stream_read(stream, inbuf, sizeof(inbuf));
+ if (ret <= 0) {
+ if (ret == 0)
+ sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
+ if (ret == -2)
+ sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
+ return;
+ }
+
+ /* Now process the SFTP packet */
+ silc_buffer_set(&packet, inbuf, ret);
+ silc_sftp_client_receive_process(context, &packet);
+ break;
case SILC_STREAM_CAN_WRITE:
- if (!silc_buffer_headlen(&sftp->packet))
+ if (!silc_buffer_headlen(sftp->packet))
return;
SILC_LOG_DEBUG(("Writing pending data to stream"));
ret = silc_stream_write(stream, sftp->packet->data,
silc_buffer_len(sftp->packet));
if (ret == 0) {
- /* EOS */
- /* XXX */
+ sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
silc_buffer_reset(sftp->packet);
return;
}
- if (i == -2) {
- /* Error */
- /* XXX */
+ if (ret == -2) {
+ sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
silc_buffer_reset(sftp->packet);
- return FALSE;
+ return;
}
- if (ret == -1) {
- /* Cannot write now, write later. */
- silc_buffer_pull(sftp->packet, silc_buffer_len(sftp->packet));
+ if (ret == -1)
return;
- }
/* Wrote data */
silc_buffer_pull(sftp->packet, ret);
}
break;
- case SILC_STREAM_CAN_READ:
- SILC_LOG_DEBUG(("Reading data from stream"));
-
- /* Make sure we have fair amount of free space in inbuf */
- if (silc_buffer_taillen(&ps->inbuf) < SILC_PACKET_DEFAULT_SIZE)
- if (!silc_buffer_realloc(&ps->inbuf, silc_buffer_truelen(&ps->inbuf) +
- SILC_PACKET_DEFAULT_SIZE * 2))
- return;
-
- /* Read data from stream */
- ret = silc_stream_read(ps->stream, &ps->inbuf.tail,
- silc_buffer_taillen(&ps->inbuf));
-
- if (ret == 0) {
- /* EOS */
- SILC_PACKET_CALLBACK_EOS(ps);
- silc_buffer_reset(&ps->inbuf);
- return;
- }
-
- if (ret == -2) {
- /* Error */
- SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_READ);
- silc_buffer_reset(&ps->inbuf);
- return;
- }
-
- if (ret == -1) {
- /* Cannot read now, do it later. */
- silc_buffer_pull(&ps->inbuf, silc_buffer_len(&ps->inbuf));
- return;
- }
-
- /* Read some data */
- silc_buffer_pull_tail(&ps->inbuf, ret);
-
- /* Now process the data */
- silc_sftp_client_receive_process(sftp);
- break;
-
default:
break;
}
/* Starts SFTP client and returns context for it. */
SilcSFTP silc_sftp_client_start(SilcStream stream,
- SilcSFTPVersionCallback callback,
+ SilcSchedule schedule,
+ SilcSFTPVersionCallback version_cb,
+ SilcSFTPErrorCallback error_cb,
void *context)
{
SilcSFTPClient sftp;
+ SILC_LOG_DEBUG(("Starting SFTP client"));
+
if (!stream)
return NULL;
if (!sftp)
return NULL;
sftp->stream = stream;
- sftp->version = callback;
- sftp->version_context = context;
+ sftp->version = version_cb;
+ sftp->error = error_cb;
+ sftp->context = context;
silc_list_init(sftp->requests, struct SilcSFTPRequestStruct, next);
/* We handle the stream now */
- silc_stream_set_notifier(stream, silc_sftp_client_io, sftp);
+ silc_stream_set_notifier(stream, schedule, silc_sftp_client_io, sftp);
/* Send the SFTP session initialization to the server */
silc_sftp_send_packet(sftp, SILC_SFTP_INIT, 4,
{
SilcSFTPClient sftp = (SilcSFTPClient)context;
+ silc_stream_set_notifier(sftp->stream, NULL, NULL, NULL);
if (sftp->packet)
silc_buffer_free(sftp->packet);
silc_free(sftp);
SilcBufferStruct buf;
SilcUInt32 id;
- SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("Process SFTP packet"));
/* Parse the packet */
- type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload,
+ type = silc_sftp_packet_decode(buffer, (unsigned char **)&payload,
&payload_len);
if (!type)
return;
silc_buffer_set(&buf, (unsigned char *)payload, payload_len);
switch (type) {
+ case SILC_SFTP_DATA:
+ {
+ unsigned char *data = NULL;
+ SilcUInt32 data_len = 0;
+
+ SILC_LOG_DEBUG(("Data packet"));
+
+ ret = silc_buffer_unformat(&buf,
+ SILC_STR_UI_INT(&id),
+ SILC_STR_UI32_NSTRING(&data, &data_len),
+ SILC_STR_END);
+ if (ret < 0)
+ break;
+
+ /* Get request */
+ req = silc_sftp_find_request(sftp, id);
+ if (!req)
+ break;
+
+ /* Call the callback */
+ silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
+ data, data_len);
+ }
+ break;
+
case SILC_SFTP_VERSION:
{
SilcSFTPVersion version;
SILC_STR_END);
if (ret < 0) {
(*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_FAILURE, 0,
- sftp->version_context);
+ sftp->context);
break;
}
/* Call the callback */
(*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_OK, version,
- sftp->version_context);
+ sftp->context);
}
break;
}
break;
- case SILC_SFTP_DATA:
- {
- unsigned char *data = NULL;
- SilcUInt32 data_len = 0;
-
- SILC_LOG_DEBUG(("Data packet"));
-
- ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(&id),
- SILC_STR_UI32_NSTRING(&data, &data_len),
- SILC_STR_END);
- if (ret < 0)
- break;
-
- /* Get request */
- req = silc_sftp_find_request(sftp, id);
- if (!req)
- break;
-
- /* Call the callback */
- silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
- data, data_len);
- }
- break;
-
case SILC_SFTP_NAME:
{
SilcUInt32 count;
filesize = sizeof(*entry);
memset(long_name, 0, sizeof(long_name));
- date = (char *)silc_get_time(entry->created);
+ date = (char *)silc_time_string(entry->created);
if (strrchr(date, ':'))
*strrchr(date, ':') = '\0';
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2004 Pekka Riikonen
+ Copyright (C) 2001 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* SFTP Server context */
typedef struct {
- SilcSFTPSendPacketCallback send_packet;
- void *send_context;
+ SilcStream stream;
SilcSFTPMonitors monitors;
SilcSFTPMonitor monitor;
void *monitor_context;
SilcSFTPFilesystem fs;
SilcBuffer packet;
+ SilcSFTPErrorCallback error;
+ void *context;
} *SilcSFTPServer;
+static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer);
+
/* General routine to send SFTP packet to the SFTP client. */
static void silc_sftp_send_packet(SilcSFTPServer sftp,
{
SilcBuffer tmp;
va_list vp;
+ int ret;
va_start(vp, len);
tmp = silc_sftp_packet_encode_vp(type, sftp->packet, len, vp);
return;
sftp->packet = tmp;
- SILC_LOG_HEXDUMP(("SFTP packet to client"), sftp->packet->data,
- sftp->packet->len);
+ SILC_LOG_HEXDUMP(("SFTP packet to client"), silc_buffer_data(sftp->packet),
+ silc_buffer_len(sftp->packet));
/* Send the packet */
- (*sftp->send_packet)(sftp->packet, sftp->send_context);
+ while (silc_buffer_len(sftp->packet) > 0) {
+ ret = silc_stream_write(sftp->stream, silc_buffer_data(sftp->packet),
+ silc_buffer_len(sftp->packet));
+ if (ret == -2) {
+ SILC_LOG_ERROR(("Error sending SFTP packet type %d", type));
+ break;
+ }
+ if (ret <= 0)
+ break;
+ silc_buffer_pull(sftp->packet, ret);
+ }
/* Clear packet */
- sftp->packet->data = sftp->packet->tail = sftp->packet->head;
- sftp->packet->len = 0;
+ silc_buffer_reset(sftp->packet);
+}
+
+/* Handles stream I/O */
+
+static void silc_sftp_server_io(SilcStream stream, SilcStreamStatus status,
+ void *context)
+{
+ SilcSFTPServer sftp = context;
+ unsigned char inbuf[30720];
+ SilcBufferStruct packet;
+ int ret;
+
+ switch (status) {
+ case SILC_STREAM_CAN_READ:
+ SILC_LOG_DEBUG(("Reading data from stream"));
+
+ /* Read data from stream */
+ ret = silc_stream_read(stream, inbuf, sizeof(inbuf));
+ if (ret <= 0) {
+ if (ret == 0)
+ sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
+ if (ret == -2)
+ sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
+ return;
+ }
+
+ /* Now process the SFTP packet */
+ silc_buffer_set(&packet, inbuf, ret);
+ silc_sftp_server_receive_process(context, &packet);
+ break;
+
+ case SILC_STREAM_CAN_WRITE:
+ if (!silc_buffer_headlen(sftp->packet))
+ return;
+
+ SILC_LOG_DEBUG(("Writing pending data to stream"));
+
+ /* Write pending data to stream */
+ silc_buffer_push(sftp->packet, silc_buffer_headlen(sftp->packet));
+ while (silc_buffer_len(sftp->packet) > 0) {
+ ret = silc_stream_write(stream, sftp->packet->data,
+ silc_buffer_len(sftp->packet));
+ if (ret == 0) {
+ sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
+ silc_buffer_reset(sftp->packet);
+ return;
+ }
+
+ if (ret == -2) {
+ sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
+ silc_buffer_reset(sftp->packet);
+ return;
+ }
+
+ if (ret == -1)
+ return;
+
+ /* Wrote data */
+ silc_buffer_pull(sftp->packet, ret);
+ }
+ break;
+
+ default:
+ break;
+ }
}
/* Sends error to the client */
return;
}
- silc_sftp_send_packet(server, SILC_SFTP_NAME, 4 + namebuf->len,
+ silc_sftp_send_packet(server, SILC_SFTP_NAME, 4 + silc_buffer_len(namebuf),
SILC_STR_UI_INT(id),
- SILC_STR_UI_XNSTRING(namebuf->data, namebuf->len),
+ SILC_STR_DATA(silc_buffer_data(namebuf),
+ silc_buffer_len(namebuf)),
SILC_STR_END);
}
return;
}
- silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + attr_buf->len,
+ silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + silc_buffer_len(attr_buf),
SILC_STR_UI_INT(id),
- SILC_STR_UI_XNSTRING(attr_buf->data, attr_buf->len),
+ SILC_STR_DATA(silc_buffer_data(attr_buf),
+ silc_buffer_len(attr_buf)),
SILC_STR_END);
silc_buffer_free(attr_buf);
by the library when it needs to send a packet. The `fs' is the
structure containing filesystem access callbacks. */
-SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
- void *send_context,
+SilcSFTP silc_sftp_server_start(SilcStream stream,
+ SilcSchedule schedule,
+ SilcSFTPErrorCallback error_cb,
+ void *context,
SilcSFTPFilesystem fs)
{
SilcSFTPServer server;
server = silc_calloc(1, sizeof(*server));
if (!server)
return NULL;
- server->send_packet = send_packet;
- server->send_context = send_context;
+ server->stream = stream;
+ server->error = error_cb;
+ server->context = context;
server->fs = fs;
+ /* We handle the stream now */
+ silc_stream_set_notifier(stream, schedule, silc_sftp_server_io, server);
+
SILC_LOG_DEBUG(("Starting SFTP server %p", server));
return (SilcSFTP)server;
/* XXX Some day this will go away and we have automatic receive callbacks
for SilcSocketConnection API or SilcPacketContext API. */
-void silc_sftp_server_receive_process(SilcSFTP sftp,
- SilcSocketConnection sock,
- SilcPacketContext *packet)
+static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
SilcSFTPPacket type;
SILC_LOG_DEBUG(("Start"));
/* Parse the packet */
- type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload,
+ type = silc_sftp_packet_decode(buffer, (unsigned char **)&payload,
&payload_len);
if (!type)
return;
data_len = 8 + strlen(request);
silc_buffer_pull(&buf, data_len);
ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_XNSTRING(&data, buf.len),
+ SILC_STR_DATA(&data, silc_buffer_len(&buf)),
SILC_STR_END);
if (ret < 0)
goto failure;
- data_len = buf.len;
+ data_len = silc_buffer_len(&buf);
/* Call monitor */
if (server->monitors & SILC_SFTP_MONITOR_EXTENDED && server->monitor) {
/*
- sftp_util.c
+ sftp_util.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2002 Pekka Riikonen
+ Copyright (C) 2001 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
to that buffer instead of allocating new one. If the new data cannot
fit to `packet_buf' will be reallocated. */
-SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet,
+SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet,
SilcBuffer packet_buf, SilcUInt32 len, ...)
{
SilcBuffer buffer;
/* Same as silc_sftp_packet_encode but takes the variable argument list
pointer as argument. */
-SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet,
- SilcBuffer packet_buf, SilcUInt32 len,
+SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet,
+ SilcBuffer packet_buf, SilcUInt32 len,
va_list vp)
{
SilcBuffer buffer;
int ret;
if (packet_buf) {
- if (packet_buf->truelen < 4 + 1 + len) {
+ if (silc_buffer_truelen(packet_buf) < 4 + 1 + len) {
packet_buf = silc_buffer_realloc(packet_buf, 4 + 1 + len);
if (!packet_buf)
return NULL;
dyn = TRUE;
}
- silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
- silc_buffer_format(buffer,
+ silc_buffer_pull_tail(buffer, 4 + 1 + len);
+ silc_buffer_format(buffer,
SILC_STR_UI_INT(len),
SILC_STR_UI_CHAR(packet),
SILC_STR_END);
if (type < SILC_SFTP_INIT || type > SILC_SFTP_EXTENDED_REPLY)
return 0;
- if (len > (packet->len - 5))
+ if (len > (silc_buffer_len(packet) - 5))
return 0;
silc_buffer_pull(packet, 5);
- ret = silc_buffer_unformat(packet,
+ ret = silc_buffer_unformat(packet,
SILC_STR_UI_XNSTRING(payload, len),
SILC_STR_END);
if (ret < 0)
len += 4;
for (i = 0; i < attr->extended_count; i++) {
len += 8;
- len += attr->extended_type[i]->len;
- len += attr->extended_data[i]->len;
+ len += silc_buffer_len(attr->extended_type[i]);
+ len += silc_buffer_len(attr->extended_data[i]);
}
}
if (!buffer)
return NULL;
- silc_buffer_format(buffer,
- SILC_STR_UI_INT(attr->flags),
+ silc_buffer_format(buffer,
+ SILC_STR_UI_INT(attr->flags),
SILC_STR_END);
silc_buffer_pull(buffer, 4);
if (attr->flags & SILC_SFTP_ATTR_SIZE) {
- silc_buffer_format(buffer,
- SILC_STR_UI_INT64(attr->size),
+ silc_buffer_format(buffer,
+ SILC_STR_UI_INT64(attr->size),
SILC_STR_END);
silc_buffer_pull(buffer, 8);
}
if (attr->flags & SILC_SFTP_ATTR_UIDGID) {
- silc_buffer_format(buffer,
- SILC_STR_UI_INT(attr->uid),
- SILC_STR_UI_INT(attr->gid),
+ silc_buffer_format(buffer,
+ SILC_STR_UI_INT(attr->uid),
+ SILC_STR_UI_INT(attr->gid),
SILC_STR_END);
silc_buffer_pull(buffer, 8);
}
if (attr->flags & SILC_SFTP_ATTR_PERMISSIONS) {
- silc_buffer_format(buffer,
- SILC_STR_UI_INT(attr->permissions),
+ silc_buffer_format(buffer,
+ SILC_STR_UI_INT(attr->permissions),
SILC_STR_END);
silc_buffer_pull(buffer, 4);
}
if (attr->flags & SILC_SFTP_ATTR_ACMODTIME) {
- silc_buffer_format(buffer,
- SILC_STR_UI_INT(attr->atime),
- SILC_STR_UI_INT(attr->mtime),
+ silc_buffer_format(buffer,
+ SILC_STR_UI_INT(attr->atime),
+ SILC_STR_UI_INT(attr->mtime),
SILC_STR_END);
silc_buffer_pull(buffer, 8);
}
if (attr->flags & SILC_SFTP_ATTR_EXTENDED) {
- silc_buffer_format(buffer,
- SILC_STR_UI_INT(attr->extended_count),
+ silc_buffer_format(buffer,
+ SILC_STR_UI_INT(attr->extended_count),
SILC_STR_END);
silc_buffer_pull(buffer, 4);
for (i = 0; i < attr->extended_count; i++) {
- ret =
- silc_buffer_format(buffer,
- SILC_STR_UI_INT(attr->extended_type[i]->len),
- SILC_STR_UI_XNSTRING(attr->extended_type[i]->data,
- attr->extended_type[i]->len),
- SILC_STR_UI_INT(attr->extended_data[i]->len),
- SILC_STR_UI_XNSTRING(attr->extended_data[i]->data,
- attr->extended_data[i]->len),
- SILC_STR_END);
+ ret =
+ silc_buffer_format(
+ buffer,
+ SILC_STR_UI_INT(silc_buffer_len(attr->extended_type[i])),
+ SILC_STR_DATA(silc_buffer_data(attr->extended_type[i]),
+ silc_buffer_len(attr->extended_type[i])),
+ SILC_STR_UI_INT(silc_buffer_len(attr->extended_data[i])),
+ SILC_STR_DATA(silc_buffer_data(attr->extended_data[i]),
+ silc_buffer_len(attr->extended_data[i])),
+ SILC_STR_END);
silc_buffer_pull(buffer, ret);
}
}
if (!attr)
return NULL;
- if (silc_buffer_unformat(buffer,
- SILC_STR_UI_INT(&attr->flags),
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI_INT(&attr->flags),
SILC_STR_END) < 0)
goto out;
silc_buffer_pull(buffer, 4);
if (attr->flags & SILC_SFTP_ATTR_SIZE) {
- if (silc_buffer_unformat(buffer,
- SILC_STR_UI_INT64(&attr->size),
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI_INT64(&attr->size),
SILC_STR_END) < 0)
goto out;
}
if (attr->flags & SILC_SFTP_ATTR_UIDGID) {
- if (silc_buffer_unformat(buffer,
- SILC_STR_UI_INT(&attr->uid),
- SILC_STR_UI_INT(&attr->gid),
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI_INT(&attr->uid),
+ SILC_STR_UI_INT(&attr->gid),
SILC_STR_END) < 0)
goto out;
}
if (attr->flags & SILC_SFTP_ATTR_PERMISSIONS) {
- if (silc_buffer_unformat(buffer,
- SILC_STR_UI_INT(&attr->permissions),
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI_INT(&attr->permissions),
SILC_STR_END) < 0)
goto out;
}
if (attr->flags & SILC_SFTP_ATTR_ACMODTIME) {
- if (silc_buffer_unformat(buffer,
- SILC_STR_UI_INT(&attr->atime),
- SILC_STR_UI_INT(&attr->mtime),
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI_INT(&attr->atime),
+ SILC_STR_UI_INT(&attr->mtime),
SILC_STR_END) < 0)
goto out;
if (attr->flags & SILC_SFTP_ATTR_EXTENDED) {
int i;
- if (silc_buffer_unformat(buffer,
- SILC_STR_UI_INT(&attr->extended_count),
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI_INT(&attr->extended_count),
SILC_STR_END) < 0)
goto out;
silc_buffer_pull(buffer, 4);
- attr->extended_type = silc_calloc(attr->extended_count,
+ attr->extended_type = silc_calloc(attr->extended_count,
sizeof(*attr->extended_type));
- attr->extended_data = silc_calloc(attr->extended_count,
+ attr->extended_data = silc_calloc(attr->extended_count,
sizeof(*attr->extended_data));
if (!attr->extended_type || !attr->extended_data)
return NULL;
unsigned char *tmp, *tmp2;
SilcUInt32 tmp_len, tmp2_len;
- if (silc_buffer_unformat(buffer,
+ if (silc_buffer_unformat(buffer,
SILC_STR_UI32_NSTRING(&tmp, &tmp_len),
SILC_STR_UI32_NSTRING(&tmp2, &tmp2_len),
SILC_STR_END) < 0)
{
name->filename = silc_realloc(name->filename, sizeof(*name->filename) *
(name->count + 1));
- name->long_filename = silc_realloc(name->long_filename,
+ name->long_filename = silc_realloc(name->long_filename,
sizeof(*name->long_filename) *
(name->count + 1));
name->attrs = silc_realloc(name->attrs, sizeof(*name->attrs) *
name->count++;
}
-/* Encodes the SilcSFTPName to a buffer and returns the allocated buffer.
+/* Encodes the SilcSFTPName to a buffer and returns the allocated buffer.
The caller must free the buffer. */
SilcBuffer silc_sftp_name_encode(SilcSFTPName name)
attr_buf[i] = silc_sftp_attr_encode(name->attrs[i]);
if (!attr_buf[i])
return NULL;
- len += attr_buf[i]->len;
+ len += silc_buffer_len(attr_buf[i]);
}
buffer = silc_buffer_alloc(len);
if (!buffer)
return NULL;
- silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
+ silc_buffer_end(buffer);
silc_buffer_format(buffer,
SILC_STR_UI_INT(name->count),
SILC_STR_UI32_STRING(name->filename[i]),
SILC_STR_UI_INT(strlen(name->long_filename[i])),
SILC_STR_UI32_STRING(name->long_filename[i]),
- SILC_STR_UI_XNSTRING(attr_buf[i]->data,
- attr_buf[i]->len),
+ SILC_STR_DATA(silc_buffer_data(attr_buf[i]),
+ silc_buffer_len(attr_buf[i])),
SILC_STR_END);
silc_buffer_pull(buffer, len);
name->count = count;
for (i = 0; i < count; i++) {
- ret =
+ ret =
silc_buffer_unformat(buffer,
SILC_STR_UI32_STRING_ALLOC(&name->filename[i]),
SILC_STR_UI32_STRING_ALLOC(&name->long_filename[i]),
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2005 Pekka Riikonen
+ Copyright (C) 2001 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*
* DESCRIPTION
*
- * SILC SFTP Interface is the implementation of the Secure File Transfer
- * Protocol. The interface defines the SFTP client and the SFTP server.
- * The SFTP is the mandatory file transfer protocol in the SILC protocol.
- * The SFTP server implementation is filesystem independent and generic
- * interface is defined to represent filesystem access.
+ * SILC SFTP Interface is the implementation of the Secure File Transfer
+ * Protocol (or SSH File Transfer Protocol). The interface defines the SFTP
+ * client and the SFTP server. The SFTP is the mandatory file transfer
+ * protocol in the SILC protocol, and when used in SILC the SFTP packets are
+ * encapsulated into SILC packets. The SFTP server implementation is
+ * filesystem independent and generic interface is defined to represent
+ * filesystem access.
*
- * The SilcSFTP context is the actual SFTP client or SFTP server, and
- * each SFTP session (associated to a socket connection) must create
- * own SFTP context.
+ * The SilcSFTP context is the actual SFTP client or SFTP server, and each
+ * SFTP session should create its own SFTP context.
+ *
+ * The SILC SFTP library is a generic SFTP implementation and not directly
+ * related to either SILC or SSH. It could be used for any general purpose
+ * SFTP application.
*
***/
SILC_SFTP_STATUS_PERMISSION_DENIED = 3, /* No sufficient permissions */
SILC_SFTP_STATUS_FAILURE = 4, /* Operation failed */
SILC_SFTP_STATUS_BAD_MESSAGE = 5, /* Bad message received */
- SILC_SFTP_STATUS_NO_CONNECTION = 6, /* No connection to server */
+ SILC_SFTP_STATUS_NO_CONNECTION = 6, /* No connection to remote */
SILC_SFTP_STATUS_CONNECTION_LOST = 7, /* Connection lost to server */
SILC_SFTP_STATUS_OP_UNSUPPORTED = 8, /* Operation unsupported */
SILC_SFTP_STATUS_INVALID_HANDLE = 9, /* Invalid file handle */
***/
typedef struct SilcSFTPHandleStruct *SilcSFTPHandle;
-/****f* silcsftp/SilcSFTPAPI/SilcSFTPSendPacketCallback
- *
- * SYNOPSIS
- *
- * typedef void (*SilcSFTPSendPacketCallback)(SilcBuffer packet,
- * void *context);
- *
- * DESCRIPTION
- *
- * Packet sending callback. The caller of this interface will provide this
- * function for the library. The libary will call this function everytime
- * it needs to send a packet to the remote host.
- *
- ***/
-typedef void (*SilcSFTPSendPacketCallback)(SilcBuffer packet, void *context);
-
/****f* silcsftp/SilcSFTPAPI/SilcSFTPVersionCallback
*
* SYNOPSIS
SilcSFTPVersion version,
void *context);
+/****f* silcsftp/SilcSFTPAPI/SilcSFTPErrorCallback
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcSFTPErrorCallback)(SilcSFTP sftp,
+ * SilcSFTPStatus status,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Error callback is called if a connection error occurs during SFTP
+ * session. If the connection or stream is closed this callback is
+ * called. Other errors are delivered in other callbacks.
+ *
+ ***/
+typedef void (*SilcSFTPErrorCallback)(SilcSFTP sftp,
+ SilcSFTPStatus status,
+ void *context);
+
/****f* silcsftp/SilcSFTPAPI/SilcSFTPStatusCallback
*
* SYNOPSIS
* SYNOPSIS
*
* SilcSFTP silc_sftp_client_start(SilcStream stream,
- * SilcSFTPVersionCallback callback,
+ * SilcSchedule schedule,
+ * SilcSFTPVersionCallback version_cb,
+ * SilcSFTPErrorCallback error_cb,
* void *context);
*
* DESCRIPTION
* been started and server has returned the version of the protocol. The
* SFTP client context is returned in the callback too. This returns the
* allocated SFTP client context or NULL on error. The `stream' will be
- * used to read from and write to the SFTP packets.
+ * used to read and write the SFTP packets.
*
***/
SilcSFTP silc_sftp_client_start(SilcStream stream,
- SilcSFTPVersionCallback callback,
+ SilcSchedule schedule,
+ SilcSFTPVersionCallback version_cb,
+ SilcSFTPErrorCallback error_cb,
void *context);
/****f* silcsftp/SilcSFTPAPI/silc_sftp_client_shutdown
*
* SYNOPSIS
*
- * SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
- * void *send_context,
+ * SilcSFTP silc_sftp_server_start(SilcStream stream,
+ * SilcSchedule schedule,
+ * SilcSFTPErrorCallback error_cb,
+ * void *context,
* SilcSFTPFilesystem fs);
*
* DESCRIPTION
* should start its own server by calling this function.
*
***/
-SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
- void *send_context,
+SilcSFTP silc_sftp_server_start(SilcStream stream,
+ SilcSchedule schedule,
+ SilcSFTPErrorCallback error_cb,
+ void *context,
SilcSFTPFilesystem fs);
/****f* silcsftp/SilcSFTPAPI/silc_sftp_server_shutdown
AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
-bin_PROGRAMS = sftp_server sftp_client
+bin_PROGRAMS = sftp_client sftp_server
sftp_server_SOURCES = sftp_server.c
sftp_client_SOURCES = sftp_client.c
/*
- sftp_client.c
+ sftp_client.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 Pekka Riikonen
+ Copyright (C) 2001 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
typedef struct {
SilcSchedule schedule;
- SilcSocketConnection sock;
+ SilcStream stream;
SilcSFTP sftp;
} *Client;
void *context);
static void end_test(void);
-static void send_packet(SilcBuffer packet, void *context)
-{
- Client client = (Client)context;
- SilcSocketConnection sock = client->sock;
- SilcPacketContext packetdata;
- const SilcBufferStruct p;
- int ret;
-
- memset(&packetdata, 0, sizeof(packetdata));
- packetdata.type = SILC_PACKET_FTP;
- packetdata.truelen = packet->len + SILC_PACKET_HEADER_LEN;
- SILC_PACKET_PADLEN(packetdata.truelen, 0, packetdata.padlen);
- silc_packet_assemble(&packetdata, NULL, NULL, NULL, sock,
- packet->data, packet->len, (const SilcBuffer)&p);
- ret = silc_packet_send(sock, TRUE);
- if (ret != -2)
- return;
-
- silc_schedule_set_listen_fd(client->schedule, sock->sock,
- (SILC_TASK_READ | SILC_TASK_WRITE), FALSE);
- SILC_SET_OUTBUF_PENDING(sock);
-}
-
-static bool packet_parse(SilcPacketParserContext *parser, void *context)
-{
- Client client = (Client)parser->context;
- SilcSocketConnection sock = parser->sock;
- SilcPacketContext *packet = parser->packet;
- int ret;
-
- ret = silc_packet_parse(packet, NULL);
- assert(packet->type == SILC_PACKET_FTP);
-
- silc_sftp_client_receive_process(client->sftp, sock, packet);
-
- return TRUE;
-}
-
-SILC_TASK_CALLBACK(packet_process)
-{
- Client client = (Client)context;
- SilcSocketConnection sock = client->sock;
- int ret;
-
- if (type == SILC_TASK_WRITE) {
- if (sock->outbuf->data - sock->outbuf->head)
- silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
-
- ret = silc_packet_send(sock, TRUE);
- if (ret < 0)
- return;
-
- silc_schedule_set_listen_fd(client->schedule, fd, SILC_TASK_READ, FALSE);
- SILC_UNSET_OUTBUF_PENDING(sock);
- silc_buffer_clear(sock->outbuf);
- return;
-
- }
-
- if (type == SILC_TASK_READ) {
- ret = silc_packet_receive(sock);
- if (ret < 0)
- return;
-
- if (ret == 0) {
- silc_net_close_connection(sock->sock);
- silc_socket_free(sock);
- exit(0);
- }
-
- silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
- packet_parse, client);
- }
-}
-
static void sftp_status(SilcSFTP sftp, SilcSFTPStatus status,
const char *message, const char *lang_tag,
void *context)
const SilcSFTPAttributes attrs, void *context)
{
SilcSFTPHandle handle = (SilcSFTPHandle)context;
- int debug = silc_debug;
int i;
-
+
fprintf(stderr, "Status %d\n", status);
if (status != SILC_SFTP_STATUS_OK) {
SILC_LOG_DEBUG(("Error status"));
end_test();
return;
}
-
- if (!debug)
- silc_debug = 1;
+
SILC_LOG_DEBUG(("Attr.flags: %d", attrs->flags));
SILC_LOG_DEBUG(("Attr.size: %lu", attrs->size));
for (i = 0; i < attrs->extended_count; i++) {
SILC_LOG_HEXDUMP(("Attr.extended_type[i]:", i),
attrs->extended_type[i]->data,
- attrs->extended_type[i]->len);
+ silc_buffer_len(attrs->extended_type[i]));
SILC_LOG_HEXDUMP(("Attr.extended_data[i]:", i),
attrs->extended_data[i]->data,
- attrs->extended_data[i]->len);
+ silc_buffer_len(attrs->extended_data[i]));
}
-
- silc_debug = debug;
if (!file) {
- fprintf(stderr, "Closing file\n");
+ fprintf(stderr, "Closing file\n");
silc_sftp_close(sftp, handle, sftp_status, context);
return;
}
-
- fprintf(stderr, "LStatting file %s\n", file);
+
+ fprintf(stderr, "LStatting file %s\n", file);
silc_sftp_lstat(sftp, file, sftp_attr, context);
file = NULL;
}
void *context)
{
SilcSFTPHandle handle = (SilcSFTPHandle)context;
- int debug = silc_debug;
if (status != SILC_SFTP_STATUS_OK) {
SilcSFTPAttributesStruct attrs;
end_test();
return;
}
-
+
if (!strcmp(file, "/sftp/sftp_server.c")) {
- fprintf(stderr, "FStatting file handle %s\n", file);
+ fprintf(stderr, "FStatting file handle %s\n", file);
silc_sftp_fstat(sftp, handle, sftp_attr, context);
return;
}
-
+
/* Open another file */
opendir = FALSE;
memset(&attrs, 0, sizeof(attrs));
return;
}
- if (!debug)
- silc_debug = 1;
SILC_LOG_HEXDUMP(("data"), (unsigned char *)data, data_len);
- silc_debug = debug;
offset += data_len;
end_test();
return;
}
-
+
fprintf(stderr, "Directory: %s\n", dir);
for (i = 0; i < name->count; i++) {
fprintf(stderr, "%s\n", name->long_filename[i]);
end_test();
return;
}
-
+
if (opendir) {
fprintf(stderr, "Reading %s\n", dir);
/* Readdir */
silc_sftp_opendir(sftp, dir, sftp_handle, client);
}
+static void sftp_error(SilcSFTP sftp, SilcSFTPStatus status,
+ void *context)
+{
+ Client client = context;
+ SILC_LOG_DEBUG(("Error %d", status));
+ silc_stream_destroy(client->stream);
+ success = FALSE;
+ end_test();
+}
+
+static void connect_callback(SilcNetStatus status, SilcStream stream,
+ void *context)
+{
+ Client client = context;
+
+ if (!stream) {
+ SILC_LOG_DEBUG(("Connect error"));
+ success = FALSE;
+ end_test();
+ }
+
+ /* Start SFTP session */
+ client->stream = stream;
+ client->sftp = silc_sftp_client_start(stream, client->schedule, sftp_version,
+ sftp_error, client);
+ if (!client->sftp) {
+ success = FALSE;
+ end_test();
+ }
+}
+
int main(int argc, char **argv)
{
Client client = silc_calloc(1, sizeof(*client));
- int sock;
gclient = client;
- if (argc > 1 && !strcmp(argv[1], "-d")) {
- silc_debug = 1;
- silc_debug_hexdump = 1;
- silc_log_set_debug_string("*sftp*");
+ if (argc > 1) {
+ if (!strcmp(argv[1], "-d"))
+ silc_log_debug(TRUE);
+ if (argc > 2 && !strcmp(argv[2], "-x"))
+ silc_log_debug_hexdump(TRUE);
+ silc_log_set_debug_string("*");
}
- client->schedule = silc_schedule_init(100, NULL);
+ client->schedule = silc_schedule_init(0, NULL);
if (!client->schedule)
return -1;
/* Connecto to server */
- sock = silc_net_create_connection(NULL, 5000, "127.0.0.1");
- if (sock < 0)
- return -1;
- silc_socket_alloc(sock, 0, NULL, &client->sock);
- silc_schedule_task_add(client->schedule, sock,
- packet_process, client, 0, 0,
- SILC_TASK_GENERIC, SILC_TASK_PRI_NORMAL);
-
- /* Start SFTP session */
- client->sftp = silc_sftp_client_start(send_packet, client,
- sftp_version, client);
+ silc_net_tcp_connect(NULL, "127.0.0.1", 5000, client->schedule,
+ connect_callback, client);
silc_schedule(client->schedule);
return 0;
/*
- sprp_server.c
+ sprp_server.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 Pekka Riikonen
+ Copyright (C) 2001 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "silc.h"
#include "silcsftp.h"
-typedef struct {
- SilcSocketConnection sock;
- void *server;
+typedef struct ServerSessionStruct {
+ SilcStream stream;
+ SilcSFTP sftp;
} *ServerSession;
typedef struct {
SilcSchedule schedule;
- int sock;
+ SilcNetListener listener;
SilcSFTPFilesystem fs;
- ServerSession sessions[100];
- SilcSFTP sftp[100];
} *Server;
-static void send_packet(SilcBuffer packet, void *context)
+static void error_cb(SilcSFTP sftp, SilcSFTPStatus status, void *context)
{
ServerSession session = context;
- Server server = session->server;
- SilcPacketContext packetdata;
- const SilcBufferStruct p;
- int ret;
-
- memset(&packetdata, 0, sizeof(packetdata));
- packetdata.type = SILC_PACKET_FTP;
- packetdata.truelen = packet->len + SILC_PACKET_HEADER_LEN;
- SILC_PACKET_PADLEN(packetdata.truelen, 0, packetdata.padlen);
- silc_packet_assemble(&packetdata, NULL, NULL, NULL, session->sock,
- packet->data, packet->len, (const SilcBuffer)&p);
- ret = silc_packet_send(session->sock, TRUE);
- if (ret != -2)
- return;
- silc_schedule_set_listen_fd(server->schedule, session->sock->sock,
- (SILC_TASK_READ | SILC_TASK_WRITE), FALSE);
- SILC_SET_OUTBUF_PENDING(session->sock);
-}
-
-static bool packet_parse(SilcPacketParserContext *parser, void *context)
-{
- Server server = (Server)parser->context;
- SilcSocketConnection sock = parser->sock;
- SilcPacketContext *packet = parser->packet;
- int ret;
-
- ret = silc_packet_parse(packet, NULL);
- assert(packet->type == SILC_PACKET_FTP);
-
- silc_sftp_server_receive_process(server->sftp[sock->sock], sock, packet);
+ if (status == SILC_SFTP_STATUS_EOF) {
+ SILC_LOG_DEBUG(("Eof"));
+ silc_stream_destroy(session->stream);
+ silc_free(session);
+ }
- return TRUE;
+ SILC_LOG_DEBUG(("Error %d", status));
}
-SILC_TASK_CALLBACK(packet_process)
+static void net_callback(SilcNetStatus status, SilcStream stream,
+ void *context)
{
Server server = context;
- ServerSession session = server->sessions[fd];
- SilcSocketConnection sock;
- int ret;
-
- if (!session)
- return;
- sock = session->sock;
-
- if (type == SILC_TASK_WRITE) {
- if (sock->outbuf->data - sock->outbuf->head)
- silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
+ ServerSession session;
- ret = silc_packet_send(sock, TRUE);
- if (ret < 0)
- return;
+ SILC_LOG_DEBUG(("New connection"));
- silc_schedule_set_listen_fd(server->schedule, fd, SILC_TASK_READ, FALSE);
- SILC_UNSET_OUTBUF_PENDING(sock);
- silc_buffer_clear(sock->outbuf);
+ session = silc_calloc(1, sizeof(*session));
+ if (!session)
return;
- }
+ session->stream = stream;
+ session->sftp = silc_sftp_server_start(stream, server->schedule, error_cb,
+ session, server->fs);
- if (type == SILC_TASK_READ) {
- ret = silc_packet_receive(sock);
- if (ret < 0)
- return;
-
- if (ret == 0) {
- silc_net_close_connection(sock->sock);
- silc_schedule_unset_listen_fd(server->schedule, sock->sock);
- silc_free(server->sessions[sock->sock]);
- server->sessions[sock->sock] = NULL;
- silc_socket_free(sock);
- return;
- }
-
- silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, packet_parse,
- server);
- }
-}
-
-SILC_TASK_CALLBACK(accept_connection)
-{
- Server server = (Server)context;
- SilcSocketConnection sc;
- int sock;
-
- sock = silc_net_accept_connection(server->sock);
- if (sock < 0)
- exit(1);
-
- silc_net_set_socket_nonblock(sock);
- silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
-
- silc_socket_alloc(sock, 0, NULL, &sc);
- server->sessions[sock] = silc_calloc(1, sizeof(server->sessions[0]));
- server->sessions[sock]->sock = sc;
- server->sessions[sock]->server = server;
- server->sftp[sock] =
- silc_sftp_server_start(send_packet, server->sessions[sock],
- server->fs);
- silc_schedule_task_add(server->schedule, sock, packet_process,
- server, 0, 0, SILC_TASK_GENERIC,
- SILC_TASK_PRI_NORMAL);
}
int main()
{
Server server = silc_calloc(1, sizeof(*server));
void *dir;
+ const char *ip = "127.0.0.1";
- silc_debug = 1;
- silc_debug_hexdump = 1;
+ silc_log_debug(TRUE);
+ silc_log_debug_hexdump(TRUE);
silc_log_set_debug_string("*sftp*");
-
- server->schedule = silc_schedule_init(100, NULL);
+
+ server->schedule = silc_schedule_init(0, NULL);
if (!server->schedule)
return -1;
- server->sock = silc_net_create_server(5000, NULL);
- if (server->sock < 0)
+ server->listener = silc_net_tcp_create_listener(&ip, 1, 5000, FALSE,
+ FALSE, server->schedule,
+ net_callback, server);
+ if (!server->listener)
return -1;
/* Make test filesystem hierarchy */
silc_sftp_fs_memory_add_file(server->fs, NULL, SILC_SFTP_FS_PERM_EXEC,
"testi", "file://sftp_client.c");
- silc_schedule_task_add(server->schedule, server->sock,
- accept_connection, server, 0, 0,
- SILC_TASK_FD, SILC_TASK_PRI_NORMAL);
silc_schedule(server->schedule);
return 0;