From 6f25b5bdcdbcb21dbfb1c86fd79bfd5b71b027db Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Fri, 12 Oct 2001 18:09:50 +0000 Subject: [PATCH] updates. --- CHANGES | 14 ++ apps/silcd/packet_receive.c | 2 +- apps/silcd/packet_send.c | 49 ++++--- apps/silcd/packet_send.h | 36 ++--- apps/silcd/server_backup.c | 102 ++++++++------ apps/silcd/server_util.c | 13 +- doc/examples/cell1_backup.conf | 8 +- doc/examples/cell1_router.conf | 8 +- doc/examples/cell2_router.conf | 8 +- doc/examples/cell3_router.conf | 8 +- lib/silcsftp/sftp_fs_memory.c | 56 ++++---- lib/silcsftp/sftp_server.c | 127 +++++++++-------- lib/silcsftp/silcsftp.h | 197 +------------------------- lib/silcsftp/silcsftp_fs.h | 229 +++++++++++++++++++++++++++++-- lib/silcsftp/tests/sftp_server.c | 4 +- 15 files changed, 464 insertions(+), 397 deletions(-) diff --git a/CHANGES b/CHANGES index 477550ee..be2ef058 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,17 @@ +Fri Oct 12 18:37:24 EDT 2001 Pekka Riikonen + + * Fixed the backup resuming protocol to work in multiple + router environment. Affected file silcd/server_backup.c. + + * Route packet only to one router in the function + silc_server_packet_send_to_channel. Affected file is + silcd/packet_send.c. + + * Fixed silc_server_send_notify_dest to set the broadcast + flag. Fixed the silc_server_send_notify_topic to actually + send the TOPIC_CHANGE notify and not SERVER_SIGNOFF notify. + Affected file silcd/packet_send.c. + Thu Oct 11 22:19:26 EDT 2001 Pekka Riikonen * Changed the backup router adding and getting interfaces diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 47d7cf0a..044bb49c 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1725,7 +1725,7 @@ SilcServerEntry silc_server_new_server(SilcServer server, packet->data, packet->len, TRUE); silc_buffer_free(packet); - /* Mark the server disabled. The data sent earlier will go but nothing + /* Mark the router disabled. The data sent earlier will go but nothing after this does not go to this connection. */ idata->status |= SILC_IDLIST_STATUS_DISABLED; } diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 535ebc0e..c6fcdf1a 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -448,6 +448,7 @@ void silc_server_packet_send_to_channel(SilcServer server, SilcHashTableList htl; SilcIDListData idata; uint32 routed_count = 0; + bool gone = FALSE; /* This doesn't send channel message packets */ assert(type != SILC_PACKET_CHANNEL_MESSAGE); @@ -515,6 +516,13 @@ void silc_server_packet_send_to_channel(SilcServer server, if (sender && sock == sender) continue; + /* Route only once to router */ + if (sock->type == SILC_SOCKET_TYPE_ROUTER) { + if (gone) + continue; + gone = TRUE; + } + /* Send the packet */ silc_server_packet_send_to_channel_real(server, sock, &packetdata, idata->send_key, @@ -962,7 +970,7 @@ void silc_server_send_error(SilcServer server, void silc_server_send_notify(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcNotifyType type, uint32 argc, ...) { @@ -992,7 +1000,7 @@ void silc_server_send_notify(SilcServer server, void silc_server_send_notify_args(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcNotifyType type, uint32 argc, SilcBuffer args) @@ -1011,7 +1019,7 @@ void silc_server_send_notify_args(SilcServer server, void silc_server_send_notify_channel_change(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelID *old_id, SilcChannelID *new_id) { @@ -1032,7 +1040,7 @@ void silc_server_send_notify_channel_change(SilcServer server, void silc_server_send_notify_nick_change(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *old_id, SilcClientID *new_id) { @@ -1053,7 +1061,7 @@ void silc_server_send_notify_nick_change(SilcServer server, void silc_server_send_notify_join(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id) { @@ -1073,7 +1081,7 @@ void silc_server_send_notify_join(SilcServer server, void silc_server_send_notify_leave(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id) { @@ -1092,7 +1100,7 @@ void silc_server_send_notify_leave(SilcServer server, void silc_server_send_notify_cmode(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, uint32 mode_mask, void *id, SilcIdType id_type, @@ -1119,7 +1127,7 @@ void silc_server_send_notify_cmode(SilcServer server, void silc_server_send_notify_cumode(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, uint32 mode_mask, void *id, SilcIdType id_type, @@ -1149,7 +1157,7 @@ void silc_server_send_notify_cumode(SilcServer server, void silc_server_send_notify_signoff(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *client_id, char *message) { @@ -1170,7 +1178,7 @@ void silc_server_send_notify_signoff(SilcServer server, void silc_server_send_notify_topic_set(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id, char *topic) @@ -1179,7 +1187,7 @@ void silc_server_send_notify_topic_set(SilcServer server, idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_SERVER_SIGNOFF, + SILC_NOTIFY_TYPE_TOPIC_SET, topic ? 2 : 1, idp->data, idp->len, topic, topic ? strlen(topic) : 0); @@ -1193,7 +1201,7 @@ void silc_server_send_notify_topic_set(SilcServer server, void silc_server_send_notify_kicked(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id, char *comment) @@ -1214,7 +1222,7 @@ void silc_server_send_notify_kicked(SilcServer server, void silc_server_send_notify_killed(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *client_id, char *comment) { @@ -1234,7 +1242,7 @@ void silc_server_send_notify_killed(SilcServer server, void silc_server_send_notify_umode(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *client_id, uint32 mode_mask) { @@ -1257,7 +1265,7 @@ void silc_server_send_notify_umode(SilcServer server, void silc_server_send_notify_ban(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, char *add, char *del) { @@ -1279,7 +1287,7 @@ void silc_server_send_notify_ban(SilcServer server, void silc_server_send_notify_invite(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id, char *add, char *del) @@ -1303,7 +1311,7 @@ void silc_server_send_notify_invite(SilcServer server, void silc_server_send_notify_dest(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, void *dest_id, SilcIdType dest_id_type, SilcNotifyType type, @@ -1315,7 +1323,8 @@ void silc_server_send_notify_dest(SilcServer server, va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); - silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0, + silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, + broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, dest_id, dest_id_type, packet->data, packet->len, FALSE); silc_buffer_free(packet); @@ -1508,7 +1517,7 @@ void silc_server_send_notify_on_channels(SilcServer server, void silc_server_send_new_id(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, void *id, SilcIdType id_type, uint32 id_len) { @@ -1538,7 +1547,7 @@ void silc_server_send_new_id(SilcServer server, void silc_server_send_new_channel(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, char *channel_name, void *channel_id, uint32 channel_id_len, diff --git a/apps/silcd/packet_send.h b/apps/silcd/packet_send.h index b055904d..f8c98233 100644 --- a/apps/silcd/packet_send.h +++ b/apps/silcd/packet_send.h @@ -95,90 +95,90 @@ void silc_server_send_error(SilcServer server, const char *fmt, ...); void silc_server_send_notify(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcNotifyType type, uint32 argc, ...); void silc_server_send_notify_args(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcNotifyType type, uint32 argc, SilcBuffer args); void silc_server_send_notify_channel_change(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelID *old_id, SilcChannelID *new_id); void silc_server_send_notify_nick_change(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *old_id, SilcClientID *new_id); void silc_server_send_notify_join(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id); void silc_server_send_notify_leave(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id); void silc_server_send_notify_cmode(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, uint32 mode_mask, void *id, SilcIdType id_type, char *cipher, char *hmac); void silc_server_send_notify_cumode(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, uint32 mode_mask, void *id, SilcIdType id_type, SilcClientID *target); void silc_server_send_notify_signoff(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *client_id, char *message); void silc_server_send_notify_topic_set(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id, char *topic); void silc_server_send_notify_kicked(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id, char *comment); void silc_server_send_notify_killed(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *client_id, char *comment); void silc_server_send_notify_umode(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcClientID *client_id, uint32 mode_mask); void silc_server_send_notify_ban(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, char *add, char *del); void silc_server_send_notify_invite(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, SilcChannelEntry channel, SilcClientID *client_id, char *add, char *del); void silc_server_send_notify_dest(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, void *dest_id, SilcIdType dest_id_type, SilcNotifyType type, @@ -196,12 +196,12 @@ void silc_server_send_notify_on_channels(SilcServer server, uint32 argc, ...); void silc_server_send_new_id(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, void *id, SilcIdType id_type, uint32 id_len); void silc_server_send_new_channel(SilcServer server, SilcSocketConnection sock, - int broadcast, + bool broadcast, char *channel_name, void *channel_id, uint32 channel_id_len, diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index 3a16e54a..8f345508 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -401,7 +401,8 @@ void silc_server_backup_resume_router(SilcServer server, SilcPacketContext *packet) { uint8 type, session; - int ret; + SilcServerBackupProtocolContext ctx; + int i, ret; if (sock->type == SILC_SOCKET_TYPE_CLIENT || sock->type == SILC_SOCKET_TYPE_UNKNOWN) @@ -409,7 +410,6 @@ void silc_server_backup_resume_router(SilcServer server, SILC_LOG_DEBUG(("Start")); - SILC_LOG_DEBUG(("********************************")); ret = silc_buffer_unformat(packet->buffer, SILC_STR_UI_CHAR(&type), SILC_STR_UI_CHAR(&session), @@ -417,14 +417,34 @@ void silc_server_backup_resume_router(SilcServer server, if (ret < 0) return; - SILC_LOG_DEBUG(("********************************")); + /* Activate the protocol for this socket if necessary */ + if ((type == SILC_SERVER_BACKUP_RESUMED || + type == SILC_SERVER_BACKUP_RESUMED_GLOBAL) && + sock->type == SILC_SOCKET_TYPE_ROUTER && !sock->protocol && + ((SilcIDListData)sock->user_data)->status & + SILC_IDLIST_STATUS_DISABLED) { + SilcServerEntry backup_router; + + if (silc_server_backup_replaced_get(server, + ((SilcServerEntry)sock-> + user_data)->id, + &backup_router)) { + SilcSocketConnection bsock = + (SilcSocketConnection)backup_router->connection; + if (bsock->protocol && bsock->protocol->protocol && + bsock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP) { + sock->protocol = bsock->protocol; + ctx = sock->protocol->context; + ctx->sock = sock; + } + } + } + /* If the backup resuming protocol is active then process the packet in the protocol. */ if (sock->protocol && sock->protocol->protocol && sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP) { - SilcServerBackupProtocolContext ctx = sock->protocol->context; - int i; - + ctx = sock->protocol->context; ctx->type = type; SILC_LOG_DEBUG(("********************************")); @@ -448,7 +468,6 @@ void silc_server_backup_resume_router(SilcServer server, return; } - SILC_LOG_DEBUG(("********************************")); /* We don't have protocol active. If we are router and the packet is coming from our primary router then lets check whether it means we've been replaced by an backup router in my cell. This is usually received @@ -463,14 +482,13 @@ void silc_server_backup_resume_router(SilcServer server, SilcIDListData idata = (SilcIDListData)sock->user_data; SILC_LOG_INFO(("We are replaced by an backup router in this cell, will " - "wait untill backup resuming protocol is executed")); + "wait until backup resuming protocol is executed")); SILC_LOG_DEBUG(("We are replaced by an backup router in this cell")); idata->status |= SILC_IDLIST_STATUS_DISABLED; return; } - SILC_LOG_DEBUG(("********************************")); if (type == SILC_SERVER_BACKUP_START || type == SILC_SERVER_BACKUP_START_GLOBAL) { /* We have received a start for resuming protocol. */ @@ -492,7 +510,6 @@ void silc_server_backup_resume_router(SilcServer server, silc_server_protocol_backup_done); silc_protocol_execute(sock->protocol, server->schedule, 0, 0); } - SILC_LOG_DEBUG(("EEEEEEEEEEEEEEEEEEEEEEEEe")); } /* Timeout task callback to connect to remote router */ @@ -949,6 +966,8 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) silc_buffer_free(packet); + SILC_LOG_INFO(("We are now the primary router of our cell again")); + /* For us this is the end of this protocol. */ if (protocol->final_callback) silc_protocol_execute_final(protocol, server->schedule); @@ -960,8 +979,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) case SILC_PROTOCOL_STATE_END: { SilcIDListData idata; - SilcServerEntry primary; - SilcServerEntry backup_router; + SilcServerEntry router, backup_router; /* We should have been received RESUMED packet from our primary router. */ @@ -978,45 +996,43 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) if (server->backup_router) server->server_type = SILC_BACKUP_ROUTER; - primary = (SilcServerEntry)ctx->sock->user_data; - if (silc_server_backup_replaced_get(server, primary->id, + router = (SilcServerEntry)ctx->sock->user_data; + if (silc_server_backup_replaced_get(server, router->id, &backup_router)) { if (backup_router == server->router) { - server->id_entry->router = ctx->sock->user_data; - server->router = ctx->sock->user_data; SILC_LOG_INFO(("Switching back to primary router %s", server->router->server_name)); - SILC_LOG_DEBUG(("********************************")); SILC_LOG_DEBUG(("Switching back to primary router %s", server->router->server_name)); - idata = (SilcIDListData)server->router; - idata->status &= ~SILC_IDLIST_STATUS_DISABLED; - - /* Update the client entries of the backup router to the new - primary router. */ - silc_server_update_clients_by_server(server, backup_router, - primary, TRUE, FALSE); - silc_server_backup_replaced_del(server, backup_router); - silc_server_backup_add(server, backup_router, - ((SilcSocketConnection)primary-> - connection)->ip, - ((SilcSocketConnection)primary-> - connection)->port, - backup_router->server_type != SILC_ROUTER ? - TRUE : FALSE); + server->id_entry->router = router; + server->router = router; + } else { + SILC_LOG_INFO(("Resuming the use of router %s", + router->server_name)); + SILC_LOG_DEBUG(("Resuming the use of router %s", + router->server_name)); } - /* Announce all of our information to the new primary router. */ + idata = (SilcIDListData)server->router; + idata->status &= ~SILC_IDLIST_STATUS_DISABLED; + + /* Update the client entries of the backup router to the new router */ + silc_server_update_clients_by_server(server, backup_router, + router, FALSE, FALSE); + silc_server_backup_replaced_del(server, backup_router); + silc_server_backup_add(server, backup_router, + ctx->sock->ip, ctx->sock->port, + backup_router->server_type != SILC_ROUTER ? + TRUE : FALSE); + + /* Announce all of our information to the router. */ if (server->server_type == SILC_ROUTER) - silc_server_announce_servers(server, FALSE, 0, - server->router->connection); + silc_server_announce_servers(server, FALSE, 0, router->connection); /* Announce our clients and channels to the router */ - silc_server_announce_clients(server, 0, - server->router->connection); - silc_server_announce_channels(server, 0, - server->router->connection); + silc_server_announce_clients(server, 0, router->connection); + silc_server_announce_channels(server, 0, router->connection); } /* Protocol has ended, call the final callback */ @@ -1065,15 +1081,19 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) SILC_LOG_ERROR(("Error occurred during backup router resuming protcool")); } + /* Remove this protocol from all server entries that has it */ if (silc_idcache_get_all(server->local_list->servers, &list)) { if (silc_idcache_list_first(list, &id_cache)) { while (id_cache) { server_entry = (SilcServerEntry)id_cache->context; sock = (SilcSocketConnection)server_entry->connection; - if (sock->protocol && sock->protocol->protocol && - sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP) + if (sock->protocol == protocol) { sock->protocol = NULL; + + if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED) + server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED; + } if (!silc_idcache_list_next(list, &id_cache)) break; diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 2d65c43f..7c6c1b3d 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -381,6 +381,11 @@ void silc_server_update_clients_by_server(SilcServer server, SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id, + SILC_ID_SERVER))); + SILC_LOG_DEBUG(("to %s", silc_id_render(to->id, + SILC_ID_SERVER))); + if (silc_idcache_get_all(server->local_list->clients, &list)) { if (silc_idcache_list_first(list, &id_cache)) { while (id_cache) { @@ -394,8 +399,8 @@ void silc_server_update_clients_by_server(SilcServer server, if (client->router == from) { /* Skip clients that are *really* owned by the `from' */ - if (SILC_ID_COMPARE(from->id, client->id, - client->id->ip.data_len)) { + if (remove_from && SILC_ID_COMPARE(from->id, client->id, + client->id->ip.data_len)) { SILC_LOG_DEBUG(("Found really owned client, skip it")); if (!silc_idcache_list_next(list, &id_cache)) break; @@ -433,8 +438,8 @@ void silc_server_update_clients_by_server(SilcServer server, if (client->router == from) { /* Skip clients that are *really* owned by the `from' */ - if (SILC_ID_COMPARE(from->id, client->id, - client->id->ip.data_len)) { + if (remove_from && SILC_ID_COMPARE(from->id, client->id, + client->id->ip.data_len)) { SILC_LOG_DEBUG(("Found really owned client, skip it")); if (!silc_idcache_list_next(list, &id_cache)) break; diff --git a/doc/examples/cell1_backup.conf b/doc/examples/cell1_backup.conf index 24cb20f0..00a076ed 100644 --- a/doc/examples/cell1_backup.conf +++ b/doc/examples/cell1_backup.conf @@ -34,10 +34,10 @@ backup.cell1.com:212.146.42.100:Kuopio, Finland:706 212.146.42.100:212.146.42.100:706 [Logging] -#infologfile:silcd2.log:10000 -#warninglogfile:/var/log/silcd_warning.log:10000 -#errorlogfile:silcd2.log:10000 -#fatallogfile:/var/log/silcd_error.log: +infologfile:cell1_backup.log: +warninglogfile:cell1_backup.log: +errorlogfile:cell1_backup.log: +fatallogfile:cell1_backup.log: [ConnectionClass] 1:100:100:100 diff --git a/doc/examples/cell1_router.conf b/doc/examples/cell1_router.conf index f243e09c..1c9e41a4 100644 --- a/doc/examples/cell1_router.conf +++ b/doc/examples/cell1_router.conf @@ -41,10 +41,10 @@ router.cell1.com:212.146.42.250:Kuopio, Finland:706 212.146.42.250:212.146.42.250:706 [Logging] -#infologfile:silcd2.log:10000 -#warninglogfile:/var/log/silcd_warning.log:10000 -#errorlogfile:silcd2.log:10000 -#fatallogfile:/var/log/silcd_error.log: +infologfile:cell1_router.log: +warninglogfile:cell1_router.log: +errorlogfile:cell1_router.log: +fatallogfile:cell1_router.log: [ConnectionClass] 1:100:100:100 diff --git a/doc/examples/cell2_router.conf b/doc/examples/cell2_router.conf index 5ac59464..46168b95 100644 --- a/doc/examples/cell2_router.conf +++ b/doc/examples/cell2_router.conf @@ -40,10 +40,10 @@ router.cell2.com:212.146.42.251:Kuopio, Finland:706 212.146.42.251:212.146.42.251:706 [Logging] -#infologfile:silcd2.log:10000 -#warninglogfile:/var/log/silcd_warning.log:10000 -#errorlogfile:silcd2.log:10000 -#fatallogfile:/var/log/silcd_error.log: +infologfile:cell2_router.log: +warninglogfile:cell2_router.log: +errorlogfile:cell2_router.log: +fatallogfile:cell2_router.log: [ConnectionClass] 1:100:100:100 diff --git a/doc/examples/cell3_router.conf b/doc/examples/cell3_router.conf index b4a9dab4..d215f630 100644 --- a/doc/examples/cell3_router.conf +++ b/doc/examples/cell3_router.conf @@ -40,10 +40,10 @@ router.cell3.com:212.146.42.252:Kuopio, Finland:706 212.146.42.252:212.146.42.252:706 [Logging] -#infologfile:silcd2.log:10000 -#warninglogfile:/var/log/silcd_warning.log:10000 -#errorlogfile:silcd2.log:10000 -#fatallogfile:/var/log/silcd_error.log: +infologfile:cell3_router.log: +warninglogfile:cell3_router.log: +errorlogfile:cell3_router.log: +fatallogfile:cell3_router.log: [ConnectionClass] 1:100:100:100 diff --git a/lib/silcsftp/sftp_fs_memory.c b/lib/silcsftp/sftp_fs_memory.c index 23d032a5..81434c13 100644 --- a/lib/silcsftp/sftp_fs_memory.c +++ b/lib/silcsftp/sftp_fs_memory.c @@ -26,6 +26,8 @@ #define DIR_SEPARATOR "/" +struct SilcSFTPFilesystemOpsStruct silc_sftp_fs_memory; + /* Memory filesystem entry */ typedef struct MemFSEntryStruct { char *name; /* Name of the entry */ @@ -305,8 +307,9 @@ static MemFSFileHandle mem_find_handle(MemFS fs, uint32 handle) silc_sftp_fs_memory_free. The `perm' is the permissions for the root directory of the filesystem (/ dir). */ -void *silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm) +SilcSFTPFilesystem silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm) { + SilcSFTPFilesystem filesystem; MemFS fs; fs = silc_calloc(1, sizeof(*fs)); @@ -316,17 +319,21 @@ void *silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm) fs->root->directory = TRUE; fs->root->name = strdup(DIR_SEPARATOR); - return (void *)fs; + filesystem = silc_calloc(1, sizeof(*filesystem)); + filesystem->fs = &silc_sftp_fs_memory; + filesystem->fs_context = (void *)fs; + + return filesystem; } /* Frees the memory filesystem context. */ -void silc_sftp_fs_memory_free(void *context) +void silc_sftp_fs_memory_free(SilcSFTPFilesystem fs) { - MemFS fs = (MemFS)context; + MemFS memfs = (MemFS)fs->fs_context; - silc_free(fs->root); - silc_free(fs); + silc_free(memfs->root); + silc_free(memfs); } /* Adds a new directory to the memory filesystem. Returns the directory @@ -338,20 +345,20 @@ void silc_sftp_fs_memory_free(void *context) not free the returned context. The `perm' will indicate the permissions for the directory and they work in POSIX style. */ -void *silc_sftp_fs_memory_add_dir(void *context, void *dir, +void *silc_sftp_fs_memory_add_dir(SilcSFTPFilesystem fs, void *dir, SilcSFTPFSMemoryPerm perm, const char *name) { - MemFS fs = (MemFS)context; + MemFS memfs = (MemFS)fs->fs_context; MemFSEntry entry; entry = silc_calloc(1, sizeof(*entry)); entry->perm = perm; entry->name = strdup(name); entry->directory = TRUE; - entry->parent = dir ? dir : fs->root; + entry->parent = dir ? dir : memfs->root; - if (!mem_add_entry(dir ? dir : fs->root, entry, FALSE)) + if (!mem_add_entry(dir ? dir : memfs->root, entry, FALSE)) return NULL; return entry; @@ -364,21 +371,21 @@ void *silc_sftp_fs_memory_add_dir(void *context, void *dir, in memory file system. The filesystem does not allow removing directories with remote access using the filesystem access function sftp_rmdir. */ -bool silc_sftp_fs_memory_del_dir(void *context, void *dir) +bool silc_sftp_fs_memory_del_dir(SilcSFTPFilesystem fs, void *dir) { - MemFS fs = (MemFS)context; + MemFS memfs = (MemFS)fs->fs_context; bool ret; if (dir) return mem_del_entry(dir, FALSE); /* Remove from root */ - ret = mem_del_entry(fs->root, FALSE); + ret = mem_del_entry(memfs->root, FALSE); - fs->root = silc_calloc(1, sizeof(*fs->root)); - fs->root->perm = fs->root_perm; - fs->root->directory = TRUE; - fs->root->name = strdup(DIR_SEPARATOR); + memfs->root = silc_calloc(1, sizeof(*memfs->root)); + memfs->root->perm = memfs->root_perm; + memfs->root->directory = TRUE; + memfs->root->name = strdup(DIR_SEPARATOR); return ret; } @@ -391,13 +398,12 @@ bool silc_sftp_fs_memory_del_dir(void *context, void *dir) file and they work in POSIX style. Returns TRUE if the file was added to the directory. */ -bool silc_sftp_fs_memory_add_file(void *context, - void *dir, +bool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir, SilcSFTPFSMemoryPerm perm, const char *filename, const char *realpath) { - MemFS fs = (MemFS)context; + MemFS memfs = (MemFS)fs->fs_context; MemFSEntry entry; entry = silc_calloc(1, sizeof(*entry)); @@ -406,21 +412,21 @@ bool silc_sftp_fs_memory_add_file(void *context, entry->data = strdup(realpath); entry->directory = FALSE; - return mem_add_entry(dir ? dir : fs->root, entry, FALSE); + return mem_add_entry(dir ? dir : memfs->root, entry, FALSE); } /* Removes a file indicated by the `filename' from the directory indicated by the `dir'. Returns TRUE if the removing was success. */ -bool silc_sftp_fs_memory_del_file(void *context, void *dir, +bool silc_sftp_fs_memory_del_file(SilcSFTPFilesystem fs, void *dir, const char *filename) { - MemFS fs = (MemFS)context; + MemFS memfs = (MemFS)fs->fs_context; if (!filename) return FALSE; - return mem_del_entry_name(dir ? dir : fs->root, filename, + return mem_del_entry_name(dir ? dir : memfs->root, filename, strlen(filename), FALSE); } @@ -1005,7 +1011,7 @@ void mem_extended(void *context, SilcSFTP sftp, callback_context); } -struct SilcSFTPFilesystemStruct silc_sftp_fs_memory = { +struct SilcSFTPFilesystemOpsStruct silc_sftp_fs_memory = { mem_get_handle, mem_encode_handle, mem_open, diff --git a/lib/silcsftp/sftp_server.c b/lib/silcsftp/sftp_server.c index d0030a0c..d62b3155 100644 --- a/lib/silcsftp/sftp_server.c +++ b/lib/silcsftp/sftp_server.c @@ -20,6 +20,7 @@ #include "silcincludes.h" #include "silcsftp.h" +#include "silcsftp_fs.h" #include "sftp_util.h" /* SFTP Server context */ @@ -28,7 +29,6 @@ typedef struct { SilcSFTPSendPacketCallback send_packet; void *send_context; SilcSFTPFilesystem fs; - void *fs_context; } *SilcSFTPServer; /* General routine to send SFTP packet to the SFTP client. */ @@ -123,8 +123,8 @@ static void silc_sftp_server_handle(SilcSFTP sftp, return; } - hdata = server->fs->sftp_encode_handle(server->fs_context, sftp, - handle, &hdata_len); + hdata = server->fs->fs->sftp_encode_handle(server->fs->fs_context, sftp, + handle, &hdata_len); if (!hdata) { silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id); return; @@ -257,8 +257,7 @@ static void silc_sftp_server_extended(SilcSFTP sftp, SilcSFTP silc_sftp_server_start(SilcSocketConnection sock, SilcSFTPSendPacketCallback send_packet, void *send_context, - SilcSFTPFilesystem fs, - void *fs_context) + SilcSFTPFilesystem fs) { SilcSFTPServer server; @@ -267,7 +266,6 @@ SilcSFTP silc_sftp_server_start(SilcSocketConnection sock, server->send_packet = send_packet; server->send_context = send_context; server->fs = fs; - server->fs_context = fs_context; SILC_LOG_DEBUG(("Starting SFTP server %p", server)); @@ -362,8 +360,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, } /* Open operation */ - server->fs->sftp_open(server->fs_context, sftp, filename, pflags, - attrs, silc_sftp_server_handle, (void *)id); + server->fs->fs->sftp_open(server->fs->fs_context, sftp, filename, pflags, + attrs, silc_sftp_server_handle, (void *)id); silc_free(filename); silc_sftp_attr_free(attrs); @@ -386,17 +384,17 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Get the handle */ - handle = server->fs->sftp_get_handle(server->fs_context, sftp, - (const unsigned char *)hdata, - hdata_len); + handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, + (const unsigned char *)hdata, + hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Close operation */ - server->fs->sftp_close(server->fs_context, sftp, handle, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_close(server->fs->fs_context, sftp, handle, + silc_sftp_server_status, (void *)id); } break; @@ -420,17 +418,18 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Get the handle */ - handle = server->fs->sftp_get_handle(server->fs_context, sftp, - (const unsigned char *)hdata, - hdata_len); + handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, + (const unsigned char *)hdata, + hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Read operation */ - server->fs->sftp_read(server->fs_context, sftp, handle, offset, len, - silc_sftp_server_data, (void *)id); + server->fs->fs->sftp_read(server->fs->fs_context, sftp, + handle, offset, len, + silc_sftp_server_data, (void *)id); } break; @@ -456,18 +455,18 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Get the handle */ - handle = server->fs->sftp_get_handle(server->fs_context, sftp, - (const unsigned char *)hdata, - hdata_len); + handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, + (const unsigned char *)hdata, + hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Write operation */ - server->fs->sftp_write(server->fs_context, sftp, handle, offset, - (const unsigned char *)data, data_len, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_write(server->fs->fs_context, sftp, handle, offset, + (const unsigned char *)data, data_len, + silc_sftp_server_status, (void *)id); } break; @@ -483,8 +482,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Remove operation */ - server->fs->sftp_remove(server->fs_context, sftp, filename, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_remove(server->fs->fs_context, sftp, filename, + silc_sftp_server_status, (void *)id); silc_free(filename); } @@ -505,8 +504,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Rename operation */ - server->fs->sftp_rename(server->fs_context, sftp, filename, newname, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_rename(server->fs->fs_context, sftp, filename, newname, + silc_sftp_server_status, (void *)id); silc_free(filename); silc_free(newname); @@ -538,8 +537,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, } /* Mkdir operation */ - server->fs->sftp_mkdir(server->fs_context, sftp, path, attrs, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_mkdir(server->fs->fs_context, sftp, path, attrs, + silc_sftp_server_status, (void *)id); silc_sftp_attr_free(attrs); silc_free(path); @@ -558,8 +557,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Rmdir operation */ - server->fs->sftp_rmdir(server->fs_context, sftp, path, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_rmdir(server->fs->fs_context, sftp, path, + silc_sftp_server_status, (void *)id); silc_free(path); } @@ -577,8 +576,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Opendir operation */ - server->fs->sftp_opendir(server->fs_context, sftp, path, - silc_sftp_server_handle, (void *)id); + server->fs->fs->sftp_opendir(server->fs->fs_context, sftp, path, + silc_sftp_server_handle, (void *)id); silc_free(path); } @@ -600,17 +599,17 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Get the handle */ - handle = server->fs->sftp_get_handle(server->fs_context, sftp, - (const unsigned char *)hdata, - hdata_len); + handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, + (const unsigned char *)hdata, + hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Readdir operation */ - server->fs->sftp_readdir(server->fs_context, sftp, handle, - silc_sftp_server_name, (void *)id); + server->fs->fs->sftp_readdir(server->fs->fs_context, sftp, handle, + silc_sftp_server_name, (void *)id); } break; @@ -626,8 +625,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Stat operation */ - server->fs->sftp_stat(server->fs_context, sftp, path, - silc_sftp_server_attr, (void *)id); + server->fs->fs->sftp_stat(server->fs->fs_context, sftp, path, + silc_sftp_server_attr, (void *)id); silc_free(path); } @@ -645,8 +644,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Lstat operation */ - server->fs->sftp_lstat(server->fs_context, sftp, path, - silc_sftp_server_attr, (void *)id); + server->fs->fs->sftp_lstat(server->fs->fs_context, sftp, path, + silc_sftp_server_attr, (void *)id); silc_free(path); } @@ -668,17 +667,17 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Get the handle */ - handle = server->fs->sftp_get_handle(server->fs_context, sftp, - (const unsigned char *)hdata, - hdata_len); + handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, + (const unsigned char *)hdata, + hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Fstat operation */ - server->fs->sftp_fstat(server->fs_context, sftp, handle, - silc_sftp_server_attr, (void *)id); + server->fs->fs->sftp_fstat(server->fs->fs_context, sftp, handle, + silc_sftp_server_attr, (void *)id); } break; @@ -707,8 +706,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, } /* Setstat operation */ - server->fs->sftp_setstat(server->fs_context, sftp, path, attrs, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_setstat(server->fs->fs_context, sftp, path, attrs, + silc_sftp_server_status, (void *)id); silc_sftp_attr_free(attrs); silc_free(path); @@ -741,17 +740,17 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, } /* Get the handle */ - handle = server->fs->sftp_get_handle(server->fs_context, sftp, - (const unsigned char *)hdata, - hdata_len); + handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, + (const unsigned char *)hdata, + hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Fsetstat operation */ - server->fs->sftp_fsetstat(server->fs_context, sftp, handle, attrs, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_fsetstat(server->fs->fs_context, sftp, handle, attrs, + silc_sftp_server_status, (void *)id); silc_sftp_attr_free(attrs); } @@ -769,8 +768,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Readlink operation */ - server->fs->sftp_readlink(server->fs_context, sftp, path, - silc_sftp_server_name, (void *)id); + server->fs->fs->sftp_readlink(server->fs->fs_context, sftp, path, + silc_sftp_server_name, (void *)id); silc_free(path); } @@ -791,8 +790,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Symlink operation */ - server->fs->sftp_symlink(server->fs_context, sftp, path, target, - silc_sftp_server_status, (void *)id); + server->fs->fs->sftp_symlink(server->fs->fs_context, sftp, path, target, + silc_sftp_server_status, (void *)id); silc_free(path); silc_free(target); @@ -811,8 +810,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, goto failure; /* Realpath operation */ - server->fs->sftp_realpath(server->fs_context, sftp, path, - silc_sftp_server_name, (void *)id); + server->fs->fs->sftp_realpath(server->fs->fs_context, sftp, path, + silc_sftp_server_name, (void *)id); silc_free(path); } @@ -843,9 +842,9 @@ void silc_sftp_server_receive_process(SilcSFTP sftp, data_len = buf.len; /* Extended operation */ - server->fs->sftp_extended(server->fs_context, sftp, - request, data, data_len, - silc_sftp_server_extended, (void *)id); + server->fs->fs->sftp_extended(server->fs->fs_context, sftp, + request, data, data_len, + silc_sftp_server_extended, (void *)id); silc_free(request); } diff --git a/lib/silcsftp/silcsftp.h b/lib/silcsftp/silcsftp.h index 4cda235e..fb81b595 100644 --- a/lib/silcsftp/silcsftp.h +++ b/lib/silcsftp/silcsftp.h @@ -834,194 +834,7 @@ void silc_sftp_extended(SilcSFTP sftp, /* SFTP Server Interface */ -/****s* silcsftp/SilcSFTPAPI/SilcSFTPFilesystem - * - * NAME - * - * typedef struct SilcSFTPFilesystemStruct { ... } *SilcSFTPFilesystem; - * - * DESCRIPTION - * - * This structure defines the generic filesystem access. When the - * filesystem is accessed these functions are called to do the requested - * filesystem operation. The level that implements the actual filesystem - * must fill this structure with the callback functions providing the - * access to the filesystem. The structure is will be given as - * argument to the silc_sftp_server_start function. - * - * SOURCE - */ -typedef struct SilcSFTPFilesystemStruct { - /* Find a file handle by the file handle data indicated by the `data'. - If the handle is not found this returns NULL. */ - SilcSFTPHandle (*sftp_get_handle)(void *context, SilcSFTP sftp, - const unsigned char *data, - uint32 data_len); - - /* Return encoded handle of `handle' or NULL on error. The caller - must free the returned buffer. */ - unsigned char *(*sftp_encode_handle)(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - uint32 *handle_len); - - /* Open a file indicated by the `filename' with flags indicated by the - `pflags', and with attributes indicated by the `attr'. Calls the - `callback' to return the opened file handle. */ - void (*sftp_open)(void *context, SilcSFTP sftp, - const char *filename, - SilcSFTPFileOperation pflags, - SilcSFTPAttributes attr, - SilcSFTPHandleCallback callback, - void *callback_context); - - /* Closes the file indicated by the file handle `handle'. Calls the - `callback' to indicate the status of the closing. */ - void (*sftp_close)(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Reads data from the file indicated by the file handle `handle' starting - from the offset of `offset' at most `len' bytes. The `callback' is - called to return the read data. */ - void (*sftp_read)(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - uint64 offset, - uint32 len, - SilcSFTPDataCallback callback, - void *callback_context); - - /* Writes to a file indicated by the file handle `handle' starting from - offset of `offset' at most `data_len' bytes of `data'. The `callback' - is called to indicate the status of the writing. */ - void (*sftp_write)(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - uint64 offset, - const unsigned char *data, - uint32 data_len, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Removes a file indicated by the `filename'. Calls the `callback' - to indicate the status of the removing. */ - void (*sftp_remove)(void *context, SilcSFTP sftp, - const char *filename, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Renames a file indicated by the `oldname' to the name `newname'. The - `callback' is called to indicate the status of the renaming. */ - void (*sftp_rename)(void *context, SilcSFTP sftp, - const char *oldname, - const char *newname, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Creates a new directory indicated by the `path' with attributes indicated - by the `attrs'. The `callback' is called to indicate the status of the - creation. */ - void (*sftp_mkdir)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttributes attrs, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Removes a directory indicated by the `path' and calls the `callback' - to indicate the status of the removal. */ - void (*sftp_rmdir)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Opens a directory indicated by the `path'. The `callback' is called - to return the opened file handle. */ - void (*sftp_opendir)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPHandleCallback callback, - void *callback_context); - - /* Reads the contents of the directory indicated by the `handle' and - calls the `callback' to return the read file(s) from the directory. */ - void (*sftp_readdir)(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPNameCallback callback, - void *callback_context); - - /* Gets the file attributes for a file indicated by the `path'. This - will follow symbolic links also. Calls the `callback' to return the - file attributes. */ - void (*sftp_stat)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttrCallback callback, - void *callback_context); - - /* Gets the file attributes for a file indicated by the `path'. This - will not follow symbolic links. Calls the `callback' to return the - file attributes. */ - void (*sftp_lstat)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttrCallback callback, - void *callback_context); - - /* Gets a file attributes for a opened file indicated by the `handle'. - Calls the `callback' to return the file attributes. */ - void (*sftp_fstat)(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPAttrCallback callback, - void *callback_context); - - /* Sets a file attributes to a file indicated by the `path' with the - attributes indicated by the `attrs'. Calls the `callback' to indicate - the status of the setting. */ - void (*sftp_setstat)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttributes attrs, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Sets a file attributes to a opened file indicated by the `handle' with - the attributes indicated by the `attrs'. Calls the `callback' to - indicate the status of the setting. */ - void (*sftp_fsetstat)(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPAttributes attrs, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Reads the target of a symbolic link indicated by the `path'. The - `callback' is called to return the target of the symbolic link. */ - void (*sftp_readlink)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPNameCallback callback, - void *callback_context); - - /* Creates a new symbolic link indicated by the `linkpath' to the target - indicated by the `targetpath'. The `callback' is called to indicate - the status of creation. */ - void (*sftp_symlink)(void *context, SilcSFTP sftp, - const char *linkpath, - const char *targetpath, - SilcSFTPStatusCallback callback, - void *callback_context); - - /* Canonicalizes the path indicated by the `path' to a absolute path. - The `callback' is called to return the absolute path. */ - void (*sftp_realpath)(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPNameCallback callback, - void *callback_context); - - /* Performs an extended operation indicated by the `request' with - optional extended operation data indicated by the `data'. The callback - is called to return any data associated with the extended request. */ - void (*sftp_extended)(void *context, SilcSFTP sftp, - const char *request, - const unsigned char *data, - uint32 data_len, - SilcSFTPExtendedCallback callback, - void *callback_context); -} *SilcSFTPFilesystem; -/****/ +#include "silcsftp_fs.h" /****f* silcsftp/SilcSFTPAPI/silc_sftp_server_start * @@ -1030,8 +843,7 @@ typedef struct SilcSFTPFilesystemStruct { * SilcSFTP silc_sftp_server_start(SilcSocketConnection sock, * SilcSFTPSendPacketCallback send_packet, * void *send_context, SilcSFTP sftp, - * SilcSFTPFilesystem fs, - * void *fs_context); + * SilcSFTPFilesystem fs); * * DESCRIPTION * @@ -1039,14 +851,13 @@ typedef struct SilcSFTPFilesystemStruct { * created SFTP server context. This function returns the allocated * SFTP client context or NULL on error. The `send_packet' is called * by the library when it needs to send a packet. The `fs' is the - * structure containing filesystem access callbacks. + * filesystem context allocated by the application. * ***/ SilcSFTP silc_sftp_server_start(SilcSocketConnection sock, SilcSFTPSendPacketCallback send_packet, void *send_context, - SilcSFTPFilesystem fs, - void *fs_context); + SilcSFTPFilesystem fs); /****f* silcsftp/SilcSFTPAPI/silc_sftp_server_shutdown * diff --git a/lib/silcsftp/silcsftp_fs.h b/lib/silcsftp/silcsftp_fs.h index baeed18d..6144dc0d 100644 --- a/lib/silcsftp/silcsftp_fs.h +++ b/lib/silcsftp/silcsftp_fs.h @@ -73,10 +73,215 @@ * ***/ -/* Available filesystems. These can be given as argument to the - silc_sftp_server_start function. */ -extern struct SilcSFTPFilesystemStruct silc_sftp_fs_memory; +/****s* silcsftp/SilcSFTPFSAPI/SilcSFTPFilesystemOps + * + * NAME + * + * typedef struct SilcSFTPFilesystemOpsStruct { ... } + * *SilcSFTPFilesystemOps; + * + * DESCRIPTION + * + * This structure defines the generic filesystem access. When the + * filesystem is accessed these functions are called to do the requested + * filesystem operation. The level that implements the actual filesystem + * must fill this structure with the callback functions providing the + * access to the filesystem. + * + * SOURCE + */ +typedef struct SilcSFTPFilesystemOpsStruct { + /* Find a file handle by the file handle data indicated by the `data'. + If the handle is not found this returns NULL. */ + SilcSFTPHandle (*sftp_get_handle)(void *context, SilcSFTP sftp, + const unsigned char *data, + uint32 data_len); + + /* Return encoded handle of `handle' or NULL on error. The caller + must free the returned buffer. */ + unsigned char *(*sftp_encode_handle)(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + uint32 *handle_len); + + /* Open a file indicated by the `filename' with flags indicated by the + `pflags', and with attributes indicated by the `attr'. Calls the + `callback' to return the opened file handle. */ + void (*sftp_open)(void *context, SilcSFTP sftp, + const char *filename, + SilcSFTPFileOperation pflags, + SilcSFTPAttributes attr, + SilcSFTPHandleCallback callback, + void *callback_context); + + /* Closes the file indicated by the file handle `handle'. Calls the + `callback' to indicate the status of the closing. */ + void (*sftp_close)(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Reads data from the file indicated by the file handle `handle' starting + from the offset of `offset' at most `len' bytes. The `callback' is + called to return the read data. */ + void (*sftp_read)(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + uint64 offset, + uint32 len, + SilcSFTPDataCallback callback, + void *callback_context); + + /* Writes to a file indicated by the file handle `handle' starting from + offset of `offset' at most `data_len' bytes of `data'. The `callback' + is called to indicate the status of the writing. */ + void (*sftp_write)(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + uint64 offset, + const unsigned char *data, + uint32 data_len, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Removes a file indicated by the `filename'. Calls the `callback' + to indicate the status of the removing. */ + void (*sftp_remove)(void *context, SilcSFTP sftp, + const char *filename, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Renames a file indicated by the `oldname' to the name `newname'. The + `callback' is called to indicate the status of the renaming. */ + void (*sftp_rename)(void *context, SilcSFTP sftp, + const char *oldname, + const char *newname, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Creates a new directory indicated by the `path' with attributes indicated + by the `attrs'. The `callback' is called to indicate the status of the + creation. */ + void (*sftp_mkdir)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttributes attrs, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Removes a directory indicated by the `path' and calls the `callback' + to indicate the status of the removal. */ + void (*sftp_rmdir)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Opens a directory indicated by the `path'. The `callback' is called + to return the opened file handle. */ + void (*sftp_opendir)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPHandleCallback callback, + void *callback_context); + /* Reads the contents of the directory indicated by the `handle' and + calls the `callback' to return the read file(s) from the directory. */ + void (*sftp_readdir)(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPNameCallback callback, + void *callback_context); + + /* Gets the file attributes for a file indicated by the `path'. This + will follow symbolic links also. Calls the `callback' to return the + file attributes. */ + void (*sftp_stat)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttrCallback callback, + void *callback_context); + + /* Gets the file attributes for a file indicated by the `path'. This + will not follow symbolic links. Calls the `callback' to return the + file attributes. */ + void (*sftp_lstat)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttrCallback callback, + void *callback_context); + + /* Gets a file attributes for a opened file indicated by the `handle'. + Calls the `callback' to return the file attributes. */ + void (*sftp_fstat)(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPAttrCallback callback, + void *callback_context); + + /* Sets a file attributes to a file indicated by the `path' with the + attributes indicated by the `attrs'. Calls the `callback' to indicate + the status of the setting. */ + void (*sftp_setstat)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttributes attrs, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Sets a file attributes to a opened file indicated by the `handle' with + the attributes indicated by the `attrs'. Calls the `callback' to + indicate the status of the setting. */ + void (*sftp_fsetstat)(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPAttributes attrs, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Reads the target of a symbolic link indicated by the `path'. The + `callback' is called to return the target of the symbolic link. */ + void (*sftp_readlink)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPNameCallback callback, + void *callback_context); + + /* Creates a new symbolic link indicated by the `linkpath' to the target + indicated by the `targetpath'. The `callback' is called to indicate + the status of creation. */ + void (*sftp_symlink)(void *context, SilcSFTP sftp, + const char *linkpath, + const char *targetpath, + SilcSFTPStatusCallback callback, + void *callback_context); + + /* Canonicalizes the path indicated by the `path' to a absolute path. + The `callback' is called to return the absolute path. */ + void (*sftp_realpath)(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPNameCallback callback, + void *callback_context); + + /* Performs an extended operation indicated by the `request' with + optional extended operation data indicated by the `data'. The callback + is called to return any data associated with the extended request. */ + void (*sftp_extended)(void *context, SilcSFTP sftp, + const char *request, + const unsigned char *data, + uint32 data_len, + SilcSFTPExtendedCallback callback, + void *callback_context); +} *SilcSFTPFilesystemOps; +/****/ + +/****s* silcsftp/SilcSFTPFSAPI/SilcSFTPFilesystem + * + * NAME + * + * typedef struct { ... } *SilcSFTPFilesystem; + * + * DESCRIPTION + * + * This context is allocated and returned by all filesystem allocation + * routines. The returned context is given as argument to the + * silc_sftp_server_start function. The caller must also free the + * context after the SFTP server is shutdown. + * + * SOURCE + */ +typedef struct { + SilcSFTPFilesystemOps fs; + void *fs_context; +} *SilcSFTPFilesystem; +/***/ /* Memory filesystem */ @@ -116,7 +321,7 @@ typedef enum { * directory of the filesystem (/ dir). * ***/ -void *silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm); +SilcSFTPFilesystem silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm); /****f* silcsftp/SilcSFTPFSAPI/silc_sftp_fs_memory_free * @@ -129,7 +334,7 @@ void *silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm); * Frees the memory filesystem context. * ***/ -void silc_sftp_fs_memory_free(void *context); +void silc_sftp_fs_memory_free(SilcSFTPFilesystem fs); /****f* silcsftp/SilcSFTPFSAPI/silc_sftp_fs_memory_add_dir * @@ -151,7 +356,7 @@ void silc_sftp_fs_memory_free(void *context); * style. * ***/ -void *silc_sftp_fs_memory_add_dir(void *context, void *dir, +void *silc_sftp_fs_memory_add_dir(SilcSFTPFilesystem fs, void *dir, SilcSFTPFSMemoryPerm perm, const char *name); @@ -159,7 +364,7 @@ void *silc_sftp_fs_memory_add_dir(void *context, void *dir, * * SYNOPSIS * - * bool silc_sftp_fs_memory_del_dir(void *context, void *dir); + * bool silc_sftp_fs_memory_del_dir(SilcSFTPFilesystem fs, void *dir); * * DESCRIPTION * @@ -172,13 +377,13 @@ void *silc_sftp_fs_memory_add_dir(void *context, void *dir, * access function sftp_rmdir. * ***/ -bool silc_sftp_fs_memory_del_dir(void *context, void *dir); +bool silc_sftp_fs_memory_del_dir(SilcSFTPFilesystem fs, void *dir); /****f* silcsftp/SilcSFTPFSAPI/silc_sftp_fs_memory_add_file * * SYNOPSIS * - * bool silc_sftp_fs_memory_add_file(void *context, void *dir, + * bool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir, * SilcSFTPFSMemoryPerm perm, * const char *filename, * const char *realpath); @@ -196,7 +401,7 @@ bool silc_sftp_fs_memory_del_dir(void *context, void *dir); * was added to the directory. * ***/ -bool silc_sftp_fs_memory_add_file(void *context, void *dir, +bool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir, SilcSFTPFSMemoryPerm perm, const char *filename, const char *realpath); @@ -205,7 +410,7 @@ bool silc_sftp_fs_memory_add_file(void *context, void *dir, * * SYNOPSIS * - * bool silc_sftp_fs_memory_del_file(void *context, void *dir, + * bool silc_sftp_fs_memory_del_file(SilcSFTPFilesystem fs, void *dir, * const char *filename); * * DESCRIPTION @@ -217,7 +422,7 @@ bool silc_sftp_fs_memory_add_file(void *context, void *dir, * access function sftp_remove. * ***/ -bool silc_sftp_fs_memory_del_file(void *context, void *dir, +bool silc_sftp_fs_memory_del_file(SilcSFTPFilesystem fs, void *dir, const char *filename); #endif /* SILCSFTP_FS_H */ diff --git a/lib/silcsftp/tests/sftp_server.c b/lib/silcsftp/tests/sftp_server.c index dc3ace48..e2aa1aa6 100644 --- a/lib/silcsftp/tests/sftp_server.c +++ b/lib/silcsftp/tests/sftp_server.c @@ -19,12 +19,11 @@ #include "silcincludes.h" #include "silcsftp.h" -#include "silcsftp_fs.h" typedef struct { SilcSchedule schedule; int sock; - void *fs; + SilcSFTPFilesystem fs; SilcSocketConnection socks[100]; SilcSFTP sftp[100]; } *Server; @@ -126,7 +125,6 @@ SILC_TASK_CALLBACK(accept_connection) server->socks[sock] = sc; server->sftp[sock] = silc_sftp_server_start(sc, send_packet, server, - (SilcSFTPFilesystem)&silc_sftp_fs_memory, server->fs); silc_schedule_task_add(server->schedule, sock, packet_process, server, 0, 0, SILC_TASK_GENERIC, -- 2.24.0