updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 26 Mar 2001 10:25:05 +0000 (10:25 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 26 Mar 2001 10:25:05 +0000 (10:25 +0000)
16 files changed:
CHANGES
README
TODO
apps/silc/client_ops.c
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
apps/silcd/server.c
apps/silcd/server.h
apps/silcd/testi2.conf
doc/draft-riikonen-silc-pp-01.nroff
doc/draft-riikonen-silc-spec-01.nroff
lib/silcclient/client_notify.c
lib/silcclient/command.c
lib/silcclient/command_reply.c

diff --git a/CHANGES b/CHANGES
index 100651d86ca2ec99076cb745db4eaccd5934c738..f20ba39e45370fe527e7809b5d3f09217c8f6344 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+Mon Mar 26 12:11:14 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Added silc_server_send_notify_invite to send the INVITE
+         notify between routers.
+
+       * Implemented the INVITE command correctly to the server.
+
+       * Implemented the INVITE notify type handling in the server.
+
+       * Implemented the INVITE command to the client library and on the
+         user interface.
+
 Sun Mar 25 20:27:09 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Added function silc_server_get_client_resolve to find the
diff --git a/README b/README
index 215f04f96d85c82c3441986eb09f7c1fc59cffcf..dfff7705f863255715b5921a685350caeaf6b843 100644 (file)
--- a/README
+++ b/README
@@ -137,6 +137,22 @@ SILC Commands
 
                Gives a little history information about a client.
 
+       /INVITE <channel> [<nickname>[@server>]
+               [+|-[<nickname>[@<server>[!<username>[@hostname>]]]]]
+
+               Invites client to a channel or manages the invite list of
+               the channel.  The first <nickname> argument is used if an
+               client is invited to the channel.  The second +|-<nickname>
+               argument is used to either add or delete invite from the
+               channel's invite list.  Wildcards may be used with this
+               command.
+
+       /BAN    <channel> [+|-[<nickname>[@<server>[!<username>[@hostname>]]]]]
+
+               Manages the ban list of the channel.  Wildcards may be used
+               with this command.  You must be channel operator to be
+               able to use this command.
+
         /KICK   <channel> <nickname>[@<server>] [<comment>]
 
                 Kicks client from channel. You have to be at least channel
diff --git a/TODO b/TODO
index 5cab469271b4c1577bf75e7f067a3a0e3a6f2911..06677ae7101ef607cfae1bce6939a7649c8f3db1 100644 (file)
--- a/TODO
+++ b/TODO
@@ -100,12 +100,9 @@ TODO In SILC Client Library
 TODO In SILC Server
 ===================
 
- o TODO in command.c and in command_reply.c:
+ o TODO in commands (command.c and command_reply.c):
 
-       o BAN is not implemented
        o RESTART is not implemented
-       o INVITE is not working correctly
-       o JOIN does not check the invite and ban lists
        o CMODE should be rewritten as it uses a lot duplicated code.
          Some of the modes may still not be implemented or is implemented
          the wrong way.
@@ -116,7 +113,10 @@ TODO In SILC Server
          situation correctly when it is called as pending command
          (it should most likely check that cmd->pending == TRUE/FALSE).
 
- o Implement the SILC_NOTIFY_TYPE_SERVER_QUIT notify type to the server.
+ o TODO in notify types (packet_receive.c):
+
+       o CHANNEL_CHANGE notify type is not implemented
+       o SERVER_SIGNOFF notify type is not implemented
 
  o Packet processing can be made faster. All packet function in the
    packet_receive.c has same prototypes.  Instead of calling those from
index e71e8ac9bc90506aa5777ad1a96b0012a1d7629a..b97484524ad96fa1e3d1c45769fdb7f0d43f0ee7 100644 (file)
@@ -102,10 +102,11 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     break;
 
   case SILC_NOTIFY_TYPE_INVITE:
+    (void)va_arg(vp, SilcChannelEntry);
+    tmp = va_arg(vp, char *);
     client_entry = va_arg(vp, SilcClientEntry);
-    channel_entry = va_arg(vp, SilcChannelEntry);
     snprintf(message, sizeof(message), "%s invites you to channel %s", 
-            client_entry->nickname, channel_entry->channel_name);
+            client_entry->nickname, tmp);
     break;
 
   case SILC_NOTIFY_TYPE_JOIN:
@@ -548,6 +549,26 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
       }
       break;
 
