updates.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 21 Jun 2001 21:44:04 +0000 (21:44 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 21 Jun 2001 21:44:04 +0000 (21:44 +0000)
CHANGES
TODO
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/server.h
lib/silcclient/client_channel.c
lib/silcclient/client_notify.c
lib/silcutil/silcschedule.c

diff --git a/CHANGES b/CHANGES
index 022a733cb9d862df923593036671c23672a13175..eab51892fd26703057d548a849df5e1f66954a64 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -29,6 +29,25 @@ Thu Jun 21 17:10:08 CEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
          libary is freed.  The affected files are
          lib/silcske/silcske[_status].[ch].
 
+       * Resolve the client entry information in the function
+         silc_client_channel_message to assure that NULL pointer is not
+         passed as client entry to the application. */
+
+       * Fixed the task timeout calculation to assure that there is
+         never negative timeouts.  The affected file is 
+         lib/silcutil/silcschedule.c.
+
+       * Fixed the channel user mode notification sending in server.
+         It was sent point-to-point to the router (or to server by router)
+         but it needs to be destined to a channel.  The routines now
+         supports sending the channel user mode notifys to the channels
+         when announcing clients and channels.  Affected files are
+         silcd/server.c and silcd/packet_receive.c.
+
+       * Fixed the CHANNEL_CHANGE notify handling in the client libary.
+         It did not actually replace the old channel entry in the cache.
+         Affected file lib/silcclient/client_notify.c.
+
 Tue Jun 19 22:10:36 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Fixed a possible crash in silc_packet_send_prepare.  It now
diff --git a/TODO b/TODO
index 47181d968fc5dd52a898ae68db82b9109b33df3a..ea16429bf5fd286abf7739289caf11d1f8b8d96f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -34,10 +34,6 @@ TODO/bugs in Irssi SILC client
 TODO/bugs In SILC Client Library
 ================================
 
- o If the silc_client_channel_message does not find the client entry
-   then it should attempt to resolve it at least once and no return
-   NULL entry to the application.
-
  o Add some silc_client_del_client and other deletion funtions for
    application to delete client entrys from the cache.
 
@@ -117,9 +113,6 @@ TODO/bugs In SILC Server
 TODO/bugs In SILC Libraries
 ===========================
 
- o The timeout calculation can go negative at least on BSD, so rewrite
-   in in lib/silcutil/silcschdule.c.
-
  o Incomplete IPv6 support:
 
        o All network routines in lib/silcutil/silcnet.[ch] does not
index 0c010bdfe97d377dd98ecf46207aaf7ac4143bfa..f207289903b432154ca047fc228dcecbcec00437 100644 (file)
@@ -701,9 +701,11 @@ void silc_server_notify(SilcServer server,
       }
       if (users_modes) {
        silc_buffer_push(users_modes, users_modes->data - users_modes->head);
-       silc_server_packet_send(server, sock,
-                               SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
-                               users_modes->data, users_modes->len, FALSE);
+       silc_server_packet_send_dest(server, sock,
+                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+                                    channel->id, SILC_ID_CHANNEL,
+                                    users_modes->data, 
+                                    users_modes->len, FALSE);
        silc_buffer_free(users_modes);
       }
     }
@@ -1964,9 +1966,11 @@ void silc_server_new_channel(SilcServer server,
       }
       if (users_modes) {
        silc_buffer_push(users_modes, users_modes->data - users_modes->head);
-       silc_server_packet_send(server, sock,
-                               SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
-                               users_modes->data, users_modes->len, FALSE);
+       silc_server_packet_send_dest(server, sock,
+                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+                                    channel->id, SILC_ID_CHANNEL,
+                                    users_modes->data, 
+                                    users_modes->len, FALSE);
        silc_buffer_free(users_modes);
       }
     }
