Added STATS command. Patch by Ville Räsänen.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 15 Sep 2002 09:40:47 +0000 (09:40 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 15 Sep 2002 09:40:47 +0000 (09:40 +0000)
CHANGES
TODO
apps/irssi/src/fe-common/silc/module-formats.c
apps/irssi/src/fe-common/silc/module-formats.h
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/silc-servers.c
lib/silcclient/command.c
lib/silcclient/command_reply.c
lib/silcutil/silclog.c
lib/silcutil/silcutil.c
lib/silcutil/silcutil.h

diff --git a/CHANGES b/CHANGES
index 7b3a637cdd4d616532062ea0601e3a73260600ea..0c4b060a2023b6807e8a8527657b375702de2329 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+Sun Sep 15 12:25:10 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Changed the silc_get_time to accept time value as argument
+         or if zero is sent return current local time.  Affected
+         file lib/silcutil/silcutil.[ch].
+
+       * Added STATS command to client library and Irssi SILC client.
+         Patch provided by Ville Räsänen <ville.rasanen@iki.fi>.
+
 Wed Sep 11 09:22:00 CEST 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Assure that channel key is set before sending it.  May
diff --git a/TODO b/TODO
index 998f6f847a9815532c6dfc0fc15afb5035c4e742..3b78256bd2001810e7803d90c6468b9851c10344 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,8 +3,6 @@ TODO/bugs in Irssi SILC client
 
  o UTF-8 encode/decode WHOIS userinfos, topic, etc.
 
- o Add STATS.
-
  o Testing
 
 
@@ -26,6 +24,8 @@ TODO/bugs In SILC Client Library
 TODO/bugs In SILC Server
 ========================
 
+ o WHOIS may not send reply in certain situations.
+
  o Add support for the <Requested Attributes> in WHOIS.  Sending and
    reception, with clients and servers should be added.
 
index 108f96e8c84e1a1d14889a012fc3ec149ea124e8..502a52be629be9065881a33549784d9ed680b8d1 100644 (file)
@@ -128,6 +128,7 @@ FORMAT_REC fecommon_silc_formats[] = {
        { "watch_umode_change", "Watch: {nick $0} is now {hilight $1}", 2, { 0, 0 } },
        { "watch_nick_change", "Watch: {nick $0} changed nickname to {nick $1}", 2, { 0, 0 } },
        { "message_data", "{nick $0} sent \"{hilight $1}\" data message: cannot display", 2, { 0, 0 } },
+       { "stats", "$[25]0: {hilight $1}", 2, { 0, 0 } },
 
        /* File transfer messages */
        { NULL, "FileTransfer", 0 },
index 035a3fdc5625f69f855b55f442f8e4c59bd8b171..e35be86c98774ce22b114655cb8d4f5e9c1e792e 100644 (file)
@@ -122,6 +122,7 @@ enum {
   SILCTXT_WATCH_UMODE_CHANGE,
   SILCTXT_WATCH_NICK_CHANGE,
   SILCTXT_MESSAGE_DATA,
+  SILCTXT_STATS,
 
   SILCTXT_FILL_5,
 
index c138a51a3eae123ba9b6739352215b32dd25621e..ff9e962dea1b017b39622128de49be60d27b3d3e 100644 (file)
@@ -1610,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);
index a67fc0b81505b3f58c83248f720ce5bb0c58045a..29cdca77bb13f449f2a765c6899dabfd4dca116d 100644 (file)
@@ -414,6 +414,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server)
 /* SYNTAX: JOIN <channel> [<passphrase>] [-cipher <cipher>] [-hmac <hmac>] [-founder] */
 /* SYNTAX: DETACH */
 /* SYNTAX: WATCH [<-add | -del> <nickname>] */
+/* SYNTAX: STATS */
 
 void silc_command_exec(SILC_SERVER_REC *server,
                       const char *command, const char *args)
@@ -966,6 +967,7 @@ void silc_server_init(void)
   command_bind_silc("file", MODULE_NAME, (SIGNAL_FUNC) command_file);
   command_bind_silc("detach", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind_silc("watch", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind_silc("stats", MODULE_NAME, (SIGNAL_FUNC) command_self);
 
   command_set_options("connect", "+silcnet");
 }
@@ -1002,6 +1004,7 @@ void silc_server_deinit(void)
   command_unbind("file", (SIGNAL_FUNC) command_file);
   command_unbind("detach", (SIGNAL_FUNC) command_self);
   command_unbind("watch", (SIGNAL_FUNC) command_self);
+  command_unbind("stats", (SIGNAL_FUNC) command_self);
 }
 
 void silc_server_free_ftp(SILC_SERVER_REC *server,
index c03f71aff18fdcabb67fd7351bbcd1c65405c52c..4a4b74ffed7752a572764b6b8ffceb63308c18d4 100644 (file)
@@ -874,6 +874,38 @@ SILC_CLIENT_CMD_FUNC(info)
   silc_client_command_free(cmd);
 }
 
+/* Command STATS. Shows server and network statistics. */
+
+SILC_CLIENT_CMD_FUNC(stats)
+{
+  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+  SilcClientConnection conn = cmd->conn;
+  SilcBuffer buffer, idp = NULL;
+
+  if (!cmd->conn) {
+    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
+    COMMAND_ERROR(SILC_STATUS_ERR_NOT_REGISTERED);
+    goto out;
+  }
+
+  idp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER); 
+  
+  /* Send the command */
+  buffer = silc_command_payload_encode_va(SILC_COMMAND_STATS,
+                                         ++conn->cmd_ident, 1,
+                                         SILC_ID_SERVER, idp->data, idp->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(idp);
+
+  /* Notify application */
+  COMMAND(SILC_STATUS_OK);
+
+ out:
+  silc_client_command_free(cmd);
+}
+
 /* Command PING. Sends ping to server. This is used to test the 
    communication channel. */
 
@@ -2433,6 +2465,7 @@ void silc_client_commands_register(SilcClient client)
   SILC_CLIENT_CMD(quit, QUIT, "QUIT", 2);
   SILC_CLIENT_CMD(kill, KILL, "KILL", 3);
   SILC_CLIENT_CMD(info, INFO, "INFO", 2);
+  SILC_CLIENT_CMD(stats, STATS, "STATS", 0);
   SILC_CLIENT_CMD(ping, PING, "PING", 2);
   SILC_CLIENT_CMD(oper, OPER, "OPER", 3);
   SILC_CLIENT_CMD(join, JOIN, "JOIN", 9);
@@ -2468,6 +2501,7 @@ void silc_client_commands_unregister(SilcClient client)
   SILC_CLIENT_CMDU(quit, QUIT, "QUIT");
   SILC_CLIENT_CMDU(kill, KILL, "KILL");
   SILC_CLIENT_CMDU(info, INFO, "INFO");
+  SILC_CLIENT_CMDU(stats, STATS, "STATS");
   SILC_CLIENT_CMDU(ping, PING, "PING");
   SILC_CLIENT_CMDU(oper, OPER, "OPER");
   SILC_CLIENT_CMDU(join, JOIN, "JOIN");
index 46832f7e74dd8ba0fdddbe2239597ca9ab040662..5772d41493df95e08f45791e0f42a8daaaa40f76 100644 (file)
@@ -830,6 +830,38 @@ SILC_CLIENT_CMD_REPLY_FUNC(info)
   silc_client_command_reply_free(cmd);
 }
 
