/************************************************************************
* IRC - Internet Relay Chat, chanmodes/cm_chanop.c
*
* Copyright (C)2000-2003 TR-IRCD Development
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Co Center
*
* 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
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "channel.h"
#include "h.h"
#include "msg.h"
#include "hook.h"
#include "chanmode.h"
#include "s_conf.h"
static int set_chanop(int adl, aChannel *chptr, int nmodes,
int *argnum, int *pidx, int *mbix, char *mbuf, char *pbuf,
aClient *cptr, aClient *sptr, int parc, char **parv)
{
char *pptr; /* temporary paramater pointer */
char *morig = mbuf; /* beginning of mbuf */
int prelen = strlen(cptr->name) + strlen(chptr->chname) + 16;
aClient *acptr; /* for walking channel member lists */
aClient *who = NULL; /* who we're doing a mode for */
int chasing = 0;
int fargnum = *argnum;
int fmbix = *mbix;
int fpidx = *pidx;
if (parv[fargnum] == NULL) {
return nmodes;
}
who = find_chasing(sptr, parv[fargnum], &chasing);
acptr = find_user_member(chptr, who);
if (acptr == NULL) {
send_me_numeric(sptr, ERR_USERNOTINCHANNEL, parv[fargnum], chptr);
fargnum++;
*argnum = fargnum;
return nmodes;
}
if (adl == CMODE_DEL) {
if (!IsPrivileged(cptr) && IsChanUser(who, chptr, CHFL_OWNER)) {
fargnum++;
*argnum = fargnum;
return nmodes;
}
}
/*
* if we're going to overflow our mode buffer,
* * drop the change instead
*/
if ((prelen + (mbuf - morig) + fpidx + NICKLEN + 1) > REALMODEBUFLEN) {
fargnum++;
*argnum = fargnum;
return nmodes;
}
mbuf[fmbix++] = 'o';
if (adl == CMODE_ADD) {
if (IsChanHideOps(chptr) && !get_flags(acptr, chptr))
send_mode_burst(acptr, chptr, '+');
update_userflags(acptr, chptr, 1, CHFL_CHANOP);
}
if (adl == CMODE_DEL) {
update_userflags(acptr, chptr, 0, CHFL_CHANOP);
if (IsChanHideOps(chptr) && !get_flags(acptr, chptr))
send_mode_burst(acptr, chptr, '-');
}
pptr = acptr->name;
if (fpidx)
pbuf[fpidx++] = ' ';
while (*pptr)
pbuf[fpidx++] = *pptr++;
fargnum++;
nmodes++;
*mbix = fmbix;
*pidx = fpidx;
*argnum = fargnum;
return nmodes;
}
static int sop_service(int adl, aChannel *chptr, int nmodes,
int *argnum, int *pidx, int *mbix, char *mbuf,
char *pbuf, aClient *cptr, aClient *sptr, int parc, char **parv)
{
if (MyClient(sptr))
send_me_numeric(sptr, ERR_CHANOPRIVSNEEDED, chptr);
else
ircstp->is_fake++;
return nmodes;
}
static int sop_server(int adl, aChannel *chptr, int nmodes,
int *argnum, int *pidx, int *mbix, char *mbuf, char *pbuf,
aClient *cptr, aClient *sptr, int parc, char **parv)
{
return set_chanop(adl, chptr, nmodes, argnum, pidx, mbix, mbuf, pbuf, cptr, sptr, parc, parv);
}
static int sop_uline(int adl, aChannel *chptr, int nmodes,
int *argnum, int *pidx, int *mbix, char *mbuf, char *pbuf,
aClient *cptr, aClient *sptr, int parc, char **parv)
{
return set_chanop(adl, chptr, nmodes, argnum, pidx, mbix, mbuf, pbuf, cptr, sptr, parc, parv);
}
static int sop_oper(int adl, aChannel *chptr, int nmodes,
int *argnum, int *pidx, int *mbix, char *mbuf, char *pbuf,
aClient *cptr, aClient *sptr, int parc, char **parv)
{
if (IsChanUser(sptr, chptr, CHFL_CHANOP) || IsOperMode(sptr) || IsServer(cptr)) {
return set_chanop(adl, chptr, nmodes, argnum, pidx, mbix, mbuf, pbuf,
cptr, sptr, parc, parv);
} else
send_me_numeric(sptr, ERR_CHANOPRIVSNEEDED, chptr);
return nmodes;
}
static int sop_user(int adl, aChannel *chptr, int nmodes,
int *argnum, int *pidx, int *mbix, char *mbuf, char *pbuf,
aClient *cptr, aClient *sptr, int parc, char **parv)
{
if (IsChanUser(sptr, chptr, CHFL_CHANOP)) {
return set_chanop(adl, chptr, nmodes, argnum, pidx, mbix, mbuf, pbuf,
cptr, sptr, parc, parv);
} else
send_me_numeric(sptr, ERR_CHANOPRIVSNEEDED, chptr);
return nmodes;
}
static struct ChanMode mode_chanop[] = {
{CHFL_CHANOP, 1, MFLG_IGNORE, CMTYPE_LIST | CMTYPE_PARAMETRIC,
sop_user, sop_oper, sop_uline, sop_server, sop_service}
};
#ifndef STATIC_MODULES
int _persistent = 1;
void _modinit(void)
#else
void chanop_modinit(void)
#endif
{
modetab[(int) 'o'] = mode_chanop[0];
GeneralOpts.lists_created = 0;
}
syntax highlighted by Code2HTML, v. 0.9.1