index cda5026b58dde21d9d39c46486fe3e32ec5e4223..ef90e6dc1d731083a5b6ba1072f510afd2974168 100644 (file)
@@ -3305,7 +3305,9 @@ void silc_server_announce_get_channels(SilcServer server,
                                       SilcIDList id_list,
                                       SilcBuffer *channels,
                                       SilcBuffer *channel_users,
-                                      SilcBuffer *channel_users_modes)
+                                      SilcBuffer **channel_users_modes,
+                                      uint32 *channel_users_modes_c,
+                                      SilcChannelID ***channel_ids)
 {
   SilcIDCacheList list;
   SilcIDCacheEntry id_cache;
@@ -3314,6 +3316,7 @@ void silc_server_announce_get_channels(SilcServer server,
   uint32 id_len;
   uint16 name_len;
   int len;
+  int i = *channel_users_modes_c;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -3343,15 +3346,24 @@ void silc_server_announce_get_channels(SilcServer server,
                           SILC_STR_END);
        silc_buffer_pull(*channels, len);
 
+       *channel_users_modes = silc_realloc(*channel_users_modes,
+                                           sizeof(**channel_users_modes) * 
+                                           (i + 1));
+       (*channel_users_modes)[i] = NULL;
+       *channel_ids = silc_realloc(*channel_ids, 
+                                   sizeof(**channel_ids) * (i + 1));
+       (*channel_ids)[i] = NULL;
        silc_server_announce_get_channel_users(server, channel,
                                               channel_users,
-                                              channel_users_modes);
-
-       silc_free(cid);
+                                              channel_users_modes[i]);
+       (*channel_ids)[i] = channel->id;
+       i++;
 
        if (!silc_idcache_list_next(list, &id_cache))
          break;
       }
+
+      *channel_users_modes_c += i;
     }
 
     silc_idcache_list_free(list);
@@ -3364,19 +3376,26 @@ void silc_server_announce_get_channels(SilcServer server,
 
 void silc_server_announce_channels(SilcServer server)
 {
-  SilcBuffer channels = NULL, channel_users = NULL, channel_users_modes = NULL;
+  SilcBuffer channels = NULL, channel_users = NULL;
+  SilcBuffer *channel_users_modes = NULL;
+  uint32 channel_users_modes_c = 0;
+  SilcChannelID **channel_ids = NULL;
 
   SILC_LOG_DEBUG(("Announcing channels and channel users"));
 
   /* Get channels and channel users in local list */
   silc_server_announce_get_channels(server, server->local_list,
                                    &channels, &channel_users,
-                                   &channel_users_modes);
+                                   &channel_users_modes,
+                                   &channel_users_modes_c,
+                                   &channel_ids);
 
   /* Get channels and channel users in global list */
   silc_server_announce_get_channels(server, server->global_list,
                                    &channels, &channel_users,
-                                   &channel_users_modes);
+                                   &channel_users_modes,
+                                   &channel_users_modes_c,
+                                   &channel_ids);
 
   if (channels) {
     silc_buffer_push(channels, channels->data - channels->head);
@@ -3406,19 +3425,24 @@ void silc_server_announce_channels(SilcServer server)
   }
 
   if (channel_users_modes) {
-    silc_buffer_push(channel_users_modes, 
-                    channel_users_modes->data - channel_users_modes->head);
-    SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes->data, 
-                    channel_users_modes->len);
-
-    /* Send the packet */
-    silc_server_packet_send(server, server->router->connection,
-                           SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
-                           channel_users_modes->data, 
-                           channel_users_modes->len,
-                           FALSE);
-
-    silc_buffer_free(channel_users_modes);
+    int i;
+
+    for (i = 0; i < channel_users_modes_c; i++) {
+      silc_buffer_push(channel_users_modes[i], 
+                      channel_users_modes[i]->data - 
+                      channel_users_modes[i]->head);
+      SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data, 
+                      channel_users_modes[i]->len);
+      silc_server_packet_send_dest(server, server->router->connection,
+                                  SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+                                  channel_ids[i], SILC_ID_CHANNEL,
+                                  channel_users_modes[i]->data, 
+                                  channel_users_modes[i]->len,
+                                  FALSE);
+      silc_buffer_free(channel_users_modes[i]);
+    }
+    silc_free(channel_users_modes);
+    silc_free(channel_ids);
   }
 }
 
index 1420221db7a4a697ef7615f77e8b23067a824326..556f835e6f0c43b681748eee1f2e44efd4d61342 100644 (file)
@@ -156,7 +156,9 @@ void silc_server_announce_get_channels(SilcServer server,
                                       SilcIDList id_list,
                                       SilcBuffer *channels,
                                       SilcBuffer *channel_users,
-                                      SilcBuffer *channel_users_modes);
+                                      SilcBuffer **channel_users_modes,
+                                      uint32 *channel_users_modes_c,
+                                      SilcChannelID ***channel_ids);
 void silc_server_announce_servers(SilcServer server);
 void silc_server_announce_clients(SilcServer server);
 void silc_server_announce_channels(SilcServer server);
index fb23a10c33f8157e4523196b2df5488702575360..9a04d07e4a95784df223697f4739cb49d1cb4a75 100644 (file)
@@ -151,6 +151,19 @@ void silc_client_send_channel_message(SilcClient client,
   silc_free(id_string);
 }
 