+/* Received reply to STATS command. */
+
+SILC_CLIENT_CMD_REPLY_FUNC(stats)
+{
+  SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
+  SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
+  unsigned char *tmp, *buf = NULL;
+  SilcUInt32 len, buf_len = 0;
+
+  if (cmd->error != SILC_STATUS_OK) {
+    SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
+       "%s", silc_get_status_message(cmd->error));
+    COMMAND_REPLY_ERROR;
+    goto out;
+  }
+
+  /* Get server ID */
+  tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
+  if (!tmp)
+    goto out;
+
+  /* Get statistics structure */
+  buf = silc_argument_get_arg_type(cmd->args, 3, &buf_len);
+
+  /* Notify application */
+  COMMAND_REPLY((ARGS, buf, buf_len));
+
+ out:
+  SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_STATS);
+  silc_client_command_reply_free(cmd);
+}
+
 /* Received reply to PING command. The reply time is shown to user. */
 
 SILC_CLIENT_CMD_REPLY_FUNC(ping)
index 5f770769103d9f085b6d5dca501ad511d4c6f3d2..8ce34c0970be2e5826597b055adc1301e896c094 100644 (file)
@@ -122,7 +122,7 @@ static void silc_log_checksize(SilcLog log)
   /* It's too big */
   fprintf(log->fp, "[%s] [%s] Cycling log file, over max "
          "logsize (%lu kilobytes)\n",
-         silc_get_time(), log->typename, log->maxsize / 1024);
+         silc_get_time(0), log->typename, log->maxsize / 1024);
   fflush(log->fp);
   fclose(log->fp);
   snprintf(newname, sizeof(newname), "%s.old", log->filename);
@@ -225,7 +225,7 @@ void silc_log_output(SilcLogType type, char *string)
  found:
   /* writes the logging string to the selected channel */
   if (silc_log_timestamp)
-    fprintf(fp, "[%s] [%s] %s\n", silc_get_time(), typename, string);
+    fprintf(fp, "[%s] [%s] %s\n", silc_get_time(0), typename, string);
   else
     fprintf(fp, "[%s] %s\n", typename, string);
 
index 74d51702c1d308a83c900c3d1453faa9d83214fe..9b0294e8a9ba632aab0fa34d4019561b8f568c57 100644 (file)
@@ -78,18 +78,23 @@ int silc_check_line(char *buf)
   return 0;
 }
 
-/* Returns current time as string. */
+/* Returns time as string.  If the the `timeval' is non-zero that
+   value is returned as string.  If it is zero the current time of the
+   local machine is returned. */
 
-char *silc_get_time()
+const char *silc_get_time(SilcUInt32 timeval)
 {
   time_t curtime;
   char *return_time;
 
-  curtime = time(NULL);
+  if (!timeval)
+    curtime = time(NULL);
+  else
+    curtime = (time_t)timeval;
   return_time = ctime(&curtime);
   return_time[strlen(return_time) - 1] = '\0';
 
-  return return_time;
+  return (const char *)return_time;
 }
 
 /* Converts string to capital characters. */
index 05995416320e674ecb62a3671953bf72d147329c..28598bf2d3d65896b6a471932964b0cdf9db7f86 100644 (file)
@@ -63,14 +63,16 @@ int silc_check_line(char *buf);
  *
  * SYNOPSIS
  *
- *    char *silc_get_time();
+ *    const char *silc_get_time(SilcUInt32 timeval)
  *
  * DESCRIPTION
  *
- *    Returns current time as string.
+ *    Returns time as string.  If the the `timeval' is non-zero that
+ *    value is returned as string.  If it is zero the current time of the
+ *    local machine is returned.
  *
  ***/
-char *silc_get_time();
+const char *silc_get_time(SilcUInt32 timeval);
 
 /****f* silcutil/SilcUtilAPI/silc_to_upper
  *