extern void m_registered(struct Client *, struct Client *, int, char *[]);
extern void m_unregistered(struct Client *, struct Client *, int, char *[]);
+/*
+ * (based on orabidoo's parser code)
+ *
+ * This has always just been a trie. Look at volume III of Knuth ACP
+ *
+ *
+ * ok, you start out with an array of pointers, each one corresponds
+ * to a letter at the current position in the command being examined.
+ *
+ * so roughly you have this for matching 'trie' or 'tie'
+ *
+ * 't' points -> [MessageTree *] 'r' -> [MessageTree *] -> 'i'
+ * -> [MessageTree *] -> [MessageTree *] -> 'e' and matches
+ *
+ * 'i' -> [MessageTree *] -> 'e' and matches
+ *
+ * BUGS (Limitations!)
+ *
+ * I designed this trie to parse ircd commands. Hence it currently
+ * casefolds. This is trivial to fix by increasing MAXPTRLEN.
+ * This trie also "folds" '{' etc. down. This means, the input to this
+ * trie must be alpha tokens only. This again, is a limitation that
+ * can be overcome by increasing MAXPTRLEN to include upper/lower case
+ * at the expense of more memory. At the extreme end, you could make
+ * MAXPTRLEN 128.
+ *
+ * This is also not a patricia trie. On short ircd tokens, this is
+ * not likely going to matter.
+ *
+ * Diane Bruce (Dianora), June 6 2003
+ */
+
+/* Must be a power of 2, and
+ * larger than 26 [a-z]|[A-Z]
+ * its used to allocate the set
+ * of pointers at each node of the tree
+ * There are MAXPTRLEN pointers at each node.
+ * Obviously, there have to be more pointers
+ * Than ASCII letters. 32 is a nice number
+ * since there is then no need to shift
+ * 'A'/'a' to base 0 index, at the expense
+ * of a few never used pointers. For a small
+ * parser like this, this is a good compromise
+ * and does make it somewhat faster.
+ *
+ * - Dianora
+ */
+#define MAXPTRLEN 32
+
+struct MessageTree
+{
+ int links; /* Count of all pointers (including msg) at this node
+ * used as reference count for deletion of _this_ node.
+ */
+ struct Message *msg;
+ struct MessageTree *pointers[MAXPTRLEN];
+};
+
+extern struct MessageTree msg_tree;
+
+
#endif /* INCLUDED_parse_h */
return ret;
}
+static void
+recurse_report_message(json_t *root, const struct MessageTree *msgtree)
+{
+ if (msgtree->msg)
+ {
+ json_t *object = json_object();
+ json_object_set_new(object, "name", json_string(msgtree->msg->cmd));
+ json_object_set_new(object, "count", json_integer(msgtree->msg->count));
+ json_object_set_new(object, "bytes", json_integer(msgtree->msg->bytes));
+ json_object_set_new(object, "rcount", json_integer(msgtree->msg->rcount));
+ json_array_append(root, object);
+ }
+
+ for (int i = 0; i < MAXPTRLEN; ++i)
+ if (msgtree->pointers[i] != NULL)
+ recurse_report_message(root, msgtree->pointers[i]);
+}
+
+static int
+http_stats_messages(struct MHD_Connection *connection, const char *url,
+ const char *method, const char *version, const char *upload_data,
+ size_t *upload_data_size)
+{
+ json_t *root = json_array();
+
+ recurse_report_message(root, &msg_tree);
+
+ const char *dump = json_dumps(root, JSON_INDENT(2));
+ if (dump == NULL)
+ return MHD_NO;
+
+ json_decref(root);
+ root = NULL;
+
+ struct MHD_Response *response = MHD_create_response_from_buffer(strlen(dump), (void *) dump, MHD_RESPMEM_MUST_FREE);
+ int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+ MHD_destroy_response(response);
+
+ return ret;
+}
+
static struct HttpResource stats_http_memory =
{
.method = MHD_HTTP_METHOD_GET,
.handler = http_stats_links
};
+static struct HttpResource stats_http_messages =
+{
+ .method = MHD_HTTP_METHOD_GET,
+ .url = "/stats/messages",
+ .handler = http_stats_messages
+};
+
#endif
#endif
#ifdef HAVE_LIBMICROHTTPD
httpd_register(&stats_http_memory);
httpd_register(&stats_http_links);
+ httpd_register(&stats_http_messages);
#endif
#endif
}
#ifdef HAVE_LIBMICROHTTPD
httpd_unregister(&stats_http_memory);
httpd_unregister(&stats_http_links);
+ httpd_unregister(&stats_http_messages);
#endif
#endif
}
#include "s_serv.h"
-/*
- * (based on orabidoo's parser code)
- *
- * This has always just been a trie. Look at volume III of Knuth ACP
- *
- *
- * ok, you start out with an array of pointers, each one corresponds
- * to a letter at the current position in the command being examined.
- *
- * so roughly you have this for matching 'trie' or 'tie'
- *
- * 't' points -> [MessageTree *] 'r' -> [MessageTree *] -> 'i'
- * -> [MessageTree *] -> [MessageTree *] -> 'e' and matches
- *
- * 'i' -> [MessageTree *] -> 'e' and matches
- *
- * BUGS (Limitations!)
- *
- * I designed this trie to parse ircd commands. Hence it currently
- * casefolds. This is trivial to fix by increasing MAXPTRLEN.
- * This trie also "folds" '{' etc. down. This means, the input to this
- * trie must be alpha tokens only. This again, is a limitation that
- * can be overcome by increasing MAXPTRLEN to include upper/lower case
- * at the expense of more memory. At the extreme end, you could make
- * MAXPTRLEN 128.
- *
- * This is also not a patricia trie. On short ircd tokens, this is
- * not likely going to matter.
- *
- * Diane Bruce (Dianora), June 6 2003
- */
-
-#define MAXPTRLEN 32
- /* Must be a power of 2, and
- * larger than 26 [a-z]|[A-Z]
- * its used to allocate the set
- * of pointers at each node of the tree
- * There are MAXPTRLEN pointers at each node.
- * Obviously, there have to be more pointers
- * Than ASCII letters. 32 is a nice number
- * since there is then no need to shift
- * 'A'/'a' to base 0 index, at the expense
- * of a few never used pointers. For a small
- * parser like this, this is a good compromise
- * and does make it somewhat faster.
- *
- * - Dianora
- */
-
-struct MessageTree
-{
- int links; /* Count of all pointers (including msg) at this node
- * used as reference count for deletion of _this_ node.
- */
- struct Message *msg;
- struct MessageTree *pointers[MAXPTRLEN];
-};
-
-static struct MessageTree msg_tree;
+struct MessageTree msg_tree = { 0 };
static char *para[MAXPARA + 2]; /* <prefix> + <params> + NULL */