Integer type name change.
[silc.git] / apps / silcd / command.c
index ab4d5cd080fe314c0c196812457e87c0df64a13b..02ec6d1d6aefaf07681f48562db78c15108bf5f7 100644 (file)
@@ -34,9 +34,9 @@ static void
 silc_server_command_send_status_data(SilcServerCommandContext cmd,
                                     SilcCommand command,
                                     SilcCommandStatus status,
-                                    uint32 arg_type,
+                                    SilcUInt32 arg_type,
                                     const unsigned char *arg,
-                                    uint32 arg_len);
+                                    SilcUInt32 arg_len);
 static bool
 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
                                        SilcServerCommandReplyContext cmdr,
@@ -89,7 +89,7 @@ SilcServerCommand silc_command_list[] =
    of arguments. */
 #define SILC_SERVER_COMMAND_CHECK(command, context, min, max)                \
 do {                                                                         \
-  uint32 _argc;                                                                      \
+  SilcUInt32 _argc;                                                                  \
                                                                              \
   SILC_LOG_DEBUG(("Start"));                                                 \
                                                                              \
@@ -131,7 +131,6 @@ static int silc_server_is_registered(SilcServer server,
 
   silc_server_command_send_status_reply(cmd, command,
                                        SILC_STATUS_ERR_NOT_REGISTERED);
-  silc_server_command_free(cmd);
   return FALSE;
 }
 
@@ -149,6 +148,11 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout)
   SilcServerCommandTimeout timeout = (SilcServerCommandTimeout)context;
   SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data;
 
+  if (!client) {
+    silc_server_command_free(timeout->ctx);
+    silc_free(timeout);
+  }
+
   /* Update access time */
   client->last_command = time(NULL);
 
@@ -159,6 +163,8 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout)
                                     timeout->ctx, 
                                     timeout->cmd->cmd))
     timeout->cmd->cb(timeout->ctx, NULL);
+  else
+    silc_server_command_free(timeout->ctx);
 
   silc_free(timeout);
 }
@@ -233,15 +239,12 @@ void silc_server_command_process(SilcServer server,
                         silc_server_command_process_timeout,
                         (void *)timeout, 
                         2 - (time(NULL) - client->last_command), 0,
-                        SILC_TASK_TIMEOUT,
-                        SILC_TASK_PRI_NORMAL);
+                        SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
     else
       silc_schedule_task_add(server->schedule, sock->sock, 
                         silc_server_command_process_timeout,
-                        (void *)timeout, 
-                        0, 1,
-                        SILC_TASK_TIMEOUT,
-                        SILC_TASK_PRI_NORMAL);
+                        (void *)timeout, 0, 1,
+                        SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
     return;
   }
 
@@ -251,6 +254,8 @@ void silc_server_command_process(SilcServer server,
     cmd->cb(ctx, NULL);
   else if (silc_server_is_registered(server, sock, ctx, cmd->cmd))
     cmd->cb(ctx, NULL);
+  else
+    silc_server_command_free(ctx);
 }
 
 /* Allocate Command Context */
