X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc-server.c;h=317a3e1a1bf99c8379cb20e83419684024c262af;hb=543f44bff8d56785dc13a74a14d4eaa96465bf05;hp=b0abb7cdf2622cac13792c4a2c708baeeaa12e48;hpb=62865f7e1910d08ad8d72cb89f830f6d9411ffa2;p=ngircd-alex.git diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index b0abb7cd..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 @@ -16,31 +16,26 @@ * IRC commands for server links */ -#include "imp.h" #include #include #include #include #include -#include "defines.h" -#include "conn.h" #include "conn-func.h" #include "conn-zip.h" #include "conf.h" #include "channel.h" -#include "lists.h" #include "log.h" #include "messages.h" #include "parse.h" #include "numeric.h" #include "ngircd.h" +#include "irc.h" #include "irc-info.h" -#include "irc-macros.h" #include "irc-write.h" #include "op.h" -#include "exp.h" #include "irc-server.h" /** @@ -72,12 +67,10 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) LogDebug("Connection %d: got SERVER command (new server link) ...", Client_Conn(Client)); - if (Req->argc != 2 && Req->argc != 3) { - IRC_SetPenalty(Client, 2); + if (Req->argc != 2 && Req->argc != 3) return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); - } /* Get configuration index of new remote server ... */ for (i = 0; i < MAX_SERVERS; i++) @@ -185,11 +178,9 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) { /* New server is being introduced to the network */ - if (Req->argc != 4) { - IRC_SetPenalty(Client, 2); + if (Req->argc != 4) return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); - } /* check for existing server with same ID */ if (!Client_CheckID(Client, Req->argv[0])) @@ -235,11 +226,9 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) Client_MyToken(c), Client_Info(c)); return CONNECTED; - } else { - IRC_SetPenalty(Client, 2); + } else return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); - } } /* IRC_SERVER */ /* @@ -257,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 */