/* IRCfs - IRC FileServ for *nix. * Copyright (C) 2002 Nick 'Zaf' Clifford * For licensing details, refer to the LICENSE file in the source * code directory. * * Module Description: Runtime stats accessable in a fserv session */ #include "runtime.h" #include "module.h" #include "str_hash.h" #include #include #include #include #include #ifdef HAVE_SYS_RESOURCE_H #include #endif #ifdef HAVE_SYS_UTSNAME_H #include #endif #include "appconf/appconf.h" #include "stats.h" #include "session.h" #include "console.h" #include "cinfo.h" int stats_session_debug(struct eventmsg *msg); int stats_event_filter(struct eventmsg *msg, void *filter); int stats_do_cmd(struct stats_request *sr, const char *cmd); int stats_cmd_help(struct eventmsg *msg); int stats_cmd_info(struct eventmsg *msg); MODULE_NAME("stats"); MODULE_INIT(stats_init); MODULE_DESTROY(stats_unload); MODULE_DEPENDS("session","appconf","console"); MODULE_REGISTER(stats); DEBUG stats_debug; struct eventobj *stats_eventobj; //static POOL pool; struct eventobj *stats_eventobj; struct stats_request { enum { stats_mode_session, stats_mode_console } mode; struct session *current_session; }; int stats_init() { stats_debug = debug_register("stats"); #ifdef ENABLE_DEBUG event_add_listener(session_get_eventobj(),session_event_said, "debug", stats_session_debug, NULL); #endif stats_eventobj = event_create_obj(NULL,NULL); event_set_filter_func(stats_eventobj,stats_event_filter); event_add_listener(stats_eventobj,stats_event_request, "info", stats_cmd_info, NULL); event_add_listener(stats_eventobj,stats_event_request_unknown, "help", stats_cmd_help, NULL); return 0; } int stats_event_filter(struct eventmsg *msg, void *filter) { struct stats_event_msg *sem; char *match = (char *) filter; const char *said,*cp; int len=0; sem = msg->msg; ASSERT(is_magic(sem, MAGIC_STATS_EVENT_MSG)); /* Only filter event_said messages */ if (msg->code != stats_event_request || filter == NULL) return 0; said = sem->str; for (cp = said; *cp && !isspace(*cp); cp++) len++; if (strlen(match) != len) return -1; if (memcmp(match,said,len) == 0) return 0; /* Match */ return -1; } int stats_unload() { return 0; } int stats_session_debug(struct eventmsg *msg) { struct session_event_msg *sem; struct stats_request sr; const char *param; sem = msg->msg; ASSERT(is_magic(sem, MAGIC_SESSION_EVENT_MSG)); param = strchr(sem->u.str,' '); while(isspace(*param)) param++; sr.mode = stats_mode_session; sr.current_session = sem->session; stats_do_cmd(&sr,param); return 0; } int stats_do_cmd(struct stats_request *sr, const char *cmd) { struct stats_event_msg sem; sem.str = cmd; sem.request = sr; set_magic(&sem, MAGIC_STATS_EVENT_MSG); if (event_raise(stats_eventobj, stats_event_request, &sem) == 0) { /* No handlers found */ event_raise(stats_eventobj, stats_event_request_unknown, &sem); } return 0; } int stats_vreplyf(struct stats_request *sr, const char *str, va_list vl); int stats_replyf(struct stats_request *sr, const char *str,...); int stats_reply(struct stats_request *sr, const char *str); int stats_vreplyf(struct stats_request *sr, const char *str, va_list vl) { switch(sr->mode) { case stats_mode_session: return session_vwritef(sr->current_session,str,vl); case stats_mode_console: return console_vwritef(str,vl); } return -1; } int stats_replyf(struct stats_request *sr, const char *str,...) { int r=-1; va_list vl; va_start(vl,str); switch(sr->mode) { case stats_mode_session: r= session_vwritef(sr->current_session,str,vl); break; case stats_mode_console: r= console_vwritef(str,vl); break; } va_end(vl); return r; } int stats_reply(struct stats_request *sr, const char *str) { switch(sr->mode) { case stats_mode_session: return session_write(sr->current_session,str); case stats_mode_console: return console_write(str); } return -1; } int stats_cmd_help(struct eventmsg *msg) { struct stats_event_msg *sem; sem = msg->msg; ASSERT(is_magic(sem, MAGIC_STATS_EVENT_MSG)); ASSERT(sem->request); debug(stats_debug,"Got request for help"); stats_reply(sem->request,"Hi"); return 0; } int stats_cmd_info(struct eventmsg *msg) { struct stats_event_msg *sem; #ifdef HAVE_UNAME struct utsname uinfo; #endif #ifdef HAVE_GETRUSAGE struct rusage ru; #endif sem = msg->msg; ASSERT(is_magic(sem, MAGIC_STATS_EVENT_MSG)); ASSERT(sem->request); stats_replyf(sem->request,"%s version %s compiled %s", PACKAGE_NAME,PACKAGE_VERSION, PACKAGE_BUILD_TIME); #ifdef HAVE_UNAME uname(&uinfo); stats_replyf(sem->request,"Running on %s %s %s %s %s", uinfo.sysname, uinfo.nodename, uinfo.release, uinfo.version, uinfo.machine); #endif #ifdef HAVE_GETRUSAGE if (getrusage(RUSAGE_SELF,&ru) == -1) { stats_replyf(sem->request,"getrusage returned -1: %d", errno); } else { stats_replyf(sem->request, "Rusage: user_time %ld.%06ld sys_time %ld.%06ld " "rss %ld", ru.ru_utime, ru.ru_stime, ru.ru_maxrss); } #endif return 0; }