}
}
+ newuser->cloak_count = 0;
+ newuser->cloak_extra = NULL;
+
if (connected) {
/* Check for nick collision */
if ((np=getnickbynick(nickname))!=NULL) {
triggerhook(HOOK_AUTH_FLAGSUPDATED, arg);
}
+
+void localuseraddcloaktarget(nick *np, nick *target) {
+ char snumeric[10], tnumeric[10];
+
+ strcpy(snumeric, longtonumeric(np->numeric,5));
+ strcpy(tnumeric, longtonumeric(target->numeric,5));
+
+ irc_send("%s CA %s", snumeric, tnumeric);
+
+ addcloaktarget(np, target);
+}
+
+void localuserclearcloaktargets(nick *np) {
+ irc_send("%s CU", longtonumeric(np->numeric,5));
+ clearcloaktargets(np);
+}
+
void localusersetumodes(nick *np, flag_t newmodes);
void sethostuser(nick *target, char *ident, char *host);
void localusersetaccountflags(authname *anp, u_int64_t accountflags);
+void localuseraddcloaktarget(nick *np, nick *target);
+void localuserclearcloaktargets(nick *np);
#endif
return;
}
+ if (IsCloaked(target)) {
+ /* Target is cloaked, never set channel modes for cloaked users */
+ return;
+ }
+
if ((modes & MC_DEOP) && (*lp & CUMODE_OP)) {
(*lp) &= ~CUMODE_OP;
if (changes->changecount >= MAXMODEARGS)
* target user is not hidechan (usermode +n)
* OR user WHOIS'ing himself
*/
- if ((!IsService(tnick) && !IsHideChan(tnick)) || snick == tnick) {
+ if ((!IsService(tnick) && !IsHideChan(tnick) && canseeuser(snick, tnick)) || snick == tnick) {
nicks[0] = (char *)snick;
nicks[1] = (char *)tnick;
nicks[2] = sourcenum;
{ 'R', UMODE_REGPRIV },
{ 'I', UMODE_HIDEIDLE },
{ 'P', UMODE_PARANOID },
+ { 'C', UMODE_CLOAKED },
{ '\0', 0 } };
const flag accountflags[] = {
registerserverhandler("AC",&handleaccountmsg,4);
registerserverhandler("P",&handleprivmsg,2);
registerserverhandler("A",&handleawaymsg,1);
+ registerserverhandler("CA",&handleaddcloak,1);
+ registerserverhandler("CU",&handleclearcloak,0);
/* Fake the addition of our own server */
handleserverchange(HOOK_SERVER_NEWSERVER,(void *)numerictolong(mynumeric->content,2));
deregisterserverhandler("AC",&handleaccountmsg);
deregisterserverhandler("P",&handleprivmsg);
deregisterserverhandler("A",&handleawaymsg);
+ deregisterserverhandler("CA",&handleaddcloak);
+ deregisterserverhandler("CU",&handleclearcloak);
}
/*
/* TODO: figure out how to cleanly remove nodes without affecting other modules */
+ /* Remove cloak entries for the user */
+ removecloaktarget(np);
+ clearcloaktargets(np);
+
/* Delete the nick from the servernick table */
*(gethandlebynumericunsafe(np->numeric))=NULL;
#endif
+int canseeuser(nick *np, nick *cloaked)
+{
+ return (np == cloaked ||
+ !IsCloaked(cloaked) ||
+ np->cloak_extra == cloaked);
+}
+
+void addcloaktarget(nick *cloaked, nick *target)
+{
+ removecloaktarget(target);
+
+ target->cloak_extra = cloaked;
+ cloaked->cloak_count++;
+}
+
+void removecloaktarget(nick *target)
+{
+ if (target->cloak_extra) {
+ target->cloak_extra->cloak_count--;
+ target->cloak_extra = NULL;
+ }
+}
+
+void clearcloaktargets(nick *cloaked)
+{
+ nick *tnp;
+ int j;
+
+ for(j=0;j<NICKHASHSIZE;j++)
+ for(tnp=nicktable[j];tnp;tnp=tnp->next)
+ if (tnp->cloak_extra == cloaked)
+ tnp->cloak_extra = NULL;
+
+ cloaked->cloak_count = 0;
+}
+
#define UMODE_REGPRIV 0x0800
#define UMODE_HIDEIDLE 0x1000
#define UMODE_PARANOID 0x2000
+#define UMODE_CLOAKED 0x4000
-#define UMODE_ALL 0x3FFF
+#define UMODE_ALL 0x7FFF
#define AFLAG_STAFF 0x0001
#define AFLAG_SUPPORT 0x0002
#define IsRegPriv(x) ((x)->umodes & UMODE_REGPRIV)
#define IsHideIdle(x) ((x)->umodes & UMODE_HIDEIDLE)
#define IsParanoid(x) ((x)->umodes & UMODE_PARANOID)
+#define IsCloaked(x) ((x)->umodes & UMODE_CLOAKED)
#define SetInvisible(x) ((x)->umodes |= UMODE_INV)
#define SetWallops(x) ((x)->umodes |= UMODE_WALLOPS)
#define SetRegPriv(x) ((x)->umodes |= UMODE_REGPRIV)
#define SetHideIdle(x) ((x)->umodes |= UMODE_HIDEIDLE)
#define SetParanoid(x) ((x)->umodes |= UMODE_PARANOID)
+#define SetCloaked(x) ((x)->umodes |= UMODE_CLOAKED)
#define ClearInvisible(x) ((x)->umodes &= ~UMODE_INV)
#define ClearWallops(x) ((x)->umodes &= ~UMODE_WALLOPS)
#define ClearRegPriv(x) ((x)->umodes &= ~UMODE_REGPRIV)
#define ClearHideIdle(x) ((x)->umodes &= ~UMODE_HIDEIDLE)
#define ClearParanoid(x) ((x)->umodes &= ~UMODE_PARANOID)
+#define ClearCloaked(x) ((x)->umodes &= ~UMODE_CLOAKED)
#define IsStaff(x) ((x)->flags & AFLAG_STAFF)
#define IsDeveloper(x) ((x)->flags & AFLAG_DEVELOPER)
time_t accountts;
sstring *away;
patricia_node_t *ipnode;
+ unsigned int cloak_count;
+ struct nick *cloak_extra;
unsigned int marker;
struct nick *next;
struct nick *nextbyhost;
void releasenickext(int index);
char *visiblehostmask(nick *np, char *buf);
char *visibleuserhost(nick *np, char *buf);
+int canseeuser(nick *np, nick *cloaked);
+void addcloaktarget(nick *cloaked, nick *target);
+void removecloaktarget(nick *target);
+void clearcloaktargets(nick *cloaked);
/* nickhandlers.c functions */
int handlenickmsg(void *source, int cargc, char **cargv);
int handleaccountmsg(void *source, int cargc, char **cargv);
int handleprivmsg(void *source, int cargc, char **cargv);
int handleawaymsg(void *source, int cargc, char **cargv);
+int handleaddcloak(void *source, int cargc, char **cargv);
+int handleclearcloak(void *source, int cargc, char **cargv);
/* These functions have been replaced by macros
nick **gethandlebynumeric(long numeric);
np->authname=NULLAUTHNAME;
np->auth=NULL;
np->accountts=0;
+ np->cloak_count = 0;
+ np->cloak_extra = NULL;
if(cargc>=9) {
int sethostarg = 6, opernamearg = 6, accountarg = 6;
return CMD_OK;
}
+
+int handleaddcloak(void *source, int cargc, char **cargv) {
+ nick *sender, *target;
+
+ /* Check source is a valid user */
+ if (!(sender=getnickbynumericstr(source))) {
+ return CMD_OK;
+ }
+
+ if (cargc < 1)
+ return CMD_OK;
+
+ if (!(target=getnickbynumericstr(cargv[0]))) {
+ return CMD_OK;
+ }
+
+ addcloaktarget(sender, target);
+
+ return CMD_OK;
+}
+
+int handleclearcloak(void *source, int cargc, char **cargv) {
+ nick *sender;
+
+ /* Check source is a valid user */
+ if (!(sender=getnickbynumericstr(source))) {
+ return CMD_OK;
+ }
+
+ clearcloaktargets(sender);
+
+ return CMD_OK;
+}
+