@@ -303,7 +308,7 @@ silc_server_command_dup(SilcServerCommandContext ctx)
 
 bool silc_server_command_pending(SilcServer server,
                                 SilcCommand reply_cmd,
-                                uint16 ident,
+                                SilcUInt16 ident,
                                 SilcCommandCb callback,
                                 void *context)
 {
@@ -333,7 +338,7 @@ bool silc_server_command_pending(SilcServer server,
 
 void silc_server_command_pending_del(SilcServer server,
                                     SilcCommand reply_cmd,
-                                    uint16 ident)
+                                    SilcUInt16 ident)
 {
   SilcServerCommandPending *r;
 
@@ -353,8 +358,8 @@ SilcServerCommandPendingCallbacks
 silc_server_command_pending_check(SilcServer server,
                                  SilcServerCommandReplyContext ctx,
                                  SilcCommand command, 
-                                 uint16 ident,
-                                 uint32 *callbacks_count)
+                                 SilcUInt16 ident,
+                                 SilcUInt32 *callbacks_count)
 {
   SilcServerCommandPending *r;
   SilcServerCommandPendingCallbacks callbacks = NULL;
@@ -404,9 +409,9 @@ static void
 silc_server_command_send_status_data(SilcServerCommandContext cmd,
                                     SilcCommand command,
                                     SilcCommandStatus status,
-                                    uint32 arg_type,
+                                    SilcUInt32 arg_type,
                                     const unsigned char *arg,
-                                    uint32 arg_len)
+                                    SilcUInt32 arg_len)
 {
   SilcBuffer buffer;
 
@@ -467,15 +472,15 @@ silc_server_command_pending_error_check(SilcServerCommandContext cmd,
 static int
 silc_server_command_whois_parse(SilcServerCommandContext cmd,
                                SilcClientID ***client_id,
-                               uint32 *client_id_count,
+                               SilcUInt32 *client_id_count,
                                char **nickname,
                                char **server_name,
                                int *count,
                                SilcCommand command)
 {
   unsigned char *tmp;
-  uint32 len;
-  uint32 argc = silc_argument_get_arg_num(cmd->args);
+  SilcUInt32 len;
+  SilcUInt32 argc = silc_argument_get_arg_num(cmd->args);
   int i, k;
 
   /* If client ID is in the command it must be used instead of nickname */
@@ -542,25 +547,27 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd,
 /* Resolve context used by both WHOIS and IDENTIFY commands */
 typedef struct {
   SilcServerEntry router;
-  uint16 ident;
+  SilcUInt16 ident;
   unsigned char **res_argv;
-  uint32 *res_argv_lens;
-  uint32 *res_argv_types;
-  uint32 res_argc;
+  SilcUInt32 *res_argv_lens;
+  SilcUInt32 *res_argv_types;
+  SilcUInt32 res_argc;
 } *SilcServerResolveContext;
 
 static bool
 silc_server_command_whois_check(SilcServerCommandContext cmd,
                                SilcClientEntry *clients,
-                               uint32 clients_count)
+                               SilcUInt32 clients_count)
 {
   SilcServer server = cmd->server;
   SilcClientEntry entry;
   SilcServerResolveContext resolve = NULL, r = NULL;
-  uint32 resolve_count = 0;
+  SilcUInt32 resolve_count = 0;
   int i, k;
   bool no_res = TRUE;
 
+  SILC_LOG_DEBUG(("Start"));
+
   for (i = 0; i < clients_count; i++) {
     entry = clients[i];
     if (!entry)
@@ -689,7 +696,7 @@ silc_server_command_whois_check(SilcServerCommandContext cmd,
 static void
 silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
                                     SilcClientEntry *clients,
-                                    uint32 clients_count,
+                                    SilcUInt32 clients_count,
                                     int count,
                                     const char *nickname,
                                     SilcClientID **client_ids)
@@ -700,7 +707,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
   SilcBuffer packet, idp, channels;
   SilcClientEntry entry;
   SilcCommandStatus status;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   char nh[256], uh[256];
   unsigned char idle[4], mode[4];
   unsigned char *fingerprint;
@@ -823,7 +830,7 @@ silc_server_command_whois_send_router(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
   SilcBuffer tmpbuf;
-  uint16 old_ident;
+  SilcUInt16 old_ident;
 
   old_ident = silc_command_get_ident(cmd->payload);
   silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -853,7 +860,7 @@ silc_server_command_whois_process(SilcServerCommandContext cmd)
   int count = 0;
   SilcClientEntry *clients = NULL, entry;
   SilcClientID **client_id = NULL;
-  uint32 client_id_count = 0, clients_count = 0;
+  SilcUInt32 client_id_count = 0, clients_count = 0;
   int i, ret = 0;
   bool check_global = FALSE;
 
@@ -1003,7 +1010,7 @@ silc_server_command_whowas_parse(SilcServerCommandContext cmd,
                                 int *count)
 {
   unsigned char *tmp;
-  uint32 len;
+  SilcUInt32 len;
 
   tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
   if (!tmp) {
@@ -1028,7 +1035,7 @@ silc_server_command_whowas_parse(SilcServerCommandContext cmd,
 static char
 silc_server_command_whowas_check(SilcServerCommandContext cmd,
                                 SilcClientEntry *clients,
-                                uint32 clients_count)
+                                SilcUInt32 clients_count)
 {
   SilcServer server = cmd->server;
   int i;
@@ -1039,7 +1046,7 @@ silc_server_command_whowas_check(SilcServerCommandContext cmd,
 
     if (!entry->nickname || !entry->username) {
       SilcBuffer tmpbuf;
-      uint16 old_ident;
+      SilcUInt16 old_ident;
 
       if (!entry->router)
        continue;
@@ -1059,7 +1066,6 @@ silc_server_command_whowas_check(SilcServerCommandContext cmd,
                                  silc_server_command_whowas, 
                                  silc_server_command_dup(cmd));
       cmd->pending = TRUE;
-      
       silc_command_set_ident(cmd->payload, old_ident);
 
       silc_buffer_free(tmpbuf);
@@ -1073,40 +1079,57 @@ silc_server_command_whowas_check(SilcServerCommandContext cmd,
 static void
 silc_server_command_whowas_send_reply(SilcServerCommandContext cmd,
                                      SilcClientEntry *clients,
-                                     uint32 clients_count)
+                                     SilcUInt32 clients_count)
 {
   SilcServer server = cmd->server;
   char *tmp;
-  int i, count = 0, len;
+  int i, k, count = 0, len;
   SilcBuffer packet, idp;
   SilcClientEntry entry = NULL;
   SilcCommandStatus status;
-  uint16 ident = silc_command_get_ident(cmd->payload);
-  char found = FALSE;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   char nh[256], uh[256];
+  int valid_count;
 
   status = SILC_STATUS_OK;
-  if (clients_count > 1)
-    status = SILC_STATUS_LIST_START;
 
+  /* Process only entries that are not registered anymore. */
+  valid_count = 0;
   for (i = 0; i < clients_count; i++) {
-    entry = clients[i];
+    if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
+      clients[i] = NULL;
+    else
+      valid_count++;
+  }
 
-    /* We will take only clients that are not valid anymore. They are the
-       ones that are not registered anymore but still have a ID. They
-       have disconnected us, and thus valid for WHOWAS. */
-    if (entry->data.status & SILC_IDLIST_STATUS_REGISTERED || !entry->id)
-      continue;
+  if (!valid_count) {
+    /* No valid entries found at all, just send error */
+    unsigned char *tmp;
+    
+    tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
+    if (tmp)
+      silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
+                                          SILC_STATUS_ERR_NO_SUCH_NICK,
+                                          3, tmp, strlen(tmp));
+    return;
+  }
 
-    if (count && i - 1 == count)
-      break;
+  if (valid_count > 1)
+    status = SILC_STATUS_LIST_START;
 
-    found = TRUE;
+  for (i = 0, k = 0; i < clients_count; i++) {
+    entry = clients[i];
+    if (!entry)
+      continue;
 
-    if (clients_count > 2)
+    if (k >= 1)
       status = SILC_STATUS_LIST_ITEM;
-    if (clients_count > 1 && i == clients_count - 1)
+    if (valid_count > 1 && k == valid_count - 1)
+      status = SILC_STATUS_LIST_END;
+    if (count && k - 1 == count)
       status = SILC_STATUS_LIST_END;
+    if (count && k - 1 > count)
+      break;
 
     /* Send WHOWAS reply */
     idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
@@ -1147,13 +1170,9 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd,
     
     silc_buffer_free(packet);
     silc_buffer_free(idp);
-  }
 
-  if (found == FALSE && entry)
-    silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
-                                        SILC_STATUS_ERR_NO_SUCH_NICK,
-                                        3, entry->nickname, 
-                                        strlen(entry->nickname));
+    k++;
+  }
 }
 
 static int
@@ -1163,7 +1182,7 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd)
   char *nick = NULL, *server_name = NULL;
   int count = 0;
   SilcClientEntry *clients = NULL;
-  uint32 clients_count = 0;
+  SilcUInt32 clients_count = 0;
   int ret = 0;
   bool check_global = FALSE;
 
@@ -1175,7 +1194,7 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd)
       server->server_type == SILC_SERVER && !cmd->pending && 
       !server->standalone) {
     SilcBuffer tmpbuf;
-    uint16 old_ident;
+    SilcUInt16 old_ident;
 
     old_ident = silc_command_get_ident(cmd->payload);
     silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -1193,7 +1212,6 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd)
                                silc_server_command_whowas,
                                silc_server_command_dup(cmd));
     cmd->pending = TRUE;
-
     silc_command_set_ident(cmd->payload, old_ident);
 
     silc_buffer_free(tmpbuf);
@@ -1278,7 +1296,7 @@ silc_server_command_identify_send_router(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
   SilcBuffer tmpbuf;
-  uint16 old_ident;
+  SilcUInt16 old_ident;
 
   old_ident = silc_command_get_ident(cmd->payload);
   silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -1303,17 +1321,17 @@ silc_server_command_identify_send_router(SilcServerCommandContext cmd)
 static int
 silc_server_command_identify_parse(SilcServerCommandContext cmd,
                                   SilcClientEntry **clients,
-                                  uint32 *clients_count,
+                                  SilcUInt32 *clients_count,
                                   SilcServerEntry **servers,
-                                  uint32 *servers_count,
+                                  SilcUInt32 *servers_count,
                                   SilcChannelEntry **channels,
-                                  uint32 *channels_count,
-                                  uint32 *count)
+                                  SilcUInt32 *channels_count,
+                                  SilcUInt32 *count)
 {
   SilcServer server = cmd->server;
   unsigned char *tmp;
-  uint32 len;
-  uint32 argc = silc_argument_get_arg_num(cmd->args);
+  SilcUInt32 len;
+  SilcUInt32 argc = silc_argument_get_arg_num(cmd->args);
   SilcIDPayload idp;
   bool check_global = FALSE;
   void *entry;
@@ -1575,12 +1593,12 @@ silc_server_command_identify_parse(SilcServerCommandContext cmd,
 static bool
 silc_server_command_identify_check_client(SilcServerCommandContext cmd,
                                          SilcClientEntry *clients,
-                                         uint32 clients_count)
+                                         SilcUInt32 clients_count)
 {
   SilcServer server = cmd->server;
   SilcClientEntry entry;
   SilcServerResolveContext resolve = NULL, r = NULL;
-  uint32 resolve_count = 0;
+  SilcUInt32 resolve_count = 0;
   int i, k;
   bool no_res = TRUE;
 
@@ -1712,18 +1730,18 @@ silc_server_command_identify_check_client(SilcServerCommandContext cmd,
 static void
 silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
                                        SilcClientEntry *clients,
-                                       uint32 clients_count,
+                                       SilcUInt32 clients_count,
                                        SilcServerEntry *servers,
-                                       uint32 servers_count,
+                                       SilcUInt32 servers_count,
                                        SilcChannelEntry *channels,
-                                       uint32 channels_count,
+                                       SilcUInt32 channels_count,
                                        int count)
 {
   SilcServer server = cmd->server;
   int i, k, len, valid_count;
   SilcBuffer packet, idp;
   SilcCommandStatus status;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   char nh[256], uh[256];
   SilcSocketConnection hsock;
 
@@ -1751,7 +1769,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
                                             SILC_STATUS_ERR_NO_SUCH_NICK,
                                             3, tmp, strlen(tmp));
       } else {
-       tmp = silc_argument_get_arg_type(cmd->args, 5, (uint32 *)&len);
+       tmp = silc_argument_get_arg_type(cmd->args, 5, (SilcUInt32 *)&len);
        silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
                                             SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
                                             2, tmp, len);
@@ -1906,12 +1924,12 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
 static int
 silc_server_command_identify_process(SilcServerCommandContext cmd)
 {
-  uint32 count = 0;
+  SilcUInt32 count = 0;
   int ret = 0;
   SilcClientEntry *clients = NULL;
   SilcServerEntry *servers = NULL;
   SilcChannelEntry *channels = NULL;
-  uint32 clients_count = 0, servers_count = 0, channels_count = 0;
+  SilcUInt32 clients_count = 0, servers_count = 0, channels_count = 0;
 
   /* Parse the IDENTIFY request */
   ret = silc_server_command_identify_parse(cmd,
@@ -1967,9 +1985,9 @@ SILC_SERVER_CMD_FUNC(nick)
   SilcServer server = cmd->server;
   SilcBuffer packet, nidp, oidp = NULL;
   SilcClientID *new_id;
-  uint32 nick_len;
+  SilcUInt32 nick_len;
   char *nick;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   int nickfail = 0;
 
   if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
@@ -2059,18 +2077,18 @@ SILC_SERVER_CMD_FUNC(nick)
 static void
 silc_server_command_list_send_reply(SilcServerCommandContext cmd,
                                    SilcChannelEntry *lch, 
-                                   uint32 lch_count,
+                                   SilcUInt32 lch_count,
                                    SilcChannelEntry *gch,
-                                   uint32 gch_count)
+                                   SilcUInt32 gch_count)
 {
   int i, k;
   SilcBuffer packet, idp;
   SilcChannelEntry entry;
   SilcCommandStatus status;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   char *topic;
   unsigned char usercount[4];
-  uint32 users;
+  SilcUInt32 users;
   int valid_lcount = 0, valid_rcount = 0;
 
   for (i = 0; i < lch_count; i++) {
@@ -2147,7 +2165,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd,
       memset(usercount, 0, sizeof(usercount));
     } else {
       topic = entry->topic;
-      users = silc_hash_table_count(entry->user_list);
+      users = entry->user_count;
       SILC_PUT32_MSB(users, usercount);
     }
 
@@ -2178,9 +2196,9 @@ SILC_SERVER_CMD_FUNC(list)
   SilcServer server = cmd->server;
   SilcChannelID *channel_id = NULL;
   unsigned char *tmp;
-  uint32 tmp_len;
+  SilcUInt32 tmp_len;
   SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
-  uint32 lch_count = 0, gch_count = 0;
+  SilcUInt32 lch_count = 0, gch_count = 0;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 1);
 
@@ -2189,7 +2207,7 @@ SILC_SERVER_CMD_FUNC(list)
   if (!cmd->pending && server->server_type == SILC_SERVER && 
       !server->standalone) {
     SilcBuffer tmpbuf;
-    uint16 old_ident;
+    SilcUInt16 old_ident;
     
     old_ident = silc_command_get_ident(cmd->payload);
     silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -2252,8 +2270,8 @@ SILC_SERVER_CMD_FUNC(topic)
   SilcChannelClientEntry chl;
   SilcBuffer packet, idp;
   unsigned char *tmp;
-  uint32 argc, tmp_len;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt32 argc, tmp_len;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_TOPIC, cmd, 1, 2);
 
@@ -2374,8 +2392,8 @@ SILC_SERVER_CMD_FUNC(invite)
   SilcIDListData idata;
   SilcBuffer idp, idp2, packet;
   unsigned char *tmp, *add, *del;
-  uint32 len;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt32 len;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4);
 
@@ -2619,7 +2637,7 @@ SILC_SERVER_CMD_FUNC(quit)
   SilcSocketConnection sock = cmd->sock;
   QuitInternal q;
   unsigned char *tmp = NULL;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_QUIT, cmd, 0, 1);
 
@@ -2656,7 +2674,7 @@ SILC_SERVER_CMD_FUNC(kill)
   SilcClientEntry remote_client;
   SilcClientID *client_id;
   unsigned char *tmp, *comment;
-  uint32 tmp_len, tmp_len2;
+  SilcUInt32 tmp_len, tmp_len2;
   bool local;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 2);
@@ -2780,9 +2798,9 @@ SILC_SERVER_CMD_FUNC(info)
   SilcServer server = cmd->server;
   SilcBuffer packet, idp;
   unsigned char *tmp;
-  uint32 tmp_len;
+  SilcUInt32 tmp_len;
   char *dest_server, *server_info = NULL, *server_name;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   SilcServerEntry entry = NULL;
   SilcServerID *server_id = NULL;
 
@@ -2831,10 +2849,10 @@ SILC_SERVER_CMD_FUNC(info)
     memset(info_string, 0, sizeof(info_string));
     snprintf(info_string, sizeof(info_string), 
             "location: %s server: %s admin: %s <%s>",
-            server->config->admin_info->location,
-            server->config->admin_info->server_type,
-            server->config->admin_info->admin_name,
-            server->config->admin_info->admin_email);
+            server->config->server_info->location,
+            server->config->server_info->server_type,
+            server->config->server_info->admin,
+            server->config->server_info->email);
 
     server_info = info_string;
     entry = server->id_entry;
@@ -2853,7 +2871,7 @@ SILC_SERVER_CMD_FUNC(info)
        server->server_type != SILC_SERVER && entry && !entry->server_info) {
       /* Send to the server */
       SilcBuffer tmpbuf;
-      uint16 old_ident;
+      SilcUInt16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
       silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -2877,7 +2895,7 @@ SILC_SERVER_CMD_FUNC(info)
     if (!entry && !cmd->pending && !server->standalone) {
       /* Send to the primary router */
       SilcBuffer tmpbuf;
-      uint16 old_ident;
+      SilcUInt16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
       silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -2938,7 +2956,7 @@ SILC_SERVER_CMD_FUNC(ping)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcServerID *id;
-  uint32 len;
+  SilcUInt32 len;
   unsigned char *tmp;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 1, 2);
@@ -2980,18 +2998,18 @@ static void silc_server_command_join_channel(SilcServer server,
                                             SilcClientID *client_id,
                                             bool created,
                                             bool create_key,
-                                            uint32 umode,
+                                            SilcUInt32 umode,
                                             const unsigned char *auth,
-                                            uint32 auth_len)
+                                            SilcUInt32 auth_len)
 {
   SilcSocketConnection sock = cmd->sock;
   unsigned char *tmp;
-  uint32 tmp_len, user_count;
+  SilcUInt32 tmp_len, user_count;
   unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4];
   SilcClientEntry client;
   SilcChannelClientEntry chl;
   SilcBuffer reply, chidp, clidp, keyp = NULL, user_list, mode_list;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   char check[512], check2[512];
   bool founder = FALSE;
   bool resolve;
@@ -3044,7 +3062,7 @@ static void silc_server_command_join_channel(SilcServer server,
       void *auth_data = (channel->founder_method == SILC_AUTH_PASSWORD ?
                         (void *)channel->founder_passwd : 
                         (void *)channel->founder_key);
-      uint32 auth_data_len = (channel->founder_method == SILC_AUTH_PASSWORD ?
+      SilcUInt32 auth_data_len = (channel->founder_method == SILC_AUTH_PASSWORD ?
                              channel->founder_passwd_len : 0);
 
       /* Check whether the client is to become founder */
@@ -3123,10 +3141,8 @@ static void silc_server_command_join_channel(SilcServer server,
   if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
     /* Get passphrase */
     tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
-    if (tmp) {
-      passphrase = silc_calloc(tmp_len, sizeof(*passphrase));
-      memcpy(passphrase, tmp, tmp_len);
-    }
+    if (tmp)
+      passphrase = silc_memdup(tmp, tmp_len);
   
     if (!passphrase || !channel->passphrase ||
         memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
@@ -3169,6 +3185,7 @@ static void silc_server_command_join_channel(SilcServer server,
   chl->channel = channel;
   silc_hash_table_add(channel->user_list, client, chl);
   silc_hash_table_add(client->channels, channel, chl);
+  channel->user_count++;
 
   /* Get users on the channel */
   silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
@@ -3247,24 +3264,24 @@ static void silc_server_command_join_channel(SilcServer server,
       /* Distribute the channel key to all backup routers. */
       silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
                              keyp->data, keyp->len, FALSE, TRUE);
+  }
 
-    /* If client became founder by providing correct founder auth data
-       notify the mode change to the channel. */
-    if (founder) {
-      SILC_PUT32_MSB(chl->mode, mode);
-      silc_server_send_notify_to_channel(server, NULL, channel, FALSE, 
-                                        SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
-                                        clidp->data, clidp->len,
-                                        mode, 4, clidp->data, clidp->len);
+  /* If client became founder by providing correct founder auth data
+     notify the mode change to the channel. */
+  if (founder) {
+    SILC_PUT32_MSB(chl->mode, mode);
+    silc_server_send_notify_to_channel(server, NULL, channel, FALSE, 
+                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
+                                      clidp->data, clidp->len,
+                                      mode, 4, clidp->data, clidp->len);
       
-      /* Set CUMODE notify type to network */
-      if (!server->standalone)
-       silc_server_send_notify_cumode(server, server->router->connection,
-                                      server->server_type == SILC_ROUTER ? 
-                                      TRUE : FALSE, channel,
-                                      chl->mode, client->id, SILC_ID_CLIENT,
-                                      client->id);
-    }
+    /* Set CUMODE notify type to network */
+    if (!server->standalone)
+      silc_server_send_notify_cumode(server, server->router->connection,
+                                    server->server_type == SILC_ROUTER ? 
+                                    TRUE : FALSE, channel,
+                                    chl->mode, client->id, SILC_ID_CLIENT,
+                                    client->id);
   }
 
   silc_buffer_free(reply);
@@ -3286,10 +3303,10 @@ SILC_SERVER_CMD_FUNC(join)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   unsigned char *auth;
-  uint32 tmp_len, auth_len;
+  SilcUInt32 tmp_len, auth_len;
   char *tmp, *channel_name = NULL, *cipher, *hmac;
   SilcChannelEntry channel;
-  uint32 umode = 0;
+  SilcUInt32 umode = 0;
   bool created = FALSE, create_key = TRUE;
   SilcClientID *client_id;
 
@@ -3367,7 +3384,7 @@ SILC_SERVER_CMD_FUNC(join)
           or joins the client to it). */
        if (server->server_type != SILC_ROUTER) {
          SilcBuffer tmpbuf;
-         uint16 old_ident;
+         SilcUInt16 old_ident;
 
          /* If this is pending command callback then we've resolved
             it and it didn't work, return since we've notified the
@@ -3391,6 +3408,8 @@ SILC_SERVER_CMD_FUNC(join)
                                      silc_server_command_join,
                                      silc_server_command_dup(cmd));
          cmd->pending = TRUE;
+          silc_command_set_ident(cmd->payload, old_ident);
+         silc_buffer_free(tmpbuf);
          goto out;
        }
        
@@ -3454,7 +3473,8 @@ SILC_SERVER_CMD_FUNC(join)
     if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
       tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
       SILC_GET32_MSB(created, tmp);
-      create_key = FALSE;      /* Router returned the key already */
+      if (silc_argument_get_arg_type(reply->args, 7, NULL))
+       create_key = FALSE;     /* Router returned the key already */
     }
 
     if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
@@ -3487,8 +3507,8 @@ SILC_SERVER_CMD_FUNC(motd)
   SilcServer server = cmd->server;
   SilcBuffer packet, idp;
   char *motd, *dest_server;
-  uint32 motd_len;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt32 motd_len;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1);
 
@@ -3505,10 +3525,10 @@ SILC_SERVER_CMD_FUNC(motd)
 
     idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
 
-    if (server->config && server->config->motd && 
-       server->config->motd->motd_file) {
+    if (server->config && server->config->server_info &&
+       server->config->server_info->motd_file) {
       /* Send motd */
-      motd = silc_file_readfile(server->config->motd->motd_file, &motd_len);
+      motd = silc_file_readfile(server->config->server_info->motd_file, &motd_len);
       if (!motd)
        goto out;
       
@@ -3543,7 +3563,7 @@ SILC_SERVER_CMD_FUNC(motd)
        entry && !entry->motd) {
       /* Send to the server */
       SilcBuffer tmpbuf;
-      uint16 old_ident;
+      SilcUInt16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
       silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -3567,7 +3587,7 @@ SILC_SERVER_CMD_FUNC(motd)
     if (!entry && !cmd->pending && !server->standalone) {
       /* Send to the primary router */
       SilcBuffer tmpbuf;
-      uint16 old_ident;
+      SilcUInt16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
       silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -3622,8 +3642,8 @@ SILC_SERVER_CMD_FUNC(umode)
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   SilcBuffer packet;
   unsigned char *tmp_mask;
-  uint32 mask;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt32 mask;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
 
   if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
     goto out;
@@ -3709,7 +3729,7 @@ SILC_SERVER_CMD_FUNC(umode)
 
 int silc_server_check_cmode_rights(SilcChannelEntry channel,
                                   SilcChannelClientEntry client,
-                                  uint32 mode)
+                                  SilcUInt32 mode)
 {
   int is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
   int is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
@@ -3787,8 +3807,8 @@ SILC_SERVER_CMD_FUNC(cmode)
   SilcBuffer packet, cidp;
   unsigned char *tmp, *tmp_id, *tmp_mask;
   char *cipher = NULL, *hmac = NULL, *passphrase = NULL;
-  uint32 mode_mask, tmp_len, tmp_len2;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt32 mode_mask, tmp_len, tmp_len2;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 2, 7);
 
@@ -3859,25 +3879,25 @@ SILC_SERVER_CMD_FUNC(cmode)
       /* The mode is removed and we need to generate and distribute
         new channel key. Clients are not using private channel keys
         anymore after this. */
-
+      
       /* Re-generate channel key */
       if (!silc_server_create_channel_key(server, channel, 0))
        goto out;
-      
+       
       /* Send the channel key. This sends it to our local clients and if
         we are normal server to our router as well. */
       silc_server_send_channel_key(server, NULL, channel, 
                                   server->server_type == SILC_ROUTER ? 
                                   FALSE : !server->standalone);
-
+       
       cipher = channel->channel_key->cipher->name;
       hmac = (char *)silc_hmac_get_name(channel->hmac);
     }
   }
-  
+
   if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
     /* User limit is set on channel */
-    uint32 user_limit;
+    SilcUInt32 user_limit;
       
     /* Get user limit */
     tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
@@ -4087,9 +4107,7 @@ SILC_SERVER_CMD_FUNC(cmode)
 
        if (channel->founder_method == SILC_AUTH_PASSWORD) {
          tmp = silc_auth_get_data(auth, &tmp_len);
-         channel->founder_passwd = 
-           silc_calloc(tmp_len + 1, sizeof(*channel->founder_passwd));
-         memcpy(channel->founder_passwd, tmp, tmp_len);
+         channel->founder_passwd = silc_memdup(tmp, tmp_len);
          channel->founder_passwd_len = tmp_len;
        } else {
          /* Verify the payload before setting the mode */
@@ -4171,9 +4189,9 @@ SILC_SERVER_CMD_FUNC(cumode)
   SilcChannelClientEntry chl;
   SilcBuffer packet, idp;
   unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
-  uint32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
+  SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
   int notify = FALSE;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
 
@@ -4283,7 +4301,7 @@ SILC_SERVER_CMD_FUNC(cumode)
     if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
       /* The client tries to claim the founder rights. */
       unsigned char *tmp_auth;
-      uint32 tmp_auth_len, auth_len;
+      SilcUInt32 tmp_auth_len, auth_len;
       void *auth;
       
       if (target_client != client) {
@@ -4418,7 +4436,7 @@ SILC_SERVER_CMD_FUNC(kick)
   SilcChannelEntry channel;
   SilcChannelClientEntry chl;
   SilcBuffer idp;
-  uint32 tmp_len, target_idp_len;
+  SilcUInt32 tmp_len, target_idp_len;
   unsigned char *tmp, *comment, *target_idp;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3);
@@ -4561,9 +4579,10 @@ SILC_SERVER_CMD_FUNC(oper)
   SilcServer server = cmd->server;
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   unsigned char *username, *auth;
-  uint32 tmp_len;
-  SilcServerConfigSectionAdminConnection *admin;
+  SilcUInt32 tmp_len;
+  SilcServerConfigAdmin *admin;
   SilcIDListData idata = (SilcIDListData)client;
+  bool result = FALSE;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
 
@@ -4579,10 +4598,10 @@ SILC_SERVER_CMD_FUNC(oper)
   }
 
   /* Get the admin configuration */
-  admin = silc_server_config_find_admin(server->config, cmd->sock->ip,
+  admin = silc_server_config_find_admin(server, cmd->sock->ip,
                                        username, client->nickname);
   if (!admin) {
-    admin = silc_server_config_find_admin(server->config, cmd->sock->hostname,
+    admin = silc_server_config_find_admin(server, cmd->sock->hostname,
                                          username, client->nickname);
     if (!admin) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
@@ -4599,10 +4618,18 @@ SILC_SERVER_CMD_FUNC(oper)
     goto out;
   }
 
-  /* Verify the authentication data */
-  if (!silc_auth_verify_data(auth, tmp_len, admin->auth_meth, 
-                            admin->auth_data, admin->auth_data_len,
-                            idata->hash, client->id, SILC_ID_CLIENT)) {
+  /* Verify the authentication data. If both passphrase and public key
+     is set then try both of them. */
+  if (admin->passphrase)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
+                                  admin->passphrase, admin->passphrase_len,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result && admin->publickey)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
+                                  admin->publickey, 0,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result) {
+    /* Authentication failed */
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
                                          SILC_STATUS_ERR_AUTH_FAILED);
     goto out;
@@ -4639,9 +4666,10 @@ SILC_SERVER_CMD_FUNC(silcoper)
   SilcServer server = cmd->server;
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   unsigned char *username, *auth;
-  uint32 tmp_len;
-  SilcServerConfigSectionAdminConnection *admin;
+  SilcUInt32 tmp_len;
+  SilcServerConfigAdmin *admin;
   SilcIDListData idata = (SilcIDListData)client;
+  bool result = FALSE;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
 
@@ -4663,10 +4691,10 @@ SILC_SERVER_CMD_FUNC(silcoper)
   }
 
   /* Get the admin configuration */
-  admin = silc_server_config_find_admin(server->config, cmd->sock->ip,
+  admin = silc_server_config_find_admin(server, cmd->sock->ip,
                                        username, client->nickname);
   if (!admin) {
-    admin = silc_server_config_find_admin(server->config, cmd->sock->hostname,
+    admin = silc_server_config_find_admin(server, cmd->sock->hostname,
                                          username, client->nickname);
     if (!admin) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
@@ -4683,11 +4711,19 @@ SILC_SERVER_CMD_FUNC(silcoper)
     goto out;
   }
 
-  /* Verify the authentication data */
-  if (!silc_auth_verify_data(auth, tmp_len, admin->auth_meth, 
-                            admin->auth_data, admin->auth_data_len,
-                            idata->hash, client->id, SILC_ID_CLIENT)) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
+  /* Verify the authentication data. If both passphrase and public key
+     is set then try both of them. */
+  if (admin->passphrase)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
+                                  admin->passphrase, admin->passphrase_len,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result && admin->publickey)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
+                                  admin->publickey, 0,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result) {
+    /* Authentication failed */
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
                                          SILC_STATUS_ERR_AUTH_FAILED);
     goto out;
   }
@@ -4723,8 +4759,8 @@ SILC_SERVER_CMD_FUNC(connect)
   SilcServer server = cmd->server;
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   unsigned char *tmp, *host;
-  uint32 tmp_len;
-  uint32 port = SILC_PORT;
+  SilcUInt32 tmp_len;
+  SilcUInt32 port = SILC_PORT;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CONNECT, cmd, 1, 2);
 
@@ -4782,8 +4818,8 @@ SILC_SERVER_CMD_FUNC(ban)
   SilcChannelClientEntry chl;
   SilcChannelID *channel_id = NULL;
   unsigned char *id, *add, *del;
-  uint32 id_len, tmp_len;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt32 id_len, tmp_len;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
 
   if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
     goto out;
@@ -4888,7 +4924,7 @@ SILC_SERVER_CMD_FUNC(ban)
                                         2, id, id_len,
                                         3, channel->ban_list, 
                                         channel->ban_list ? 
-                                        strlen(channel->ban_list) : 0);
+                                        strlen(channel->ban_list) -1 : 0);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
                          packet->data, packet->len, FALSE);
     
