/*
- 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;