+static void silc_client_channel_message_cb(SilcClient client,
+                                          SilcClientConnection conn,
+                                          SilcClientEntry *clients,
+                                          uint32 clients_count,
+                                          void *context)
+{
+  SilcPacketContext *packet = (SilcPacketContext *)context;
+
+  if (clients)
+    silc_client_channel_message(client, conn->sock, packet);
+  silc_packet_context_free(packet);
+}
+
 /* Process received message to a channel (or from a channel, really). This
    decrypts the channel message with channel specific key and parses the
    channel payload. Finally it displays the message on the screen. */
@@ -167,7 +180,7 @@ void silc_client_channel_message(SilcClient client,
   SilcChannelUser chu;
   SilcIDCacheEntry id_cache = NULL;
   SilcClientID *client_id = NULL;
-  int found = FALSE;
+  bool found = FALSE;
   unsigned char *message;
 
   SILC_LOG_DEBUG(("Start"));
@@ -216,8 +229,6 @@ void silc_client_channel_message(SilcClient client,
     goto out;
   }
 
-  message = silc_channel_message_get_data(payload, NULL);
-
   /* Find client entry */
   silc_list_start(channel->clients);
   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
@@ -227,9 +238,18 @@ void silc_client_channel_message(SilcClient client,
     }
   }
 
+  if (!found) {
+    /* Resolve the client info */
+    silc_client_get_client_by_id_resolve(client, conn, client_id,
+                                        silc_client_channel_message_cb,
+                                        silc_packet_context_dup(packet));
+    goto out;
+  }
+
+  message = silc_channel_message_get_data(payload, NULL);
+
   /* Pass the message to application */
-  client->ops->channel_message(client, conn, found ? chu->client : NULL,
-                              channel, 
+  client->ops->channel_message(client, conn, chu->client, channel,
                               silc_channel_message_get_flags(payload),
                               message);
 
index ce8204e2b6065f8beff0ef2837de7bec64b35706..44ae2fbe62e37861f49cf8edb87f58765e7a0cb8 100644 (file)
@@ -506,10 +506,11 @@ void silc_client_notify_by_server(SilcClient client,
       goto out;
 
     /* Find Client entry */
-    client_entry = 
-      silc_client_get_client_by_id(client, conn, client_id);
-    if (!client_entry)
+    client_entry = silc_client_get_client_by_id(client, conn, client_id);
+    if (!client_entry) {
+      silc_client_notify_by_server_resolve(client, conn, packet, client_id);
       goto out;
+    }
 
     /* Get the mode */
     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
@@ -591,11 +592,14 @@ void silc_client_notify_by_server(SilcClient client,
     
     /* Get the channel entry */
     if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
-                                &id_cache))
+                                    &id_cache))
       break;
 
     channel = (SilcChannelEntry)id_cache->context;
 
+    SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
+                   silc_id_render(channel->id, SILC_ID_CHANNEL)));
+
     /* Free the old ID */
     silc_free(channel->id);
 
@@ -607,7 +611,13 @@ void silc_client_notify_by_server(SilcClient client,
     if (!channel->id)
       goto out;
 
-    id_cache->id = (void *)channel->id;
+    SILC_LOG_DEBUG(("New Channel ID id(%s)", 
+                   silc_id_render(channel->id, SILC_ID_CHANNEL)));
+
+    /* Remove the old cache entry and create a new one */
+    silc_idcache_del_by_context(conn->channel_cache, channel);
+    silc_idcache_add(conn->channel_cache, channel->channel_name, 
+                    channel->id, channel, FALSE);
 
     /* Notify application */
     client->ops->notify(client, conn, type, channel, channel);
index abc0043cba9a92d9b1b2dc3585bab9d33a542031..5929720daf4ed2c6c770a891a04359996cd9b4ba 100644 (file)
@@ -328,10 +328,14 @@ do {                                                                          \
           /* Calculate the next timeout for select() */                            \
           queue->timeout.tv_sec = task->timeout.tv_sec - curtime.tv_sec;    \
           queue->timeout.tv_usec = task->timeout.tv_usec - curtime.tv_usec; \
+         if (queue->timeout.tv_sec < 0)                                    \
+            queue->timeout.tv_sec = 0;                                             \
                                                                            \
           /* We wouldn't want to go under zero, check for it. */           \
           if (queue->timeout.tv_usec < 0) {                                \
             queue->timeout.tv_sec -= 1;                                            \
+           if (queue->timeout.tv_sec < 0)                                  \
+              queue->timeout.tv_sec = 0;                                   \
             queue->timeout.tv_usec += 1000000L;                                    \
           }                                                                \
         }                                                                  \