@@ -4909,9 +4945,9 @@ SILC_SERVER_CMD_FUNC(close)
   SilcServerEntry server_entry;
   SilcSocketConnection sock;
   unsigned char *tmp;
-  uint32 tmp_len;
+  SilcUInt32 tmp_len;
   unsigned char *name;
-  uint32 port = SILC_PORT;
+  SilcUInt32 port = SILC_PORT;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CLOSE, cmd, 1, 2);
 
@@ -5014,7 +5050,7 @@ SILC_SERVER_CMD_FUNC(leave)
   SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
   SilcChannelID *id = NULL;
   SilcChannelEntry channel;
-  uint32 len;
+  SilcUInt32 len;
   unsigned char *tmp;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
@@ -5095,12 +5131,12 @@ SILC_SERVER_CMD_FUNC(users)
   SilcChannelID *id = NULL;
   SilcBuffer packet, idp;
   unsigned char *channel_id;
-  uint32 channel_id_len;
+  SilcUInt32 channel_id_len;
   SilcBuffer client_id_list;
   SilcBuffer client_mode_list;
   unsigned char lc[4];
-  uint32 list_count = 0;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt32 list_count = 0;
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   char *channel_name;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
@@ -5235,9 +5271,9 @@ SILC_SERVER_CMD_FUNC(getkey)
   SilcClientID *client_id = NULL;
   SilcServerID *server_id = NULL;
   SilcIDPayload idp = NULL;
