X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/91f165edc0ea333e74409bc0b2cac7aae3e4a268..78546f2b0f59b5c8fede1ce5535972716eb17041:/channel/channelhandlers.c diff --git a/channel/channelhandlers.c b/channel/channelhandlers.c index 649c6dbd..19faac26 100644 --- a/channel/channelhandlers.c +++ b/channel/channelhandlers.c @@ -212,7 +212,7 @@ int handleburstmsg(void *source, int cargc, char **cargv) { int handlejoinmsg(void *source, int cargc, char **cargv) { char *pos,*nextchan; nick *np; - void *harg[2]; + void *harg[3]; channel *cp,**ch; long timestamp=0; int i; @@ -230,7 +230,7 @@ int handlejoinmsg(void *source, int cargc, char **cargv) { /* Find out who we are talking about here */ np=getnickbynumericstr(source); if (np==NULL) { - Error("channel",ERR_WARNING,"Channel join from non existent user %s",source); + Error("channel",ERR_WARNING,"Channel join from non existent user %s",(char *)source); return CMD_OK; } @@ -257,6 +257,7 @@ int handlejoinmsg(void *source, int cargc, char **cargv) { /* Send hook */ harg[0]=ch[i]; harg[1]=np; + harg[2]=NULL; triggerhook(HOOK_CHANNEL_PART,harg); delnickfromchannel(ch[i],np->numeric,0); } @@ -283,16 +284,23 @@ int handlejoinmsg(void *source, int cargc, char **cargv) { if (newchan) { delchannel(cp); } - } else { + } else { + chanindex *cip=cp->index; + /* If we just created a channel, flag it */ if (newchan) { triggerhook(HOOK_CHANNEL_NEWCHANNEL,cp); } - - /* send hook */ - harg[0]=cp; - harg[1]=np; - triggerhook(HOOK_CHANNEL_JOIN,harg); + + /* Don't send HOOK_CHANNEL_JOIN if the channel doesn't exist any + * more (can happen if something destroys it in response to + * HOOK_CHANNEL_NEWCHANNEL) */ + if (cp == cip->channel) { + /* send hook */ + harg[0]=cp; + harg[1]=np; + triggerhook(HOOK_CHANNEL_JOIN,harg); + } } } nextchan=pos; @@ -317,7 +325,7 @@ int handlecreatemsg(void *source, int cargc, char **cargv) { /* Find out who we are talking about here */ np=getnickbynumericstr(source); if (np==NULL) { - Error("channel",ERR_WARNING,"Channel create from non existent user %s",source); + Error("channel",ERR_WARNING,"Channel create from non existent user %s",(char *)source); return CMD_OK; } @@ -354,16 +362,22 @@ int handlecreatemsg(void *source, int cargc, char **cargv) { if (newchan) { delchannel(cp); } - } else { + } else { + chanindex *cip = cp->index; + /* Flag the channel as new if necessary */ if (newchan) { triggerhook(HOOK_CHANNEL_NEWCHANNEL,cp); } - /* Trigger hook */ - harg[0]=cp; - harg[1]=np; - triggerhook(HOOK_CHANNEL_CREATE,harg); + /* If HOOK_CHANNEL_NEWCHANNEL has caused the channel to be deleted, + * don't trigger the CREATE hook. */ + if (cip->channel == cp) { + /* Trigger hook */ + harg[0]=cp; + harg[1]=np; + triggerhook(HOOK_CHANNEL_CREATE,harg); + } } nextchan=pos; } @@ -394,7 +408,7 @@ int handlepartmsg(void *source, int cargc, char **cargv) { /* Find out who we are talking about here */ np=getnickbynumericstr(source); if (np==NULL) { - Error("channel",ERR_WARNING,"PART from non existent numeric %s",source); + Error("channel",ERR_WARNING,"PART from non existent numeric %s",(char *)source); return CMD_OK; } @@ -441,7 +455,7 @@ int handlekickmsg(void *source, int cargc, char **cargv) { /* Find out who we are talking about here */ if ((np=getnickbynumericstr(cargv[1]))==NULL) { - Error("channel",ERR_DEBUG,"Non-existant numeric %s kicked from channel %s",source,cargv[0]); + Error("channel",ERR_DEBUG,"Non-existant numeric %s kicked from channel %s",(char *)source,cargv[0]); return CMD_OK; } @@ -494,10 +508,15 @@ int handletopicmsg(void *source, int cargc, char **cargv) { if (cargc>3) timestamp=strtol(cargv[cargc-3], NULL, 10); - if ((np=getnickbynumericstr((char *)source))==NULL) { + np=getnickbynumericstr((char *)source); + + /* The following check removed because servers can set topics.. */ +#if 0 + if (np==NULL) { /* We should check the sender exists, but we still change the topic even if it doesn't */ Error("channel",ERR_WARNING,"Topic change by non-existent user %s",(char *)source); } +#endif /* Grab channel pointer */ if ((cp=findchannel(cargv[0]))==NULL) { @@ -544,11 +563,11 @@ int handlemodemsg(void *source, int cargc, char **cargv) { int arg=2; char *modestr; unsigned long *lp; - void *harg[3]; + void *harg[4]; nick *np, *target; int hooknum; int changes=0; - + if (cargc<2) { return CMD_OK; } @@ -575,6 +594,7 @@ int handlemodemsg(void *source, int cargc, char **cargv) { /* Set up the hook data */ harg[0]=cp; harg[1]=np; + harg[3]=(void *)(long)(cp->flags); /* Process the mode string one character at a time */ /* Maybe I'll write this more intelligently one day if I can comprehend the ircu code that does this */ @@ -652,6 +672,16 @@ int handlemodemsg(void *source, int cargc, char **cargv) { changes |= MODECHANGE_MODES; break; + case 'M': + if (dir) { SetModNoAuth(cp); } else { ClearModNoAuth(cp); } + changes |= MODECHANGE_MODES; + break; + + case 'T': + if (dir) { SetSingleTarg(cp); } else { ClearSingleTarg(cp); } + changes |= MODECHANGE_MODES; + break; + /* Parameter modes: advance parameter and possibly read it in */ case 'l': @@ -733,7 +763,7 @@ int handlemodemsg(void *source, int cargc, char **cargv) { } } - harg[2]=(void *)changes; + harg[2]=(void *)((long)changes); triggerhook(HOOK_CHANNEL_MODECHANGE,(void *)harg); return CMD_OK; } @@ -746,7 +776,7 @@ int handlemodemsg(void *source, int cargc, char **cargv) { int handleclearmodemsg(void *source, int cargc, char **cargv) { channel *cp; - void *harg[3]; + void *harg[4]; nick *np, *target; char *mcp; unsigned long usermask=0; @@ -773,7 +803,8 @@ int handleclearmodemsg(void *source, int cargc, char **cargv) { harg[0]=cp; harg[1]=np; - + harg[3]=(void *)(long)(cp->flags); + for (mcp=cargv[1];*mcp;mcp++) { switch (*mcp) { case 'o': @@ -845,6 +876,16 @@ int handleclearmodemsg(void *source, int cargc, char **cargv) { ClearNoNotice(cp); changes |= MODECHANGE_MODES; break; + + case 'M': + ClearModNoAuth(cp); + changes |= MODECHANGE_MODES; + break; + + case 'T': + ClearSingleTarg(cp); + changes |= MODECHANGE_MODES; + break; case 'b': clearallbans(cp); @@ -889,56 +930,70 @@ int handleclearmodemsg(void *source, int cargc, char **cargv) { } } - harg[2]=(void *)changes; + harg[2]=(void *)((long)changes); triggerhook(HOOK_CHANNEL_MODECHANGE, harg); return CMD_OK; } void handlewhoischannels(int hooknum, void *arg) { - channel** chans; + channel **chans; char buffer[1024]; - sstring* name; - unsigned long* num; + unsigned int bufpos; + sstring *name; + unsigned long *num; int i; - void **args = (void **)arg; - nick *sender = (nick *)args[0], *target = (nick *)args[1]; - - if(IsService(target) || IsHideChan(target)) + char **args = (char **)arg; + nick *sender = (nick *)args[0]; /* sender nick */ + nick *target = (nick *)args[1]; /* target nick */ + char *sourcenum = args[2]; /* source numeric */ + + /* do not show channels for +k service clients or IRC Operators + * do not show channels for +n users + * unless they whois themselves + */ + if ((IsService(target) || IsHideChan(target)) && sender != target) return; chans = (channel **)(target->channels->content); buffer[0] = '\0'; - + bufpos=0; + /* Not handling delayed joins. */ - for(i=0;ichannels->cursi;i++) { - if(IsSecret(chans[i]) || IsPrivate(chans[i])) { /* check common channels */ - int j; - channel **senderchans = (channel **)(sender->channels->content); - for(j=0;jchannels->cursi;j++) - if(senderchans[j] == chans[i]) - break; - if(j == sender->channels->cursi) + for(i=target->channels->cursi-1;i>=0;i--) { + /* Secret / Private channels: only show if the sender is on the channel as well */ + if(IsSecret(chans[i]) || IsPrivate(chans[i])) { + if (!getnumerichandlefromchanhash(chans[i]->users, sender->numeric)) continue; } + name = chans[i]->index->name; - if (strlen(buffer) + name->length > 508) { /* why 508? */ + if (bufpos + name->length > 508) { /* why 508? - need room for -@#channame\0 + 1 slack */ irc_send("%s", buffer); buffer[0] = '\0'; + bufpos=0; } + /* + * 319 RPL_WHOISCHANNELS "source 319 target nick :channels" + * "irc.netsplit.net 319 foobar barfoo :@#chan1 +#chan2 #chan3" + * "irc.netsplit.net 319 foobar barfoo :-@#chan1 -+#chan2 -#chan3" + */ if(buffer[0] == '\0') - snprintf(buffer, sizeof(buffer), ":%s 319 %s %s :", myserver->content, sender->nick, target->nick); - else - strlcat(buffer, " ", sizeof(buffer)); + bufpos=snprintf(buffer, sizeof(buffer), "%s 319 %s %s :", getmynumeric(), sourcenum, target->nick); num = getnumerichandlefromchanhash(chans[i]->users, target->numeric); + + /* Adding these flags might make the string "unsafe" (without terminating \0). */ + /* sprintf'ing the channel name afterwards is guaranteed to fix it though */ + if (IsDeaf(target)) + buffer[bufpos++]='-'; if (*num & CUMODE_OP) - strlcat(buffer, "@", sizeof(buffer)); + buffer[bufpos++]='@'; else if (*num & CUMODE_VOICE) - strlcat(buffer, "+", sizeof(buffer)); + buffer[bufpos++]='+'; - strlcat(buffer, name->content, sizeof(buffer)); + bufpos += sprintf(buffer+bufpos, "%s ",name->content); } if (buffer[0] != '\0')