/************************************************************************ * IRC - Internet Relay Chat, modules/m_svsmode.c * * Copyright (C) 2000-2003 TR-IRCD Development * * Copyright (C) 1990 Jarkko Oikarinen and * University of Oulu, Co Center * * See file AUTHORS in IRC package for additional names of * the programmers. * * 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. */ /* * $Id: m_svsmode.c,v 1.3 2003/06/14 13:55:51 tr-ircd Exp $ */ #include "struct.h" #include "common.h" #include "sys.h" #include "numeric.h" #include "msg.h" #include "channel.h" #include "h.h" #include "hook.h" #include "language.h" #include "chanmode.h" #include "usermode.h" static char *token = TOK1_SVSMODE; static int hookid_channel_svsmode = 0; static struct Message _msgtab[] = { {MSG_SVSMODE, 0, MAXPARA, M_SLOW, 0L, m_unregistered, m_ignore, m_ignore, m_svsmode, m_ignore} }; #ifndef STATIC_MODULES char *_version = "$Revision: 1.3 $"; void _modinit(void) { mod_add_cmd(_msgtab); tok1_msgtab[(u_char) *token].msg = _msgtab; hookid_channel_svsmode = hook_add_event("channel svsmode"); } void _moddeinit(void) { mod_del_cmd(_msgtab); tok1_msgtab[(u_char) *token].msg = NULL; hook_del_event("channel svsmode"); } #else void m_svsmode_init(void) { mod_add_cmd(_msgtab); tok1_msgtab[(u_char) *token].msg = _msgtab; hookid_channel_svsmode = hook_add_event("channel svsmode"); } #endif /* * channel_svsmode: * * parv[0] sender * * parv[1] channel * * parv[2] modes * * parv[3] nick * * parv[4] nickts * * preconditions: parc >= 4, sptr is ulined */ static int channel_svsmode(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aChannel *chptr; aClient *acptr = NULL; char *m, *nick = NULL; char change = '+'; long nickts = 0; int sendmsg = 1; struct hook_data thisdata; if (parc < 4) return 0; if (!(chptr = find_channel(parv[1]))) return 0; /* We do not need link traversal here, because users * do not exist in the root channel, and it is already * set to +tnL, after cleaning. -TimeMr14C */ nick = parv[3]; if (parc > 4) nickts = atol(parv[4]); acptr = find_person(nick); if (!acptr || (nickts && acptr->tsval != nickts)) return 0; for (m = parv[2]; *m; m++) switch (*m) { case '+': case '-': change = *m; break; default: if (MyClient(acptr) && change == '-') { thisdata.channel = chptr; thisdata.client_p = acptr; thisdata.source_p = &me; thisdata.statchar = *m; hook_call_event(hookid_channel_svsmode, &thisdata); sendmsg--; } else { sendmsg++; } break; } if (!sendmsg) return 0; sendto_serv_butone(cptr, sptr, TOK1_SVSMODE, "%s %s %s %T", parv[1], parv[2], nick, acptr); return 0; } /* * m_svsmode - df function integrated * * - Raistlin * * -- Behaviour changed - Epi (11/30/99) * * parv[0] - sender * * parv[1] - nick * * parv[2] - TS (or mode, depending on svs version) * * parv[3] - mode (or services id if old svs version) * * parv[4] - optional arguement (services id) * Expanded with TRIRCD Extensions (language) - TimeMr14C 16.04.2002 */ int m_svsmode(aClient *cptr, aClient *sptr, int parc, char *parv[]) { int flag, what; char *m, *modes, *optargs, *largs; aClient *acptr; long ts = 0; if (!IsULine(sptr) || (parc < 3)) return 0; if (parv[1][0] == '#') return channel_svsmode(cptr, sptr, parc, parv); if ((parc >= 4) && ((parv[3][0] == '+') || (parv[3][0] == '-'))) { ts = atol(parv[2]); modes = parv[3]; if (parc > 4) { optargs = parv[4]; if (parc > 5) largs = parv[5]; else largs = optargs; } else { optargs = NULL; largs = NULL; } } else { modes = parv[2]; optargs = (parc > 3) ? parv[3] : NULL; largs = optargs; } if (!(acptr = find_person(parv[1]))) return 0; if (ts && (ts != acptr->tsval)) return 0; what = CMODE_ADD; for (m = modes; *m; m++) switch (*m) { case '+': what = CMODE_ADD; break; case '-': what = CMODE_DEL; break; case ' ': case '\n': case '\r': case '\t': break; case 'z': if (MyClient(acptr)) { if (what == CMODE_ADD) { acptr->protoflags |= PFLAGS_ZOMBIE; send_me_notice(acptr, ":You are now marked as a zombie"); } else if (what == CMODE_DEL) { ClearZombie(acptr); send_me_notice(acptr, ":You are no longer marked as a zombie"); } break; /* Only break if our client -TimeMr14C */ } case 'd': if (optargs && IsDigit(*optargs)) acptr->user->servicestamp = strtoul(optargs, NULL, 0); break; case 'L': if (largs && IsDigit(*largs)) acptr->lang = set_language(atoi(largs)); break; default: if (umodetab[(int) *m].in_use) { flag = umodetab[(int) *m].type; if (what == CMODE_ADD) acptr->umode |= flag; else acptr->umode &= ~flag; } break; } if (optargs) sendto_serv_butone(cptr, sptr, TOK1_SVSMODE, "%~C %T %s %s", acptr, acptr, modes, optargs); else sendto_serv_butone(cptr, sptr, TOK1_SVSMODE, "%~C %T %s", acptr, acptr, modes); return 0; }