+    case SILC_COMMAND_INVITE:
+      {
+       SilcChannelEntry channel;
+       char *invite_list;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       invite_list = va_arg(vp, char *);
+
+       if (invite_list)
+         silc_say(client, conn, "%s invite list: %s", channel->channel_name,
+                  invite_list);
+       else
+         silc_say(client, conn, "%s invite list not set", 
+                  channel->channel_name);
+      }
+      break;
+
     case SILC_COMMAND_JOIN:
       {
        unsigned int mode;
index afd888f1d5094f0cecbf540326cc02c17db66e46..43cc4d21101d041612a7165723760dcf1dd635e4 100644 (file)
@@ -2104,11 +2104,12 @@ SILC_SERVER_CMD_FUNC(invite)
   SilcChannelEntry channel;
   SilcChannelID *channel_id = NULL;
   SilcIDListData idata;
-  SilcBuffer idp;
+  SilcBuffer idp, idp2, packet;
   unsigned char *tmp, *add, *del;
   unsigned int len;
+  unsigned short ident = silc_command_get_ident(cmd->payload);
 
-  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INVITE, cmd, 1, 2);
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INVITE, cmd, 1, 4);
 
   /* Get Channel ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
@@ -2202,13 +2203,10 @@ SILC_SERVER_CMD_FUNC(invite)
     }
     
     /* Get route to the client */
-    dest_sock = silc_server_get_client_route(server, tmp, len, &idata);
+    dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id, &idata);
 
+    memset(invite, 0, sizeof(invite));
     strncat(invite, dest->nickname, strlen(dest->nickname));
-    if (!strchr(dest->nickname, '@')) {
-      strncat(invite, "@", 1);
-      strncat(invite, server->server_name, strlen(server->server_name));
-    }
     strncat(invite, "!", 1);
     strncat(invite, dest->username, strlen(dest->username));
     if (!strchr(dest->username, '@')) {
@@ -2221,7 +2219,7 @@ SILC_SERVER_CMD_FUNC(invite)
       channel->invite_list = silc_calloc(len + 2, 
                                         sizeof(*channel->invite_list));
     else
-      channel->invite_list = silc_realloc(channel->ban_list, 
+      channel->invite_list = silc_realloc(channel->invite_list, 
                                          sizeof(*channel->invite_list) * 
                                          (len + 
                                           strlen(channel->invite_list) + 2));
@@ -2229,23 +2227,27 @@ SILC_SERVER_CMD_FUNC(invite)
     strncat(channel->invite_list, ",", 1);
 
     /* Send notify to the client that is invited to the channel */
-    idp = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
-    tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
+    idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
+    idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
     silc_server_send_notify_dest(server, dest_sock, FALSE, dest_id, 
                                 SILC_ID_CLIENT,
-                                SILC_NOTIFY_TYPE_INVITE, 2, 
-                                idp->data, idp->len, tmp, len);
+                                SILC_NOTIFY_TYPE_INVITE, 3, 
+                                idp->data, idp->len, 
+                                channel->channel_name, 
+                                strlen(channel->channel_name),
+                                idp2->data, idp2->len);
     silc_buffer_free(idp);
+    silc_buffer_free(idp2);
   }
 
   /* Add the client to the invite list of the channel */
   add = silc_argument_get_arg_type(cmd->args, 3, &len);
-  if (add && strlen(add) == len) {
+  if (add) {
     if (!channel->invite_list)
       channel->invite_list = silc_calloc(len + 2, 
                                         sizeof(*channel->invite_list));
     else
-      channel->invite_list = silc_realloc(channel->ban_list, 
+      channel->invite_list = silc_realloc(channel->invite_list, 
                                          sizeof(*channel->invite_list) * 
                                          (len + 
                                           strlen(channel->invite_list) + 2));
@@ -2265,33 +2267,40 @@ SILC_SERVER_CMD_FUNC(invite)
                 strlen(channel->invite_list) - 1)) {
       silc_free(channel->invite_list);
       channel->invite_list = NULL;
-      goto out0;
-    }
-
-    start = strstr(channel->invite_list, del);
-    if (start && strlen(start) >= len) {
-      end = start + len;
-      n = silc_calloc(strlen(channel->invite_list) - len, sizeof(*n));
-      strncat(n, channel->invite_list, start - channel->invite_list);
-      strncat(n, end + 1, ((channel->invite_list + 
-                           strlen(channel->invite_list)) - end) - 1);
-      silc_free(channel->invite_list);
-      channel->invite_list = n;
+    } else {
+      start = strstr(channel->invite_list, del);
+      if (start && strlen(start) >= len) {
+       end = start + len;
+       n = silc_calloc(strlen(channel->invite_list) - len, sizeof(*n));
+       strncat(n, channel->invite_list, start - channel->invite_list);
+       strncat(n, end + 1, ((channel->invite_list + 
+                             strlen(channel->invite_list)) - end) - 1);
+       silc_free(channel->invite_list);
+       channel->invite_list = n;
+      }
     }
   }
 
