* CMDDESC: Displays information about a user.
* CMDFUNC: csu_dowhois
* CMDPROTO: int csu_dowhois(void *source, int cargc, char **cargv);
+ * CMDHELP: Usage: WHOIS <user>
+ * CMDHELP: Displays information about a user, where:
+ * CMDHELP: user - user to request information for, either the nickname of an active user on
+ * CMDHELP: the network or #accountname.
*/
#include "../chanserv.h"
#include "../../lib/irc_string.h"
+#include "../../lib/strlfunc.h"
+#include "../../lib/ccassert.h"
#include <stdio.h>
#include <string.h>
int csu_dowhois(void *source, int cargc, char **cargv) {
nick *sender=source;
- reguser *rup=getreguserfromnick(sender), *target;
+ reguser *rup, *target;
char buf[200];
char nbpos=0;
- nicklist *nlp;
- struct tm *tmp;
regchanuser *rcup, *rcup2;
flag_t flagmask, flags;
int doneheader=0;
+ authname *anp;
+ nick *tnp;
+
+ CCASSERT(sizeof(buf) > TIMELEN);
if (!(rup=getreguserfromnick(sender)))
return CMD_ERROR;
}
if (!(target=findreguser(sender, cargv[0]))) {
- nick* np;
+ nick *np;
- if ((np=getnickbynick(cargv[0]))) {
- activeuser* aup=getactiveuserfromnick(np);
+ if (cs_privcheck(QPRIV_VIEWFULLWHOIS, sender) && (np=getnickbynick(cargv[0]))) {
+ activeuser *aup=getactiveuserfromnick(np);
chanservsendmessage(sender, "%s has attempted to auth %d time%s.", np->nick, aup->authattempts,
aup->authattempts==1?"":"s");
}
}
if (cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) {
- flagmask=QUFLAG_ALL;
+ flagmask=QUFLAG_ALL & ~(QUFLAG_SUSPENDED | QUFLAG_GLINE | QUFLAG_DELAYEDGLINE);
+ if (UIsDev(rup))
+ flagmask=QUFLAG_ALL;
+
+ if (UHasSuspension(target)) {
+ char expiresbuf[100];
+ char *reason, *suspendtype, *whom;
+
+ CCASSERT(sizeof(expiresbuf) > TIMELEN);
+
+ if(UIsDelayedGline(target)) {
+ suspendtype = "delayed gline";
+ } else if(UIsGline(target)) {
+ suspendtype = "gline";
+ } else if(UIsSuspended(target)) {
+ suspendtype = "suspended";
+ } else {
+ suspendtype = "???";
+ }
+
+ if(target->suspendexp) {
+ if(time(NULL) >= target->suspendexp) {
+ strlcpy(expiresbuf, "(next auth)", sizeof(expiresbuf));
+ } else {
+ q9strftime(expiresbuf, sizeof(expiresbuf), target->suspendexp);
+ }
+ } else {
+ strlcpy(expiresbuf, "(never)", sizeof(expiresbuf));
+ }
+
+ if(cs_privcheck(QPRIV_VIEWSUSPENDEDBY, sender)) {
+ reguser *trup = findreguserbyID(target->suspendby);
+ if(trup) {
+ whom = trup->username;
+ } else {
+ whom = "(unknown)";
+ }
+ } else {
+ whom = "(hidden)";
+ }
+
+ if(target->suspendreason && target->suspendreason->content) {
+ reason = target->suspendreason->content;
+ } else {
+ reason = "(none)";
+ }
+
+ chanservstdmessage(sender, QM_USERSUSPENDEDTYPE, suspendtype);
+ chanservstdmessage(sender, QM_USERSUSPENDEDBY, whom);
+ chanservstdmessage(sender, QM_USERSUSPENDEDREASON, reason);
+ chanservstdmessage(sender, QM_USERSUSPENDEDAT, target->suspendtime);
+ chanservstdmessage(sender, QM_USERSUSPENDEDEXPIRY, expiresbuf);
+ }
} else {
+ /* Incidentally none of the QM_USERIS* mesages take parameters. Just thought I'd mention it.. */
if (UIsAdmin(target))
chanservstdmessage(sender, QM_USERISADMIN, target->username);
else if (UIsOper(target))
chanservstdmessage(sender, QM_USERISOPER, target->username);
else if (UIsHelper(target))
chanservstdmessage(sender, QM_USERISHELPER, target->username);
+ else if (UIsStaff(target))
+ chanservstdmessage(sender, QM_USERISSTAFF, target->username);
if (UIsDev(target))
chanservstdmessage(sender, QM_USERISDEV, target->username);
}
if (rup==target)
- flagmask|=(QUFLAG_OPER | QUFLAG_DEV | QUFLAG_HELPER |
- QUFLAG_ADMIN | QUFLAG_INFO | QUFLAG_NOTICE);
+ flagmask|=(QUFLAG_OPER | QUFLAG_DEV | QUFLAG_HELPER | QUFLAG_ADMIN |
+ QUFLAG_INFO | QUFLAG_NOTICE | QUFLAG_STAFF | QUFLAG_ACHIEVEMENTS);
if (flagmask & target->flags)
- chanservstdmessage(sender, QM_WHOIS_FLAGS, printflags(flagmask & target->flags, ruflags));
+ chanservstdmessage(sender, QM_WHOIS_FLAGS, printflagsornone(flagmask & target->flags, ruflags));
- if (!target->nicks) {
+ if (!(anp=findauthname(target->ID)) || !anp->nicks) {
chanservstdmessage(sender, QM_WHOIS_USERS, "(none)");
} else {
- for (nlp=target->nicks; ;nlp=nlp->next) {
- if (nbpos>0 && (!nlp || nbpos+strlen(nlp->np->nick) > 60)) {
+ for (tnp=anp->nicks; ;tnp=tnp->nextbyauthname) {
+ if (nbpos>0 && (!tnp || nbpos+strlen(tnp->nick) > 60)) {
chanservstdmessage(sender, QM_WHOIS_USERS, buf);
nbpos=0;
}
- if (!nlp)
+ if (!tnp)
break;
- nbpos+=sprintf(buf+nbpos,"%s ",nlp->np->nick);
+ nbpos+=sprintf(buf+nbpos,"%s ",tnp->nick);
}
}
- if (target->created) {
- tmp=gmtime(&(target->created));
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
-
- chanservstdmessage(sender, QM_WHOIS_CREATED, buf);
- }
-
- tmp=gmtime(&(target->lastauth));
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
+ if (target->created)
+ chanservstdmessage(sender, QM_WHOIS_CREATED, target->created);
+ if (target->lastauth == 0) {
+ snprintf(buf,sizeof(buf),"(never)");
+ } else {
+ q9strftime(buf,sizeof(buf),target->lastauth);
+ }
chanservstdmessage(sender, QM_WHOIS_LASTAUTH, buf);
- if (target->lastuserhost && (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender))) {
+ /* The third clause of this hides user@host of opers from non-opered staff. */
+ if (target->lastuserhost && (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender)) &&
+ (!UHasOperPriv(target) || UHasOperPriv(rup)) ) {
+/* Commenting out language until we implement some - splidge
chanservstdmessage(sender, QM_WHOIS_USERLANG, cslanguages[target->languageid] ?
- cslanguages[target->languageid]->name->content : "(unknown)");
+ cslanguages[target->languageid]->name->content : "(unknown)"); */
chanservstdmessage(sender, QM_WHOIS_LASTUSERHOST, target->lastuserhost->content);
}
if (target->email && (rup==target || cs_privcheck(QPRIV_VIEWEMAIL, sender))) {
chanservstdmessage(sender, QM_WHOIS_EMAIL, target->email->content);
- tmp=gmtime(&(target->lastemailchange));
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
-
- chanservstdmessage(sender, QM_WHOIS_EMAILSET, buf);
+ if (target->lastemailchange)
+ chanservstdmessage(sender, QM_WHOIS_EMAILSET, target->lastemailchange);
+ if (target->lastpasschange)
+ chanservstdmessage(sender, QM_WHOIS_PASSSET, target->lastpasschange);
}
- if (target->info) {
+ if (target->info && *target->info->content) {
chanservstdmessage(sender, QM_WHOIS_INFO, target->info->content);
}
}
for (rcup=target->knownon;rcup;rcup=rcup->nextbyuser) {
- if (!UHasHelperPriv(rup)) {
+ if (!UHasHelperPriv(rup) || (UHasOperPriv(target) && UHasHelperPriv(rup) && !UHasOperPriv(rup))) {
if (!(rcup2=findreguseronchannel(rcup->chan,rup)))
continue;
- if (!CUHasVoicePriv(rcup2))
+ if (!CUKnown(rcup2))
continue;
flagmask = (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOVOICE |
- QCUFLAG_AUTOOP | QCUFLAG_TOPIC);
+ QCUFLAG_AUTOOP | QCUFLAG_TOPIC | QCUFLAG_KNOWN | QCUFLAG_PROTECT );
if (CUHasMasterPriv(rcup2))
- flagmask |= (QCUFLAG_DENY | QCUFLAG_QUIET | QCUFLAG_BANNED);
+ flagmask |= QCUFLAGS_PUNISH;
+
+ if (rcup2==rcup)
+ flagmask |= QCUFLAGS_PERSONAL;
} else {
flagmask=QCUFLAG_ALL;
}
chanservstdmessage(sender, QM_ENDOFLIST);
+ if (rup==target) {
+ triggerhook(HOOK_CHANSERV_WHOAMI, sender);
+ } else {
+ triggerhook(HOOK_CHANSERV_WHOIS, sender);
+ }
+
return CMD_OK;
}