[BACK]Return to irc-op.c CVS log [TXT][DIR] Up to [local] / ircnowd / src / ngircd

Annotation of ircnowd/src/ngircd/irc-op.c, Revision 1.1

1.1     ! tomglok     1: /*
        !             2:  * ngIRCd -- The Next Generation IRC Daemon
        !             3:  * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify
        !             6:  * it under the terms of the GNU General Public License as published by
        !             7:  * the Free Software Foundation; either version 2 of the License, or
        !             8:  * (at your option) any later version.
        !             9:  * Please read the file COPYING, README and AUTHORS for more information.
        !            10:  */
        !            11:
        !            12: #include "portab.h"
        !            13:
        !            14: /**
        !            15:  * @file
        !            16:  * Channel operator commands
        !            17:  */
        !            18:
        !            19: #include <assert.h>
        !            20: #include <string.h>
        !            21:
        !            22: #include "conn.h"
        !            23: #include "channel.h"
        !            24: #include "irc-macros.h"
        !            25: #include "irc-write.h"
        !            26: #include "lists.h"
        !            27: #include "log.h"
        !            28: #include "messages.h"
        !            29: #include "parse.h"
        !            30:
        !            31: #include "irc-op.h"
        !            32:
        !            33: /* Local functions */
        !            34:
        !            35: static bool
        !            36: try_kick(CLIENT *peer, CLIENT* from, const char *nick, const char *channel,
        !            37:         const char *reason)
        !            38: {
        !            39:        CLIENT *target = Client_Search(nick);
        !            40:
        !            41:        if (!target)
        !            42:                return IRC_WriteErrClient(from, ERR_NOSUCHNICK_MSG,
        !            43:                                          Client_ID(from), nick);
        !            44:
        !            45:        Channel_Kick(peer, target, from, channel, reason);
        !            46:        return true;
        !            47: }
        !            48:
        !            49: /* Global functions */
        !            50:
        !            51: /**
        !            52:  * Handler for the IRC command "KICK".
        !            53:  *
        !            54:  * @param Client The client from which this command has been received.
        !            55:  * @param Req Request structure with prefix and all parameters.
        !            56:  * @return CONNECTED or DISCONNECTED.
        !            57:  */
        !            58: GLOBAL bool
        !            59: IRC_KICK(CLIENT *Client, REQUEST *Req)
        !            60: {
        !            61:        CLIENT *from;
        !            62:        char *itemList = Req->argv[0];
        !            63:        const char* currentNick, *currentChannel, *reason;
        !            64:        unsigned int channelCount = 1;
        !            65:        unsigned int nickCount = 1;
        !            66:
        !            67:        assert( Client != NULL );
        !            68:        assert( Req != NULL );
        !            69:
        !            70:        _IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
        !            71:
        !            72:        while (*itemList) {
        !            73:                if (*itemList == ',') {
        !            74:                        *itemList = '\0';
        !            75:                        channelCount++;
        !            76:                }
        !            77:                itemList++;
        !            78:        }
        !            79:
        !            80:        itemList = Req->argv[1];
        !            81:        while (*itemList) {
        !            82:                if (*itemList == ',') {
        !            83:                        *itemList = '\0';
        !            84:                        nickCount++;
        !            85:                }
        !            86:                itemList++;
        !            87:        }
        !            88:
        !            89:        reason = Req->argc == 3 ? Req->argv[2] : Client_ID(from);
        !            90:        currentNick = Req->argv[1];
        !            91:        currentChannel = Req->argv[0];
        !            92:        if (channelCount == 1) {
        !            93:                while (nickCount > 0) {
        !            94:                        if (!try_kick(Client, from, currentNick,
        !            95:                                      currentChannel, reason))
        !            96:                                return false;
        !            97:
        !            98:                        while (*currentNick)
        !            99:                                currentNick++;
        !           100:
        !           101:                        currentNick++;
        !           102:                        nickCount--;
        !           103:                }
        !           104:        } else if (channelCount == nickCount) {
        !           105:                while (nickCount > 0) {
        !           106:                        if (!try_kick(Client, from, currentNick,
        !           107:                                      currentChannel, reason))
        !           108:                                return false;
        !           109:
        !           110:                        while (*currentNick)
        !           111:                                currentNick++;
        !           112:
        !           113:                        while (*currentChannel)
        !           114:                                currentChannel++;
        !           115:
        !           116:                        currentNick++;
        !           117:                        currentChannel++;
        !           118:                        nickCount--;
        !           119:                }
        !           120:        } else {
        !           121:                return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
        !           122:                                        Client_ID(Client), Req->command);
        !           123:        }
        !           124:        return true;
        !           125: } /* IRC_KICK */
        !           126:
        !           127: /**
        !           128:  * Handler for the IRC command "INVITE".
        !           129:  *
        !           130:  * @param Client The client from which this command has been received.
        !           131:  * @param Req Request structure with prefix and all parameters.
        !           132:  * @return CONNECTED or DISCONNECTED.
        !           133:  */
        !           134: GLOBAL bool
        !           135: IRC_INVITE(CLIENT *Client, REQUEST *Req)
        !           136: {
        !           137:        CHANNEL *chan;
        !           138:        CLIENT *target, *from;
        !           139:        const char *colon_if_necessary;
        !           140:        bool remember = false;
        !           141:
        !           142:        assert( Client != NULL );
        !           143:        assert( Req != NULL );
        !           144:
        !           145:        _IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
        !           146:
        !           147:        /* Search user */
        !           148:        target = Client_Search(Req->argv[0]);
        !           149:        if (!target || (Client_Type(target) != CLIENT_USER))
        !           150:                return IRC_WriteErrClient(from, ERR_NOSUCHNICK_MSG,
        !           151:                                          Client_ID(Client), Req->argv[0]);
        !           152:
        !           153:        if (Req->argv[1][0] == '&') {
        !           154:                /* Local channel. Make sure the target user is on this server! */
        !           155:                if (Client_Conn(target) == NONE)
        !           156:                        return IRC_WriteErrClient(from, ERR_USERNOTONSERV_MSG,
        !           157:                                                  Client_ID(Client),
        !           158:                                                  Req->argv[0]);
        !           159:        }
        !           160:
        !           161:        chan = Channel_Search(Req->argv[1]);
        !           162:        if (chan) {
        !           163:                /* Channel exists. Is the user a valid member of the channel? */
        !           164:                if (!Channel_IsMemberOf(chan, from))
        !           165:                        return IRC_WriteErrClient(from, ERR_NOTONCHANNEL_MSG,
        !           166:                                                  Client_ID(Client),
        !           167:                                                  Req->argv[1]);
        !           168:
        !           169:                /* Is the channel "invite-disallow"? */
        !           170:                if (Channel_HasMode(chan, 'V'))
        !           171:                        return IRC_WriteErrClient(from, ERR_NOINVITE_MSG,
        !           172:                                                  Client_ID(from),
        !           173:                                                  Channel_Name(chan));
        !           174:
        !           175:                /* Is the channel "invite-only"? */
        !           176:                if (Channel_HasMode(chan, 'i')) {
        !           177:                        /* Yes. The user issuing the INVITE command must be
        !           178:                         * channel owner/admin/operator/halfop! */
        !           179:                        if (!Channel_UserHasMode(chan, from, 'q') &&
        !           180:                            !Channel_UserHasMode(chan, from, 'a') &&
        !           181:                            !Channel_UserHasMode(chan, from, 'o') &&
        !           182:                            !Channel_UserHasMode(chan, from, 'h'))
        !           183:                                return IRC_WriteErrClient(from,
        !           184:                                                          ERR_CHANOPRIVSNEEDED_MSG,
        !           185:                                                          Client_ID(from),
        !           186:                                                          Channel_Name(chan));
        !           187:                        remember = true;
        !           188:                }
        !           189:
        !           190:                /* Is the target user already member of the channel? */
        !           191:                if (Channel_IsMemberOf(chan, target))
        !           192:                        return IRC_WriteErrClient(from, ERR_USERONCHANNEL_MSG,
        !           193:                                                  Client_ID(from),
        !           194:                                                  Req->argv[0], Req->argv[1]);
        !           195:
        !           196:                /* If the target user is banned on that channel: remember invite */
        !           197:                if (Lists_Check(Channel_GetListBans(chan), target))
        !           198:                        remember = true;
        !           199:
        !           200:                if (remember) {
        !           201:                        /* We must remember this invite */
        !           202:                        if (!Channel_AddInvite(chan, Client_MaskCloaked(target),
        !           203:                                                true, Client_ID(from)))
        !           204:                                return CONNECTED;
        !           205:                }
        !           206:        }
        !           207:
        !           208:        LogDebug("User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask(from),
        !           209:                 Req->argv[0], Req->argv[1]);
        !           210:
        !           211:        /*
        !           212:         * RFC 2812 states:
        !           213:         * 'There is no requirement that the channel [..] must exist or be a
        !           214:         * valid channel'. The problem with this is that this allows the
        !           215:         * "channel" to contain spaces, in which case we must prefix its name
        !           216:         * with a colon to make it clear that it is only a single argument.
        !           217:         */
        !           218:        colon_if_necessary = strchr(Req->argv[1], ' ') ? ":":"";
        !           219:        /* Inform target client */
        !           220:        IRC_WriteStrClientPrefix(target, from, "INVITE %s %s%s", Req->argv[0],
        !           221:                                  colon_if_necessary, Req->argv[1]);
        !           222:
        !           223:        if (Client_Conn(target) > NONE) {
        !           224:                /* The target user is local, so we have to send the status code */
        !           225:                if (!IRC_WriteStrClientPrefix(from, target, RPL_INVITING_MSG,
        !           226:                                               Client_ID(from), Req->argv[0],
        !           227:                                               colon_if_necessary, Req->argv[1]))
        !           228:                        return DISCONNECTED;
        !           229:
        !           230:                if (Client_HasMode(target, 'a') &&
        !           231:                        !IRC_WriteStrClient(from, RPL_AWAY_MSG, Client_ID(from),
        !           232:                                        Client_ID(target), Client_Away(target)))
        !           233:                                return DISCONNECTED;
        !           234:        }
        !           235:        return CONNECTED;
        !           236: } /* IRC_INVITE */
        !           237:
        !           238: /* -eof- */

CVSweb