- out0:
-
-  idp = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
-
   /* Send notify to the primary router */
-
+  if (!server->standalone)
+    silc_server_send_notify_invite(server, server->router->connection,
+                                  server->server_type == SILC_ROUTER ?
+                                  TRUE : FALSE, channel,
+                                  sender->id, SILC_ID_CLIENT_LEN,
+                                  add, del);
 
   /* Send command reply */
-  silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
-                                       SILC_STATUS_OK);
-
-  silc_buffer_free(idp);
+  tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
+  packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
+                                               SILC_STATUS_OK, ident, 2,
+                                               2, tmp, len,
+                                               3, channel->invite_list,
+                                               channel->invite_list ?
+                                               strlen(channel->invite_list) :
+                                               0);
+  silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
+                         packet->data, packet->len, FALSE);
+  silc_buffer_free(packet);
 
  out:
   if (dest_id)
@@ -2699,7 +2708,13 @@ static void silc_server_command_join_channel(SilcServer server,
 
   /* Check invite list if channel is invite-only channel */
   if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT && 
-      channel->mode & SILC_CHANNEL_MODE_INVITE && channel->invite_list) {
+      channel->mode & SILC_CHANNEL_MODE_INVITE) {
+    if (!channel->invite_list) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
+                                           SILC_STATUS_ERR_NOT_INVITED);
+      goto out;
+    }
+
     if (!silc_string_match(channel->invite_list, check)) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                            SILC_STATUS_ERR_NOT_INVITED);
@@ -4529,7 +4544,7 @@ SILC_SERVER_CMD_FUNC(ban)
 
   /* Get the new ban and add it to the ban list */
   add = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
-  if (add && strlen(add) == tmp_len) {
+  if (add) {
     if (!channel->ban_list)
       channel->ban_list = silc_calloc(tmp_len + 2, sizeof(*channel->ban_list));
     else
@@ -4552,23 +4567,20 @@ SILC_SERVER_CMD_FUNC(ban)
     if (!strncmp(channel->ban_list, del, strlen(channel->ban_list) - 1)) {
       silc_free(channel->ban_list);
       channel->ban_list = NULL;
-      goto out0;
-    }
-
-    start = strstr(channel->ban_list, del);
-    if (start && strlen(start) >= tmp_len) {
-      end = start + tmp_len;
-      n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
-      strncat(n, channel->ban_list, start - channel->ban_list);
-      strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) - 
-                          end) - 1);
-      silc_free(channel->ban_list);
-      channel->ban_list = n;
+    } else {
+      start = strstr(channel->ban_list, del);
+      if (start && strlen(start) >= tmp_len) {
+       end = start + tmp_len;
+       n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
+       strncat(n, channel->ban_list, start - channel->ban_list);
+       strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) - 
+                            end) - 1);
+       silc_free(channel->ban_list);
+       channel->ban_list = n;
+      }
     }
   }
 
- out0:
-
   /* Send the BAN notify type to our primary router. */
   if (!server->standalone && (add || del))
     silc_server_send_notify_ban(server, server->router->connection,
index a938e53c86a21d5fd1e5fb9030c7565ec5098e8c..937cc2e7eada0657c19cf2417e45b2e0437ac686 100644 (file)
@@ -64,7 +64,7 @@ void silc_server_notify(SilcServer server,
 
     /* Get the route to the client */
     dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                           packet->dst_id_len, &idata);
+                                           packet->dst_id_len, NULL, &idata);
     if (dst_sock)
       /* Relay the packet */
       silc_server_relay_packet(server, dst_sock, idata->send_key,
@@ -498,7 +498,75 @@ void silc_server_notify(SilcServer server,
     break;
 
   case SILC_NOTIFY_TYPE_INVITE:
-    SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
+
+    if (packet->dst_id_type == SILC_ID_CLIENT)
+      goto out;
+
+    SILC_LOG_DEBUG(("INVITE notify"));
+
+    /* Get Channel ID */
+    tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+    if (!tmp)
+      goto out;
+    channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!channel_id)
+      goto out;
+
+    /* Get channel entry */
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
+                                            channel_id, NULL);
+    if (!channel) {
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
+                                              channel_id, NULL);
+      if (!channel) {
+       silc_free(channel_id);
+       goto out;
+      }
+    }
+    silc_free(channel_id);
+
+    /* Get the added invite */
+    tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
+    if (tmp) {
+      if (!channel->invite_list)
+       channel->invite_list = silc_calloc(tmp_len + 2, 
+                                          sizeof(*channel->invite_list));
+      else
+       channel->invite_list = silc_realloc(channel->invite_list, 
+                                           sizeof(*channel->invite_list) * 
+                                           (tmp_len + 
+                                            strlen(channel->invite_list) + 
+                                            2));
+      if (tmp[tmp_len - 1] == ',')
+       tmp[tmp_len - 1] = '\0';
+      
+      strncat(channel->invite_list, tmp, tmp_len);
+      strncat(channel->invite_list, ",", 1);
+    }
+
+    /* Get the deleted invite */
+    tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
+    if (tmp && channel->invite_list) {
+      char *start, *end, *n;
+      
+      if (!strncmp(channel->invite_list, tmp, 
+                  strlen(channel->invite_list) - 1)) {
+       silc_free(channel->invite_list);
+       channel->invite_list = NULL;
+      } else {
+       start = strstr(channel->invite_list, tmp);
+       if (start && strlen(start) >= tmp_len) {
+         end = start + tmp_len;
+         n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
+         strncat(n, channel->invite_list, start - channel->invite_list);
+         strncat(n, end + 1, ((channel->invite_list + 
+                               strlen(channel->invite_list)) - end) - 1);
+         silc_free(channel->invite_list);
+         channel->invite_list = n;
+       }
+      }
+    }
+
     break;
 
   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
