updates
[silc.git] / apps / silcd / command.c
index cf17f380acb087c7b7cd4886409bfb0e63bcefc4..c951889e53f0e37377bf1678c14fba17ef040a36 100644 (file)
@@ -461,8 +461,8 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
       if (!strchr(entry->username, '@')) {
        strncat(uh, "@", 1);
        hsock = (SilcSocketConnection)entry->connection;
-       len = hsock->hostname ? strlen(hsock->hostname) : strlen(hsock->ip);
-       strncat(uh, hsock->hostname ? hsock->hostname : hsock->ip, len);
+       len = strlen(hsock->hostname);
+       strncat(uh, hsock->hostname, len);
       }
       
       SILC_PUT32_MSB((time(NULL) - entry->data.last_receive), idle);
@@ -681,7 +681,7 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
      mandatory fields that WHOIS command reply requires. Check for these and
      make query from the server who owns the client if some fields are 
      missing. */
-  if (!cmd->pending && server->server_type == SILC_ROUTER &&
+  if (server->server_type == SILC_ROUTER &&
       !silc_server_command_whois_check(cmd, clients, clients_count)) {
     ret = -1;
     goto out;
@@ -787,6 +787,55 @@ silc_server_command_identify_parse(SilcServerCommandContext cmd,
   return TRUE;
 }
 
+/* Checks that all mandatory fields are present. If not then send WHOIS 
+   request to the server who owns the client. We use WHOIS because we want
+   to get as much information as possible at once. */
+
+static char
+silc_server_command_identify_check(SilcServerCommandContext cmd,
+                                  SilcClientEntry *clients,
+                                  unsigned int clients_count)
+{
+  SilcServer server = cmd->server;
+  int i;
+  SilcClientEntry entry;
+
+  for (i = 0; i < clients_count; i++) {
+    entry = clients[i];
+
+    if (!entry->nickname) {
+      SilcBuffer tmpbuf;
+      unsigned short old_ident;
+      
+      old_ident = silc_command_get_ident(cmd->payload);
+      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_command(cmd->payload, SILC_COMMAND_WHOIS);
+      tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+      
+      /* Send WHOIS request. We send WHOIS since we're doing the requesting
+        now anyway so make it a good one. */
+      silc_server_packet_send(server, entry->router->connection,
+                             SILC_PACKET_COMMAND, cmd->packet->flags,
+                             tmpbuf->data, tmpbuf->len, TRUE);
+      
+      /* Reprocess this packet after received reply */
+      silc_server_command_pending(server, SILC_COMMAND_WHOIS, 
+                                 silc_command_get_ident(cmd->payload),
+                                 silc_server_command_identify, (void *)cmd);
+      cmd->pending = TRUE;
+      
+      /* Put old data back to the Command Payload we just changed */
+      silc_command_set_ident(cmd->payload, old_ident);
+      silc_command_set_command(cmd->payload, SILC_COMMAND_IDENTIFY);
+
+      silc_buffer_free(tmpbuf);
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
 static void
 silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
                                        SilcClientEntry *clients,
@@ -847,8 +896,8 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
        if (!strchr(entry->username, '@')) {
          strncat(uh, "@", 1);
          hsock = (SilcSocketConnection)entry->connection;
-         len = hsock->hostname ? strlen(hsock->hostname) : strlen(hsock->ip);
-         strncat(uh, hsock->hostname ? hsock->hostname : hsock->ip, len);
+         len = strlen(hsock->hostname);
+         strncat(uh, hsock->hostname, len);
        }
       
        packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
@@ -956,6 +1005,14 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
     goto out;
   }
 
+  /* Check that all mandatory fields are present and request those data
+     from the server who owns the client if necessary. */
+  if (!cmd->pending && server->server_type == SILC_ROUTER &&
+      !silc_server_command_identify_check(cmd, clients, clients_count)) {
+    ret = -1;
+    goto out;
+  }
+
   /* Send the command reply to the client */
   silc_server_command_identify_send_reply(cmd, clients, clients_count);
 
@@ -1036,7 +1093,15 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
     goto out;
   }
 
-  /* Send the command reply to the client */
+  /* Check that all mandatory fields are present and request those data
+     from the server who owns the client if necessary. */
+  if (!cmd->pending && server->server_type == SILC_ROUTER &&
+      !silc_server_command_identify_check(cmd, clients, clients_count)) {
+    ret = -1;
+    goto out;
+  }
+
+  /* Send the command reply */
   silc_server_command_identify_send_reply(cmd, clients, clients_count);
 
  out:
@@ -1097,14 +1162,7 @@ SILC_SERVER_CMD_FUNC(nick)
   SilcClientID *new_id;
   char *nick;
 
-  SILC_LOG_DEBUG(("Start"));
-
-  /* Check number of arguments */
-  if (silc_argument_get_arg_num(cmd->args) < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_NICK, cmd, 1, 1);
 
   /* Check nickname */
   nick = silc_argument_get_arg_type(cmd->args, 1, NULL);
@@ -1194,18 +1252,9 @@ SILC_SERVER_CMD_FUNC(topic)
   unsigned char *tmp;
   unsigned int argc, tmp_len;
 
-  /* Check number of arguments */
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_TOPIC, cmd, 1, 2);
+
   argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 2) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
 
   /* Get Channel ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
@@ -1305,20 +1354,9 @@ SILC_SERVER_CMD_FUNC(invite)
   SilcChannelID *channel_id;
   SilcBuffer sidp;
   unsigned char *tmp;
-  unsigned int argc, len;
+  unsigned int len;
 
-  /* Check number of arguments */
-  argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 2) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INVITE, cmd, 1, 2);
 
   /* Get destination ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
@@ -1454,20 +1492,9 @@ SILC_SERVER_CMD_FUNC(info)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcBuffer packet, idp;
-  unsigned int argc;
   char info_string[256], *dest_server;
 
-  argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 1, 1);
 
   /* Get server name */
   dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
