X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fs_debug.c;h=53338c225d43e5a7e9bb26302c36a2a2b32560ac;hb=refs%2Fheads%2Fupstream;hp=b6fa0f6ea05691458354cf8a17ed9c11988cf86c;hpb=e44343128ccfa8f5c16dd0332984974dd308c1bc;p=ircu2.10.12-pk.git diff --git a/ircd/s_debug.c b/ircd/s_debug.c index b6fa0f6..53338c2 100644 --- a/ircd/s_debug.c +++ b/ircd/s_debug.c @@ -17,185 +17,154 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/** @file + * @brief Debug support for the ircd. + * @version $Id$ + */ +#include "config.h" -#include "sys.h" -#if HAVE_SYS_FILE_H -#include -#endif -#if defined(HPUX) && HAVE_FCNTL_H -#include -#endif -#ifdef HPUX -#include -#define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b) -#endif -#if HAVE_GETRUSAGE -#include -#else -#if HAVE_TIMES -#include -#endif -#endif -#if HAVE_UNISTD_H -#include -#endif -#include -#include "h.h" -#include "struct.h" -#include "numeric.h" -#include "hash.h" -#include "send.h" -#include "s_conf.h" +#include "s_debug.h" +#include "channel.h" #include "class.h" +#include "client.h" +#include "gline.h" +#include "hash.h" +#include "ircd_alloc.h" +#include "ircd_features.h" +#include "ircd_log.h" +#include "ircd_osdep.h" +#include "ircd_reply.h" #include "ircd.h" +#include "jupe.h" +#include "list.h" +#include "listener.h" +#include "motd.h" +#include "msgq.h" +#include "numeric.h" +#include "numnicks.h" +#include "res.h" #include "s_bsd.h" -#include "bsd.h" +#include "s_conf.h" +#include "s_user.h" +#include "s_stats.h" +#include "send.h" +#include "struct.h" +#include "sys.h" #include "whowas.h" -#include "s_serv.h" -#include "res.h" -#include "channel.h" -#include "numnicks.h" - -RCSTAG_CC("$Id$"); -/* *INDENT-OFF* */ +/* #include -- Now using assert in ircd_log.h */ +#include +#include +#include +#include /* offsetof */ +#include +#include +#include /* * Option string. Must be before #ifdef DEBUGMODE. */ -char serveropts[] = { -#if BUFFERPOOL < 1000000 - 'b', -#if BUFFERPOOL > 99999 - (char)('0' + (BUFFERPOOL/100000)), -#endif -#if BUFFERPOOL > 9999 - (char)('0' + (BUFFERPOOL/10000) % 10), -#endif - (char)('0' + (BUFFERPOOL/1000) % 10), -#else - 'B', -#if BUFFERPOOL > 99999999 - (char)('0' + (BUFFERPOOL/100000000)), -#endif -#if BUFFERPOOL > 9999999 - (char)('0' + (BUFFERPOOL/10000000) % 10), -#endif - (char)('0' + (BUFFERPOOL/1000000) % 10), -#endif -#ifdef CHROOTDIR - 'c', -#endif -#ifdef CMDLINE_CONFIG - 'C', -#endif -#ifdef DO_ID - 'd', -#endif -#ifdef DEBUGMODE - 'D', -#endif -#ifdef LOCOP_REHASH - 'e', -#endif -#ifdef OPER_REHASH - 'E', -#endif -#ifdef HUB - 'H', -#endif -#if defined(SHOW_INVISIBLE_USERS) || defined(SHOW_ALL_INVISIBLE_USERS) -#ifdef SHOW_ALL_INVISIBLE_USERS - 'I', -#else - 'i', -#endif -#endif -#ifdef OPER_KILL -#ifdef LOCAL_KILL_ONLY - 'k', -#else - 'K', -#endif -#endif -#ifdef LEAST_IDLE - 'L', -#endif -#ifdef IDLE_FROM_MSG - 'M', -#endif -#ifdef USEONE - 'O', -#endif -#ifdef CRYPT_OPER_PASSWORD - 'p', -#endif -#ifdef CRYPT_LINK_PASSWORD - 'P', -#endif -#ifdef DEBUGMALLOC -#ifdef MEMLEAKSTATS - 'Q', -#else - 'q', -#endif -#endif -#ifdef RELIABLE_CLOCK - 'R', -#endif -#ifdef LOCOP_RESTART - 's', -#endif -#ifdef OPER_RESTART - 'S', +static char serveropts[256]; /* should be large enough for anything */ + +/** Return a string describing important configuration information. + * @return Pointer to a static buffer. + */ +const char* debug_serveropts(void) +{ + int bp; + int i = 0; +#define AddC(c) serveropts[i++] = (c) + + bp = feature_int(FEAT_BUFFERPOOL); + if (bp < 1000000) { + AddC('b'); + if (bp > 99999) + AddC((char)('0' + (bp / 100000))); + if (bp > 9999) + AddC((char)('0' + (bp / 10000) % 10)); + AddC((char)('0' + (bp / 1000) % 10)); + } else { + AddC('B'); + if (bp > 99999999) + AddC((char)('0' + (bp / 100000000))); + if (bp > 9999999) + AddC((char)('0' + (bp / 10000000) % 10)); + AddC((char)('0' + (bp / 1000000) % 10)); + } + +#ifndef NDEBUG + AddC('A'); #endif -#ifdef OPER_REMOTE - 't', +#ifdef DEBUGMODE + AddC('D'); #endif + + if (feature_bool(FEAT_HUB)) + AddC('H'); + + if (feature_bool(FEAT_IDLE_FROM_MSG)) + AddC('M'); + + if (feature_bool(FEAT_RELIABLE_CLOCK)) + AddC('R'); + #if defined(USE_POLL) && defined(HAVE_POLL_H) - 'U', -#endif -#ifdef VIRTUAL_HOST - 'v', -#endif -#ifdef BADCHAN - 'W', -#ifdef LOCAL_BADCHAN - 'w', + AddC('U'); #endif +#ifdef IPV6 + AddC('6'); #endif -#ifdef UNIXPORT - 'X', -#endif -#ifdef USE_SYSLOG - 'Y', -#endif - '\0' -}; -/* *INDENT-ON* */ + serveropts[i] = '\0'; -#ifdef DEBUGMODE -static char debugbuf[1024]; + return serveropts; +} +/** Initialize debugging. + * If the -t option is not given on the command line when the server is + * started, all debugging output is sent to the file set by LPATH in config.h + * Here we just open that file and make sure it is opened to fd 2 so that + * any fprintf's to stderr also go to the logfile. If the debuglevel is not + * set from the command line by -x, use /dev/null as the dummy logfile as long + * as DEBUGMODE has been defined, else don't waste the fd. + * @param use_tty Passed to log_debug_init(). + */ +void debug_init(int use_tty) +{ +#ifdef DEBUGMODE + if (debuglevel >= 0) { + printf("isatty = %d ttyname = %s\n", isatty(2), ttyname(2)); + log_debug_init(use_tty); + } +#endif +} + +#ifdef DEBUGMODE +/** Log a debug message using a va_list. + * If the current #debuglevel is less than \a level, do not display. + * @param level Debug level for message. + * @param form Format string, passed to log_vwrite(). + * @param vl Varargs argument list for format string. + */ void vdebug(int level, const char *form, va_list vl) { + static int loop = 0; int err = errno; - if ((debuglevel >= 0) && (level <= debuglevel)) + if (!loop && (debuglevel >= 0) && (level <= debuglevel)) { - vsprintf(debugbuf, form, vl); - if (loc_clients[2]) - { - loc_clients[2]->sendM++; - loc_clients[2]->sendB += strlen(debugbuf); - } - fprintf(stderr, "%s", debugbuf); - fputc('\n', stderr); + loop = 1; + log_vwrite(LS_DEBUG, L_DEBUG, 0, form, vl); + loop = 0; } errno = err; } +/** Log a debug message using a variable number of arguments. + * This is a simple wrapper around debug(\a level, \a form, vl). + * @param level Debug level for message. + * @param form Format string of message. + */ void debug(int level, const char *form, ...) { va_list vl; @@ -204,259 +173,191 @@ void debug(int level, const char *form, ...) va_end(vl); } -/* - * This is part of the STATS replies. There is no offical numeric for this - * since this isnt an official command, in much the same way as HASH isnt. - * It is also possible that some systems wont support this call or have - * different field names for "struct rusage". - * -avalon +/** Send a literal RPL_STATSDEBUG message to a user. + * @param cptr Client to receive the message. + * @param msg Text message to send to user. */ -void send_usage(aClient *cptr, char *nick) +static void debug_enumerator(struct Client* cptr, const char* msg) { + assert(0 != cptr); + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":%s", msg); +} -#if HAVE_GETRUSAGE - struct rusage rus; - time_t secs, rup; -#ifdef hz -#define hzz hz -#else -#ifdef HZ -#define hzz HZ -#else - int hzz = 1; -#ifdef HPUX - hzz = (int)sysconf(_SC_CLK_TCK); -#endif -#endif -#endif - - if (getrusage(RUSAGE_SELF, &rus) == -1) - { - if (MyUser(cptr) || Protocol(cptr->from) < 10) - sendto_one(cptr, ":%s NOTICE %s :Getruseage error: %s.", - me.name, nick, sys_errlist[errno]); - else - sendto_one(cptr, "%s NOTICE %s%s :Getruseage error: %s.", - NumServ(&me), NumNick(cptr), sys_errlist[errno]); - return; - } - secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec; - rup = now - me.since; - if (secs == 0) - secs = 1; - -#if defined(__sun__) || defined(__bsdi__) || (__GLIBC__ >= 2) || defined(__NetBSD__) - sendto_one(cptr, ":%s %d %s :CPU Secs %ld:%ld User %ld:%ld System %ld:%ld", -#else - sendto_one(cptr, ":%s %d %s :CPU Secs %ld:%ld User %d:%d System %d:%d", -#endif - me.name, RPL_STATSDEBUG, nick, secs / 60, secs % 60, - rus.ru_utime.tv_sec / 60, rus.ru_utime.tv_sec % 60, - rus.ru_stime.tv_sec / 60, rus.ru_stime.tv_sec % 60); - sendto_one(cptr, ":%s %d %s :RSS %ld ShMem %ld Data %ld Stack %ld", - me.name, RPL_STATSDEBUG, nick, rus.ru_maxrss, - rus.ru_ixrss / (rup * hzz), rus.ru_idrss / (rup * hzz), - rus.ru_isrss / (rup * hzz)); - sendto_one(cptr, ":%s %d %s :Swaps %ld Reclaims %ld Faults %ld", - me.name, RPL_STATSDEBUG, nick, rus.ru_nswap, - rus.ru_minflt, rus.ru_majflt); - sendto_one(cptr, ":%s %d %s :Block in %ld out %ld", - me.name, RPL_STATSDEBUG, nick, rus.ru_inblock, rus.ru_oublock); - sendto_one(cptr, ":%s %d %s :Msg Rcv %ld Send %ld", - me.name, RPL_STATSDEBUG, nick, rus.ru_msgrcv, rus.ru_msgsnd); - sendto_one(cptr, ":%s %d %s :Signals %ld Context Vol. %ld Invol %ld", - me.name, RPL_STATSDEBUG, nick, rus.ru_nsignals, - rus.ru_nvcsw, rus.ru_nivcsw); -#else /* HAVE_GETRUSAGE */ -#if HAVE_TIMES - struct tms tmsbuf; - time_t secs, mins; - int hzz = 1, ticpermin; - int umin, smin, usec, ssec; - -#ifdef HPUX - hzz = sysconf(_SC_CLK_TCK); -#endif - ticpermin = hzz * 60; - - umin = tmsbuf.tms_utime / ticpermin; - usec = (tmsbuf.tms_utime % ticpermin) / (float)hzz; - smin = tmsbuf.tms_stime / ticpermin; - ssec = (tmsbuf.tms_stime % ticpermin) / (float)hzz; - secs = usec + ssec; - mins = (secs / 60) + umin + smin; - secs %= hzz; +/** Send resource usage statistics to a client. + * @param cptr Client to send data to. + * @param sd StatDesc that generated the stats request (ignored). + * @param param Extra parameter from user (ignored). + */ +void send_usage(struct Client *cptr, const struct StatDesc *sd, + char *param) +{ + os_get_rusage(cptr, CurrentTime - cli_since(&me), debug_enumerator); - if (times(&tmsbuf) == -1) - { - sendto_one(cptr, ":%s %d %s :times(2) error: %s.", - me.name, RPL_STATSDEBUG, nick, strerror(errno)); - return; - } - secs = tmsbuf.tms_utime + tmsbuf.tms_stime; - - sendto_one(cptr, ":%s %d %s :CPU Secs %d:%d User %d:%d System %d:%d", - me.name, RPL_STATSDEBUG, nick, mins, secs, umin, usec, smin, ssec); -#endif /* HAVE_TIMES */ -#endif /* HAVE_GETRUSAGE */ - sendto_one(cptr, ":%s %d %s :Reads %d Writes %d", - me.name, RPL_STATSDEBUG, nick, readcalls, writecalls); - sendto_one(cptr, ":%s %d %s :DBUF alloc %d used %d", - me.name, RPL_STATSDEBUG, nick, DBufAllocCount, DBufUsedCount); - sendto_one(cptr, - ":%s %d %s :Writes: <0 %d 0 %d <16 %d <32 %d <64 %d", - me.name, RPL_STATSDEBUG, nick, - writeb[0], writeb[1], writeb[2], writeb[3], writeb[4]); - sendto_one(cptr, - ":%s %d %s :<128 %d <256 %d <512 %d <1024 %d >1024 %d", - me.name, RPL_STATSDEBUG, nick, - writeb[5], writeb[6], writeb[7], writeb[8], writeb[9]); - return; + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":DBUF alloc %d used %d", + DBufAllocCount, DBufUsedCount); } #endif /* DEBUGMODE */ -void count_memory(aClient *cptr, char *nick) +/** Report memory usage statistics to a client. + * @param cptr Client to send data to. + * @param sd StatDesc that generated the stats request (ignored). + * @param param Extra parameter from user (ignored). + */ +void count_memory(struct Client *cptr, const struct StatDesc *sd, + char *param) { - Reg1 aClient *acptr; - Reg2 Link *link; - Reg3 aChannel *chptr; - Reg4 aConfItem *aconf; - Reg5 aConfClass *cltmp; - - int lc = 0, /* local clients */ - ch = 0, /* channels */ - lcc = 0, /* local client conf links */ - rc = 0, /* remote clients */ - us = 0, /* user structs */ - chu = 0, /* channel users */ - chi = 0, /* channel invites */ - chb = 0, /* channel bans */ - wwu = 0, /* whowas users */ - cl = 0, /* classes */ - co = 0; /* conf lines */ - - int usi = 0, /* users invited */ - usc = 0, /* users in channels */ - aw = 0, /* aways set */ - wwa = 0; /* whowas aways */ - - size_t chm = 0, /* memory used by channels */ - chbm = 0, /* memory used by channel bans */ - lcm = 0, /* memory used by local clients */ - rcm = 0, /* memory used by remote clients */ - awm = 0, /* memory used by aways */ - wwam = 0, /* whowas away memory used */ - wwm = 0, /* whowas array memory used */ - com = 0, /* memory used by conf lines */ - dbufs_allocated = 0, /* memory used by dbufs */ - dbufs_used = 0, /* memory used by dbufs */ - rm = 0, /* res memory used */ + struct Client *acptr; + struct SLink *link; + struct Ban *ban; + struct Channel *chptr; + struct ConfItem *aconf; + const struct ConnectionClass* cltmp; + struct Membership* member; + + int acc = 0, /* accounts */ + c = 0, /* clients */ + cn = 0, /* connections */ + ch = 0, /* channels */ + lcc = 0, /* local client conf links */ + chi = 0, /* channel invites */ + chb = 0, /* channel bans */ + wwu = 0, /* whowas users */ + cl = 0, /* classes */ + co = 0, /* conf lines */ + listeners = 0, /* listeners */ + memberships = 0; /* channel memberships */ + + int usi = 0, /* users invited */ + aw = 0, /* aways set */ + wwa = 0, /* whowas aways */ + gl = 0, /* glines */ + ju = 0; /* jupes */ + + size_t chm = 0, /* memory used by channels */ + chbm = 0, /* memory used by channel bans */ + cm = 0, /* memory used by clients */ + cnm = 0, /* memory used by connections */ + us = 0, /* user structs */ + usm = 0, /* memory used by user structs */ + awm = 0, /* memory used by aways */ + wwam = 0, /* whowas away memory used */ + wwm = 0, /* whowas array memory used */ + glm = 0, /* memory used by glines */ + jum = 0, /* memory used by jupes */ + com = 0, /* memory used by conf lines */ + dbufs_allocated = 0, /* memory used by dbufs */ + dbufs_used = 0, /* memory used by dbufs */ + msg_allocated = 0, /* memory used by struct Msg */ + msgbuf_allocated = 0, /* memory used by struct MsgBuf */ + listenersm = 0, /* memory used by listetners */ + rm = 0, /* res memory used */ totcl = 0, totch = 0, totww = 0, tot = 0; count_whowas_memory(&wwu, &wwm, &wwa, &wwam); - wwm += sizeof(aWhowas) * NICKNAMEHISTORYLENGTH; - wwm += sizeof(aWhowas *) * WW_MAX; + wwm += sizeof(struct Whowas) * feature_int(FEAT_NICKNAMEHISTORYLENGTH); + wwm += sizeof(struct Whowas *) * WW_MAX; - for (acptr = client; acptr; acptr = acptr->next) + for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) { - if (IsPing(acptr)) - continue; + c++; if (MyConnect(acptr)) { - lc++; - for (link = acptr->confs; link; link = link->next) - lcc++; + cn++; + for (link = cli_confs(acptr); link; link = link->next) + lcc++; } - else - rc++; - if (acptr->user) + if (cli_user(acptr)) { - us++; - for (link = acptr->user->invited; link; link = link->next) - usi++; - for (link = acptr->user->channel; link; link = link->next) - usc++; - if (acptr->user->away) + for (link = cli_user(acptr)->invited; link; link = link->next) + usi++; + for (member = cli_user(acptr)->channel; member; member = member->next_channel) + ++memberships; + if (cli_user(acptr)->away) { - aw++; - awm += (strlen(acptr->user->away) + 1); + aw++; + awm += (strlen(cli_user(acptr)->away) + 1); } } + + if (IsAccount(acptr)) + acc++; } - lcm = lc * CLIENT_LOCAL_SIZE; - rcm = rc * CLIENT_REMOTE_SIZE; + cm = c * sizeof(struct Client); + cnm = cn * sizeof(struct Connection); + user_count_memory(&us, &usm); - for (chptr = channel; chptr; chptr = chptr->nextch) + for (chptr = GlobalChannelList; chptr; chptr = chptr->next) { ch++; - chm += (strlen(chptr->chname) + sizeof(aChannel)); - for (link = chptr->members; link; link = link->next) - chu++; + chm += (strlen(chptr->chname) + sizeof(struct Channel)); for (link = chptr->invites; link; link = link->next) chi++; - for (link = chptr->banlist; link; link = link->next) + for (ban = chptr->banlist; ban; ban = ban->next) { chb++; - chbm += (strlen(link->value.cp) + 1 + sizeof(Link)); + chbm += strlen(ban->who) + strlen(ban->banstr) + 2 + sizeof(*ban); } } - for (aconf = conf; aconf; aconf = aconf->next) + for (aconf = GlobalConfList; aconf; aconf = aconf->next) { co++; com += aconf->host ? strlen(aconf->host) + 1 : 0; com += aconf->passwd ? strlen(aconf->passwd) + 1 : 0; com += aconf->name ? strlen(aconf->name) + 1 : 0; - com += sizeof(aConfItem); + com += sizeof(struct ConfItem); } - for (cltmp = classes; cltmp; cltmp = cltmp->next) + for (cltmp = get_class_list(); cltmp; cltmp = cltmp->next) cl++; - sendto_one(cptr, ":%s %d %s :Client Local %d(" SIZE_T_FMT - ") Remote %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, lc, lcm, rc, rcm); - sendto_one(cptr, ":%s %d %s :Users %d(" SIZE_T_FMT - ") Invites %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, us, us * sizeof(anUser), usi, - usi * sizeof(Link)); - sendto_one(cptr, ":%s %d %s :User channels %d(" SIZE_T_FMT - ") Aways %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, usc, usc * sizeof(Link), aw, awm); - sendto_one(cptr, ":%s %d %s :Attached confs %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, lcc, lcc * sizeof(Link)); - - totcl = lcm + rcm + us * sizeof(anUser) + usc * sizeof(Link) + awm; - totcl += lcc * sizeof(Link) + usi * sizeof(Link); - - sendto_one(cptr, ":%s %d %s :Conflines %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, co, com); - - sendto_one(cptr, ":%s %d %s :Classes %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, cl, cl * sizeof(aConfClass)); - - sendto_one(cptr, ":%s %d %s :Channels %d(" SIZE_T_FMT - ") Bans %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, ch, chm, chb, chbm); - sendto_one(cptr, ":%s %d %s :Channel membrs %d(" SIZE_T_FMT - ") invite %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, chu, chu * sizeof(Link), - chi, chi * sizeof(Link)); - - totch = chm + chbm + chu * sizeof(Link) + chi * sizeof(Link); - - sendto_one(cptr, ":%s %d %s :Whowas users %d(" SIZE_T_FMT - ") away %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, wwu, wwu * sizeof(anUser), wwa, wwam); - sendto_one(cptr, ":%s %d %s :Whowas array %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, NICKNAMEHISTORYLENGTH, wwm); - - totww = wwu * sizeof(anUser) + wwam + wwm; - - sendto_one(cptr, ":%s %d %s :Hash: client %d(" SIZE_T_FMT - "), chan is the same", - me.name, RPL_STATSDEBUG, nick, HASHSIZE, sizeof(void *) * HASHSIZE); - + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Clients %d(%zu) Connections %d(%zu)", c, cm, cn, cnm); + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Users %zu(%zu) Accounts %d(%zu) Invites %d(%zu)", + us, usm, acc, acc * (ACCOUNTLEN + 1), + usi, usi * sizeof(struct SLink)); + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":User channels %d(%zu) Aways %d(%zu)", memberships, + memberships * sizeof(struct Membership), aw, awm); + + totcl = cm + cnm + us * sizeof(struct User) + memberships * sizeof(struct Membership) + awm; + totcl += lcc * sizeof(struct SLink) + usi * sizeof(struct SLink); + + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Conflines %d(%zu) Attached %d(%zu) Classes %d(%zu)", + co, com, lcc, lcc * sizeof(struct SLink), + cl, cl * sizeof(struct ConnectionClass)); + + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Channels %d(%zu) Bans %d(%zu)", ch, chm, chb, chbm); + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Channel Members %d(%zu) Invites %d(%zu)", memberships, + memberships * sizeof(struct Membership), chi, + chi * sizeof(struct SLink)); + + totch = chm + chbm + chi * sizeof(struct SLink); + + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Whowas Users %d(%zu) Away %d(%zu) Array %d(%zu)", + wwu, wwu * sizeof(struct User), wwa, wwam, + feature_int(FEAT_NICKNAMEHISTORYLENGTH), wwm); + + totww = wwu * sizeof(struct User) + wwam + wwm; + + motd_memory_count(cptr); + + gl = gline_memory_count(&glm); + ju = jupe_memory_count(&jum); + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Glines %d(%zu) Jupes %d(%zu)", gl, glm, ju, jum); + + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Hash: client %d(%zu), chan is the same", HASHSIZE, + sizeof(void *) * HASHSIZE); + + count_listener_memory(&listeners, &listenersm); + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Listeners allocated %d(%zu)", listeners, listenersm); /* * NOTE: this count will be accurate only for the exact instant that this * message is being sent, so the count is affected by the dbufs that @@ -466,147 +367,29 @@ void count_memory(aClient *cptr, char *nick) * are sent. */ dbuf_count_memory(&dbufs_allocated, &dbufs_used); - sendto_one(cptr, - ":%s %d %s :DBufs allocated %d(" SIZE_T_FMT ") used %d(" SIZE_T_FMT ")", - me.name, RPL_STATSDEBUG, nick, DBufAllocCount, dbufs_allocated, - DBufUsedCount, dbufs_used); + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":DBufs allocated %d(%zu) used %d(%zu)", DBufAllocCount, + dbufs_allocated, DBufUsedCount, dbufs_used); + + /* The DBuf caveats now count for this, but this routine now sends + * replies all on its own. + */ + msgq_count_memory(cptr, &msg_allocated, &msgbuf_allocated); rm = cres_mem(cptr); tot = - totww + totch + totcl + com + cl * sizeof(aConfClass) + dbufs_allocated + - rm; + totww + totch + totcl + com + cl * sizeof(struct ConnectionClass) + + dbufs_allocated + msg_allocated + msgbuf_allocated + rm; tot += sizeof(void *) * HASHSIZE * 3; - sendto_one(cptr, ":%s %d %s :Total: ww " SIZE_T_FMT " ch " SIZE_T_FMT - " cl " SIZE_T_FMT " co " SIZE_T_FMT " db " SIZE_T_FMT, - me.name, RPL_STATSDEBUG, nick, totww, totch, totcl, com, dbufs_allocated); - return; -} - -#ifdef MSGLOG_ENABLED - -/* Define here what level of messages you want to log */ -#define LOG_MASK_LEVEL LEVEL_MODE /* This that change some data */ - -static struct log_entry log_table[MSGLOG_SIZE]; - -static int unused_log_entries = MSGLOG_SIZE; -static int last_log_entry = -1; /* Nothing stored yet */ -static int entry_stored_forlog = 0; /* Just a flag */ - -/* - * RollBackMsgLog - * - * Just a little utility function used to retract - * an half stored Message log entry - */ -void RollBackMsgLog(void) -{ - /* We won't log this, abort and free the entry */ - last_log_entry--; - unused_log_entries++; - return; -} - -/* - * Log_Message (macroed as LogMessage) - * - * Permanently stores a log entry into the recent log memory area - * Store_Buffer MUST have been called before calling Log_Message - */ -void Log_Message(aClient *sptr, int msgclass) -{ - register int n = last_log_entry; - - /* Clear our flag, since we are going to - * finish the processing of this entry */ - entry_stored_forlog = 0; - - /* Check if the level of this message is high enough */ - if (msgclass < LOG_MASK_LEVEL) - { - RollBackMsgLog(); - return; - } - - /* Check if we wanna log the type of connection from - * where this message did come from */ - if (!((0x8000 >> (8 + log_table[n].cptr_status)) & LOG_MASK_TYPE)) - { - RollBackMsgLog(); - return; - } - - /* Complete the entry */ - if (sptr) - { - log_table[n].sptr_status = sptr->status; - strncpy(log_table[n].sptr_name, sptr->name, HOSTLEN); - log_table[n].sptr_name[HOSTLEN] = '\0'; - strncpy(log_table[n].sptr_yxx, sptr->yxx, 4); - log_table[n].sptr = sptr; - - if (sptr->from) - { - strncpy(log_table[n].sptr_from_name, sptr->name, HOSTLEN); - log_table[n].sptr_from_name[HOSTLEN] = '\0'; - } - else - { - memset(log_table[n].sptr_from_name, 0, HOSTLEN); - } - } - else - { - log_table[n].sptr_status = 0xFF; /* Dummy value */ - memset(&log_table[n].sptr_name, 0, HOSTLEN); - memset(log_table[n].sptr_yxx, 0, 4); +#if defined(MDEBUG) + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Allocations: %zu(%zu)", + fda_get_block_count(), fda_get_byte_count()); +#endif - log_table[n].sptr = 0; - memset(&log_table[n].sptr_from_name, 0, HOSTLEN); - } + send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":Total: ww %zu ch %zu cl %zu co %zu db %zu ms %zu mb %zu", + totww, totch, totcl, com, dbufs_allocated, msg_allocated, + msgbuf_allocated); } - -/* - * Store_Buffer (macroed as StoreBuffer) - * - * Saves the buffer and cptr info at the very first stage - * of parsing, if Log_Message doesn't get called between - * two Store_Buffer calls this function assumes that the parser - * has rejected the message and therefore calls Log_Message - * as if the message class was 0 and the sptr null - */ -void Store_Buffer(char *buf, aClient *cptr) -{ - register int n; - - /* Check if we have an entry pending, if so - * complete it's processing */ - if (entry_stored_forlog) - Log_Message((aClient *)NULL, 0); - - /* Update the "half used entry" flag */ - entry_stored_forlog = 1; - - /* First update the free entries counter */ - if (unused_log_entries) - unused_log_entries--; - - /* Get an entry */ - n = (last_log_entry + 1) % MSGLOG_SIZE; - - /* Update the last_log_entry index */ - last_log_entry = n; - - /* Store what we have by now in it */ - log_table[n].cptr_status = cptr->status; - strncpy(log_table[n].cptr_name, cptr->name, HOSTLEN); - log_table[n].cptr_name[HOSTLEN] = '\0'; - strncpy(log_table[n].cptr_yxx, cptr->yxx, 4); - log_table[n].cptr_fd = cptr->fd; - log_table[n].cptr = cptr; /* No checking for this, is lossy */ - strncpy(log_table[n].buffer, buf, 511); -} - -#endif /* MSGLOG_ENABLED */