@@ -714,18 +782,17 @@ void silc_server_notify(SilcServer server,
       if (!strcmp(channel->ban_list, tmp)) {
        silc_free(channel->ban_list);
        channel->ban_list = NULL;
-       break;
-      }
-      
-      start = strstr(channel->ban_list, tmp);
-      if (start && strlen(start) >= tmp_len) {
-       end = start + tmp_len;
-       n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
-       strncat(n, channel->ban_list, start - channel->ban_list);
-       strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) - 
-                            end) - 1);
-       silc_free(channel->ban_list);
-       channel->ban_list = n;
+      } else {
+       start = strstr(channel->ban_list, tmp);
+       if (start && strlen(start) >= tmp_len) {
+         end = start + tmp_len;
+         n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
+         strncat(n, channel->ban_list, start - channel->ban_list);
+         strncat(n, end + 1, ((channel->ban_list + 
+                               strlen(channel->ban_list)) - end) - 1);
+         silc_free(channel->ban_list);
+         channel->ban_list = n;
+       }
       }
     }
 
@@ -820,7 +887,7 @@ void silc_server_private_message(SilcServer server,
 
   /* Get the route to the client */
   dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                         packet->dst_id_len, &idata);
+                                         packet->dst_id_len, NULL, &idata);
   if (!dst_sock)
     return;
 
@@ -852,7 +919,7 @@ void silc_server_private_message_key(SilcServer server,
 
   /* Get the route to the client */
   dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                         packet->dst_id_len, &idata);
+                                         packet->dst_id_len, NULL, &idata);
   if (!dst_sock)
     return;
 
@@ -1741,7 +1808,7 @@ void silc_server_key_agreement(SilcServer server,
 
   /* Get the route to the client */
   dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                         packet->dst_id_len, &idata);
+                                         packet->dst_id_len, NULL, &idata);
   if (!dst_sock)
     return;
 
index 2dba70f34e4a2c6e4ed17eb294bc92c1066eeea0..4b271c4d9cc5c94e84b04063c3352e3c18cfa342 100644 (file)
@@ -1125,7 +1125,7 @@ void silc_server_send_notify_umode(SilcServer server,
   silc_buffer_free(idp);
 }
 
-/* Sends BAN notify type. This tells that `ban' has been either `add'ed
+/* Sends BAN notify type. This tells that ban has been either `add'ed
    or `del'eted on the `channel. This function is used to send the packet
    between routers as broadcast packet. */
 
@@ -1146,6 +1146,34 @@ void silc_server_send_notify_ban(SilcServer server,
   silc_buffer_free(idp);
 }
 
