X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc-server.c;h=317a3e1a1bf99c8379cb20e83419684024c262af;hp=e85e9beda214a0dd77bf4fc367007503fb6a57fd;hb=3f7caff630d3268beb657dfc0f2662fd5b567dcd;hpb=b130b35f48d19450240748425e12d21f2c38350f diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index e85e9bed..317a3e1a 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,10 +31,13 @@ #include "parse.h" #include "numeric.h" #include "ngircd.h" +#include "irc.h" #include "irc-info.h" #include "irc-write.h" #include "op.h" +#include "irc-server.h" + /** * Handler for the IRC "SERVER" command. * @@ -243,66 +246,96 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req ) CHANNEL *chan; CLIENT *c; - assert( Client != NULL ); - assert( Req != NULL ); + assert(Client != NULL); + assert(Req != NULL); - strlcpy( nick_in, Req->argv[1], sizeof( nick_in )); - strcpy( nick_out, "" ); + strlcpy(nick_in, Req->argv[1], sizeof(nick_in)); + strcpy(nick_out, ""); channame = Req->argv[0]; - ptr = strtok( nick_in, "," ); - while( ptr ) - { + + ptr = strtok(nick_in, ","); + while (ptr) { is_owner = is_chanadmin = is_op = is_halfop = is_voiced = false; /* cut off prefixes */ - while(( *ptr == '~') || ( *ptr == '&' ) || ( *ptr == '@' ) || - ( *ptr == '%') || ( *ptr == '+' )) - { - if( *ptr == '~' ) is_owner = true; - if( *ptr == '&' ) is_chanadmin = true; - if( *ptr == '@' ) is_op = true; - if( *ptr == 'h' ) is_halfop = true; - if( *ptr == '+' ) is_voiced = true; + while ((*ptr == '~') || (*ptr == '&') || (*ptr == '@') || + (*ptr == '%') || (*ptr == '+')) { + if (*ptr == '~') + is_owner = true; + if (*ptr == '&') + is_chanadmin = true; + if (*ptr == '@') + is_op = true; + if (*ptr == '%') + is_halfop = true; + if (*ptr == '+') + is_voiced = true; ptr++; } - c = Client_Search( ptr ); - if( c ) - { - Channel_Join( c, channame ); - chan = Channel_Search( channame ); - assert( chan != NULL ); - - if( is_owner ) Channel_UserModeAdd( chan, c, 'q' ); - if( is_chanadmin ) Channel_UserModeAdd( chan, c, 'a' ); - if( is_op ) Channel_UserModeAdd( chan, c, 'o' ); - if( is_halfop ) Channel_UserModeAdd( chan, c, 'h' ); - if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' ); - - /* announce to channel... */ - IRC_WriteStrChannelPrefix( Client, chan, c, false, "JOIN :%s", channame ); - - /* set Channel-User-Modes */ - strlcpy( modes, Channel_UserModes( chan, c ), sizeof( modes )); - if( modes[0] ) - { - /* send modes to channel */ - IRC_WriteStrChannelPrefix( Client, chan, Client, false, "MODE %s +%s %s", channame, modes, Client_ID( c )); - } + c = Client_Search(ptr); + if (!c) { + /* Client not found? */ + Log(LOG_ERR, + "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", + ptr, channame); + goto skip_njoin; + } - if( nick_out[0] != '\0' ) strlcat( nick_out, ",", sizeof( nick_out )); - if( is_owner ) strlcat( nick_out, "~", sizeof( nick_out )); - if( is_chanadmin ) strlcat( nick_out, "&", sizeof( nick_out )); - if( is_op ) strlcat( nick_out, "@", sizeof( nick_out )); - if( is_halfop ) strlcat( nick_out, "%", sizeof( nick_out )); - if( is_voiced ) strlcat( nick_out, "+", sizeof( nick_out )); - strlcat( nick_out, ptr, sizeof( nick_out )); + if (!Channel_Join(c, channame)) { + /* Failed to join channel. Ooops!? */ + Log(LOG_ALERT, + "Failed to join client \"%s\" to channel \"%s\" (NJOIN): killing it!", + ptr, channame); + IRC_KillClient(NULL, NULL, ptr, "Internal NJOIN error!"); + Log(LOG_DEBUG, "... done."); + goto skip_njoin; } - else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame ); - /* search for next Nick */ - ptr = strtok( NULL, "," ); + chan = Channel_Search(channame); + assert(chan != NULL); + + if (is_owner) + Channel_UserModeAdd(chan, c, 'q'); + if (is_chanadmin) + Channel_UserModeAdd(chan, c, 'a'); + if (is_op) + Channel_UserModeAdd(chan, c, 'o'); + if (is_halfop) + Channel_UserModeAdd(chan, c, 'h'); + if (is_voiced) + Channel_UserModeAdd(chan, c, 'v'); + + /* Announce client to the channel */ + IRC_WriteStrChannelPrefix(Client, chan, c, false, + "JOIN :%s", channame); + + /* Announce "channel user modes" to the channel, if any */ + strlcpy(modes, Channel_UserModes(chan, c), sizeof(modes)); + if (modes[0]) + IRC_WriteStrChannelPrefix(Client, chan, Client, false, + "MODE %s +%s %s", channame, + modes, Client_ID(c)); + + /* Build nick list for forwarding command */ + if (nick_out[0] != '\0') + strlcat(nick_out, ",", sizeof(nick_out)); + if (is_owner) + strlcat(nick_out, "~", sizeof(nick_out)); + if (is_chanadmin) + strlcat(nick_out, "&", sizeof(nick_out)); + if (is_op) + strlcat(nick_out, "@", sizeof(nick_out)); + if (is_halfop) + strlcat(nick_out, "%", sizeof(nick_out)); + if (is_voiced) + strlcat(nick_out, "+", sizeof(nick_out)); + strlcat(nick_out, ptr, sizeof(nick_out)); + + skip_njoin: + /* Get next nick, if any ... */ + ptr = strtok(NULL, ","); } /* forward to other servers */