diff --git a/include/client.h b/include/client.h index 5ed61a7f..25fac62a 100644 --- a/include/client.h +++ b/include/client.h @@ -93,7 +93,7 @@ typedef unsigned long flagpage_t; #define FlagClr(set,flag) ((set)->bits[FLAGSET_INDEX(flag)] &= ~FLAGSET_MASK(flag)) /** String containing valid user modes, in no particular order. */ -#define infousermodes "diOoswkgx" +#define infousermodes "diOoswkgxI" /** Operator privileges. */ enum Priv @@ -171,9 +171,10 @@ enum Flag FLAG_ACCOUNT, /**< account name has been set */ FLAG_HIDDENHOST, /**< user's host is hidden */ FLAG_CAP302, /**< client supports IRCv3.2 */ - FLAG_LAST_FLAG, /**< number of flags */ + FLAG_HIDEIDLE, /**< Hide idle time from non-opers */ FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */ - FLAG_GLOBAL_UMODES = FLAG_OPER /**< First global mode flag */ + FLAG_GLOBAL_UMODES = FLAG_OPER, /**< First global mode flag */ + FLAG_LAST_FLAG /**< number of flags */ }; /** Declare flagset type for operator privileges. */ @@ -612,6 +613,8 @@ struct Client { #define IsAccount(x) HasFlag(x, FLAG_ACCOUNT) /** Return non-zero if the client has set mode +x (hidden host). */ #define IsHiddenHost(x) HasFlag(x, FLAG_HIDDENHOST) +/** Return non-zero if the client has set mode +I (hide idle time). */ +#define IsHideIdle(x) HasFlag(x, FLAG_HIDEIDLE) /** Return non-zero if the client has an active PING request. */ #define IsPingSent(x) HasFlag(x, FLAG_PINGSENT) @@ -658,6 +661,8 @@ struct Client { #define SetAccount(x) SetFlag(x, FLAG_ACCOUNT) /** Mark a client as having mode +x (hidden host). */ #define SetHiddenHost(x) SetFlag(x, FLAG_HIDDENHOST) +/** Mark a client as having mode +I (hide idle time). */ +#define SetHideIdle(x) SetFlag(x, FLAG_HIDEIDLE) /** Mark a client as having a pending PING. */ #define SetPingSent(x) SetFlag(x, FLAG_PINGSENT) @@ -691,6 +696,8 @@ struct Client { #define ClearServNotice(x) ClrFlag(x, FLAG_SERVNOTICE) /** Remove mode +x (hidden host) from the client. */ #define ClearHiddenHost(x) ClrFlag(x, FLAG_HIDDENHOST) +/** Remove mode +I (hide idle time) from the client. */ +#define ClearHideIdle(x) ClrFlag(x, FLAG_HIDEIDLE) /** Clear the client's pending PING flag. */ #define ClearPingSent(x) ClrFlag(x, FLAG_PINGSENT) /** Clear the client's HUB flag. */ diff --git a/ircd/m_whois.c b/ircd/m_whois.c index 09664614..8cc87214 100644 --- a/ircd/m_whois.c +++ b/ircd/m_whois.c @@ -223,7 +223,8 @@ static void do_whois(struct Client* sptr, struct Client *acptr, int parc) */ if (MyConnect(acptr) && (!feature_bool(FEAT_HIS_WHOIS_IDLETIME) || - (sptr == acptr || IsAnOper(sptr) || parc >= 3))) + (sptr == acptr || IsAnOper(sptr) || parc >= 3)) + && (!IsHideIdle(acptr) || sptr == acptr || IsAnOper(sptr))) send_reply(sptr, RPL_WHOISIDLE, name, CurrentTime - user->last, cli_firsttime(acptr)); if (MyConnect(acptr) diff --git a/ircd/s_user.c b/ircd/s_user.c index 13c61cb1..2fdb7fe4 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -499,7 +499,8 @@ static const struct UserMode { { FLAG_CHSERV, 'k' }, { FLAG_DEBUG, 'g' }, { FLAG_ACCOUNT, 'r' }, - { FLAG_HIDDENHOST, 'x' } + { FLAG_HIDDENHOST, 'x' }, + { FLAG_HIDEIDLE, 'I' } }; /** Length of #userModeList. */ @@ -1085,6 +1086,12 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, } /* There is no -r */ break; + case 'I': + if (what == MODE_ADD) + SetHideIdle(sptr); + else + ClearHideIdle(sptr); + break; default: send_reply(sptr, ERR_UMODEUNKNOWNFLAG, *m); break; diff --git a/ircd/whocmds.c b/ircd/whocmds.c index 0b166ba0..b441fbf1 100644 --- a/ircd/whocmds.c +++ b/ircd/whocmds.c @@ -227,7 +227,8 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan, *p1++ = ' '; if (MyUser(acptr) && (IsAnOper(sptr) || !feature_bool(FEAT_HIS_WHO_SERVERNAME) || - acptr == sptr)) + acptr == sptr) && + (!IsHideIdle(acptr) || sptr == acptr || IsAnOper(sptr))) p1 += ircd_snprintf(0, p1, 11, "%d", CurrentTime - cli_user(acptr)->last); else