From 8974e90552baa2ea831b6720a061a74127edcca0 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 11 Dec 2007 11:29:43 +0000 Subject: [PATCH] implement '/STAT u' (uptime) --- ChangeLog | 3 +- src/ngircd/irc-info.c | 130 ++++++++++++++++++++++++++++++------------ src/ngircd/messages.h | 3 +- 3 files changed, 96 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 66b76404..0293fb89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ ngIRCd HEAD + - Add support for /STAT u (server uptime) command. - New [Server] configuration Option "Bind" allows to specify the source ip adress to use when connecting to remote server. - New configuration option "MaxNickLength" to specify the allowed maximum @@ -720,4 +721,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: ChangeLog,v 1.330 2007/11/23 16:28:05 fw Exp $ +$Id: ChangeLog,v 1.331 2007/12/11 11:29:43 fw Exp $ diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c index 683f7d1b..24db75de 100644 --- a/src/ngircd/irc-info.c +++ b/src/ngircd/irc-info.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-info.c,v 1.40 2007/11/21 12:16:36 alex Exp $"; +static char UNUSED id[] = "$Id: irc-info.c,v 1.41 2007/12/11 11:29:44 fw Exp $"; #include "imp.h" #include @@ -335,6 +335,41 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req ) } /* IRC_NAMES */ +static unsigned int +t_diff(time_t *t, const time_t div) +{ + time_t diff, remain; + + diff = *t / div; + + remain = diff * div; + *t -= remain; + + return diff; +} + + +static unsigned int +uptime_days(time_t *now) +{ + return t_diff(now, 60 * 60 * 24); +} + + +static unsigned int +uptime_hrs(time_t *now) +{ + return t_diff(now, 60 * 60); +} + + +static unsigned int +uptime_mins(time_t *now) +{ + return t_diff(now, 60); +} + + GLOBAL bool IRC_STATS( CLIENT *Client, REQUEST *Req ) { @@ -342,75 +377,94 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) CONN_ID con; char query; COMMAND *cmd; + time_t time_now; + unsigned int days, hrs, mins; assert( Client != NULL ); assert( Req != NULL ); /* Falsche Anzahl Parameter? */ - if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if (Req->argc > 2) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); /* From aus Prefix ermitteln */ - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + if (Client_Type(Client) == CLIENT_SERVER) + from = Client_Search(Req->prefix); + else + from = Client; - if( Req->argc == 2 ) - { + if (! from) + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix); + + if (Req->argc == 2) { /* an anderen Server forwarden */ target = Client_Search( Req->argv[1] ); - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] ); + if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) + return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] ); - if( target != Client_ThisServer( )) - { + if( target != Client_ThisServer()) { /* Ok, anderer Server ist das Ziel: forwarden */ return IRC_WriteStrClientPrefix( target, from, "STATS %s %s", Req->argv[0], Req->argv[1] ); } } - if( Req->argc > 0 ) query = Req->argv[0][0] ? Req->argv[0][0] : '*'; - else query = '*'; + if (Req->argc > 0) + query = Req->argv[0][0] ? Req->argv[0][0] : '*'; + else + query = '*'; - switch ( query ) - { + switch (query) { case 'l': /* Links */ case 'L': - con = Conn_First( ); - while( con != NONE ) - { - cl = Conn_GetClient( con ); - if( cl && (( Client_Type( cl ) == CLIENT_SERVER ) || ( cl == Client ))) - { + time_now = time(NULL); + for (con = Conn_First(); con != NONE ;con = Conn_Next(con)) { + cl = Conn_GetClient(con); + if (!cl) + continue; + if ((Client_Type(cl) == CLIENT_SERVER) || (cl == Client)) { /* Server link or our own connection */ #ifdef ZLIB - if( Conn_Options( con ) & CONN_ZIP ) - { - if( ! IRC_WriteStrClient( from, RPL_STATSLINKINFOZIP_MSG, Client_ID( from ), Client_Mask( cl ), Conn_SendQ( con ), Conn_SendMsg( con ), Zip_SendBytes( con ), Conn_SendBytes( con ), Conn_RecvMsg( con ), Zip_RecvBytes( con ), Conn_RecvBytes( con ), (long)( time( NULL ) - Conn_StartTime( con )))) return DISCONNECTED; + if (Conn_Options(con) & CONN_ZIP) { + if (!IRC_WriteStrClient(from, RPL_STATSLINKINFOZIP_MSG, + Client_ID(from), Client_Mask(cl), Conn_SendQ(con), + Conn_SendMsg(con), Zip_SendBytes(con), Conn_SendBytes(con), + Conn_RecvMsg(con), Zip_RecvBytes(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con)))) + return DISCONNECTED; + continue; } - else #endif - { - if( ! IRC_WriteStrClient( from, RPL_STATSLINKINFO_MSG, Client_ID( from ), Client_Mask( cl ), Conn_SendQ( con ), Conn_SendMsg( con ), Conn_SendBytes( con ), Conn_RecvMsg( con ), Conn_RecvBytes( con ), (long)( time( NULL ) - Conn_StartTime( con )))) return DISCONNECTED; - } + if (!IRC_WriteStrClient(from, RPL_STATSLINKINFO_MSG, Client_ID(from), + Client_Mask(cl), Conn_SendQ(con), Conn_SendMsg(con), Conn_SendBytes(con), + Conn_RecvMsg(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con)))) + return DISCONNECTED; } - con = Conn_Next( con ); } break; - case 'm': /* IRC-Befehle */ + case 'm': /* IRC-Commands */ case 'M': cmd = Parse_GetCommandStruct( ); - while( cmd->name ) - { - if( cmd->lcount > 0 || cmd->rcount > 0 ) - { - if( ! IRC_WriteStrClient( from, RPL_STATSCOMMANDS_MSG, Client_ID( from ), cmd->name, cmd->lcount, cmd->bytes, cmd->rcount )) return DISCONNECTED; - } - cmd++; + for (; cmd->name ; cmd++) { + if (cmd->lcount == 0 && cmd->rcount == 0) + continue; + if (!IRC_WriteStrClient(from, RPL_STATSCOMMANDS_MSG, Client_ID(from), + cmd->name, cmd->lcount, cmd->bytes, cmd->rcount)) + return DISCONNECTED; } break; + case 'u': /* server uptime */ + case 'U': + time_now = time(NULL) - NGIRCd_Start; + days = uptime_days(&time_now); + hrs = uptime_hrs(&time_now); + mins = uptime_mins(&time_now); + if (!IRC_WriteStrClient(from, RPL_STATSUPTIME, Client_ID(from), + days, hrs, mins, (unsigned int) time_now)) + return DISCONNECTED; + break; } - IRC_SetPenalty( from, 2 ); - return IRC_WriteStrClient( from, RPL_ENDOFSTATS_MSG, Client_ID( from ), query ); + IRC_SetPenalty(from, 2); + return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG, Client_ID(from), query); } /* IRC_STATS */ diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h index 872a251b..ccf9aa09 100644 --- a/src/ngircd/messages.h +++ b/src/ngircd/messages.h @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: messages.h,v 1.73 2007/10/04 15:03:56 alex Exp $ + * $Id: messages.h,v 1.74 2007/12/11 11:29:44 fw Exp $ * * IRC numerics (Header) */ @@ -32,6 +32,7 @@ #define RPL_STATSCOMMANDS_MSG "212 %s %s %ld %ld %ld" #define RPL_ENDOFSTATS_MSG "219 %s %c :End of STATS report" #define RPL_UMODEIS_MSG "221 %s +%s" +#define RPL_STATSUPTIME "242 %s :Server Up %u days %u:%02u:%02u" #define RPL_LUSERCLIENT_MSG "251 %s :There are %ld users and %ld services on %ld servers" #define RPL_LUSEROP_MSG "252 %s %lu :operator(s) online" #define RPL_LUSERUNKNOWN_MSG "253 %s %lu :unknown connection(s)" -- 2.39.2