+/* Sends INVITE notify type. This tells that invite has been either `add'ed
+   or `del'eted on the `channel.  The sender of the invite is the `client_id'.
+   This function is used to send the packet between routers as broadcast
+   packet. */
+
+void silc_server_send_notify_invite(SilcServer server,
+                                   SilcSocketConnection sock,
+                                   int broadcast,
+                                   SilcChannelEntry channel,
+                                   SilcClientID *client_id,
+                                   unsigned int client_id_len,
+                                   char *add, char *del)
+{
+  SilcBuffer idp, idp2;
+
+  idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
+  idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+  silc_server_send_notify(server, sock, broadcast,
+                         SILC_NOTIFY_TYPE_INVITE, 5,
+                         idp->data, idp->len,
+                         channel->channel_name, strlen(channel->channel_name),
+                         idp2->data, idp2->len,
+                         add, add ? strlen(add) : 0,
+                         del, del ? strlen(del) : 0);
+  silc_buffer_free(idp);
+  silc_buffer_free(idp2);
+}
+
 /* Sends notify message destined to specific entity. */
 
 void silc_server_send_notify_dest(SilcServer server,
index b856e0e44bf01ad1a8efb8e8c6c085510467f70f..cef2bbe4298138b804756f8b8d8a28e55e45ba26 100644 (file)
@@ -179,6 +179,13 @@ void silc_server_send_notify_ban(SilcServer server,
                                 int broadcast,
                                 SilcChannelEntry channel,
                                 char *add, char *del);
+void silc_server_send_notify_invite(SilcServer server,
+                                   SilcSocketConnection sock,
+                                   int broadcast,
+                                   SilcChannelEntry channel,
+                                   SilcClientID *client_id,
+                                   unsigned int client_id_len,
+                                   char *add, char *del);
 void silc_server_send_notify_dest(SilcServer server,
                                  SilcSocketConnection sock,
                                  int broadcast,
index 6134452413234de6dd20afb86fa2f1d52cab4ed4..a82d494c862250c75b6ed7b91d64ab3801802adf 100644 (file)
@@ -3130,11 +3130,13 @@ void silc_server_save_users_on_channel(SilcServer server,
 
 /* Lookups route to the client indicated by `id' client ID. The connection
    object and internal data object is returned. Returns NULL if route
-   could not be found to the client. */
+   could not be found to the client. If the `client_id' is specified then
+   it is used and the `id_data' is ignored. */
 
 SilcSocketConnection silc_server_get_client_route(SilcServer server,
                                                  unsigned char *id_data,
                                                  unsigned int id_len,
+                                                 SilcClientID *client_id,
                                                  SilcIDListData *idata)
 {
   SilcClientID *id;
@@ -3143,10 +3145,14 @@ SilcSocketConnection silc_server_get_client_route(SilcServer server,
   SILC_LOG_DEBUG(("Start"));
 
   /* Decode destination Client ID */
-  id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
-  if (!id) {
-    SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
-    return NULL;
+  if (!client_id) {
+    id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
+    if (!id) {
+      SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
+      return NULL;
+    }
+  } else {
+    id = silc_id_dup(client_id, SILC_ID_CLIENT);
   }
 
   /* If the destination belongs to our server we don't have to route
index ded8b8086ae10146c956b5273ae50f520453ff89..d02bda7545b8a748a13b30afb31fc3a38a5dc80e 100644 (file)
@@ -160,6 +160,7 @@ void silc_server_save_users_on_channel(SilcServer server,
 SilcSocketConnection silc_server_get_client_route(SilcServer server,
                                                  unsigned char *id_data,
                                                  unsigned int id_len,
+                                                 SilcClientID *client_id,
                                                  SilcIDListData *idata);
 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
                                               SilcClientEntry client);
index 1eaa60712ab7aae1843e23183e8026d08547a0f6..42ed3eae557fcc11cf459bdcbb77c8bacb6813ad 100644 (file)
@@ -1,23 +1,17 @@
 [Cipher]
-aes-256-cbc:../lib/silcsim/modules/aes.sim.so:32:16
-aes-192-cbc:../lib/silcsim/modules/aes.sim.so:24:16
-aes-128-cbc:../lib/silcsim/modules/aes.sim.so:16:16
-twofish-256-cbc:../lib/silcsim/modules/twofish.sim.so:32:16
-twofish-192-cbc:../lib/silcsim/modules/twofish.sim.so:24:16
-twofish-128-cbc:../lib/silcsim/modules/twofish.sim.so:16:16
-mars-256-cbc:../lib/silcsim/modules/mars.sim.so:32:16
-mars-192-cbc:../lib/silcsim/modules/mars.sim.so:24:16
-mars-128-cbc:../lib/silcsim/modules/mars.sim.so:16:16
+rc6:../lib/silcsim/modules/rc6.sim.so:16:16
+twofish:../lib/silcsim/modules/twofish.sim.so:16:16
+mars:../lib/silcsim/modules/mars.sim.so:16:16
 none:../lib/silcsim/modules/none.sim.so:0:0
 
-[Hash]
+[Hash] 
 md5::64:16
 sha1::64:20
 
 [hmac]
 hmac-sha1-96:sha1:12
 hmac-md5-96:md5:12
-hmac-sha1:sha1:20   
+hmac-sha1:sha1:20
 hmac-md5:md5:16
 
 #[PKCS]
@@ -31,10 +25,10 @@ nobody:nobody
 Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
 
 [ServerInfo]
-lassi.kuo.fi.ssh.com:212.146.42.253:Kuopio, Finland:1334
+lassi.kuo.fi.ssh.com:10.2.1.7:Kuopio, Finland:1334
 
 [ListenPort]
-212.146.42.253:212.146.42.253:1334
+10.2.1.7:10.2.1.7:1334
 
 [Logging]
 infologfile:silcd2.log:10000
@@ -53,13 +47,16 @@ errorlogfile:silcd2.log:10000
 :::1336:1
 
 [AdminConnection]
-*:priikone:*:passwd:testi
+*:silc:silc:passwd:testi
 
 [ServerConnection]
-212.146.42.253:passwd:priikone:1333:1:1
+10.2.1.7:passwd:priikone:1333:1:1
 
 [RouterConnection]
-212.146.42.253:passwd:priikone:1335:1:1:0
+10.2.1.7:passwd:priikone:1335:1:1:0
 
 [DenyConnection]
 [RedirectClient]
+
+[motd]
+./motd
index fed19883d135d2143815a2cad67076b08799d498..0567d6d75c246cd5accdfd8cab9071c343885ae0 100644 (file)
@@ -1126,24 +1126,26 @@ ID's sent in arguments are sent inside ID Payload.
       Sent when an client is invited to a channel.  This is also sent
       when the invite list of the channel is changed.  This notify type
       is sent between routers and if the <Client ID> is argument is
-      provided to the client as well.
+      provided to the client as well.  In this case the packet is
+      destined to the client.
 
       Max Arguments:  5
-          Arguments:  (1) <Channel ID>          (2) [<Client ID>]
-                      (3) [<sender Client ID>]  (3) [<adding client>]
-                      (4) [<removing client>]
-
-      The <Client ID> is the client which was invited to the channel.
-      The <Channel ID> is the channel.  The <sender Client ID> is the
+          Arguments:  (1) <Channel ID>          (2) <channel name>
+                      (3) [<sender Client ID>]  (4) [<adding client>]
+                      (5) [<removing client>]
+
+      The <Channel ID> is the channel.  The <channel name> is the name
+      of the channel and is provided because the client which receives 
+      this notify packet may not have a way to resolve the name of the
+      channel from the <Channel ID>.  The <sender Client ID> is the
       Client ID who invited the client to the channel.  The <adding client>
-      and the <removing client> indicates the added or removed client from
-      the channel's invite list.  The format of the <adding client and the
-      <removing client> is defined in the [SILC1] with SILC_COMMAND_INVITE
-      command.
+      and the <removing client> indicates the added or removed client
+      from the channel's invite list.  The format of the <adding client
+      and the <removing client> is defined in the [SILC1] with
+      SILC_COMMAND_INVITE command.
 
       The <adding client> and <removing client> is never sent to the
-      client indicated by the <Client ID>.  Also note that the lists
-      include the <Client ID> already.
+      client indicated by the <Client ID>.
 
 
 2     SILC_NOTIFY_TYPE_JOIN
@@ -1262,7 +1264,7 @@ ID's sent in arguments are sent inside ID Payload.
 10    SILC_NOTIFY_TYPE_CHANNEL_CHANGE
 
       Sent when channel's ID has changed for a reason or another.  This 
-      is sent by noral server to the client.  Client must change the 
+      is sent by normal server to the client.  Client must change the 
       old Channel ID to the new one.  This type must be sent only to the
       clients who is joined on the channel.
 
index 7dda5ce7b4f89fe3a9165a8d16f0d9690cf8b855..4bf88c496aefe7f4f9836d82f592ff202a6ea07b 100644 (file)
@@ -2303,10 +2303,12 @@ List of all defined commands in SILC follows.
 
         Reply messages to the command:
 
-        Max Arguments:  2
-            Arguments:  (1) <Status Payload>
+        Max Arguments:  3
+            Arguments:  (1) <Status Payload>  (2) <Channel ID>
+                        (3) [<invite list>]
 
-        This command replies only with Status Payload.
+       This command replies with the invite list of the channel if it
+       exists.
 
         Status messages:
 
index d1668cae208d21dd6b99a92940ff4de875faf9ba..744ad2893c3b4a59eb9f0f4158f899ecb854df1c 100644 (file)
@@ -107,11 +107,26 @@ void silc_client_notify_by_server(SilcClient client,
      * for the application.
      */
     
-    /* Get Client ID */
+    /* Get Channel ID */
     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
     if (!tmp)
       goto out;
 
+    channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!channel_id)
+      goto out;
+
+    /* Get the channel entry */
+    channel = NULL;
+    if (silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
+                                    SILC_ID_CHANNEL, &id_cache))
+      channel = (SilcChannelEntry)id_cache->context;
+
+    /* Get sender Client ID */
+    tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
+    if (!tmp)
+      goto out;
+
     client_id = silc_id_payload_parse_id(tmp, tmp_len);
     if (!client_id)
       goto out;
@@ -123,28 +138,13 @@ void silc_client_notify_by_server(SilcClient client,
       goto out;
     }
 
-    /* Get Channel ID */
+    /* Get the channel name */
     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
     if (!tmp)
       goto out;
 
-    channel_id = silc_id_payload_parse_id(tmp, tmp_len);
-    if (!channel_id)
-      goto out;
-
-    /* XXX Will ALWAYS fail because currently we don't have way to resolve
-       channel information for channel that we're not joined to. */
-    /* XXX ways to fix: use (extended) LIST command, or define the channel
-       name to the notfy type when name resolving is not mandatory. */
-    /* Find channel entry */
-    if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
-                                    SILC_ID_CHANNEL, &id_cache))
-      goto out;
-
-    channel = (SilcChannelEntry)id_cache->context;
-
     /* Notify application */
-    client->ops->notify(client, conn, type, client_entry, channel);
+    client->ops->notify(client, conn, type, channel, tmp, client_entry);
     break;
 
   case SILC_NOTIFY_TYPE_JOIN:
index 1ef9975d122c6d08c6b88315710a5b067fee61ff..82b07fb3f186e3fcbc85f03e26a3d8b75b9a7abf 100644 (file)
@@ -530,18 +530,20 @@ SILC_CLIENT_CMD_FUNC(topic)
   silc_client_command_free(cmd);
 }
 
-/* Command INVITE. Invites specific client to join a channel. */
+/* Command INVITE. Invites specific client to join a channel. This is
+   also used to mange the invite list of the channel. */
 
 SILC_CLIENT_CMD_FUNC(invite)
 {
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClient client = cmd->client;
   SilcClientConnection conn = cmd->conn;
-  SilcClientEntry client_entry;
-  SilcChannelEntry channel_entry;
+  SilcClientEntry client_entry = NULL;
+  SilcChannelEntry channel;
   SilcBuffer buffer, clidp, chidp;
-  unsigned int num = 0;
-  char *nickname = NULL, *server = NULL;
+  unsigned int num = 0, type = 0;
+  char *nickname = NULL, *server = NULL, *name;
+  char *invite = NULL;
 
   if (!cmd->conn) {
     SILC_NOT_CONNECTED(cmd->client, cmd->conn);
@@ -549,63 +551,104 @@ SILC_CLIENT_CMD_FUNC(invite)
     goto out;
   }
 
-  if (cmd->argc != 3) {
+  if (cmd->argc < 2) {
     cmd->client->ops->say(cmd->client, conn,
-                         "Usage: /INVITE <nickname>[@<server>] <channel>");
+                  "Usage: /INVITE <channel> [<nickname>[@server>]"
+                  "[+|-[<nickname>[@<server>[!<username>[@hostname>]]]]]");
     COMMAND_ERROR;
     goto out;
   }
 
-  /* Parse the typed nickname. */
-  if (!silc_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
-    cmd->client->ops->say(cmd->client, conn, "Bad nickname");
-    COMMAND_ERROR;
-    goto out;
-  }
+  if (cmd->argv[1][0] == '*') {
+    if (!conn->current_channel) {
+      cmd->client->ops->say(cmd->client, conn, "You are not on any channel");
+      COMMAND_ERROR;
+      goto out;
+    }
 
-  /* Find client entry */
-  client_entry = silc_idlist_get_client(client, conn, nickname, server, num,
-                                       TRUE);
-  if (!client_entry) {
-    if (nickname)
-      silc_free(nickname);
-    if (server)
-      silc_free(server);
+    channel = conn->current_channel;
+  } else {
+    name = cmd->argv[1];
 
-    /* Client entry not found, it was requested thus mark this to be
-       pending command. */
-    silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident,
-                               silc_client_command_destructor,
-                               silc_client_command_invite, 
-                               silc_client_command_dup(cmd));
-    cmd->pending = 1;
-    return;
+    channel = silc_client_get_channel(cmd->client, conn, name);
+    if (!channel) {
+      cmd->client->ops->say(cmd->client, conn, "You are on that channel");
+      COMMAND_ERROR;
+      goto out;
+    }
   }
 
-  /* Find channel entry */
-  channel_entry = silc_client_get_channel(client, conn, cmd->argv[2]);
-  if (!channel_entry) {
-    cmd->client->ops->say(cmd->client, conn, "You are not on that channel");
-    COMMAND_ERROR;
-    goto out;
+  /* 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, "Bad nickname");
+       COMMAND_ERROR;
+       goto out;
+      }
+      
+      /* Find client entry */
+      client_entry = silc_idlist_get_client(client, conn, nickname, 
+                                           server, num, TRUE);
+      if (!client_entry) {
+       if (nickname)
+         silc_free(nickname);
+       if (server)
+         silc_free(server);
+       
+       if (cmd->pending) {
+         COMMAND_ERROR;
+         goto out;
+       }
+      
+       /* Client entry not found, it was requested thus mark this to be
+          pending command. */
+       silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, 
+                                   conn->cmd_ident,
+                                   silc_client_command_destructor,
+                                   silc_client_command_invite, 
+                                   silc_client_command_dup(cmd));
+       cmd->pending = 1;
+       return;
+      }
+      
+      cmd->client->ops->say(cmd->client, conn, 
+                           "Inviting %s to channel %s", cmd->argv[2], 
+                           channel->channel_name);
+    } else {
+      invite = cmd->argv[2];
+      invite++;
+      if (cmd->argv[2][0] == '+')
+       type = 3;
+      else
+       type = 4;
+    }
+  }
+
+  /* Send the command */
+  chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+  if (client_entry) {
+    clidp = silc_id_payload_encode(client_entry->id, SILC_ID_CLIENT);
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_INVITE, 
+                                           ++conn->cmd_ident, 3,
+                                           1, chidp->data, chidp->len,
+                                           2, clidp->data, clidp->len,
+                                           type, invite, invite ?
+                                           strlen(invite) : 0);
+    silc_buffer_free(clidp);
+  } else {
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_INVITE, 
+                                           ++conn->cmd_ident, 2,
+                                           1, chidp->data, chidp->len,
+                                           type, invite, invite ?
+                                           strlen(invite) : 0);
   }
 