-  uint16 ident = silc_command_get_ident(cmd->payload);
+  SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   unsigned char *tmp, *pkdata;
-  uint32 tmp_len, pklen;
+  SilcUInt32 tmp_len, pklen;
   SilcBuffer pk = NULL;
   SilcIdType id_type;
   SilcPublicKey public_key;
@@ -5273,7 +5309,7 @@ SILC_SERVER_CMD_FUNC(getkey)
        (client && !client->connection && !cmd->pending) ||
        (client && !client->data.public_key && !cmd->pending)) {
       SilcBuffer tmpbuf;
-      uint16 old_ident;
+      SilcUInt16 old_ident;
       SilcSocketConnection dest_sock;
       
       dest_sock = silc_server_get_client_route(server, NULL, 0, 
@@ -5344,7 +5380,7 @@ SILC_SERVER_CMD_FUNC(getkey)
         (server_entry && !server_entry->data.public_key && !cmd->pending &&
          !server->standalone))) {
       SilcBuffer tmpbuf;
-      uint16 old_ident;
+      SilcUInt16 old_ident;
       
       old_ident = silc_command_get_ident(cmd->payload);
       silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -5360,7 +5396,6 @@ SILC_SERVER_CMD_FUNC(getkey)
                                  silc_server_command_getkey,
                                  silc_server_command_dup(cmd));
       cmd->pending = TRUE;
-      
       silc_command_set_ident(cmd->payload, old_ident);
       silc_buffer_free(tmpbuf);
       goto out;