Watcher list support added.
[silc.git] / apps / silcd / packet_send.c
index 019df0699a68c825613d772a9ab75ff9b2794593..85e7695d70f267c814bd9f6852f1104e49cdc33e 100644 (file)
@@ -721,7 +721,7 @@ void silc_server_packet_relay_to_channel(SilcServer server,
   SilcPacketContext packetdata;
   SilcClientEntry client = NULL;
   SilcServerEntry *routed = NULL;
-  SilcChannelClientEntry chl;
+  SilcChannelClientEntry chl, chl_sender;
   SilcUInt32 routed_count = 0;
   SilcIDListData idata;
   SilcHashTableList htl;
@@ -730,6 +730,9 @@ void silc_server_packet_relay_to_channel(SilcServer server,
 
   SILC_LOG_DEBUG(("Relaying packet to channel"));
 
+  if (!silc_server_client_on_channel(sender_entry, channel, &chl_sender))
+    return;
+
   /* This encrypts the packet, if needed. It will be encrypted if
      it came from the router thus it needs to be encrypted with the
      channel key. If the channel key does not exist, then we know we
@@ -784,8 +787,18 @@ void silc_server_packet_relay_to_channel(SilcServer server,
   silc_hash_table_list(channel->user_list, &htl);
   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
     client = chl->client;
-    if (!client || client == sender_entry || 
-       chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
+    if (!client || client == sender_entry)
+      continue;
+
+    /* Check whether message sending is blocked */
+    if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
+      continue;
+    if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS &&
+       !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANOP) &&
+       !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANFO))
+      continue;
+    if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS &&
+       sender_entry->mode & SILC_UMODE_ROBOT)
       continue;
 
     /* If the client has set router it means that it is not locally
@@ -1378,6 +1391,32 @@ void silc_server_send_notify_invite(SilcServer server,
   silc_buffer_free(idp2);
 }
 
+/* Sends WATCH notify type. This tells that the `client' was watched and
+   its status in the network has changed. */
+
+void silc_server_send_notify_watch(SilcServer server,
+                                  SilcSocketConnection sock,
+                                  SilcClientEntry watcher,
+                                  SilcClientEntry client,
+                                  const char *nickname,
+                                  SilcNotifyType type)
+{
+  SilcBuffer idp;
+  unsigned char mode[4], n[2];
+
+  idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+  SILC_PUT16_MSB(type, n);
+  SILC_PUT32_MSB(client->mode, mode);
+  silc_server_send_notify_dest(server, sock, FALSE, watcher->id,
+                              SILC_ID_CLIENT, SILC_NOTIFY_TYPE_WATCH,
+                              4, idp->data, idp->len,
+                              nickname, strlen(nickname),
+                              mode, sizeof(mode), 
+                              type != SILC_NOTIFY_TYPE_NONE ?
+                              n : NULL, sizeof(n));
+  silc_buffer_free(idp);
+}
+
 /* Sends notify message destined to specific entity. */
 
 void silc_server_send_notify_dest(SilcServer server,
@@ -1723,8 +1762,8 @@ void silc_server_send_command(SilcServer server,
 void silc_server_send_command_reply(SilcServer server, 
                                    SilcSocketConnection sock,
                                    SilcCommand command, 
-                                   SilcCommandStatus status,
-                                   SilcCommandStatus error,
+                                   SilcStatus status,
+                                   SilcStatus error,
                                    SilcUInt16 ident,
                                    SilcUInt32 argc, ...)
 {
@@ -1749,8 +1788,8 @@ void silc_server_send_dest_command_reply(SilcServer server,
                                         void *dst_id,
                                         SilcIdType dst_id_type,
                                         SilcCommand command, 
-                                        SilcCommandStatus status,
-                                        SilcCommandStatus error,
+                                        SilcStatus status,
+                                        SilcStatus error,
                                         SilcUInt16 ident,
                                         SilcUInt32 argc, ...)
 {