Added STATS command. Patch by Ville Räsänen.
[silc.git] / apps / irssi / src / silc / core / client_ops.c
index 1651b20058013e9760f1e049164e7f39f1f5209f..ff9e962dea1b017b39622128de49be60d27b3d3e 100644 (file)
@@ -39,6 +39,7 @@
 #include "fe-common/silc/module-formats.h"
 
 #include "core.h"
+#include "blob.h"
 
 static void 
 silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
@@ -110,6 +111,20 @@ void silc_say_error(char *msg, ...)
   va_end(va);
 }
 
+void silc_emit_mime_sig(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel,
+                       const char *data, SilcUInt32 data_len,
+                       const char *encoding, const char *type,
+                       const char *nick)
+{
+  BLOB_REC blob;
+
+  blob_fill(&blob);
+  blob.octets = data_len;
+  blob.data = (char *)data;
+
+  signal_emit("mime", 6, server, channel, &blob, encoding, type, nick);
+}
+
 /* Message for a channel. The `sender' is the nickname of the sender 
    received in the packet. The `channel_name' is the name of the channel. */
 
@@ -142,12 +157,14 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
 
   if (flags & SILC_MESSAGE_FLAG_DATA) {
     /* MIME object received, try to display it as well as we can */
-    char type[128];
+    char type[128], enc[128];
     unsigned char *data;
+    SilcUInt32 data_len;
 
     memset(type, 0, sizeof(type));
+    memset(enc, 0, sizeof(enc));
     if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1,
-                        NULL, 0, &data, NULL))
+                        enc, sizeof(enc) - 1, &data, &data_len))
       return;
 
     /* Then figure out what we can display */
@@ -156,9 +173,8 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
       /* It is something textual, display it */
       message = (const unsigned char *)data;
     } else {
-      printformat_module("fe-common/silc", server, channel->channel_name,
-                        MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
-                        nick == NULL ? "[<unknown>]" : nick->nick, type);
+      silc_emit_mime_sig(server, chanrec, data, data_len, 
+                        enc, type, nick->nick);
       message = NULL;
     }
   }
@@ -185,7 +201,7 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
        cp = dm;
       }
 
-      silc_utf8_decode(message, message_len, SILC_STRING_ASCII,
+      silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
                       cp, message_len);
       signal_emit("message public", 6, server, cp,
                  nick == NULL ? "[<unknown>]" : nick->nick,
@@ -223,12 +239,14 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
 
   if (flags & SILC_MESSAGE_FLAG_DATA) {
     /* MIME object received, try to display it as well as we can */
-    char type[128];
+    char type[128], enc[128];
     unsigned char *data;
+    SilcUInt32 data_len;
 
     memset(type, 0, sizeof(type));
+    memset(enc, 0, sizeof(enc));
     if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1,
-                        NULL, 0, &data, NULL))
+                        enc, sizeof(enc) - 1, &data, &data_len))
       return;
 
     /* Then figure out what we can display */
@@ -237,10 +255,8 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
       /* It is something textual, display it */
       message = (const unsigned char *)data;
     } else {
-      printformat_module("fe-common/silc", server, NULL,
-                        MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
-                        sender->nickname ? sender->nickname : "[<unknown>]",
-                        type);
+      silc_emit_mime_sig(server, NULL, data, data_len, 
+                        enc, type, sender->nickname);
       message = NULL;
     }
   }
@@ -258,7 +274,7 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
       cp = dm;
     }
 