@@ -1526,20 +1553,10 @@ SILC_SERVER_CMD_FUNC(ping)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcServerID *id;
-  unsigned int argc, len;
+  unsigned int len;
   unsigned char *tmp;
 
-  argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 2) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 1, 2);
 
   /* Get Server ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
@@ -1700,6 +1717,8 @@ static void silc_server_command_join_channel(SilcServer server,
   SilcChannelClientEntry chl;
   SilcBuffer reply, chidp, clidp;
 
+  SILC_LOG_DEBUG(("Start"));
+
   if (!channel)
     return;
 
@@ -1986,23 +2005,10 @@ SILC_SERVER_CMD_FUNC(motd)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
-  unsigned int argc;
   char *motd;
   int motd_len;
   
-  SILC_LOG_DEBUG(("Start"));
-
-  argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 2) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_MOTD, cmd, 1, 2);
 
   /* XXX show currently only our motd */
 
@@ -2465,22 +2471,10 @@ SILC_SERVER_CMD_FUNC(cumode)
   SilcChannelClientEntry chl;
   SilcBuffer packet, idp;
   unsigned char *tmp_id, *tmp_mask;
-  unsigned int argc, target_mask, sender_mask, tmp_len;
+  unsigned int target_mask, sender_mask, tmp_len;
   int notify = FALSE;
 
-  SILC_LOG_DEBUG(("Start"));
-
-  argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 3) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 3) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CUMODE, cmd, 3, 3);
 
   /* Get Channel ID */
   tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
@@ -2665,22 +2659,10 @@ SILC_SERVER_CMD_FUNC(leave)
   SilcChannelID *id;
   SilcChannelEntry channel;
   SilcBuffer packet;
-  unsigned int i, argc, len;
+  unsigned int i, len;
   unsigned char *tmp;
 
-  SILC_LOG_DEBUG(("Start"));
-
-  argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 2) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_LEAVE, cmd, 1, 2);
 
   /* Get Channel ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
@@ -2771,25 +2753,13 @@ SILC_SERVER_CMD_FUNC(names)
   SilcChannelClientEntry chl;
   SilcChannelID *id;
   SilcBuffer packet;
-  unsigned int i, len, len2, tmp_len, argc;
+  unsigned int i, len, len2, tmp_len;
   unsigned char *tmp;
   char *name_list = NULL, *n;
   SilcBuffer client_id_list;
   SilcBuffer client_mode_list;
 
-  SILC_LOG_DEBUG(("Start"));
-
-  argc = silc_argument_get_arg_num(cmd->args);
-  if (argc < 1) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_NAMES,
-                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-    goto out;
-  }
-  if (argc > 2) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_NAMES,
-                                         SILC_STATUS_ERR_TOO_MANY_PARAMS);
-    goto out;
-  }
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_NAMES, cmd, 1, 2);
 
   /* Get Channel ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);