X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Firssi%2Fsrc%2Fsilc%2Fcore%2Fsilc-servers.c;h=e16fb02cdc056fef1116a982f49259c3bf0d7483;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=476205d450e0cfcf3c00b81e9f4da307873bf1b2;hpb=c257b555225193e54d85daf541d29578b3c93882;p=silc.git diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 476205d4..e16fb02c 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -1,7 +1,7 @@ /* silc-server.c : irssi - Copyright (C) 2000 - 2005 Timo Sirainen + Copyright (C) 2000 - 2007 Timo Sirainen Pekka Riikonen This program is free software; you can redistribute it and/or modify @@ -33,6 +33,7 @@ #include "settings.h" #include "servers-setup.h" +#include "channels-setup.h" #include "client_ops.h" #include "silc-servers.h" @@ -63,9 +64,9 @@ int silc_send_channel(SILC_SERVER_REC *server, cmd_return_error_value(CMDERR_NOT_JOINED, FALSE); } - silc_client_send_channel_message(silc_client, server->conn, rec->entry, - NULL, flags, msg, strlen(msg), TRUE); - return TRUE; + return silc_client_send_channel_message(silc_client, server->conn, + rec->entry, NULL, flags, sha1hash, + msg, strlen(msg)); } typedef struct { @@ -81,56 +82,45 @@ typedef struct { static void silc_send_msg_clients(SilcClient client, SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, + SilcStatus status, + SilcDList clients, void *context) { PRIVMSG_REC *rec = context; SILC_SERVER_REC *server = rec->server; SilcClientEntry target; - char *nickname = NULL; - if (!clients_count) { + if (!clients) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "%s: There is no such client", rec->nick); - } else { - if (clients_count > 1) { - silc_parse_userfqdn(rec->nick, &nickname, NULL); - - /* Find the correct one. The rec->nick might be a formatted nick - so this will find the correct one. */ - clients = silc_client_get_clients_local(silc_client, server->conn, - nickname, rec->nick, - &clients_count); - if (!clients) { - printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, - "%s: There is no such client", rec->nick); - silc_free(nickname); - goto out; - } - silc_free(nickname); - } - - target = clients[0]; + goto out; + } - /* Still check for exact math for nickname, this compares the - real (formatted) nickname and the nick (maybe formatted) that - use gave. This is to assure that `nick' does not match - `nick@host'. */ - if (!silc_utf8_strcasecmp(rec->nick, clients[0]->nickname)) { + /* Find the correct one. The rec->nick might be a formatted nick + so this will find the correct one. */ + target = silc_dlist_get(clients); + clients = silc_client_get_clients_local(silc_client, server->conn, + rec->nick, FALSE); + if (!clients) { + if (strchr(rec->nick, '@') && target->server) printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, - "%s: There is no such client", rec->nick); - goto out; - } - - /* Send the private message */ - silc_client_send_private_message(client, conn, target, - rec->flags, - rec->msg, rec->len, - TRUE); + "%s: There is no such client (did you mean %s@%s?)", rec->nick, + target->nickname, target->server); + else + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, + "%s: There is no such client (did you mean %s?)", rec->nick, + target->nickname); + goto out; } + /* Send the private message */ + silc_dlist_start(clients); + target = silc_dlist_get(clients); + silc_client_send_private_message(client, conn, target, rec->flags, sha1hash, + rec->msg, rec->len); + out: + silc_client_list_free(silc_client, server->conn, clients); g_free(rec->nick); g_free(rec->msg); g_free(rec); @@ -140,20 +130,16 @@ int silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg, int msg_len, SilcMessageFlags flags) { PRIVMSG_REC *rec; - SilcClientEntry *clients; - SilcUInt32 clients_count; - char *nickname = NULL; - - if (!silc_parse_userfqdn(nick, &nickname, NULL)) { - printformat_module("fe-common/silc", server, NULL, - MSGLEVEL_CRAP, SILCTXT_BAD_NICK, nick); - return FALSE; - } + SilcDList clients; + SilcClientEntry target; + int ret; /* Find client entry */ - clients = silc_client_get_clients_local(silc_client, server->conn, - nickname, nick, &clients_count); + clients = silc_client_get_clients_local(silc_client, server->conn, nick, + FALSE); if (!clients) { + char *nickname = NULL; + rec = g_new0(PRIVMSG_REC, 1); rec->nick = g_strdup(nick); rec->msg = g_strdup(msg); @@ -161,19 +147,26 @@ int silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg, rec->flags = flags; rec->len = msg_len; + silc_client_nickname_parse(silc_client, server->conn, nick, &nickname); + if (!nickname) + nickname = strdup(nick); + /* Could not find client with that nick, resolve it from server. */ - silc_client_get_clients(silc_client, server->conn, - nickname, NULL, silc_send_msg_clients, rec); + silc_client_get_clients_whois(silc_client, server->conn, nickname, + NULL, NULL, silc_send_msg_clients, rec); silc_free(nickname); return TRUE; } /* Send the private message directly */ - silc_free(nickname); - silc_client_send_private_message(silc_client, server->conn, - clients[0], flags, - msg, msg_len, TRUE); - return TRUE; + target = silc_dlist_get(clients); + ret = silc_client_send_private_message(silc_client, server->conn, + target, flags, sha1hash, + msg, msg_len); + + silc_client_list_free(silc_client, server->conn, clients); + + return ret; } void silc_send_mime(SILC_SERVER_REC *server, int channel, const char *to, @@ -206,7 +199,8 @@ void silc_send_mime(SILC_SERVER_REC *server, int channel, const char *to, silc_client_send_channel_message(silc_client, server->conn, rec->entry, NULL, SILC_MESSAGE_FLAG_DATA | (sign ? SILC_MESSAGE_FLAG_SIGNED : 0), - unescaped_data, unescaped_data_len, TRUE); + sha1hash, unescaped_data, + unescaped_data_len); } else { silc_send_msg(server, (char *)to, unescaped_data, unescaped_data_len, SILC_MESSAGE_FLAG_DATA | @@ -219,7 +213,7 @@ void silc_send_mime(SILC_SERVER_REC *server, int channel, const char *to, silc_free(unescaped_data); } -static int isnickflag_func(char flag) +static int isnickflag_func(SERVER_REC *server, char flag) { return flag == '@' || flag == '+'; } @@ -229,7 +223,7 @@ static int ischannel_func(SERVER_REC *server, const char *data) return FALSE; } -const char *get_nick_flags(void) +const char *get_nick_flags(SERVER_REC *server) { return "@\0\0"; } @@ -239,6 +233,7 @@ static void send_message(SILC_SERVER_REC *server, char *target, { char *message = NULL, *t = NULL; int len; + SilcBool sign; g_return_if_fail(server != NULL); g_return_if_fail(target != NULL); @@ -251,10 +246,13 @@ static void send_message(SILC_SERVER_REC *server, char *target, silc_utf8_encode(msg, strlen(msg), SILC_STRING_LOCALE, message, len); } - if (target_type == SEND_TARGET_CHANNEL) + if (target_type == SEND_TARGET_CHANNEL) { + sign = settings_get_bool("sign_channel_messages"); silc_send_channel(server, target, message ? message : msg, - SILC_MESSAGE_FLAG_UTF8); - else { + SILC_MESSAGE_FLAG_UTF8 | + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0)); + } else { + sign = settings_get_bool("sign_private_messages"); if (!silc_term_utf8()) { len = silc_utf8_encoded_len(target, strlen(target), SILC_STRING_LOCALE); t = silc_calloc(len + 1, sizeof(*t)); @@ -264,70 +262,183 @@ static void send_message(SILC_SERVER_REC *server, char *target, silc_send_msg(server, t ? t : target, message ? message : msg, message ? strlen(message) : strlen(msg), - SILC_MESSAGE_FLAG_UTF8); + SILC_MESSAGE_FLAG_UTF8 | + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0)); } silc_free(message); silc_free(t); } -void silc_send_heartbeat(SilcSocketConnection sock, - void *hb_context) +/* Connection callback */ + +static void silc_connect_cb(SilcClient client, + SilcClientConnection conn, + SilcClientConnectionStatus status, + SilcStatus error, + const char *message, + void *context) { - SILC_SERVER_REC *server = SILC_SERVER(hb_context); + SILC_SERVER_REC *server = context; + FtpSession ftp; + char *file; - if (server == NULL) - return; + SILC_LOG_DEBUG(("Connection callback %p, status %d, error %d, message %s", + conn, status, error, message ? message : "N/A")); + + server->op = NULL; + + switch (status) { + case SILC_CLIENT_CONN_SUCCESS: + if (server->disconnected) { + silc_client_close_connection(client, conn); + return; + } + + /* We have successfully connected to server */ + + /* Enable queueing until we have our requested nick */ + if (((opt_nickname && + !silc_utf8_strcasecmp(opt_nickname, + conn->local_entry->nickname)) || + (settings_get_str("nick") && + !silc_utf8_strcasecmp(settings_get_str("nick"), + conn->local_entry->nickname))) && + silc_utf8_strcasecmp(conn->local_entry->nickname, + conn->local_entry->username)) + silc_queue_enable(conn); + + /* Put default attributes */ + silc_query_attributes_default(silc_client, conn); + + server->connected = TRUE; + server->conn = conn; + server->conn->context = server; + signal_emit("event connected", 1, server); + break; + + case SILC_CLIENT_CONN_SUCCESS_RESUME: + if (server->disconnected) { + silc_client_close_connection(client, conn); + return; + } + + /* We have successfully resumed old detached session */ + server->connected = TRUE; + server->conn = conn; + server->conn->context = server; + signal_emit("event connected", 1, server); + + /* Put default attributes */ + silc_query_attributes_default(silc_client, conn); + + /* Remove the detach data now */ + file = silc_get_session_filename(server); + unlink(file); + silc_free(file); + break; + + case SILC_CLIENT_CONN_DISCONNECTED: + /* Server disconnected */ + if (server->conn && server->conn->local_entry) { + nicklist_rename_unique(SERVER(server), + server->conn->local_entry, server->nick, + server->conn->local_entry, + silc_client->username); + silc_change_nick(server, silc_client->username); + } - silc_client_send_packet(silc_client, server->conn, SILC_PACKET_HEARTBEAT, - NULL, 0); + if (message) + silc_say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, + "Server closed connection: %s (%d) %s", + silc_get_status_message(error), error, + message ? message : ""); + + /* Close FTP sessions */ + silc_dlist_start(server->ftp_sessions); + while ((ftp = silc_dlist_get(server->ftp_sessions))) + silc_client_file_close(client, conn, ftp->session_id); + silc_dlist_uninit(server->ftp_sessions); + + if (server->conn) + server->conn->context = NULL; + server->conn = NULL; + server->connection_lost = TRUE; + if (!server->disconnected) + server_disconnect(SERVER(server)); + server_unref(SERVER(server)); + break; + + default: + file = silc_get_session_filename(server); + if (silc_file_size(file) > 0) + printformat_module("fe-common/silc", server, NULL, + MSGLEVEL_CRAP, SILCTXT_REATTACH_FAILED, file); + silc_free(file); + + server->connection_lost = TRUE; + server->conn = NULL; + if (server->conn) + server->conn->context = NULL; + if (!server->disconnected) + server_disconnect(SERVER(server)); + server_unref(SERVER(server)); + break; + } } -static void sig_connected(SILC_SERVER_REC *server) +/* Called after TCP stream has been created */ + +static void sig_connected_stream_created(SilcSocketStreamStatus status, + SilcStream stream, void *context) { - SilcClientConnection conn; + SILC_SERVER_REC *server = context; SilcClientConnectionParams params; char *file; - int fd; - if (!IS_SILC_SERVER(server)) + server->tcp_op = NULL; + if (!stream) { + server->connection_lost = TRUE; + server_disconnect(SERVER(server)); return; + } - /* Try to read detached session data and use it if found. */ + if (server->disconnected) { + silc_stream_destroy(stream); + return; + } + + /* Set connection parameters */ memset(¶ms, 0, sizeof(params)); + params.nickname = (opt_nickname ? (char *)opt_nickname : + (char *)settings_get_str("nick")); + params.timeout_secs = settings_get_int("key_exchange_timeout_secs"); + params.rekey_secs = settings_get_int("key_exchange_rekey_secs"); + params.pfs = settings_get_bool("key_exchange_rekey_pfs"); + + /* Try to read detached session data and use it if found. */ file = silc_get_session_filename(server); params.detach_data = silc_file_readfile(file, ¶ms.detach_data_len); if (params.detach_data) params.detach_data[params.detach_data_len] = 0; - - /* Add connection to the client library */ - conn = silc_client_add_connection(silc_client, ¶ms, - server->connrec->address, - server->connrec->port, - server); - server->conn = conn; - if (params.detach_data) printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP, SILCTXT_REATTACH, server->tag); + silc_free(file); + + /* Start key exchange */ + server->op = silc_client_key_exchange(silc_client, ¶ms, + irssi_pubkey, irssi_privkey, + stream, SILC_CONN_SERVER, + silc_connect_cb, server); + if (!server->op) { + server->connection_lost = TRUE; + server_disconnect(SERVER(server)); + silc_stream_destroy(stream); + return; + } - silc_free(params.detach_data); - - fd = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle)); - - /* Start key exchange with the server */ - silc_client_start_key_exchange(silc_client, conn, fd); - - /* Put default attributes */ - silc_query_attributes_default(silc_client, conn); - - /* initialize heartbeat sending */ - if (settings_get_int("heartbeat") > 0) - silc_socket_set_heartbeat(conn->sock, settings_get_int("heartbeat"), - (void *)server, - (SilcSocketConnectionHBCb)silc_send_heartbeat, - silc_client->schedule); - + server_ref(SERVER(server)); server->ftp_sessions = silc_dlist_init(); server->isnickflag = isnickflag_func; server->ischannel = ischannel_func; @@ -335,17 +446,41 @@ static void sig_connected(SILC_SERVER_REC *server) server->send_message = (void *) send_message; } -static void sig_disconnected(SILC_SERVER_REC *server) +static void sig_connected(SILC_SERVER_REC *server) { + int fd; + if (!IS_SILC_SERVER(server)) return; - silc_dlist_uninit(server->ftp_sessions); + /* Wrap the socket to TCP stream */ + fd = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle)); + server->tcp_op = + silc_socket_tcp_stream_create(fd, TRUE, FALSE, + silc_client->schedule, + sig_connected_stream_created, server); +} - if (server->conn && server->conn->sock != NULL) { +static void sig_disconnected(SILC_SERVER_REC *server) +{ + if (!IS_SILC_SERVER(server)) + return; + + if (server->conn) { + /* Close connection */ silc_client_close_connection(silc_client, server->conn); + } else if (server->op) { + /* Abort on going connecting (key exchange) */ + silc_async_abort(server->op, NULL, NULL); + server->op = NULL; + } else if (server->tcp_op) { + /* Abort on going TCP stream creation */ + silc_async_abort(server->tcp_op, NULL, NULL); + server->tcp_op = NULL; + } - /* SILC closes the handle */ + /* SILC closes the handle */ + if (server->handle) { g_io_channel_unref(net_sendbuffer_handle(server->handle)); net_sendbuffer_destroy(server->handle, FALSE); server->handle = NULL; @@ -399,8 +534,14 @@ char *silc_server_get_channels(SILC_SERVER_REC *server) chans = g_string_new(NULL); for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *channel = tmp->data; + CHANNEL_SETUP_REC *schannel; - g_string_sprintfa(chans, "%s,", channel->name); + if ((schannel = channel_setup_find(channel->name, server->connrec->chatnet)) && + schannel->password) + g_string_sprintfa(chans, "%s %s,", channel->name, + schannel->password); + else + g_string_sprintfa(chans, "%s,", channel->name); } if (chans->len > 0) @@ -432,7 +573,6 @@ char *silc_server_get_channels(SILC_SERVER_REC *server) /* SYNTAX: WHOIS [[@]] [-details] [-pubkey ] [] */ /* SYNTAX: WHOWAS [@] [] */ /* SYNTAX: CLOSE [] */ -/* SYNTAX: SHUTDOWN */ /* SYNTAX: MOTD [] */ /* SYNTAX: LIST [] */ /* SYNTAX: ME */ @@ -443,7 +583,6 @@ char *silc_server_get_channels(SILC_SERVER_REC *server) /* SYNTAX: NOTICE [-sign] [-channel] */ /* SYNTAX: PART [] */ /* SYNTAX: PING */ -/* SYNTAX: SCONNECT [] */ /* SYNTAX: USERS */ /* SYNTAX: FILE SEND [ []] [-no-listener]*/ /* SYNTAX: FILE ACCEPT [] */ @@ -492,21 +631,6 @@ static void command_self(const char *data, SILC_SERVER_REC *server, signal_stop(); } -/* SCONNECT command. Calls actually SILC's CONNECT command since Irssi - has CONNECT command for other purposes. */ - -static void command_sconnect(const char *data, SILC_SERVER_REC *server) -{ - CMD_SILC_SERVER(server); - if (!IS_SILC_SERVER(server) || !server->connected) { - printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Not connected to server"); - return; - } - - silc_command_exec(server, "CONNECT", data); - signal_stop(); -} - /* SMSG command, to send digitally signed messages */ static void command_smsg(const char *data, SILC_SERVER_REC *server, @@ -632,7 +756,8 @@ static void silc_client_file_monitor(SilcClient client, if (ftp == SILC_LIST_END) return; - if (status == SILC_CLIENT_FILE_MONITOR_ERROR) { + if (status == SILC_CLIENT_FILE_MONITOR_ERROR || + status == SILC_CLIENT_FILE_MONITOR_DISCONNECT) { if (error == SILC_CLIENT_FILE_NO_SUCH_FILE) printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, SILCTXT_FILE_ERROR_NO_SUCH_FILE, @@ -645,9 +770,9 @@ static void silc_client_file_monitor(SilcClient client, else printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, SILCTXT_FILE_ERROR, client_entry->nickname); - silc_schedule_task_add(silc_client->schedule, 0, - silc_client_file_close_later, ftp, - 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); + silc_schedule_task_add_timeout(silc_client->schedule, + silc_client_file_close_later, ftp, + 1, 0); silc_dlist_del(server->ftp_sessions, ftp); if (ftp == server->current_session) { server->current_session = NULL; @@ -685,9 +810,9 @@ static void silc_client_file_monitor(SilcClient client, printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, SILCTXT_FILE_TRANSMITTED, filepath, fsize, client_entry->nickname, ftp->kps); - silc_schedule_task_add(silc_client->schedule, 0, - silc_client_file_close_later, ftp, - 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); + silc_schedule_task_add_timeout(silc_client->schedule, + silc_client_file_close_later, ftp, + 1, 0); silc_dlist_del(server->ftp_sessions, ftp); if (ftp == server->current_session) { server->current_session = NULL; @@ -710,9 +835,9 @@ static void silc_client_file_monitor(SilcClient client, printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, SILCTXT_FILE_RECEIVED, filepath, fsize, client_entry->nickname, ftp->kps); - silc_schedule_task_add(silc_client->schedule, 0, - silc_client_file_close_later, ftp, - 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); + silc_schedule_task_add_timeout(silc_client->schedule, + silc_client_file_close_later, ftp, + 1, 0); silc_dlist_del(server->ftp_sessions, ftp); if (ftp == server->current_session) { server->current_session = NULL; @@ -733,15 +858,15 @@ typedef struct { static void silc_client_command_file_get_clients(SilcClient client, SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, + SilcStatus status, + SilcDList clients, void *context) { FileGetClients internal = (FileGetClients)context; if (!clients) { - printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown nick: %s", - internal->nick); + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, + "There was no such nickname: %s", internal->nick); silc_free(internal->data); silc_free(internal->nick); silc_free(internal); @@ -760,9 +885,9 @@ static void command_file(const char *data, SILC_SERVER_REC *server, WI_ITEM_REC *item) { SilcClientConnection conn; - SilcClientEntry *entrys, client_entry; + SilcClientEntry client_entry; + SilcDList entries; SilcClientFileError ret; - SilcUInt32 entry_count; char *nickname = NULL, *tmp; unsigned char **argv; SilcUInt32 argc; @@ -773,6 +898,7 @@ static void command_file(const char *data, SILC_SERVER_REC *server, SilcUInt32 local_port = 0; SilcUInt32 session_id; bool do_not_bind = FALSE; + SilcClientConnectionParams params; CMD_SILC_SERVER(server); if (!server || !IS_SILC_SERVER(server) || !server->connected) @@ -806,27 +932,24 @@ static void command_file(const char *data, SILC_SERVER_REC *server, cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); /* Parse the typed nickname. */ - if (!silc_parse_userfqdn(argv[3], &nickname, NULL)) { - printformat_module("fe-common/silc", server, NULL, - MSGLEVEL_CRAP, SILCTXT_BAD_NICK, argv[3]); - goto out; - } + silc_client_nickname_parse(silc_client, conn, argv[3], &nickname); + if (!nickname) + nickname = strdup(argv[3]); /* Find client entry */ - entrys = silc_client_get_clients_local(silc_client, conn, nickname, - argv[3], &entry_count); - if (!entrys) { + entries = silc_client_get_clients_local(silc_client, conn, argv[3], FALSE); + if (!entries) { FileGetClients inter = silc_calloc(1, sizeof(*inter)); inter->server = server; inter->data = strdup(data); inter->nick = strdup(nickname); inter->item = item; - silc_client_get_clients(silc_client, conn, nickname, argv[3], + silc_client_get_clients(silc_client, conn, nickname, NULL, silc_client_command_file_get_clients, inter); goto out; } - client_entry = entrys[0]; - silc_free(entrys); + silc_dlist_start(entries); + client_entry = silc_dlist_get(entries); if (argc >= 5) { if (!strcasecmp(argv[4], "-no-listener")) @@ -845,10 +968,31 @@ static void command_file(const char *data, SILC_SERVER_REC *server, do_not_bind = TRUE; } - ret = - silc_client_file_send(silc_client, conn, silc_client_file_monitor, - server, local_ip, local_port, do_not_bind, - client_entry, argv[2], &session_id); + memset(¶ms, 0, sizeof(params)); + if (!do_not_bind) { + if (local_ip) + params.local_ip = strdup(local_ip); + params.local_port = local_port; + if (!params.local_ip && settings_get_bool("use_auto_addr")) { + params.local_ip = (char *)settings_get_str("auto_public_ip"); + if ((params.local_ip) && (*params.local_ip == '\0')) { + params.local_ip = silc_net_localip(); + } else { + params.bind_ip = (char *)settings_get_str("auto_bind_ip"); + if ((params.bind_ip) && (*params.bind_ip == '\0')) + params.bind_ip = NULL; + params.local_port = settings_get_int("auto_bind_port"); + } + } + if (!params.local_ip) + params.local_ip = silc_net_localip(); + } + params.timeout_secs = settings_get_int("key_exchange_timeout_secs"); + + ret = silc_client_file_send(silc_client, conn, client_entry, ¶ms, + irssi_pubkey, irssi_privkey, + silc_client_file_monitor, server, argv[2], + &session_id); if (ret == SILC_CLIENT_FILE_OK) { ftp = silc_calloc(1, sizeof(*ftp)); ftp->session_id = session_id; @@ -874,32 +1018,33 @@ static void command_file(const char *data, SILC_SERVER_REC *server, client_entry->nickname, argv[2]); } + silc_client_list_free(silc_client, server->conn, entries); break; case 2: /* Parse the typed nickname. */ if (argc >= 3) { - if (!silc_parse_userfqdn(argv[2], &nickname, NULL)) { - printformat_module("fe-common/silc", server, NULL, - MSGLEVEL_CRAP, SILCTXT_BAD_NICK, argv[2]); - goto out; - } + /* Parse the typed nickname. */ + silc_client_nickname_parse(silc_client, conn, argv[2], &nickname); + if (!nickname) + nickname = strdup(argv[2]); /* Find client entry */ - entrys = silc_client_get_clients_local(silc_client, conn, nickname, - argv[2], &entry_count); - if (!entrys) { + entries = silc_client_get_clients_local(silc_client, conn, argv[2], + FALSE); + if (!entries) { FileGetClients inter = silc_calloc(1, sizeof(*inter)); inter->server = server; inter->data = strdup(data); inter->nick = strdup(nickname); inter->item = item; - silc_client_get_clients(silc_client, conn, nickname, argv[2], + silc_client_get_clients(silc_client, conn, nickname, NULL, silc_client_command_file_get_clients, inter); goto out; } - client_entry = entrys[0]; - silc_free(entrys); + silc_dlist_start(entries); + client_entry = silc_dlist_get(entries); + silc_client_list_free(silc_client, server->conn, entries); } else { if (!server->current_session) { printformat_module("fe-common/silc", server, NULL, @@ -907,7 +1052,24 @@ static void command_file(const char *data, SILC_SERVER_REC *server, goto out; } - ret = silc_client_file_receive(silc_client, conn, + memset(¶ms, 0, sizeof(params)); + if (settings_get_bool("use_auto_addr")) { + params.local_ip = (char *)settings_get_str("auto_public_ip"); + if ((params.local_ip) && (*params.local_ip == '\0')) { + params.local_ip = silc_net_localip(); + } else { + params.bind_ip = (char *)settings_get_str("auto_bind_ip"); + if ((params.bind_ip) && (*params.bind_ip == '\0')) + params.bind_ip = NULL; + params.local_port = settings_get_int("auto_bind_port"); + } + } + if (!params.local_ip) + params.local_ip = silc_net_localip(); + params.timeout_secs = settings_get_int("key_exchange_timeout_secs"); + + ret = silc_client_file_receive(silc_client, conn, ¶ms, + irssi_pubkey, irssi_privkey, silc_client_file_monitor, server, NULL, server->current_session->session_id, NULL, NULL); @@ -939,7 +1101,24 @@ static void command_file(const char *data, SILC_SERVER_REC *server, silc_dlist_start(server->ftp_sessions); while ((ftp = silc_dlist_get(server->ftp_sessions)) != SILC_LIST_END) { if (ftp->client_entry == client_entry && !ftp->filepath) { - ret = silc_client_file_receive(silc_client, conn, + memset(¶ms, 0, sizeof(params)); + if (settings_get_bool("use_auto_addr")) { + params.local_ip = (char *)settings_get_str("auto_public_ip"); + if ((params.local_ip) && (*params.local_ip == '\0')) { + params.local_ip = silc_net_localip(); + } else { + params.bind_ip = (char *)settings_get_str("auto_bind_ip"); + if ((params.bind_ip) && (*params.bind_ip == '\0')) + params.bind_ip = NULL; + params.local_port = settings_get_int("auto_bind_port"); + } + } + if (!params.local_ip) + params.local_ip = silc_net_localip(); + params.timeout_secs = settings_get_int("key_exchange_timeout_secs"); + + ret = silc_client_file_receive(silc_client, conn, ¶ms, + irssi_pubkey, irssi_privkey, silc_client_file_monitor, server, NULL, ftp->session_id, NULL, NULL); if (ret != SILC_CLIENT_FILE_OK) { @@ -977,27 +1156,27 @@ static void command_file(const char *data, SILC_SERVER_REC *server, case 3: /* Parse the typed nickname. */ if (argc >= 3) { - if (!silc_parse_userfqdn(argv[2], &nickname, NULL)) { - printformat_module("fe-common/silc", server, NULL, - MSGLEVEL_CRAP, SILCTXT_BAD_NICK, argv[2]); - goto out; - } + /* Parse the typed nickname. */ + silc_client_nickname_parse(silc_client, conn, argv[2], &nickname); + if (!nickname) + nickname = strdup(argv[2]); /* Find client entry */ - entrys = silc_client_get_clients_local(silc_client, conn, nickname, - argv[2], &entry_count); - if (!entrys) { + entries = silc_client_get_clients_local(silc_client, conn, argv[2], + FALSE); + if (!entries) { FileGetClients inter = silc_calloc(1, sizeof(*inter)); inter->server = server; inter->data = strdup(data); inter->nick = strdup(nickname); inter->item = item; - silc_client_get_clients(silc_client, conn, nickname, argv[2], + silc_client_get_clients(silc_client, conn, nickname, NULL, silc_client_command_file_get_clients, inter); goto out; } - client_entry = entrys[0]; - silc_free(entrys); + silc_dlist_start(entries); + client_entry = silc_dlist_get(entries); + silc_client_list_free(silc_client, server->conn, entries); } else { if (!server->current_session) { printformat_module("fe-common/silc", server, NULL, @@ -1082,6 +1261,7 @@ static void command_file(const char *data, SILC_SERVER_REC *server, out: silc_free(nickname); + return; } void silc_server_init(void) @@ -1110,9 +1290,7 @@ void silc_server_init(void) command_bind_silc("ping", MODULE_NAME, (SIGNAL_FUNC) command_self); command_bind_silc("motd", MODULE_NAME, (SIGNAL_FUNC) command_self); command_bind_silc("close", MODULE_NAME, (SIGNAL_FUNC) command_self); - command_bind_silc("shutdown", MODULE_NAME, (SIGNAL_FUNC) command_self); command_bind_silc("getkey", MODULE_NAME, (SIGNAL_FUNC) command_self); - command_bind_silc("sconnect", MODULE_NAME, (SIGNAL_FUNC) command_sconnect); command_bind_silc("file", MODULE_NAME, (SIGNAL_FUNC) command_file); command_bind_silc("detach", MODULE_NAME, (SIGNAL_FUNC) command_self); command_bind_silc("watch", MODULE_NAME, (SIGNAL_FUNC) command_self); @@ -1149,9 +1327,7 @@ void silc_server_deinit(void) command_unbind("motd", (SIGNAL_FUNC) command_self); command_unbind("ban", (SIGNAL_FUNC) command_self); command_unbind("close", (SIGNAL_FUNC) command_self); - command_unbind("shutdown", (SIGNAL_FUNC) command_self); command_unbind("getkey", (SIGNAL_FUNC) command_self); - command_unbind("sconnect", (SIGNAL_FUNC) command_sconnect); command_unbind("file", (SIGNAL_FUNC) command_file); command_unbind("detach", (SIGNAL_FUNC) command_self); command_unbind("watch", (SIGNAL_FUNC) command_self); @@ -1178,7 +1354,7 @@ void silc_server_free_ftp(SILC_SERVER_REC *server, bool silc_term_utf8(void) { const char *str; - str = settings_get_str("term_type"); + str = settings_get_str("term_charset"); if (str) if (g_strcasecmp(str, "utf-8") == 0) return TRUE;