-    silc_utf8_decode(message, message_len, SILC_STRING_ASCII,
+    silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
                     cp, message_len);
     signal_emit("message private", 4, server, cp,
                sender->nickname ? sender->nickname : "[<unknown>]",
@@ -833,7 +849,7 @@ void silc_connect(SilcClient client, SilcClientConnection conn,
 {
   SILC_SERVER_REC *server = conn->context;
 
-  if (!server) {
+  if (!server || server->disconnected) {
     silc_client_close_connection(client, conn);
     return;
   }
@@ -875,7 +891,8 @@ void silc_connect(SilcClient client, SilcClientConnection conn,
 
 /* Called to indicate that connection was disconnected to the server. */
 
-void silc_disconnect(SilcClient client, SilcClientConnection conn)
+void silc_disconnect(SilcClient client, SilcClientConnection conn,
+                    SilcStatus status, const char *message)
 {
   SILC_SERVER_REC *server = conn->context;
 
@@ -892,6 +909,12 @@ void silc_disconnect(SilcClient client, SilcClientConnection conn)
     silc_change_nick(server, silc_client->username);
   }
 
+  if (message)
+    silc_say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+            "Server closed connection: %s (%d) %s",
+            silc_get_status_message(status), status,
+            message ? message : "");
+
   server->conn->context = NULL;
   server->conn = NULL;
   server->connection_lost = TRUE;
@@ -1587,6 +1610,135 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
   case SILC_COMMAND_WATCH:
     break;
+  
+  case SILC_COMMAND_STATS:
+    {
+      SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops,
+                my_router_ops, cell_clients, cell_channels, cell_servers,
+                clients, channels, servers, routers, server_ops, router_ops;
+      SilcUInt32 buf_len;
+      SilcBufferStruct buf;
+      unsigned char *tmp_buf;
+      char tmp[40];
+      const char *tmptime;
+      int days, hours, mins, secs;
+
+      if (!success)
+       return;
+
+      tmp_buf = va_arg(vp, unsigned char *);
+      buf_len = va_arg(vp, SilcUInt32);
+
+      if (!tmp_buf || !buf_len) {
+       printtext(server, NULL, MSGLEVEL_CRAP, "No statistics available");
+       return;
+      }
+
+      /* Get statistics structure */
+      silc_buffer_set(&buf, tmp_buf, buf_len);
+      silc_buffer_unformat(&buf,
+                          SILC_STR_UI_INT(&starttime),
+                          SILC_STR_UI_INT(&uptime),
+                          SILC_STR_UI_INT(&my_clients),
+                          SILC_STR_UI_INT(&my_channels),
+                          SILC_STR_UI_INT(&my_server_ops),
+                          SILC_STR_UI_INT(&my_router_ops),
+                          SILC_STR_UI_INT(&cell_clients),
+                          SILC_STR_UI_INT(&cell_channels),
+                          SILC_STR_UI_INT(&cell_servers),
+                          SILC_STR_UI_INT(&clients),
+                          SILC_STR_UI_INT(&channels),
+                          SILC_STR_UI_INT(&servers),
+                          SILC_STR_UI_INT(&routers),
+                          SILC_STR_UI_INT(&server_ops),
+                          SILC_STR_UI_INT(&router_ops),
+                          SILC_STR_END);
+
+      tmptime = silc_get_time(starttime);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local server start time", tmptime);
+
+      days = uptime / (24 * 60 * 60);
+      uptime -= days * (24 * 60 * 60);
+      hours = uptime / (60 * 60);
+      uptime -= hours * (60 * 60);
+      mins = uptime / 60;
+      uptime -= mins * 60;
+      secs = uptime;
+      snprintf(tmp, sizeof(tmp) - 1, "%d days %d hours %d mins %d secs",
+              days, hours, mins, secs);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local server uptime", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_clients);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local server clients", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_channels);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local server channels", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_server_ops);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local server operators", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_router_ops);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local router operators", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_clients);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local cell clients", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_channels);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local cell channels", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_servers);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Local cell servers", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)clients);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Total clients", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)channels);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Total channels", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)servers);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Total servers", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)routers);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Total routers", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)server_ops);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                          "Total server operators", tmp);
+
+      snprintf(tmp, sizeof(tmp) - 1, "%d", (int)router_ops);
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_STATS,
+                        "Total router operators", tmp);
+    }
+    break;
+
   }
 
   va_end(vp);