Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

m_mode.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: m_mode.c,v 1.47.2.3 2005/04/14 20:29:07 amcwilliam Exp $
 */

#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "channel.h"
#include "h.h"
#include "memory.h"
#include "modules.h"
#include "xmode.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

Module MOD_HEADER(m_mode) = {
      "m_mode",
      "/MODE command",
      6, "$Revision: 1.47.2.3 $"
};

int MOD_LOAD(m_mode)()
{
      if (register_command(&MOD_HEADER(m_mode), &CMD_MODE, m_mode) == NULL) {
            return MOD_FAILURE;
      }
      MOD_SET_FLAG(&MOD_HEADER(m_mode), MOD_FLAG_PERM);
      return MOD_SUCCESS;
}

int MOD_UNLOAD(m_mode)()
{
      return MOD_SUCCESS;
}

static inline int get_privilege_level(aClient *sptr, aChannel *chptr)
{
      chanMember *cm = NULL;

      if (IsServer(sptr) && (chptr->channelts > 0)) {
            return CPRIV_SERVER;
      }
      if (IsULine(sptr) || (HasMode(sptr, UMODE_SADMIN) && !MyClient(sptr))) {
            return CPRIV_ULINE;
      }
      if ((cm = find_user_member(sptr->user->channel, chptr)) != NULL) {
            if (cm->flags & CMODE_CHANOP) {
                  return CPRIV_CHANOP;
            }
            if (cm->flags & CMODE_HALFOP) {
                  return CPRIV_HALFOP;
            }
            return CPRIV_NONE;
      }
      return -1;
}

int do_chan_mode(aClient *cptr, aClient *sptr, aChannel *chptr, int parc, char *parv[], int level)
{
      int count = parse_mode(cptr, sptr, chptr, level, parc, parv);

      Debug((DEBUG_DEBUG, "MODE(%s) modebuf [%s] parabuf [%s] idparabuf [%s]", chptr->chname,
            modebuf, parabuf, idparabuf));

      if (count < 1) {
            return 0;
      }
      if (*parabuf != '\0') {
            sendto_channel_local_msg_butone(NULL, sptr, chptr, ALL_MEMBERS, &CMD_MODE,
                  "%s %s %s", chptr->chname, modebuf, parabuf);

            sendto_serv_capab_msg_butone(cptr, sptr, NO_CAPS, CAP_TSMODE, &CMD_MODE,
                  "%s %s %s", chptr->chname, modebuf, parabuf);

            sendto_serv_capab_msg_butone(cptr, sptr, CAP_TSMODE, ID_CAPS, &CMD_MODE,
                  "%s %ld %s %s", chptr->chname, chptr->channelts, modebuf, parabuf);
            sendto_serv_capab_msg_butone(cptr, sptr, CAP_TSMODE|ID_CAPS, NO_CAPS, &CMD_MODE,
                  "%s %B %s %s", chptr->chname, chptr->channelts, modebuf, parabuf);
      }
      else {
            sendto_channel_local_msg_butone(NULL, sptr, chptr, ALL_MEMBERS, &CMD_MODE,
                  "%s %s", chptr->chname, modebuf);

            sendto_serv_capab_msg_butone(cptr, sptr, NO_CAPS, CAP_TSMODE, &CMD_MODE,
                  "%s %s", chptr->chname, modebuf);

            sendto_serv_capab_msg_butone(cptr, sptr, CAP_TSMODE, ID_CAPS, &CMD_MODE,
                  "%s %ld %s", chptr->chname, chptr->channelts, modebuf);
            sendto_serv_capab_msg_butone(cptr, sptr, CAP_TSMODE|ID_CAPS, NO_CAPS, &CMD_MODE,
                  "%s %B %s", chptr->chname, chptr->channelts, modebuf);
      }
      return count;
}

/*
 * m_mode
 *    parv[0] = sender prefix
 *    parv[1] = channel
 */
int m_mode(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
      int sub_parc = 2, level = CPRIV_NONE;
      aChannel *chptr;

      if (parc < 2 || BadPtr(parv[1])) {
            send_me_numeric(sptr, ERR_NEEDMOREPARAMS, "MODE");
            return 0;
      }

      if (!IsChanPrefix(*parv[1])) {
            return do_user_mode(cptr, sptr, parc, parv);
      }

      if (!check_channel_name(sptr, parv[1])) {
            send_me_numeric(sptr, ERR_BADCHANNAME, parv[1]);
            return 0;
      }

      if ((chptr = find_channel(parv[1], NULL)) == NULL) {
            if (MyConnect(sptr)) {
                  send_me_numeric(sptr, ERR_NOSUCHCHANNEL, parv[1]);
            }
            return 0;
      }

      if (parc < 3) {
            get_chan_modes(sptr, chptr, modebuf, parabuf);
            send_me_numeric(sptr, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
            send_me_numeric(sptr, RPL_CREATIONTIME, chptr->chname, chptr->channelts);
            return 0;
      }

      if ((level = get_privilege_level(sptr, chptr)) == -1) {
            send_me_numeric(sptr, ERR_CHANOPRIVSNEEDED, chptr->chname);
            return 0;
      }

      if (IsServer(cptr) && (IsDigit(*parv[2]) || *parv[2] == '!')) {
            if (CapTSMODE(cptr)) {
                  long mode_ts = get_ts(parv[2]);

                  if ((mode_ts > 0) && (mode_ts > chptr->channelts)) {
                        return 0;
                  }
            }
            else {
                  /* This shouldn't really happen but it's still possible... */
                  ircdlog(LOG_ERROR, "Received TSMODE from non-TSMODE server %s",
                        cptr->name);
                  sendto_realops_lev(DEBUG_LEV, "Server %s attempted a TSMODE but "
                        "is not TSMODE capable!");
            }
            sub_parc++;
      }

      do_chan_mode(cptr, sptr, chptr, parc - sub_parc, parv + sub_parc, level);
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index