Added statistics updating and statisics dumping with SIGUSR1.
[silc.git] / apps / silcd / command.c
index 2c092734057fe7e0567fae2f80bb2757ae67ceb1..168f7bb3e8c7f85bb3637090bcead14592fe9de4 100644 (file)
@@ -201,7 +201,6 @@ void silc_server_command_process(SilcServer server,
                                            packet->buffer->len);
   if (!ctx->payload) {
     SILC_LOG_ERROR(("Bad command payload, packet dropped"));
-    silc_buffer_free(packet->buffer);
     silc_packet_context_free(packet);
     silc_socket_free(ctx->sock);
     silc_free(ctx);
@@ -3421,6 +3420,13 @@ static void silc_server_command_join_channel(SilcServer server,
                                     clidp->data, clidp->len,
                                     chidp->data, chidp->len);
 
+  /* Update statistics */
+  server->stat.my_chanclients++;
+  if (server->server_type == SILC_ROUTER) {
+    server->stat.cell_chanclients++;
+    server->stat.chanclients++;
+  }
+
   if (!cmd->pending) {
     /* Send JOIN notify packet to our primary router */
     if (!server->standalone)
@@ -3860,6 +3866,22 @@ SILC_SERVER_CMD_FUNC(umode)
       }
     }
 
+    /* Update statistics */
+    if (mask & SILC_UMODE_GONE) {
+      if (!client->mode & SILC_UMODE_GONE)
+       server->stat.my_aways++;
+    } else {
+      if (client->mode & SILC_UMODE_GONE)
+       server->stat.my_aways--;
+    }
+    if (mask & SILC_UMODE_DETACHED) {
+      if (!client->mode & SILC_UMODE_DETACHED)
+       server->stat.my_detached++;
+    } else {
+      if (client->mode & SILC_UMODE_DETACHED)
+       server->stat.my_detached--;
+    }
+
     /* Change the mode */
     client->mode = mask;
 
@@ -4413,6 +4435,8 @@ SILC_SERVER_CMD_FUNC(cumode)
       /* The client tries to claim the founder rights. */
       unsigned char *tmp_auth;
       SilcUInt32 tmp_auth_len;
+      SilcChannelClientEntry chl2;
+      SilcHashTableList htl;
 
       if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
          !channel->founder_key || !idata->public_key ||
@@ -4439,7 +4463,6 @@ SILC_SERVER_CMD_FUNC(cumode)
        goto out;
       }
 
-      sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
       notify = TRUE;
       founder_key = channel->founder_key;
       fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
@@ -4448,6 +4471,20 @@ SILC_SERVER_CMD_FUNC(cumode)
                                              SILC_STATUS_ERR_AUTH_FAILED, 0);
        goto out;
       }
+
+      /* There cannot be anyone else as founder on the channel now.  This
+        client is definitely the founder due to this authentication */
+      silc_hash_table_list(channel->user_list, &htl);
+      while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+       if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+         chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+         silc_server_force_cumode_change(server, NULL, channel, chl2,
+                                         chl2->mode);
+         break;
+       }
+      silc_hash_table_list_reset(&htl);
+
+      sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
     }
   } else {
     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
@@ -4466,27 +4503,11 @@ SILC_SERVER_CMD_FUNC(cumode)
   if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
     /* Promote to operator */
     if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
-      if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
-         !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
-                                             SILC_STATUS_ERR_NO_CHANNEL_PRIV,
-                                             0);
-       goto out;
-      }
-
       chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
       notify = TRUE;
     }
   } else {
     if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
-      if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
-         !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
-                                             SILC_STATUS_ERR_NO_CHANNEL_PRIV,
-                                             0);
-       goto out;
-      }
-
       /* Demote to normal user */
       chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
       notify = TRUE;
@@ -4565,6 +4586,28 @@ SILC_SERVER_CMD_FUNC(cumode)
     }
   }
 
+  if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
+    if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
+      if (client == target_client) {
+       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                             SILC_STATUS_ERR_PERM_DENIED, 0);
+       goto out;
+      }
+      chl->mode |= SILC_CHANNEL_UMODE_QUIET;
+      notify = TRUE;
+    }
+  } else {
+    if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
+      if (client == target_client) {
+       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                             SILC_STATUS_ERR_PERM_DENIED, 0);
+       goto out;
+      }
+      chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
+      notify = TRUE;
+    }
+  }
+
   idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
   tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);