+Thu Sep 6 12:47:37 EEST 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Renamed function silc_parse_nickname to silc_parse_userfqdn
+ to generally parse user@fqdn format strings. Affected file
+ lib/silcutil/silcutil.c.
+
+ * Added nickname_format and nickname_force_format fields to the
+ SilcClientParams structure. The first one defines the format
+ for the nicknames that the library will enforce if the receives
+ multiple same nicknames. The second one is boolean value and
+ can be used to force the library to always enforce the format
+ to the nicknames regardles whether there are multiple nicknames
+ or not. This configurable formatting was employed to flexibly
+ support accessing multiple nicknames from the user interface.
+ The userinterface can now set the nicknames to what ever format
+ they prefer. Affected file lib/silcclient/silcapi.h.
+
+ Added function silc_client_nickname_format to the file
+ lib/silcclient/idlist.c. It performs the nickname formatting.
+
+ Added new field `hostname´ to the SilcClientEntry context.
+ It holds the hostname of the client. Affected file is
+ lib/silcclient/idlist.h.
+
+ * Irssi SILC Client sets the nicknames in nick@hostn format.
+ Fe. priikone@otaku, priikone@otaku2 etc. Affected file
+ irssi/src/silc/core/silc-core.c.
+
+ The WHOIS printing now also shows both the real nickname and
+ the formatted nickname so that user knows how to access the
+ user if there are multiple same nicknames cached. Affected
+ file irssi/src/silc/core/client_ops.c. Changed the WHOIS
+ printing formatting too to take the hostname now as a separate
+ argument. The Affected file is
+ irssi/src/fe-common/silc/modules-formats.[ch].
+
+ * Changed the silc_client_get_clients_local to accept the formatted
+ nickname as argument. It accepts the real nickname too but the
+ formatted nickname can be used to find the true entry from
+ multiple entries. Affected file lib/silcclient/silcapi.h and
+ lib/silcclient/idlist.c.
+
+ * Added nickname_format_parse field to the SilcClientParams.
+ It is a callback function provided by the application to parse
+ the nickname out of the formatted nickname string. The library
+ calls it to get the nickname from the formatted string. Since
+ the application generally knows better the format of the nickname
+ string it parses it instead of the library, even though library
+ encodes the formatted string. If the callback function is not
+ provided then the library will use the string as is. The
+ affected file is lib/silcclient/silcapi.h.
+
+ * All the nickname strings passed to the client library in
+ commands are now expected to be formatted nickname strings.
+ If the command does not support the formatted nickname string
+ it will assume that the sent string is the actual nickname.
+ Affected file lib/silcclient/command.c.
+
Tue Sep 4 22:31:28 EEST 2001 Pekka Riikonen <priikone@silcnet.org>
* Added public key authentication support to OPER and SILCOPER
o The QUIT command should wait for servers disconnection (at least for
a while) before exiting the application.
- o The JOIN commands HELP is generated from Irssi IRCs JOIN help and
+ o The JOIN command's HELP is generated from Irssi IRCs JOIN help and
the syntax is not same in SILC. This must be fixed.
+ o With USERS command to a channel user is not joined the name of the
+ channel is printed as garbled.
+
o Add PERL scripting support from Irssi CVS.
o Extend the /HELP command to support sub commands or something. So
TODO/bugs In SILC Client Library
================================
- o The client library must manage somehow when receiving client that has
- same nickname, same server, same username but different Client ID than
- what we have in the cache. It is now assumed that they are different
- client but it might not be. It should at least number the clients
- using the client->num so that they can be accessed from the user
- interface separately or it could just remove the old client unless
- it is on some channels.
+ o JOIN command's argument handling is buggy. See the XXX in the code.
TODO/bugs In SILC Server
o Add perhaps /var/run/silcd.pid for PID information for the server.
+ o Add a timeout to handling incmoing JOIN commands. It should be
+ enforced that JOIN command is executed only once in a second or two
+ seconds. Now it is possible to accept n incoming JOIN commands
+ and process them without any timeouts. THis must be employed because
+ each JOIN command will create and distribute the new channel key
+ to everybody on the channel.
+
o Incomplete IPv6 support:
o silcd/serverid.c and its routines supports only IPv4.
/* WHOIS, WHOWAS and USERS (alias WHO) messages */
{ NULL, "Who Queries", 0 },
- { "whois", "{nick $0} {nickhost $1}%: realname : $2", 3, { 0, 0, 0 } },
+ { "whois", "{nick $0} {nickhost $1@$2}%: nickname : $3 ($4)", 5, { 0, 0, 0, 0, 0 } },
+ { "whois_realname", " realname : $0", 1, { 0 } },
{ "whois_channels", " channels : $0", 1, { 0 } },
{ "whois_modes", " modes : $0", 1, { 0 } },
{ "whois_idle", " idle : $0", 1, { 0 } },
SILCTXT_FILL_2,
SILCTXT_WHOIS_USERINFO,
+ SILCTXT_WHOIS_REALNAME,
SILCTXT_WHOIS_CHANNELS,
SILCTXT_WHOIS_MODES,
SILCTXT_WHOIS_IDLE,
switch(command) {
case SILC_COMMAND_WHOIS:
{
- char buf[1024], *nickname, *username, *realname;
+ char buf[1024], *nickname, *username, *realname, *nick;
uint32 idle, mode;
SilcBuffer channels;
+ SilcClientEntry client_entry;
if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
if (!success)
return;
- (void)va_arg(vp, SilcClientEntry);
+ client_entry = va_arg(vp, SilcClientEntry);
nickname = va_arg(vp, char *);
username = va_arg(vp, char *);
realname = va_arg(vp, char *);
mode = va_arg(vp, uint32);
idle = va_arg(vp, uint32);
+ silc_parse_userfqdn(nickname, &nick, NULL);
+ printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
+ SILCTXT_WHOIS_USERINFO, nickname,
+ client_entry->username, client_entry->hostname,
+ nick, client_entry->nickname);
printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
- SILCTXT_WHOIS_USERINFO, nickname, username,
- realname);
+ SILCTXT_WHOIS_REALNAME, realname);
+ silc_free(nick);
if (channels) {
SilcDList list = silc_channel_payload_parse_list(channels);
SilcClientConnection conn = server->conn;
SilcClientEntry client_entry = NULL;
SilcChannelEntry channel_entry = NULL;
- uint32 num = 0;
- char *nickname = NULL, *serv = NULL, *tmp;
+ char *nickname = NULL, *tmp;
int command = 0, port = 0, type = 0;
char *hostname = NULL;
KeyInternal internal = NULL;
nickname = "*";
} else {
/* Parse the typed nickname. */
- if (!silc_parse_nickname(argv[2], &nickname, &serv, &num)) {
+ if (!silc_parse_userfqdn(argv[2], &nickname, NULL)) {
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_BAD_NICK, argv[2]);
return;
/* Find client entry */
client_entry = silc_idlist_get_client(silc_client, conn, nickname,
- serv, num, TRUE);
+ argv[2], TRUE);
if (!client_entry) {
KeyGetClients inter = silc_calloc(1, sizeof(*inter));
inter->server = server;
if (argv[2][0] == '*') {
if (!conn->current_channel) {
- if (nickname)
- silc_free(nickname);
- if (serv)
- silc_free(serv);
+ silc_free(nickname);
cmd_return_error(CMDERR_NOT_JOINED);
}
name = conn->current_channel->channel_name;
channel_entry = silc_client_get_channel(silc_client, conn, name);
if (!channel_entry) {
- if (nickname)
- silc_free(nickname);
- if (serv)
- silc_free(serv);
+ silc_free(nickname);
cmd_return_error(CMDERR_NOT_JOINED);
}
}
}
out:
- if (nickname)
- silc_free(nickname);
- if (serv)
- silc_free(serv);
+ silc_free(nickname);
}
/* Lists locally saved client and server public keys. */
args_register(options);
}
+static void silc_nickname_format_parse(const char *nickname,
+ char **ret_nickname)
+{
+ silc_parse_userfqdn(nickname, ret_nickname, NULL);
+}
+
/* Finalize init. Called from src/fe-text/silc.c */
void silc_core_init_finish(void)
{
CHAT_PROTOCOL_REC *rec;
+ SilcClientParams params;
if (opt_create_keypair == TRUE) {
/* Create new key pair and exit */
settings_add_str("server", "alternate_nick", NULL);
silc_init_userinfo();
+ /* Initialize client parameters */
+ memset(¶ms, 0, sizeof(params));
+ strcat(params.nickname_format, "%n@%h%a");
+ params.nickname_parse = silc_nickname_format_parse;
+
/* Allocate SILC client */
- silc_client = silc_client_alloc(&ops, NULL, NULL, silc_version_string);
+ silc_client = silc_client_alloc(&ops, ¶ms, NULL, silc_version_string);
/* Load local config file */
silc_config = silc_client_config_alloc(SILC_CLIENT_HOME_CONFIG_FILE);
typedef struct {
char *nick;
char *msg;
+ SILC_SERVER_REC *server;
} PRIVMSG_REC;
/* Callback function that sends the private message if the client was
void *context)
{
PRIVMSG_REC *rec = context;
+ SILC_SERVER_REC *server = rec->server;
SilcClientEntry target;
-
- if (clients_count == 0) {
+ char *nickname = NULL;
+
+ if (!clients_count) {
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown nick: %s", rec->nick);
} else {
- target = clients[0]; /* FIXME: not a good idea :) */
-
+ 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, "Unknown nick: %s",
+ rec->nick);
+ silc_free(nickname);
+ goto out;
+ }
+ silc_free(nickname);
+ }
+
+ target = clients[0];
+
+ /* Send the private message */
silc_client_send_private_message(client, conn, target, 0,
rec->msg, strlen(rec->msg),
TRUE);
}
+ out:
g_free(rec->nick);
g_free(rec->msg);
g_free(rec);
static void silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg)
{
PRIVMSG_REC *rec;
- SilcClientEntry client_entry;
- uint32 num = 0;
- char *nickname = NULL, *serv = NULL;
-
- if (!silc_parse_nickname(nick, &nickname, &serv, &num)) {
+ SilcClientEntry *clients;
+ uint32 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;
}
/* Find client entry */
- client_entry = silc_idlist_get_client(silc_client, server->conn,
- nickname, serv, num, FALSE);
- if (!client_entry) {
+ clients = silc_client_get_clients_local(silc_client, server->conn,
+ nickname, nick, &clients_count);
+ silc_free(nickname);
+
+ if (!clients) {
rec = g_new0(PRIVMSG_REC, 1);
rec->nick = g_strdup(nick);
rec->msg = g_strdup(msg);
+ rec->server = server;
/* Could not find client with that nick, resolve it from server. */
silc_client_get_clients(silc_client, server->conn,
- nickname, serv, silc_send_msg_clients, rec);
+ nickname, NULL, silc_send_msg_clients, rec);
return;
}
/* Send the private message directly */
- silc_client_send_private_message(silc_client, server->conn, client_entry, 0,
- msg, strlen(msg), TRUE);
+ silc_client_send_private_message(silc_client, server->conn,
+ clients[0], 0, msg, strlen(msg), TRUE);
}
static int isnickflag_func(char flag)
/* SYNTAX: BAN <channel> [+|-[<nickname>[@<server>[!<username>[@hostname>]]]]] */
/* SYNTAX: CMODE <channel> +|-<modes> [{ <arguments>}] */
-/* SYNTAX: CUMODE <channel> +|-<modes> <nickname>[@<server>] [-pubkey|<passwd>] */
+/* SYNTAX: CUMODE <channel> +|-<modes> <nickname>[@<hostname>] [-pubkey|<passwd>] */
/* SYNTAX: GETKEY <nickname or server name> */
-/* SYNTAX: INVITE <channel> [<nickname>[@server>] */
+/* SYNTAX: INVITE <channel> [<nickname>[@hostname>] */
/* SYNTAX: INVITE <channel> [+|-[<nickname>[@<server>[!<username>[@hostname>]]]]] */
/* SYNTAX: KEY MSG <nickname> set|unset|list|agreement|negotiate [<arguments>] */
/* SYNTAX: KEY CHANNEL <channel> set|unset|list|agreement|negotiate [<arguments>] */
-/* SYNTAX: KICK <channel> <nickname>[@<server>] [<comment>] */
-/* SYNTAX: KILL <channel> <nickname>[@<server>] [<comment>] */
+/* SYNTAX: KICK <channel> <nickname>[@<hostname>] [<comment>] */
+/* SYNTAX: KILL <channel> <nickname>[@<hostname>] [<comment>] */
/* SYNTAX: OPER <username> [-pubkey] */
/* SYNTAX: SILCOPER <username> [-pubkey] */
/* SYNTAX: TOPIC <channel> [<topic>] */
/* SYNTAX: UMODE +|-<modes> */
-/* SYNTAX: WHOIS <nickname>[@<server>] [<count>] */
-/* SYNTAX: WHOWAS <nickname>[@<server>] [<count>] */
+/* SYNTAX: WHOIS <nickname>[@<hostname>] [<count>] */
+/* SYNTAX: WHOWAS <nickname>[@<hostname>] [<count>] */
/* SYNTAX: CLOSE <server> [<port>] */
/* SYNTAX: SHUTDOWN */
/* SYNTAX: MOTD [<server>] */
Reply messages to the command:
Max Arguments: 4
- Arguments: (1) <Status Payload> (2) <Client ID>
+ Arguments: (1) <Status Payload> (2) <ID Payload>
(3) [<entity's name>] (4) [<info>]
This command may reply with several command reply messages to form
one reply the status is set to normal STATUS_OK.
When querying clients the <entity's name> must include the client's
- nickname in the following format: nickname>[@server]. The
+ nickname in the following format: nickname[@server]. The
<info> must include the client's username and host in the following
format: username@host.
client.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
Copyright (C) 1997 - 2001 Pekka Riikonen
if (params)
memcpy(new_client->params, params, sizeof(*params));
+ if (!new_client->params->task_max)
+ new_client->params->task_max = 200;
+
if (!new_client->params->rekey_secs)
new_client->params->rekey_secs = 3600;
if (!new_client->params->connauth_request_secs)
new_client->params->connauth_request_secs = 2;
+ new_client->params->
+ nickname_format[sizeof(new_client->params->nickname_format) - 1] = 0;
+
return new_client;
}
silc_schedule(client->schedule);
}
+static void silc_client_entry_destructor(SilcIDCache cache,
+ SilcIDCacheEntry entry)
+{
+ silc_free(entry->name);
+}
+
/* Allocates and adds new connection to the client. This adds the allocated
connection to the connection table and returns a pointer to it. A client
can have multiple connections to multiple servers. Every connection must
conn = silc_calloc(1, sizeof(*conn));
/* Initialize ID caches */
- conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT, NULL);
+ conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT,
+ silc_client_entry_destructor);
conn->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
conn->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
conn->client = client;
used only if the application performed the connecting outside the library.
The library however may use this internally. */
-int silc_client_start_key_exchange(SilcClient client,
- SilcClientConnection conn,
- int fd)
+bool silc_client_start_key_exchange(SilcClient client,
+ SilcClientConnection conn,
+ int fd)
{
SilcProtocol protocol;
SilcClientKEInternalContext *proto_ctx;
silc_client_connect_to_server_second);
if (!protocol) {
client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
- "Error: Could not start authentication protocol");
+ "Error: Could not start key exchange protocol");
return FALSE;
}
conn->sock->protocol = protocol;
conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
conn->local_entry->nickname = conn->nickname;
- if (!conn->local_entry->username) {
- conn->local_entry->username =
- silc_calloc(strlen(client->username) + strlen(client->hostname) + 1,
- sizeof(conn->local_entry->username));
- sprintf(conn->local_entry->username, "%s@%s", client->username,
- client->hostname);
- }
+ if (!conn->local_entry->username)
+ conn->local_entry->username = strdup(client->username);
+ if (!conn->local_entry->hostname)
+ conn->local_entry->hostname = strdup(client->hostname);
conn->local_entry->server = strdup(conn->remote_host);
conn->local_entry->id = conn->local_id;
/* Put it to the ID cache */
- silc_idcache_add(conn->client_cache, conn->nickname, conn->local_id,
+ silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id,
(void *)conn->local_entry, FALSE);
/* Issue INFO command to fetch the real server name and server information
client.h
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
Copyright (C) 1997 - 2001 Pekka Riikonen
/* Get channel entry */
if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
- &id_cache))
+ &id_cache))
break;
channel = (SilcChannelEntry)id_cache->context;
SilcClientEntry client_entry = NULL;
SilcChannelEntry channel;
SilcBuffer buffer, clidp, chidp;
- uint32 num = 0, type = 0;
- char *nickname = NULL, *server = NULL, *name;
+ uint32 type = 0;
+ char *nickname = NULL, *name;
char *invite = NULL;
if (!cmd->conn) {
/* Parse the typed nickname. */
if (cmd->argc == 3) {
if (cmd->argv[2][0] != '+' && cmd->argv[2][0] != '-') {
- if (!silc_parse_nickname(cmd->argv[2], &nickname, &server, &num)) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
-
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[2], &nickname);
+ else
+ nickname = strdup(cmd->argv[2]);
+
/* Find client entry */
client_entry = silc_idlist_get_client(client, conn, nickname,
- server, num, TRUE);
+ cmd->argv[2], TRUE);
if (!client_entry) {
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
if (cmd->pending) {
COMMAND_ERROR;
COMMAND;
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
SILC_CLIENT_CMD_FUNC(kill)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
SilcClientConnection conn = cmd->conn;
SilcBuffer buffer, idp;
SilcClientEntry target;
- uint32 num = 0;
- char *nickname = NULL, *server = NULL;
+ char *nickname = NULL;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
}
/* Parse the typed nickname. */
- if (!silc_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[1], &nickname);
+ else
+ nickname = strdup(cmd->argv[1]);
/* Get the target client */
target = silc_idlist_get_client(cmd->client, conn, nickname,
- server, num, TRUE);
+ cmd->argv[1], TRUE);
if (!target) {
silc_free(nickname);
- if (server)
- silc_free(server);
if (cmd->pending) {
COMMAND_ERROR;
COMMAND;
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
SILC_CLIENT_CMD_FUNC(cumode)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
SilcClientConnection conn = cmd->conn;
SilcChannelEntry channel;
SilcChannelUser chu;
SilcBuffer buffer, clidp, chidp, auth = NULL;
unsigned char *name, *cp, modebuf[4];
uint32 mode = 0, add, len;
- char *nickname = NULL, *server = NULL;
- uint32 num = 0;
+ char *nickname = NULL;
int i;
if (!cmd->conn) {
}
/* Parse the typed nickname. */
- if (!silc_parse_nickname(cmd->argv[3], &nickname, &server, &num)) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[3], &nickname);
+ else
+ nickname = strdup(cmd->argv[3]);
/* Find client entry */
- client_entry = silc_idlist_get_client(cmd->client, conn,
- nickname, server, num, TRUE);
+ client_entry = silc_idlist_get_client(cmd->client, conn, nickname,
+ cmd->argv[3], TRUE);
if (!client_entry) {
+ silc_free(nickname);
+
if (cmd->pending) {
COMMAND_ERROR;
goto out;
COMMAND;
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
SILC_CLIENT_CMD_FUNC(kick)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
SilcClientConnection conn = cmd->conn;
SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
SilcBuffer buffer, idp, idp2;
SilcClientEntry target;
char *name;
- uint32 num = 0;
- char *nickname = NULL, *server = NULL;
+ char *nickname = NULL;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
channel = (SilcChannelEntry)id_cache->context;
/* Parse the typed nickname. */
- if (!silc_parse_nickname(cmd->argv[2], &nickname, &server, &num)) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[2], &nickname);
+ else
+ nickname = strdup(cmd->argv[2]);
/* Get the target client */
target = silc_idlist_get_client(cmd->client, conn, nickname,
- server, num, FALSE);
+ cmd->argv[2], FALSE);
if (!target) {
cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
"No such client: %s",
COMMAND;
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
SilcClient client = cmd->client;
SilcClientEntry client_entry = NULL;
SilcServerEntry server_entry = NULL;
- uint32 num = 0;
- char *nickname = NULL, *server = NULL;
+ char *nickname = NULL;
SilcBuffer idp, buffer;
if (!cmd->conn) {
}
/* Parse the typed nickname. */
- if (!silc_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO, "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[1], &nickname);
+ else
+ nickname = strdup(cmd->argv[1]);
/* Find client entry */
- client_entry = silc_idlist_get_client(client, conn, nickname, server, num,
+ client_entry = silc_idlist_get_client(client, conn, nickname, cmd->argv[1],
FALSE);
if (!client_entry) {
/* Check whether user requested server actually */
- server_entry = silc_client_get_server(client, conn, nickname);
+ server_entry = silc_client_get_server(client, conn, cmd->argv[1]);
if (!server_entry) {
/* No. what ever user wants we don't have it, so resolve it. We
bound to be wrong. */
/* This will send the IDENTIFY command */
- silc_idlist_get_client(client, conn, nickname, server, num, TRUE);
+ silc_idlist_get_client(client, conn, nickname, cmd->argv[1], TRUE);
silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
conn->cmd_ident,
silc_client_command_destructor,
/* This sends the INFO command to resolve the server. */
silc_client_send_command(client, conn, SILC_COMMAND_INFO,
++conn->cmd_ident, 1,
- 1, nickname, strlen(nickname));
+ 1, cmd->argv[1], cmd->argv_lens[1]);
silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
conn->cmd_ident,
silc_client_command_destructor,
silc_client_command_dup(cmd));
cmd->pending = 1;
+ silc_free(nickname);
return;
}
COMMAND;
out:
+ silc_free(nickname);
silc_client_command_free(cmd);
}
silc_hash_client_id_compare, NULL,
&id_cache)) {
SILC_LOG_DEBUG(("Adding new client entry"));
-
- client_entry = silc_calloc(1, sizeof(*client_entry));
- client_entry->id = client_id;
- silc_parse_nickname(nickname, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
- client_entry->username = strdup(username);
- if (realname)
- client_entry->realname = strdup(realname);
- client_entry->mode = mode;
-
- /* Add client to cache */
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_id, (void *)client_entry, FALSE);
+ client_entry =
+ silc_client_add_client(cmd->client, conn, nickname, username, realname,
+ client_id, mode);
} else {
client_entry = (SilcClientEntry)id_cache->context;
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (client_entry->username)
- silc_free(client_entry->username);
- if (client_entry->realname)
- silc_free(client_entry->realname);
- client_entry->mode = mode;
-
- SILC_LOG_DEBUG(("Updating client entry"));
-
- silc_parse_nickname(nickname, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
- client_entry->username = strdup(username);
- if (realname)
- client_entry->realname = strdup(realname);
-
- /* Remove the old cache entry and create a new one */
- silc_idcache_del_by_context(conn->client_cache, client_entry);
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_entry->id, client_entry, FALSE);
+ silc_client_update_client(cmd->client, conn, client_entry,
+ nickname, username, realname, mode);
silc_free(client_id);
}
silc_hash_client_id_compare, NULL,
&id_cache)) {
SILC_LOG_DEBUG(("Adding new client entry"));
-
- client_entry = silc_calloc(1, sizeof(*client_entry));
- client_entry->id = silc_id_dup(client_id, id_type);
- silc_parse_nickname(name, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
- if (info)
- client_entry->username = strdup(info);
-
- /* Add client to cache */
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_entry->id, (void *)client_entry, FALSE);
+ client_entry =
+ silc_client_add_client(cmd->client, conn, name, info, NULL,
+ silc_id_dup(client_id, id_type), 0);
} else {
client_entry = (SilcClientEntry)id_cache->context;
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (info && client_entry->username)
- silc_free(client_entry->username);
-
- SILC_LOG_DEBUG(("Updating client entry"));
-
- silc_parse_nickname(name, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
-
- if (info)
- client_entry->username = strdup(info);
-
- /* Remove the old cache entry and create a new one */
- silc_idcache_del_by_context(conn->client_cache, client_entry);
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_entry->id, client_entry, FALSE);
+ silc_client_update_client(cmd->client, conn, client_entry,
+ name, info, NULL, 0);
}
/* Notify application */
silc_hash_client_id_compare, NULL,
&id_cache)) {
/* No, we don't have it, add entry for it. */
- client_entry = silc_calloc(1, sizeof(*client_entry));
- client_entry->id = silc_id_dup(client_id, SILC_ID_CLIENT);
- silc_idcache_add(conn->client_cache, NULL, client_entry->id,
- (void *)client_entry, FALSE);
+ client_entry =
+ silc_client_add_client(cmd->client, conn, NULL, NULL, NULL,
+ silc_id_dup(client_id, SILC_ID_CLIENT), 0);
} else {
/* Yes, we have it already */
client_entry = (SilcClientEntry)id_cache->context;
idlist.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2000 Pekka Riikonen
+ Copyright (C) 2001 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
void silc_client_get_clients(SilcClient client,
SilcClientConnection conn,
- char *nickname,
- char *server,
+ const char *nickname,
+ const char *server,
SilcGetClientCallback completion,
void *context)
{
(void *)i);
}
-/* Same as above function but does not resolve anything from the server.
- This checks local cache and returns all clients from the cache. */
+/* Same as silc_client_get_clients function but does not resolve anything
+ from the server. This checks local cache and returns all matching
+ clients from the local cache. If none was found this returns NULL.
+ The `nickname' is the real nickname of the client, and the `format'
+ is the formatted nickname to find exact match from multiple found
+ entries. The format must be same as given in the SilcClientParams
+ structure to the client library. If the `format' is NULL all found
+ clients by `nickname' are returned. */
SilcClientEntry *silc_client_get_clients_local(SilcClient client,
SilcClientConnection conn,
- char *nickname,
- char *server,
+ const char *nickname,
+ const char *format,
uint32 *clients_count)
{
SilcIDCacheEntry id_cache;
bool found = FALSE;
/* Find ID from cache */
- if (!silc_idcache_find_by_name(conn->client_cache, nickname, &list))
+ if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname, &list))
return NULL;
if (!silc_idcache_list_count(list)) {
clients = silc_calloc(silc_idcache_list_count(list), sizeof(*clients));
*clients_count = silc_idcache_list_count(list);
- if (!server) {
+ if (!format) {
/* Take all without any further checking */
silc_idcache_list_first(list, &id_cache);
while (id_cache) {
silc_idcache_list_first(list, &id_cache);
while (id_cache) {
entry = (SilcClientEntry)id_cache->context;
-
- if (entry->server &&
- strncasecmp(server, entry->server, strlen(server))) {
+ if (strcasecmp(entry->nickname, format)) {
if (!silc_idcache_list_next(list, &id_cache)) {
break;
} else {
SilcClientEntry silc_idlist_get_client(SilcClient client,
SilcClientConnection conn,
- char *nickname,
- char *server,
- uint32 num,
- int query)
+ const char *nickname,
+ const char *format,
+ bool query)
{
SilcIDCacheEntry id_cache;
SilcIDCacheList list = NULL;
SilcClientEntry entry = NULL;
/* Find ID from cache */
- if (!silc_idcache_find_by_name(conn->client_cache, nickname, &list)) {
+ if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname,
+ &list)) {
identify:
if (query) {
return NULL;
}
- if (!server && !num) {
+ if (!format) {
/* Take first found cache entry */
if (!silc_idcache_list_first(list, &id_cache))
goto identify;
} else {
/* Check multiple cache entries for match */
silc_idcache_list_first(list, &id_cache);
- entry = (SilcClientEntry)id_cache->context;
-
- while (entry) {
- if (server && entry->server &&
- !strncasecmp(server, entry->server, strlen(server)))
- break;
-
- if (num && entry->num == num)
- break;
+ while (id_cache) {
+ entry = (SilcClientEntry)id_cache->context;
- if (!silc_idcache_list_next(list, &id_cache)) {
- entry = NULL;
- break;
+ if (strcasecmp(entry->nickname, format)) {
+ if (!silc_idcache_list_next(list, &id_cache)) {
+ entry = NULL;
+ break;
+ } else {
+ entry = NULL;
+ continue;
+ }
}
- entry = (SilcClientEntry)id_cache->context;
+ break;
}
/* If match weren't found, request it */
(void *)i);
}
+/* Creates new client entry and adds it to the ID cache. Returns pointer
+ to the new entry. */
+
+SilcClientEntry
+silc_client_add_client(SilcClient client, SilcClientConnection conn,
+ char *nickname, char *username,
+ char *userinfo, SilcClientID *id, uint32 mode)
+{
+ SilcClientEntry client_entry;
+ char *nick = NULL;
+
+ /* Save the client infos */
+ client_entry = silc_calloc(1, sizeof(*client_entry));
+ client_entry->id = id;
+ silc_parse_userfqdn(nickname, &nick, &client_entry->server);
+ silc_parse_userfqdn(username, &client_entry->username,
+ &client_entry->hostname);
+ if (userinfo)
+ client_entry->realname = strdup(userinfo);
+ client_entry->mode = mode;
+ if (nick)
+ client_entry->nickname = strdup(nick);
+
+ /* Format the nickname */
+ silc_client_nickname_format(client, conn, client_entry);
+
+ /* Add client to cache, the non-formatted nickname is saved to cache */
+ if (!silc_idcache_add(conn->client_cache, nick, client_entry->id,
+ (void *)client_entry, FALSE)) {
+ silc_free(client_entry->nickname);
+ silc_free(client_entry->username);
+ silc_free(client_entry->hostname);
+ silc_free(client_entry->server);
+ silc_free(client_entry);
+ return NULL;
+ }
+
+ return client_entry;
+}
+
+/* Updates the `client_entry' with the new information sent as argument. */
+
+void silc_client_update_client(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientEntry client_entry,
+ const char *nickname,
+ const char *username,
+ const char *userinfo,
+ uint32 mode)
+{
+ char *nick = NULL;
+
+ if (!client_entry->username && username)
+ silc_parse_userfqdn(username, &client_entry->username,
+ &client_entry->hostname);
+ if (!client_entry->realname && userinfo)
+ client_entry->realname = strdup(userinfo);
+ if (!client_entry->nickname && nickname) {
+ silc_parse_userfqdn(nickname, &nick, &client_entry->server);
+ client_entry->nickname = strdup(nick);
+ silc_client_nickname_format(client, conn, client_entry);
+ }
+ client_entry->mode = mode;
+
+ if (nick) {
+ /* Remove the old cache entry and create a new one */
+ silc_idcache_del_by_context(conn->client_cache, client_entry);
+ silc_idcache_add(conn->client_cache, nick, client_entry->id,
+ client_entry, FALSE);
+ }
+}
+
/* Deletes the client entry and frees all memory. */
void silc_client_del_client_entry(SilcClient client,
silc_free(server);
return ret;
}
+
+/* Formats the nickname of the client specified by the `client_entry'.
+ If the format is specified by the application this will format the
+ nickname and replace the old nickname in the client entry. If the
+ format string is not specified then this function has no effect. */
+
+void silc_client_nickname_format(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientEntry client_entry)
+{
+ char *cp;
+ char *newnick = NULL;
+ int i, off = 0, len;
+ SilcClientEntry *clients;
+ uint32 clients_count;
+
+ if (!client->params->nickname_format[0])
+ return;
+
+ if (!client_entry->nickname)
+ return;
+
+ /* Get all clients with same nickname. Do not perform the formatting
+ if there aren't any clients with same nickname unless the application
+ is forcing us to do so. */
+ clients = silc_client_get_clients_local(client, conn,
+ client_entry->nickname, NULL,
+ &clients_count);
+ if (!clients && !client->params->nickname_force_format)
+ return;
+
+ cp = client->params->nickname_format;
+ while (*cp) {
+ if (*cp == '%') {
+ cp++;
+ continue;
+ }
+
+ switch(*cp) {
+ case 'n':
+ /* Nickname */
+ if (!client_entry->nickname)
+ break;
+ len = strlen(client_entry->nickname);
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + len));
+ memcpy(&newnick[off], client_entry->nickname, len);
+ off += len;
+ break;
+ case 'h':
+ /* Stripped hostname */
+ if (!client_entry->hostname)
+ break;
+ len = strcspn(client_entry->hostname, ".");
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + len));
+ memcpy(&newnick[off], client_entry->hostname, len);
+ off += len;
+ break;
+ case 'H':
+ /* Full hostname */
+ if (!client_entry->hostname)
+ break;
+ len = strlen(client_entry->hostname);
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + len));
+ memcpy(&newnick[off], client_entry->hostname, len);
+ off += len;
+ break;
+ case 's':
+ /* Stripped server name */
+ if (!client_entry->server)
+ break;
+ len = strcspn(client_entry->server, ".");
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + len));
+ memcpy(&newnick[off], client_entry->server, len);
+ off += len;
+ break;
+ case 'S':
+ /* Full server name */
+ if (!client_entry->server)
+ break;
+ len = strlen(client_entry->server);
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + len));
+ memcpy(&newnick[off], client_entry->server, len);
+ off += len;
+ break;
+ case 'a':
+ /* Ascending number */
+ {
+ char tmp[6];
+ int num, max = 1;
+
+ if (clients_count == 1)
+ break;
+
+ for (i = 0; i < clients_count; i++) {
+ if (strncmp(clients[i]->nickname, newnick, off))
+ continue;
+ if (strlen(clients[i]->nickname) <= off)
+ continue;
+ num = atoi(&clients[i]->nickname[off]);
+ if (num > max)
+ max = num;
+ }
+
+ memset(tmp, 0, sizeof(tmp));
+ snprintf(tmp, sizeof(tmp) - 1, "%d", ++max);
+ len = strlen(tmp);
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + len));
+ memcpy(&newnick[off], tmp, len);
+ off += len;
+ }
+ break;
+ default:
+ /* Some other character in the string */
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + 1));
+ memcpy(&newnick[off], cp, 1);
+ off++;
+ break;
+ }
+
+ cp++;
+ }
+
+ newnick = silc_realloc(newnick, sizeof(*newnick) * (off + 1));
+ newnick[off] = 0;
+
+ silc_free(client_entry->nickname);
+ client_entry->nickname = newnick;
+ silc_free(clients);
+}
idlist.h
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2000 Pekka Riikonen
+ Copyright (C) 1997 - 2001 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
they are used. */
typedef struct {
char *nickname; /* nickname */
- char *username; /* username[@host] */
+ char *username; /* username */
+ char *hostname; /* hostname */
char *server; /* SILC server name */
char *realname; /* Realname (userinfo) */
uint32 num;
/* Prototypes. These are used only by the library. Application should not
call these directly. */
+SilcClientEntry
+silc_client_add_client(SilcClient client, SilcClientConnection conn,
+ char *nickname, char *username,
+ char *userinfo, SilcClientID *id, uint32 mode);
+void silc_client_update_client(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientEntry client_entry,
+ const char *nickname,
+ const char *username,
+ const char *userinfo,
+ uint32 mode);
void silc_client_del_client_entry(SilcClient client,
SilcClientEntry client_entry);
SilcClientEntry silc_idlist_get_client(SilcClient client,
SilcClientConnection conn,
- char *nickname,
- char *server,
- uint32 num,
- int query);
+ const char *nickname,
+ const char *format,
+ bool query);
SilcChannelEntry silc_idlist_get_channel_by_id(SilcClient client,
SilcClientConnection conn,
SilcChannelID *channel_id,
int query);
+void silc_client_nickname_format(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientEntry client_entry);
#endif
silcapi.h
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
Copyright (C) 2000 - 2001 Pekka Riikonen
} SilcClientOperations;
/***/
+/****f* silcclient/SilcClientAPI/SilcNicknameFormatParse
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcNicknameFormatParse)(const char *nickname,
+ * char **ret_nickname);
+ *
+ * DESCRIPTION
+ *
+ * A callback function provided by the application for the library in
+ * SilcClientParams structure. This function parses the formatted
+ * nickname string `nickname' and returns the true nickname to the
+ * `ret_nickname' pointer. The library can call this function at
+ * any time.
+ *
+ ***/
+typedef void (*SilcNicknameFormatParse)(const char *nickname,
+ char **ret_nickname);
+
/****s* silcclient/SilcClientAPI/SilcClientParams
*
* NAME
in this time interval we'll assume the reply will not come at all.
If set to zero, the default value (2 seconds) will be used. */
unsigned int connauth_request_secs;
+
+ /* Nickname format string. This can be used to order the client library
+ to save the nicknames in the library in a certain format. Since
+ nicknames are not unique in SILC it is possible to have multiple same
+ nicknames. Using this format string it is possible to order the library
+ to separate the multiple same nicknames from each other. The format
+ types are defined below and they can appear in any order in the format
+ string. If this is NULL then default format is used which is the
+ default nickname without anything else. The string MUST be NULL
+ terminated.
+
+ Following format types are available:
+
+ %n nickname - the real nickname returned by the server (mandatory)
+ %h hostname - the stripped hostname of the client
+ %H full hostname - the full hostname of the client
+ %s server name - the server name the client is connected
+ %S full server - the full server name the client is connected
+ %a number - ascending number in case there are several
+ same nicknames (fe. nick@host and nick@host2)
+
+ Example format strings: "%n@%h%a" (fe. nick@host, nick@host2)
+ "%a!%n@%s" (fe. nick@server, 2!nick@server)
+ "%n@%H" (fe. nick@host.domain.com)
+
+ By default this format is employed to the nicknames by the libary
+ only when there appears multiple same nicknames. If the library has
+ only one nickname cached the nickname is saved as is and without the
+ defined format. If you want always to save the nickname in the defined
+ format set the boolean field `nickname_force_format' to value TRUE.
+ */
+ char nickname_format[32];
+
+ /* If this is set to TRUE then the `nickname_format' is employed to all
+ saved nicknames even if there are no multiple same nicknames in the
+ cache. By default this is FALSE, which means that the `nickname_format'
+ is employed only if the library will receive a nickname that is
+ already saved in the cache. It is recommended to leave this to FALSE
+ value. */
+ bool nickname_force_format;
+
+ /* A callback function provided by the application for the library to
+ parse the nickname from the formatted nickname string. Even though
+ the libary formats the nicknames the application knows generally the
+ format better so this function should be provided for the library
+ if the application sets the `nickname_format' field. The library
+ will call this to get the true nickname from the provided formatted
+ nickname string whenever it needs the true nickname. */
+ SilcNicknameFormatParse nickname_parse;
+
} SilcClientParams;
/***/
* directly if application is performing its own connecting and does not
* use the connecting provided by this library. This function is normally
* used only if the application performed the connecting outside the
- * library. The library however may use this internally.
+ * library. The library however may use this internally. Returns FALSE
+ * if the key exchange could not be started.
*
***/
-int silc_client_start_key_exchange(SilcClient client,
- SilcClientConnection conn,
- int fd);
+bool silc_client_start_key_exchange(SilcClient client,
+ SilcClientConnection conn,
+ int fd);
/****f* silcclient/SilcClientAPI/silc_client_close_connection
*
*
* void silc_client_get_clients(SilcClient client,
* SilcClientConnection conn,
- * char *nickname,
- * char *server,
+ * const char *nickname,
+ * const char *server,
* SilcGetClientCallback completion,
* void *context);
*
***/
void silc_client_get_clients(SilcClient client,
SilcClientConnection conn,
- char *nickname,
- char *server,
+ const char *nickname,
+ const char *server,
SilcGetClientCallback completion,
void *context);
*
* SilcClientEntry *silc_client_get_clients_local(SilcClient client,
* SilcClientConnection conn,
- * char *nickname,
- * char *server,
+ * const char *nickname,
+ * const char *format,
* uint32 *clients_count);
*
* DESCRIPTION
*
* Same as silc_client_get_clients function but does not resolve anything
- * from the server. This checks local cache and returns all clients from
- * the local cache.
+ * from the server. This checks local cache and returns all matching
+ * clients from the local cache. If none was found this returns NULL.
+ * The `nickname' is the real nickname of the client, and the `format'
+ * is the formatted nickname to find exact match from multiple found
+ * entries. The format must be same as given in the SilcClientParams
+ * structure to the client library. If the `format' is NULL all found
+ * clients by `nickname' are returned.
*
***/
SilcClientEntry *silc_client_get_clients_local(SilcClient client,
SilcClientConnection conn,
- char *nickname,
- char *server,
+ const char *nickname,
+ const char *format,
uint32 *clients_count);
/****f* silcclient/SilcClientAPI/silc_client_get_clients_by_list
#ifdef HAVE_GETPID
silc_rng_xor(rng, getpid(), 1);
#ifdef HAVE_GETPGID
- silc_rng_xor(rng, getpgid(getpid() << 8), 2);
- silc_rng_xor(rng, getpgid(getpid() << 8), 3);
+ silc_rng_xor(rng, getpgid(getpid()) << 8, 2);
+ silc_rng_xor(rng, getpgid(getpid()) << 8, 3);
#endif
silc_rng_xor(rng, getgid(), 4);
#endif
silc_rng_xor(rng, getpgrp(), 5);
#endif
#ifdef HAVE_GETSID
- silc_rng_xor(rng, getsid(getpid() << 16), 6);
+ silc_rng_xor(rng, getsid(getpid()) << 16, 6);
#endif
silc_rng_xor(rng, times(&ptime), 7);
silc_rng_xor(rng, ptime.tms_utime, 8);
silc_rng_xor(rng, clock() << 4, pos++);
#ifndef SILC_WIN32
#ifdef HAVE_GETPGID
- silc_rng_xor(rng, getpgid(getpid() << 8), pos++);
+ silc_rng_xor(rng, getpgid(getpid()) << 8, pos++);
#endif
#ifdef HAVE_GETPGRP
silc_rng_xor(rng, getpgrp(), pos++);
#endif
#ifdef HAVE_SETSID
- silc_rng_xor(rng, getsid(getpid() << 16), pos++);
+ silc_rng_xor(rng, getsid(getpid()) << 16, pos++);
#endif
silc_rng_xor(rng, times(&ptime), pos++);
silc_rng_xor(rng, ptime.tms_utime, pos++);
silc_task_queue_alloc(&schedule->timeout_queue);
silc_task_queue_alloc(&schedule->generic_queue);
+ if (!max_tasks)
+ max_tasks = 200;
+
/* Initialize the scheduler */
schedule->fd_list = silc_calloc(max_tasks, sizeof(*schedule->fd_list));
schedule->max_fd = max_tasks;
return data;
}
-/* Parse nickname string. The format may be <num>!<nickname>@<server> to
- support multiple same nicknames. The <num> is the final unifier if same
- nickname is on same server. Note, this is only local format and server
- does not know anything about these. */
+/* Parse userfqdn string which is in user@fqdn format */
-int silc_parse_nickname(char *string, char **nickname, char **server,
- uint32 *num)
+bool silc_parse_userfqdn(const char *string, char **left, char **right)
{
uint32 tlen;
if (!string)
return FALSE;
- if (strchr(string, '!')) {
- char *tmp;
- tlen = strcspn(string, "!");
- tmp = silc_calloc(tlen + 1, sizeof(*tmp));
- memcpy(tmp, string, tlen);
-
- if (num)
- *num = atoi(tmp);
-
- silc_free(tmp);
-
- if (tlen >= strlen(string))
- return FALSE;
-
- string += tlen + 1;
- }
-
if (strchr(string, '@')) {
tlen = strcspn(string, "@");
- if (nickname) {
- *nickname = silc_calloc(tlen + 1, sizeof(char));
- memcpy(*nickname, string, tlen);
+ if (left) {
+ *left = silc_calloc(tlen + 1, sizeof(char));
+ memcpy(*left, string, tlen);
}
- if (server) {
- *server = silc_calloc((strlen(string) - tlen) + 1, sizeof(char));
- memcpy(*server, string + tlen + 1, strlen(string) - tlen - 1);
+ if (right) {
+ *right = silc_calloc((strlen(string) - tlen) + 1, sizeof(char));
+ memcpy(*right, string + tlen + 1, strlen(string) - tlen - 1);
}
} else {
- if (nickname)
- *nickname = strdup(string);
+ if (left)
+ *left = strdup(string);
}
return TRUE;
char *silc_encode_pem_file(unsigned char *data, uint32 data_len);
unsigned char *silc_decode_pem(unsigned char *pem, uint32 pem_len,
uint32 *ret_len);
-int silc_parse_nickname(char *string, char **nickname, char **server,
- uint32 *num);
+bool silc_parse_userfqdn(const char *string, char **left, char **right);
void silc_parse_command_line(unsigned char *buffer,
unsigned char ***parsed,
uint32 **parsed_lens,
silc_idlist_get_channel_by_id @ 136 ; \r
silc_idlist_get_client @ 137 ; \r
silc_client_abort_key_agreement @ 138 ; \r
+ silc_client_set_away_message @ 139 ; \r
+ silc_client_request_authentication_method @ 140 ; \r
+\r