/* Finds clients by nickname from local cache. */
-SilcDList silc_client_get_clients_local(SilcClient client,
- SilcClientConnection conn,
- const char *nickname,
- const char *format)
+SilcDList silc_client_get_clients_local_ext(SilcClient client,
+ SilcClientConnection conn,
+ const char *nickname,
+ SilcBool get_all,
+ SilcBool get_valid)
{
SilcIDCacheEntry id_cache;
SilcList list;
SilcDList clients;
SilcClientEntry entry;
- char *nicknamec;
+ char *nicknamec, *parsed = NULL, *format = NULL;
if (!client || !conn || !nickname)
return NULL;
- SILC_LOG_DEBUG(("Find clients by nickname %s", nickname));
+ /* Parse nickname if it is formatted */
+ if (!silc_client_nickname_parse(client, conn, (char *)nickname, &parsed))
+ return NULL;
+
+ if (!get_all && parsed)
+ format = (char *)nickname;
+ if (!parsed) {
+ parsed = silc_memdup(nickname, strlen(nickname));
+ if (!parsed)
+ return NULL;
+ }
+
+ SILC_LOG_DEBUG(("Find clients by nickname %s", parsed));
/* Normalize nickname for search */
- nicknamec = silc_identifier_check(nickname, strlen(nickname),
+ nicknamec = silc_identifier_check(parsed, strlen(parsed),
SILC_STRING_UTF8, 128, NULL);
- if (!nicknamec)
+ if (!nicknamec) {
+ silc_free(parsed);
return NULL;
+ }
clients = silc_dlist_init();
if (!clients) {
silc_free(nicknamec);
+ silc_free(parsed);
return NULL;
}
&list)) {
silc_mutex_unlock(conn->internal->lock);
silc_free(nicknamec);
+ silc_free(parsed);
silc_dlist_uninit(clients);
return NULL;
}
+ silc_list_start(list);
- if (!format) {
+ if (!format && get_all) {
/* Take all without any further checking */
- silc_list_start(list);
while ((id_cache = silc_list_get(list))) {
entry = id_cache->context;
- if (entry->internal.valid) {
+ if (!get_valid || entry->internal.valid) {
silc_client_ref_client(client, conn, id_cache->context);
silc_dlist_add(clients, id_cache->context);
}
}
} else {
/* Check multiple cache entries for exact match */
- silc_list_start(list);
while ((id_cache = silc_list_get(list))) {
entry = id_cache->context;
- if (silc_utf8_strcasecmp(entry->nickname, format) &&
- entry->internal.valid) {
+ if (silc_utf8_strcasecmp(entry->nickname,
+ format ? format : parsed) &&
+ (!get_valid || entry->internal.valid)) {
silc_client_ref_client(client, conn, entry);
silc_dlist_add(clients, entry);
+
+ /* If format is NULL, we find one exact match with the base
+ nickname (parsed). */
+ if (!format)
+ break;
}
}
}
silc_mutex_unlock(conn->internal->lock);
- silc_dlist_start(clients);
-
silc_free(nicknamec);
+ silc_free(parsed);
+
+ if (!silc_dlist_count(clients)) {
+ silc_dlist_uninit(clients);
+ return NULL;
+ }
+
+ silc_dlist_start(clients);
return clients;
}
+/* Finds clients by nickname from local cache. */
+
+SilcDList silc_client_get_clients_local(SilcClient client,
+ SilcClientConnection conn,
+ const char *nickname,
+ SilcBool return_all)
+{
+ return silc_client_get_clients_local_ext(client, conn, nickname, return_all,
+ TRUE);
+}
+
/********************** Client Resolving from Server ************************/
/* Resolving context */
/* 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 = silc_client_get_clients_local_ext(client, conn,
+ client_entry->nickname,
+ TRUE, FALSE);
if (!clients)
return NULL;
if (silc_dlist_count(clients) == 1 &&
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, ".");
- 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);
- memcpy(&newnick[off], client_entry->server, len);
- off += len;
- break;
case 'a':
/* Ascending number */
{
SilcBool n = FALSE;
int len;
- if (!client->internal->params->nickname_format[0])
+ if (!client->internal->params->nickname_format[0]) {
+ *ret_nick = NULL;
return TRUE;
+ }
if (!nickname || !nickname[0])
return FALSE;
case 'h':
case 'H':
- case 's':
- case 'S':
case 'a':
break;
break;
}
- cp++;
+ cp++;
}
if (!n)
return FALSE;
const char *server_info);
SilcBool silc_client_del_server(SilcClient client, SilcClientConnection conn,
SilcServerEntry server);
-SilcBool silc_client_nickname_parse(SilcClient client,
- SilcClientConnection conn,
- char *nickname,
- char **ret_nick);
SilcUInt16 silc_client_get_clients_by_list(SilcClient client,
SilcClientConnection conn,
SilcUInt32 list_count,
unsigned char count[4], *tmp = NULL;
SilcBool details = FALSE, nick = FALSE;
unsigned char *pubkey = NULL;
+ char *nickname = NULL;
int i;
/* Given without arguments fetches client's own information */
&obj, sizeof(obj));
}
+ silc_client_nickname_parse(client, conn, cmd->argv[1], &nickname);
+ if (!nickname)
+ nickname = strdup(cmd->argv[1]);
+
/* Send command */
silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL,
- 3, 1, nick ? cmd->argv[1] : NULL,
- nick ? cmd->argv_lens[1] : 0,
+ 3, 1, nick ? nickname : NULL,
+ nick ? strlen(nickname) : 0,
2, tmp ? tmp : NULL, tmp ? 4 : 0,
3, silc_buffer_datalen(attrs));
+ silc_free(nickname);
/* Notify application */
COMMAND(SILC_STATUS_OK);
silc_client_nickname_parse(client, conn, cmd->argv[2], &nickname);
/* Find client entry */
- clients = silc_client_get_clients_local(client, conn, nickname,
- cmd->argv[2]);
+ clients = silc_client_get_clients_local(client, conn, cmd->argv[2],
+ FALSE);
if (!clients)
/* Resolve client information */
SILC_FSM_CALL(silc_client_get_clients(
- client, conn, nickname,
- cmd->argv[2],
+ client, conn, nickname, NULL,
silc_client_command_resolve_continue,
cmd));
return SILC_FSM_FINISH;
/* Get the target client */
- clients = silc_client_get_clients_local(client, conn, nickname,
- cmd->argv[1]);
+ clients = silc_client_get_clients_local(client, conn, cmd->argv[1], FALSE);
if (!clients)
/* Resolve client information */
- SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname,
- cmd->argv[1],
+ SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname, NULL,
silc_client_command_resolve_continue,
cmd));
silc_client_nickname_parse(client, conn, cmd->argv[3], &nickname);
/* Find client entry */
- clients = silc_client_get_clients_local(client, conn, nickname,
- cmd->argv[3]);
+ clients = silc_client_get_clients_local(client, conn, cmd->argv[3], FALSE);
if (!clients)
/* Resolve client information */
- SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname, cmd->argv[3],
+ SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname, NULL,
silc_client_command_resolve_continue,
cmd));
SilcClientEntry target;
SilcDList clients = NULL;
char *name;
- char *nickname = NULL;
if (cmd->argc < 3) {
SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO,
goto out;
}
- /* Parse the typed nickname. */
- silc_client_nickname_parse(client, conn, cmd->argv[2], &nickname);
-
/* Get the target client */
- clients = silc_client_get_clients_local(client, conn, nickname,
- cmd->argv[2]);
+ clients = silc_client_get_clients_local(client, conn, cmd->argv[2], FALSE);
if (!clients) {
SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO,
"No such client: %s", cmd->argv[2]);
silc_buffer_free(idp);
silc_buffer_free(idp2);
- silc_free(nickname);
silc_client_list_free(client, conn, clients);
silc_client_unref_channel(client, conn, channel);
out:
silc_client_unref_channel(client, conn, channel);
- silc_free(nickname);
return SILC_FSM_FINISH;
}
SilcClientEntry client_entry;
SilcServerEntry server_entry;
SilcDList clients;
- char *nickname = NULL;
SilcBuffer idp;
if (cmd->argc < 2) {
return SILC_FSM_FINISH;
}
- /* Parse the typed nickname. */
- if (!silc_client_nickname_parse(client, conn, cmd->argv[1], &nickname)) {
- COMMAND_ERROR(SILC_STATUS_ERR_RESOURCE_LIMIT);
- return SILC_FSM_FINISH;
- }
-
/* Find client entry */
- clients = silc_client_get_clients_local(client, conn, nickname,
- cmd->argv[1]);
+ clients = silc_client_get_clients_local(client, conn, cmd->argv[1], FALSE);
if (!clients) {
/* Check whether user requested server */
server_entry = silc_client_get_server(client, conn, cmd->argv[1]);
1, silc_buffer_datalen(idp));
silc_buffer_free(idp);
- silc_free(nickname);
/* Notify application */
COMMAND(SILC_STATUS_OK);
Following format types are available:
%n nickname - the real nickname returned by the server (mandatory)
+ %a number - ascending number in case there are several
+ same nicknames (fe. nick#2 and nick#3)
%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)
+ Example format strings: "%n#%a" (fe. nick#2, nick#3)
+ "%n@%h%a" (fe. nick@host, nick@host2)
+ "%a!%n@%h" (fe. nick@host, 2!nick@host)
Note that there must always be some separator characters around '%n'
format. It is not possible to put format characters before or after
- '%n' without separators (such ash '@'). Also note that the separator
+ '%n' without separators (such ash '#'). Also note that the separator
character should be a character that cannot be part of normal nickname.
*/
char nickname_format[32];
SilcClientEntry client_entry,
SilcBool priority);
+/****f* silcclient/SilcClientAPI/silc_client_nickname_parse
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_client_nickname_parse(SilcClient client,
+ * SilcClientConnection conn,
+ * char *nickname,
+ * char **ret_nick);
+ *
+ * DESCRIPTION
+ *
+ * Parses the `nickname' according to the format string given in the
+ * SilcClientParams. Returns the parsed nickname into the `ret_nick'.
+ * The caller must free the returned pointer. Returns FALSE if error
+ * occurred during parsing. Returns TRUE if the nickname was parsed,
+ * it was not formatted or if the format string has not been specified
+ * in SilcClientParams.
+ *
+ ***/
+SilcBool silc_client_nickname_parse(SilcClient client,
+ SilcClientConnection conn,
+ char *nickname,
+ char **ret_nick);
+
#ifdef __cplusplus
}
#endif
* completion callback will be called when the client entries has been
* found. After the server returns the client information it is cached
* and can be accesses locally at a later time. The resolving is done
- * with IDENTIFY command. The `server' may be NULL. Returns 0 on
- * error and the command identifier used with the command otherwise.
+ * with IDENTIFY command. The `server' may be NULL. The server
+ * associated with the nickname may be in the `nickname' (nick@server).
+ * Returns 0 on error and the command identifier used with the command
+ * otherwise.
*
* NOTES
*
* completion callback will be called when the client entries has been
* found. After the server returns the client information it is cached
* and can be accesses locally at a later time. The resolving is done
- * with WHOIS command. The `server' may be NULL. Returns 0 on error,
- * and the command identifier used with the command otherwise.
+ * with WHOIS command. The `server' may be NULL. The server
+ * associated with the nickname may be in the `nickname' (nick@server).
+ * Returns 0 on error and the command identifier used with the command
+ * otherwise.
*
* If the `attributes' is non-NULL then the buffer includes Requested
* Attributes which can be used to fetch very detailed information
* SilcDList silc_client_get_clients_local(SilcClient client,
* SilcClientConnection conn,
* const char *nickname,
- * const char *format);
+ * SilcBool return_all);
*
* DESCRIPTION
*
* 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. The caller must free the
- * returned list by silc_client_list_free function.
+ * from the server. This checks local cache and returns matching clients
+ * from the local cache. If none was found this returns NULL. The
+ * `nickname' is the nickname to find and it may be a formatted nickname
+ * or a base nickname. If the `return_all' is TRUE this call will return
+ * all clients matching the `nickname' base. If it is FALSE this will
+ * return the exact match if `nickname' is a formatted nickname or the
+ * first matching nickname if it is not formatted. The formatted nickname
+ * must of the format specified in SilcClientParams. The caller must free
+ * the returned list by calling silc_client_list_free function.
*
* NOTES
*
SilcDList silc_client_get_clients_local(SilcClient client,
SilcClientConnection conn,
const char *nickname,
- const char *format);
+ SilcBool return_all);
/****f* silcclient/SilcClientAPI/silc_client_get_clients_by_channel
*