ID cache system.
command_reply.c \
clientconfig.c \
clientutil.c \
+ idlist.c \
protocol.c \
screen.c
/*
* $Id$
* $Log$
+ * Revision 1.8 2000/07/12 05:56:32 priikone
+ * Major rewrite of ID Cache system. Support added for the new
+ * ID cache system.
+ *
* Revision 1.7 2000/07/10 05:40:33 priikone
* Minor bug fixes.
*
win->remote_port = -1;
win->sock = NULL;
+ /* Initialize ID caches */
+ win->client_cache = silc_idcache_alloc(0);
+ win->channel_cache = silc_idcache_alloc(0);
+ win->server_cache = silc_idcache_alloc(0);
+
/* Create the actual screen */
screen = (void *)silc_screen_create_output_window(client->screen);
silc_screen_create_input_window(client->screen);
win->screen = silc_screen_add_output_window(client->screen);
win->sock = NULL;
+ /* Initialize ID caches */
+ win->client_cache = silc_idcache_alloc(0);
+ win->channel_cache = silc_idcache_alloc(0);
+ win->server_cache = silc_idcache_alloc(0);
+
/* Add the window to windows table */
client->windows = silc_realloc(client->windows, sizeof(*client->windows)
* (client->windows_count + 1));
SilcSocketConnection sock)
{
SilcClientWindow win;
- int i;
/* We won't listen for this connection anymore */
silc_schedule_unset_listen_fd(sock->sock);
/* XXX Free all client entries and channel entries. */
/* Clear ID caches */
- for (i = 0; i < 96; i++)
- silc_idcache_del_all(&win->client_id_cache[i],
- win->client_id_cache_count[i]);
- for (i = 0; i < 96; i++)
- silc_idcache_del_all(&win->channel_id_cache[i],
- win->channel_id_cache_count[i]);
+ silc_idcache_del_all(win->client_cache);
+ silc_idcache_del_all(win->channel_cache);
/* Free data */
if (win->remote_host)
unsigned char *id_string)
{
SilcClientWindow win = (SilcClientWindow)sock->user_data;
- char *nickname = win->nickname;
-
-#define CIDC(x) win->client_id_cache[(x) - 32]
-#define CIDCC(x) win->client_id_cache_count[(x) - 32]
/* Delete old ID from ID cache */
- silc_idcache_del_by_id(CIDC(nickname[0]), CIDCC(nickname[0]),
- SILC_ID_CLIENT, win->local_id);
+ silc_idcache_del_by_id(win->client_cache, SILC_ID_CLIENT, win->local_id);
/* Save the new ID */
if (win->local_id)
win->local_entry->id = win->local_id;
/* Put it to the ID cache */
- CIDCC(nickname[0]) = silc_idcache_add(&CIDC(nickname[0]),
- CIDCC(nickname[0]),
- win->nickname, SILC_ID_CLIENT,
- win->local_id,
- (void *)win->local_entry);
-#undef CIDC
-#undef CIDCC
+ silc_idcache_add(win->client_cache, win->nickname, SILC_ID_CLIENT,
+ win->local_id, (void *)win->local_entry, TRUE);
}
/* Processed received Channel ID for a channel. This is called when client
SILC_LOG_DEBUG(("New channel ID"));
-#define CIDC(x) win->channel_id_cache[(x) - 32]
-#define CIDCC(x) win->channel_id_cache_count[(x) - 32]
-
id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
channel = silc_calloc(1, sizeof(*channel));
channel->channel_name = channel_name;
win->current_channel = channel;
/* Put it to the ID cache */
- CIDCC(channel_name[0]) = silc_idcache_add(&CIDC(channel_name[0]),
- CIDCC(channel_name[0]),
- channel_name, SILC_ID_CHANNEL,
- id, (void *)channel);
-#undef CIDC
-#undef CIDCC
+ silc_idcache_add(win->channel_cache, channel_name, SILC_ID_CHANNEL,
+ (void *)id, (void *)channel, TRUE);
}
/* Processes received key for channel. The received key will be used
SilcSocketConnection sock,
SilcBuffer packet)
{
- int i;
unsigned char *id_string, *key, *cipher;
unsigned int key_len;
SilcClientWindow win = (SilcClientWindow)sock->user_data;
SilcChannelID *id;
- SilcIDCache *id_cache = NULL;
+ SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
SilcChannelKeyPayload payload;
SILC_LOG_DEBUG(("Received key for channel"));
-#define CIDC(x) win->channel_id_cache[(x)]
-#define CIDCC(x) win->channel_id_cache_count[(x)]
-
payload = silc_channel_key_parse_payload(packet);
if (!payload)
return;
}
id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
- /* Find channel. XXX: This is bad and slow. */
- for (i = 0; i < 96; i++) {
- if (CIDC(i) == NULL)
- continue;
- if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
- SILC_ID_CHANNEL, &id_cache))
- break;
- }
-
- if (!id_cache)
+ /* Find channel. */
+ if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
+ SILC_ID_CHANNEL, &id_cache))
goto out;
-
+
/* Save the key */
key = silc_channel_key_get_key(payload, &key_len);
cipher = silc_channel_key_get_cipher(payload, NULL);
out:
silc_free(id);
silc_channel_key_free_payload(payload);
-#undef CIDC
-#undef CIDCC
}
/* Process received message to a channel (or from a channel, really). This
SilcSocketConnection sock,
SilcPacketContext *packet)
{
- int i;
SilcClientWindow win = (SilcClientWindow)sock->user_data;
SilcBuffer buffer = packet->buffer;
SilcChannelPayload payload = NULL;
SilcChannelID *id = NULL;
SilcChannelEntry channel;
- SilcIDCache *id_cache = NULL;
-
-#define CIDC(x) win->channel_id_cache[(x)]
-#define CIDCC(x) win->channel_id_cache_count[(x)]
+ SilcIDCacheEntry id_cache = NULL;
/* Sanity checks */
if (packet->dst_id_type != SILC_ID_CHANNEL)
id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
/* Find the channel entry from channels on this window */
- for (i = 0; i < 96; i++) {
- if (CIDC(i) == NULL)
- continue;
- if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
- SILC_ID_CHANNEL, &id_cache))
- break;
- }
-
- if (!id_cache)
+ if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
+ SILC_ID_CHANNEL, &id_cache))
goto out;
channel = (SilcChannelEntry)id_cache->context;
silc_free(id);
if (payload)
silc_channel_free_payload(payload);
-#undef CIDC
-#undef CIDCC
}
#ifndef CLIENT_H
#define CLIENT_H
+/* Forward declaration for client */
+typedef struct SilcClientObject *SilcClient;
+
+/* Forward declaration for client window */
+typedef struct SilcClientWindowObject *SilcClientWindow;
+
+#include "idlist.h"
+
/* Structure to hold ping time information. Every PING command will
add entry of this structure and is removed after reply to the ping
as been received. */
connection (window) specific data to this structure. How the window
actually appears on the screen in handeled by the silc_screen*
routines in screen.c. */
-typedef struct {
+struct SilcClientWindowObject {
/*
* Local data
*/
/* Client ID and Channel ID cache. Messages transmitted in SILC network
are done using different unique ID's. These are the cache for
thoses ID's used in the communication. */
- SilcIDCache *client_id_cache[96];
- unsigned int client_id_cache_count[96];
- SilcIDCache *channel_id_cache[96];
- unsigned int channel_id_cache_count[96];
- SilcIDCache *server_id_cache;
- unsigned int server_id_cache_count;
+ SilcIDCache client_cache;
+ SilcIDCache channel_cache;
+ SilcIDCache server_cache;
/* Current channel on window. All channel's are saved (allocated) into
the cache entries. */
/* The actual physical screen. This data is handled by the
screen handling routines. */
void *screen;
-} *SilcClientWindow;
+};
-typedef struct {
+struct SilcClientObject {
char *username;
char *realname;
SilcSimContext **sim;
unsigned int sim_count;
#endif
-} SilcClientObject;
-
-typedef SilcClientObject *SilcClient;
+};
/* Macros */
/*
* $Id$
* $Log$
+ * Revision 1.9 2000/07/12 05:56:32 priikone
+ * Major rewrite of ID Cache system. Support added for the new
+ * ID cache system.
+ *
* Revision 1.8 2000/07/10 05:39:11 priikone
* Added INFO and VERSION commands. Minor changes to SERVER command
* to show current servers when giving without arguments.
SILC_CLIENT_CMD_FUNC(invite)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
SilcClientWindow win = NULL;
+ SilcClientEntry client_entry;
+ SilcChannelEntry channel_entry;
SilcBuffer buffer;
- SilcIDCache *id_cache;
+ unsigned int num = 0;
+ char *nickname = NULL, *server = NULL;
unsigned char *client_id, *channel_id;
-#define CIDC(x) win->client_id_cache[(x) - 32], \
- win->client_id_cache_count[(x) - 32]
-#define CHIDC(x) win->channel_id_cache[(x) - 32], \
- win->channel_id_cache_count[(x) - 32]
-
if (cmd->argc != 3) {
silc_say(cmd->client, "Usage: /INVITE <nickname>[@<server>] <channel>");
goto out;
win = (SilcClientWindow)cmd->sock->user_data;
- /* Get client ID of the client to be invited. If we don't have it
- we will request it and cache it. This same command will be called
- again after we have received the reply (ie. pending). */
- if (!silc_idcache_find_by_data(CIDC(cmd->argv[1][0]), cmd->argv[1],
- &id_cache)) {
- SilcClientCommandContext ctx;
- char ident[512];
-
- ctx = silc_calloc(1, sizeof(*ctx));
- ctx->client = cmd->client;
- ctx->sock = cmd->sock;
- memset(ident, 0, sizeof(ident));
- snprintf(ident, sizeof(ident), "/IDENTIFY %s", cmd->argv[1]);
- silc_client_parse_command_line(ident, &ctx->argv, &ctx->argv_lens,
- &ctx->argv_types, &ctx->argc, 2);
- silc_client_command_identify(ctx);
+ /* Parse the typed nickname. */
+ if (!silc_client_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
+ silc_say(cmd->client, "Bad nickname");
+ goto out;
+ }
+
+ /* Find client entry */
+ client_entry = silc_idlist_get_client(client, win, nickname, server, num);
+ if (!client_entry) {
+ /* Client entry not found, it was requested thus mark this to be
+ pending command. */
silc_client_command_pending(SILC_COMMAND_IDENTIFY,
silc_client_command_invite, context);
return;
}
+
+ client_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
- client_id = silc_id_id2str(id_cache->id, SILC_ID_CLIENT);
-
- /* Get Channel ID of the channel. */
- if (!silc_idcache_find_by_data(CHIDC(cmd->argv[2][0]), cmd->argv[2],
- &id_cache)) {
+ /* Find channel entry */
+ channel_entry = silc_idlist_get_channel(client, win, cmd->argv[2]);
+ if (!channel_entry) {
silc_say(cmd->client, "You are not on that channel");
silc_free(client_id);
goto out;
}
- channel_id = silc_id_id2str(id_cache->id, SILC_ID_CHANNEL);
+ channel_id = silc_id_id2str(channel_entry->id, SILC_ID_CHANNEL);
buffer = silc_command_encode_payload_va(SILC_COMMAND_INVITE, 2,
1, client_id, SILC_ID_CLIENT_LEN,
out:
silc_client_command_free(cmd);
-#undef CIDC
-#undef CHIDC
}
/* Command QUIT. Closes connection with current server. */
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientWindow win = NULL;
- SilcIDCache *id_cache = NULL;
+ SilcIDCacheEntry id_cache = NULL;
SilcBuffer buffer;
-#define CIDC(x) win->channel_id_cache[(x) - 32]
-#define CIDCC(x) win->channel_id_cache_count[(x) - 32]
-
if (cmd->argc < 2) {
/* Show channels currently joined to */
if (!cmd->client->current_win->sock) {
win = (SilcClientWindow)cmd->sock->user_data;
/* See if we have joined to the requested channel already */
- silc_idcache_find_by_data(CIDC(cmd->argv[1][0]), CIDCC(cmd->argv[1][0]),
- cmd->argv[1], &id_cache);
-
- if (id_cache) {
+ if (silc_idcache_find_by_data_one(win->channel_cache, cmd->argv[1],
+ &id_cache)) {
silc_say(cmd->client, "You are talking to channel %s", cmd->argv[1]);
win->current_channel = (SilcChannelEntry)id_cache->context;
cmd->client->screen->bottom_line->channel = cmd->argv[1];
out:
silc_client_command_free(cmd);
-#undef CIDC
-#undef CIDCC
}
SILC_CLIENT_CMD_FUNC(motd)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientWindow win = NULL;
- SilcIDCache *id_cache = NULL;
+ SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
SilcBuffer buffer;
unsigned char *id_string;
char *name;
-#define CIDC(x) win->channel_id_cache[(x) - 32]
-#define CIDCC(x) win->channel_id_cache_count[(x) - 32]
-
if (cmd->argc != 2) {
silc_say(cmd->client, "Usage: /LEAVE <channel>");
goto out;
}
/* Get the Channel ID of the channel */
- silc_idcache_find_by_data(CIDC(name[0]), CIDCC(name[0]), name, &id_cache);
- if (!id_cache) {
+ if (!silc_idcache_find_by_data_one(win->channel_cache, name, &id_cache)) {
silc_say(cmd->client, "You are not on that channel");
goto out;
}
win->current_channel = NULL;
}
- silc_idcache_del_by_id(CIDC(name[0]), CIDCC(name[0]),
- SILC_ID_CHANNEL, channel->id);
+ silc_idcache_del_by_id(win->channel_cache, SILC_ID_CHANNEL, channel->id);
silc_free(channel->channel_name);
silc_free(channel->id);
silc_free(channel->key);
out:
silc_client_command_free(cmd);
-#undef CIDC
-#undef CIDCC
}
/* Command NAMES. Requests the names of the clients joined on requested
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientWindow win = NULL;
- SilcIDCache *id_cache = NULL;
+ SilcIDCacheEntry id_cache = NULL;
SilcBuffer buffer;
char *name;
unsigned char *id_string;
-#define CIDC(x) win->channel_id_cache[(x) - 32]
-#define CIDCC(x) win->channel_id_cache_count[(x) - 32]
-
if (cmd->argc != 2) {
silc_say(cmd->client, "Usage: /NAMES <channel>");
goto out;
name = cmd->argv[1];
/* Get the Channel ID of the channel */
- silc_idcache_find_by_data(CIDC(name[0]), CIDCC(name[0]), name, &id_cache);
- if (!id_cache) {
+ if (!silc_idcache_find_by_data_one(win->channel_cache, name, &id_cache)) {
/* XXX should resolve the channel ID; LIST command */
silc_say(cmd->client, "You are not on that channel", name);
goto out;
/* XXX this is kludge and should be removed after pending command reply
support is added. Currently only commands may be pending not command
replies. */
- silc_client_command_pending(SILC_COMMAND_NAMES, silc_client_command_names,
- NULL);
+ silc_client_command_pending(SILC_COMMAND_NAMES,
+ silc_client_command_names, NULL);
out:
silc_client_command_free(cmd);
-#undef CIDC
-#undef CIDCC
}
/*
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientWindow win = NULL;
SilcClient client = cmd->client;
- SilcIDCache *id_cache;
-
-#define CIDC(x) win->client_id_cache[(x) - 32], \
- win->client_id_cache_count[(x) - 32]
+ SilcClientEntry client_entry = NULL;
+ unsigned int num = 0;
+ char *nickname = NULL, *server = NULL;
if (cmd->argc < 3) {
silc_say(cmd->client, "Usage: /MSG <nickname> <message>");
win = (SilcClientWindow)cmd->sock->user_data;
- /* Find ID from cache */
- if (silc_idcache_find_by_data(CIDC(cmd->argv[1][0]), cmd->argv[1],
- &id_cache) == FALSE) {
- SilcClientCommandContext ctx;
- char ident[512];
-
- SILC_LOG_DEBUG(("Requesting Client ID from server"));
-
- /* No ID found. Do query from the server. The query is done by
- sending simple IDENTIFY command to the server. */
- ctx = silc_calloc(1, sizeof(*ctx));
- ctx->client = client;
- ctx->sock = cmd->sock;
- memset(ident, 0, sizeof(ident));
- snprintf(ident, sizeof(ident), "/IDENTIFY %s", cmd->argv[1]);
- silc_client_parse_command_line(ident, &ctx->argv, &ctx->argv_lens,
- &ctx->argv_types, &ctx->argc, 2);
- silc_client_command_identify(ctx);
-
- /* Mark this command to be pending command and to be executed after
- we have received the IDENTIFY reply from server. */
+ /* Parse the typed nickname. */
+ if (!silc_client_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
+ silc_say(cmd->client, "Bad nickname");
+ goto out;
+ }
+
+ /* Find client entry */
+ client_entry = silc_idlist_get_client(client, win, nickname, server, num);
+ if (!client_entry) {
+ /* Client entry not found, it was requested thus mark this to be
+ pending command. */
silc_client_command_pending(SILC_COMMAND_IDENTIFY,
silc_client_command_msg, context);
return;
silc_print(client, "-> *%s* %s", cmd->argv[1], cmd->argv[2]);
/* Send the private message */
- silc_client_packet_send_private_message(client, cmd->sock, id_cache->context,
+ silc_client_packet_send_private_message(client, cmd->sock, client_entry,
cmd->argv[2], cmd->argv_lens[2],
TRUE);
out:
silc_client_command_free(cmd);
-#undef CIDC
}
SILC_CLIENT_CMD_FUNC(away)
/*
* $Id$
* $Log$
+ * Revision 1.7 2000/07/12 05:56:32 priikone
+ * Major rewrite of ID Cache system. Support added for the new
+ * ID cache system.
+ *
* Revision 1.6 2000/07/10 05:38:32 priikone
* Added INFO command.
*
SILC_CLIENT_CMD_REPLY_FUNC(whois)
{
SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
- SilcClient client = cmd->client;
SilcCommandStatus status;
unsigned char *tmp;
unsigned char *id_data;
char *nickname = NULL, *username = NULL;
char *realname = NULL;
- void *id;
memset(buf, 0, sizeof(buf));
SILC_LOG_DEBUG(("Start"));
-#define CIDC(x) win->client_id_cache[(x) - 32]
-#define CIDCC(x) win->client_id_cache_count[(x) - 32]
-
tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
SILC_GET16_MSB(status, tmp);
if (status != SILC_STATUS_OK) {
client_entry->nickname = strdup(nickname);
/* Save received Client ID to ID cache */
- CIDCC(nickname[0]) =
- silc_idcache_add(&CIDC(nickname[0]), CIDCC(nickname[0]),
- client_entry->nickname, SILC_ID_CLIENT,
- client_entry->id, client_entry);
+ silc_idcache_add(win->client_cache, client_entry->nickname,
+ SILC_ID_CLIENT, client_entry->id, client_entry, TRUE);
}
if (status == SILC_STATUS_LIST_START) {
out:
silc_client_command_reply_free(cmd);
-#undef CIDC
-#undef CIDCC
}
/* Received reply for command NICK. If everything went without errors
SILC_CLIENT_CMD_REPLY_FUNC(leave)
{
SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
- SilcClient client = cmd->client;
SilcCommandStatus status;
unsigned char *tmp;
SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
SilcClientWindow win = (SilcClientWindow)cmd->sock->user_data;
SilcCommandStatus status;
- SilcIDCache *id_cache = NULL;
+ SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
SilcChannelID *channel_id = NULL;
SilcBuffer client_id_list;
SILC_LOG_DEBUG(("Start"));
-#define CIDC(x) win->channel_id_cache[(x)]
-#define CIDCC(x) win->channel_id_cache_count[(x)]
-#define CLC(x) win->client_id_cache[(x) - 32]
-#define CLCC(x) win->client_id_cache_count[(x) - 32]
-
tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
SILC_GET16_MSB(status, tmp);
if (status != SILC_STATUS_OK) {
silc_buffer_put(client_id_list, tmp, len2);
/* Get the channel name */
- for (i = 0; i < 96; i++) {
- if (CIDC(i) == NULL)
- continue;
- if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)channel_id,
- SILC_ID_CHANNEL, &id_cache))
- break;
- }
- if (!id_cache)
+ if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)channel_id,
+ SILC_ID_CHANNEL, &id_cache))
goto out;
channel = (SilcChannelEntry)id_cache->context;
client->id = client_id;
client->nickname = nickname;
- CLCC(nickname[0]) = silc_idcache_add(&CLC(nickname[0]), CLCC(nickname[0]),
- nickname, SILC_ID_CLIENT,
- client_id, (void *)client);
-
+ silc_idcache_add(win->client_cache, nickname, SILC_ID_CLIENT,
+ client_id, (void *)client, TRUE);
name_list = name_list + nick_len + 1;
}
if (channel_id)
silc_free(channel_id);
silc_client_command_reply_free(cmd);
-#undef CIDC
-#undef CIDCC
-#undef CLC
-#undef CLCC
}
/* Private message received. This processes the private message and
SilcBuffer buffer = (SilcBuffer)cmd->context;
unsigned short nick_len;
unsigned char *nickname, *message;
- SilcIDCache *id_cache;
- unsigned char *id_string;
- void *id;
/* Get nickname */
silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING_ALLOC(&nickname, &nick_len),
SILC_STR_END);
silc_buffer_pull(buffer, 2 + nick_len);
-
-#if 0
- /* Get ID of the sender */
- id_string = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char *));
- silc_buffer_push(buffer, SILC_ID_CLIENT_LEN + SILC_ID_CLIENT_LEN);
- memcpy(id_string, buffer->data, SILC_ID_CLIENT_LEN);
- silc_buffer_pull(buffer, SILC_ID_CLIENT_LEN + SILC_ID_CLIENT_LEN);
- id = silc_id_str2id(id_string, SILC_ID_CLIENT);
- silc_free(id_string);
-
- /* Nickname should be verified if we don't have it in the cache */
- if (silc_idcache_find_by_data(client->current_win->
- client_id_cache[nickname[0] - 32],
- client->current_win->
- client_id_cache_count[nickname[0] - 32],
- nickname, &id_cache) == FALSE) {
-
- SilcClientCommandContext ctx;
- char whois[255];
-
- /* Private message from unknown source, try to resolve it. */
-
-
- return;
- }
-#endif
message = silc_calloc(buffer->len + 1, sizeof(char));
memcpy(message, buffer->data, buffer->len);