-  /* Send command */
-  clidp = silc_id_payload_encode(client_entry->id, SILC_ID_CLIENT);
-  chidp = silc_id_payload_encode(channel_entry->id, SILC_ID_CHANNEL);
-  buffer = silc_command_payload_encode_va(SILC_COMMAND_INVITE, 0, 2,
-                                         1, clidp->data, clidp->len,
-                                         2, chidp->data, chidp->len);
   silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL, 
                          0, NULL, NULL, buffer->data, buffer->len, TRUE);
   silc_buffer_free(buffer);
-  silc_buffer_free(clidp);
   silc_buffer_free(chidp);
 
-  cmd->client->ops->say(cmd->client, conn, 
-                       "Inviting %s to channel %s", cmd->argv[1], 
-                       cmd->argv[2]);
-
   /* Notify application */
   COMMAND;
 
@@ -715,6 +758,11 @@ SILC_CLIENT_CMD_FUNC(kill)
     if (server)
       silc_free(server);
 
+    if (cmd->pending) {
+      COMMAND_ERROR;
+      goto out;
+    }
+
     /* Client entry not found, it was requested thus mark this to be
        pending command. */
     silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, 
@@ -1292,6 +1340,11 @@ SILC_CLIENT_CMD_FUNC(cumode)
   client_entry = silc_idlist_get_client(cmd->client, conn, 
                                        nickname, server, num, TRUE);
   if (!client_entry) {
+    if (cmd->pending) {
+      COMMAND_ERROR;
+      goto out;
+    }
+
     /* Client entry not found, it was requested thus mark this to be
        pending command. */
     silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, 
index a97b23529fef89d2c432f04a57c6906f384b119c..f091e8cff9b8b9e95267ad1c6d6dbaeabe6a4108 100644 (file)
@@ -712,7 +712,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(invite)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
   SilcCommandStatus status;
+  SilcChannelEntry channel;
+  SilcChannelID *channel_id;
+  SilcIDCacheEntry id_cache;
   unsigned char *tmp;
+  unsigned int len;
 
   tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
   SILC_GET16_MSB(status, tmp);
@@ -725,12 +729,35 @@ SILC_CLIENT_CMD_REPLY_FUNC(invite)
     return;
   }
 
+  /* Take Channel ID */
+  tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
+  if (!tmp)
+    goto out;
+
+  channel_id = silc_id_payload_parse_id(tmp, len);
+  if (!channel_id)
+    goto out;
+
+  /* Get the channel entry */
+  if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
+                                  SILC_ID_CHANNEL, &id_cache)) {
+    silc_free(channel_id);
+    COMMAND_REPLY_ERROR;
+    goto out;
+  }
+  
+  channel = (SilcChannelEntry)id_cache->context;
+
+  /* Get the invite list */
+  tmp = silc_argument_get_arg_type(cmd->args, 3, &len);
+
   /* Notify application */
-  COMMAND_REPLY((ARGS));
+  COMMAND_REPLY((ARGS, channel, tmp));
 
   /* Execute any pending command callbacks */
   SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_INVITE);
 
+ out:
   SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_INVITE);
   silc_client_command_reply_free(cmd);
 }