/* * 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_svsmode.c,v 1.26.2.2 2005/01/15 23:53:34 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_svsmode) = { "m_svsmode", "/SVSMODE command", 6, "$Revision: 1.26.2.2 $" }; int MOD_LOAD(m_svsmode)() { if (register_command(&MOD_HEADER(m_svsmode), &CMD_SVSMODE, m_svsmode) == NULL) { return MOD_FAILURE; } return MOD_SUCCESS; } int MOD_UNLOAD(m_svsmode)() { return MOD_SUCCESS; } /* * m_svsmode * parv[0] = sender prefix * parv[1] = nickname * parv[2] = TS (or mode, depending on SVS version) * parv[3] = mode (or serviceid, if old SVS version) * parv[4] = optional argument (serviceid) */ int m_svsmode(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aClient *acptr; char *modes, *opt_arg = NULL, *p; xMode *t = NULL; short change = XMODE_ADD; unsigned long old_umodes = 0; time_t ts = 0; int i; if (!IsULine(sptr) || parc < 3) { return 0; } if (parc >= 4 && (*parv[3] == '+' || *parv[3] == '-')) { ts = get_ts(parv[2]); modes = parv[3]; opt_arg = (parc > 4) ? parv[4] : NULL; } else { modes = parv[2]; opt_arg = (parc > 3) ? parv[3] : NULL; } if ((acptr = find_person_target(parv[1])) == NULL) { return 0; } if (ts && (ts != acptr->tsinfo)) { return 0; } old_umodes = acptr->umode; for (p = modes; *p != '\0'; p++) { switch (*p) { case '+': change = XMODE_ADD; break; case '-': change = XMODE_DEL; break; case ' ': case '\n': case '\r': case '\t': break; case 'd': if (opt_arg != NULL && IsDigit(*opt_arg)) { acptr->user->servicestamp = strtoul(opt_arg, NULL, 0); } break; default: if ((i = usermodes->map[(unsigned char)*p]) != -1) { t = &usermodes->table[i]; if (change == XMODE_ADD) { acptr->umode |= t->mode; } else { acptr->umode &= ~t->mode; } if (MyConnect(acptr) && (change == XMODE_DEL) && (t->mode == UMODE_OPER) && !HasMode(acptr, UMODE_OPER)) { dlink_del(&oper_list, acptr, NULL); } } break; } } if (opt_arg != NULL) { sendto_serv_capab_msg_butone(cptr, sptr, NO_CAPS, ID_CAPS, &CMD_SVSMODE, "%s %ld %s %s", acptr->name, acptr->tsinfo, modes, opt_arg); sendto_serv_capab_msg_butone(cptr, sptr, ID_CAPS, NO_CAPS, &CMD_SVSMODE, "%s %B %s %s", get_id(acptr), acptr->tsinfo, modes, opt_arg); } else { sendto_serv_capab_msg_butone(cptr, sptr, NO_CAPS, ID_CAPS, &CMD_SVSMODE, "%s %ld %s", acptr->name, acptr->tsinfo, modes); sendto_serv_capab_msg_butone(cptr, sptr, ID_CAPS, NO_CAPS, &CMD_SVSMODE, "%s %B %s", get_id(acptr), acptr->tsinfo, modes); } if (MyClient(acptr) && (old_umodes != acptr->umode)) { char buf[BUFSIZE]; send_umode(acptr, acptr, old_umodes, ALL_UMODES, buf); } return 0; }