/** * sendops.C: This file contains code for the Memoserv SENDOPS function * * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are as documented in COPYING. * * * Portions of this file were derived from sources bearing the following license: * Copyright © 2005-2007 Atheme Development Group * Rights to this code are as documented in doc/pod/license.pod. * * $Id: sendops.C,v 1.7 2007/09/22 14:27:27 pippijn Exp $ */ #include "atheme.h" #include #include #include #include #include #include static char const rcsid[] = "$Id: sendops.C,v 1.7 2007/09/22 14:27:27 pippijn Exp $"; REGISTER_MODULE ("memoserv/sendops", false, "The Ermyth Team "); static void ms_cmd_sendops (sourceinfo_t *si, int parc, char *parv[]); command_t const ms_sendops = { "SENDOPS", N_("Sends a memo to all ops on a channel."), AC_NONE, 2, ms_cmd_sendops }; E cmdvec ms_cmdtree; E helpvec ms_helptree; bool _modinit (module *m) { ms_cmdtree << ms_sendops; help_addentry (ms_helptree, "SENDOPS", "help/memoserv/sendops", NULL); return true; } void _moddeinit () { ms_cmdtree >> ms_sendops; help_delentry (ms_helptree, "SENDOPS"); } static void ms_cmd_sendops (sourceinfo_t *si, int parc, char *parv[]) { /* misc structs etc */ myuser_t *tmu; node_t *tn; mymemo_t *memo; mychan_t *mc; int sent = 0, tried = 0; bool ignored; myuser_t::mzignore_vector::iterator miit, miit_end; /* Grab args */ char *target = parv[0]; char *m = parv[1]; /* Arg validation */ if (!target || !m) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "SENDOPS"); command_fail (si, fault::needmoreparams, "Syntax: SENDOPS "); return; } /* user logged in? */ if (!si->smu) { command_fail (si, fault::noprivs, _("You are not logged in.")); return; } if (si->smu->flags & MU_WAITAUTH) { command_fail (si, fault::notverified, _("You need to verify your email address before you may send memos.")); return; } /* rate limit it -- jilles */ if (NOW - si->smu->memo_ratelimit_time > MEMO_MAX_TIME) si->smu->memo_ratelimit_num = 0; if (si->smu->memo_ratelimit_num > MEMO_MAX_NUM && !has_priv (si, PRIV_FLOOD)) { command_fail (si, fault::toomany, _("You have used this command too many times; please wait a while and try again.")); return; } si->smu->memo_ratelimit_num++; si->smu->memo_ratelimit_time = NOW; /* Check for memo text length -- includes/common.h */ if (strlen (m) >= MEMOLEN) { command_fail (si, fault::badparams, "Please make sure your memo is less than %d characters", MEMOLEN); return; } /* Check to make sure the memo doesn't contain hostile CTCP responses. * realistically, we'll probably want to check the _entire_ message for this... --nenolod */ if (*m == '\001') { command_fail (si, fault::badparams, _("Your memo contains invalid characters.")); return; } mc = mychan_t::find (target); if (mc == NULL) { command_fail (si, fault::nosuch_target, "\2%s\2 is not registered.", target); return; } if (!chanacs_user_has_flag (mc, si->su, CA_ACLVIEW)) { command_fail (si, fault::noprivs, _("You are not authorized to perform this operation.")); return; } LIST_FOREACH (tn, mc->chanacs.head) { chanacs_t *ca = (chanacs_t *) tn->data; tmu = ca->myuser; if (!(ca->level & (CA_OP | CA_AUTOOP)) || tmu == NULL || tmu == si->smu) continue; tried++; /* Does the user allow memos? --pfish */ if (tmu->flags & MU_NOMEMO) continue; /* Check to make sure target inbox not full */ if (tmu->memos.size () >= me.mdlimit) continue; /* As in SEND to a single user, make ignore fail silently */ sent++; /* Make sure we're not on ignore */ ignored = false; for (miit = tmu->memo_ignores.begin (), miit_end = tmu->memo_ignores.end (); miit != miit_end; ++miit) { if (!strcasecmp (*miit, si->smu->name)) ignored = true; } if (ignored) continue; /* Malloc and populate struct */ memo = new mymemo_t; memo->sent = NOW; memo->status = MEMO_CHANNEL; strlcpy (memo->sender, si->smu->name, NICKLEN); snprintf (memo->text, MEMOLEN, "%s %s", mc->name, m); /* Create a linked list node and add to memos */ tmu->memos.insert (memo); tmu->memoct_new++; /* Should we email this? */ if (tmu->flags & MU_EMAILMEMOS) { if (sendemail (si->su, EMAIL_MEMO, tmu, memo->text)) continue; } /* Is the user online? If so, tell them about the new memo. */ if (si->su == NULL || !irccasecmp (si->su->nick, si->smu->name)) tmu->notice (memosvs.nick, _("You have a new memo from %s."), si->smu->name); else tmu->notice (memosvs.nick, _("You have a new memo from %s (nick: %s)."), si->smu->name, si->su->nick); } /* Tell user memo sent, return */ logcommand (si, CMDLOG_SET, "SENDOPS to %s (%d/%d sent)", mc->name, sent, tried); command_success_nodata (si, _("The memo has been successfully sent to %d ops on \2%s\2."), sent, mc->name); return; }