1 |
/** |
2 |
* sendops.C: This file contains code for the Memoserv SENDOPS function |
3 |
* |
4 |
* Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team |
5 |
* Rights to this code are as documented in COPYING. |
6 |
* |
7 |
* |
8 |
* Portions of this file were derived from sources bearing the following license: |
9 |
* Copyright © 2005-2007 Atheme Development Group |
10 |
* Rights to this code are as documented in doc/pod/license.pod. |
11 |
* |
12 |
* $Id: sendops.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $ |
13 |
*/ |
14 |
|
15 |
#include "atheme.h" |
16 |
#include <libermyth.h> |
17 |
#include <ermyth/module.h> |
18 |
#include <account/chanacs.h> |
19 |
#include <account/mychan.h> |
20 |
#include <account/myuser.h> |
21 |
#include <account/mymemo.h> |
22 |
|
23 |
static char const rcsid[] = "$Id: sendops.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $"; |
24 |
|
25 |
REGISTER_MODULE ("memoserv/sendops", false, "The Ermyth Team <http://ermyth.xinutec.org>"); |
26 |
|
27 |
static void ms_cmd_sendops (sourceinfo_t *si, int parc, char *parv[]); |
28 |
|
29 |
command_t const ms_sendops = { "SENDOPS", N_("Sends a memo to all ops on a channel."), AC_NONE, 2, ms_cmd_sendops }; |
30 |
|
31 |
E cmdvec ms_cmdtree; |
32 |
E helpvec ms_helptree; |
33 |
|
34 |
bool |
35 |
_modinit (module *m) |
36 |
{ |
37 |
ms_cmdtree << ms_sendops; |
38 |
help_addentry (ms_helptree, "SENDOPS", "help/memoserv/sendops", NULL); |
39 |
|
40 |
return true; |
41 |
} |
42 |
|
43 |
void |
44 |
_moddeinit () |
45 |
{ |
46 |
ms_cmdtree >> ms_sendops; |
47 |
help_delentry (ms_helptree, "SENDOPS"); |
48 |
} |
49 |
|
50 |
static void |
51 |
ms_cmd_sendops (sourceinfo_t *si, int parc, char *parv[]) |
52 |
{ |
53 |
/* misc structs etc */ |
54 |
myuser_t *tmu; |
55 |
node_t *tn; |
56 |
mymemo_t *memo; |
57 |
mychan_t *mc; |
58 |
int sent = 0, tried = 0; |
59 |
bool ignored; |
60 |
myuser_t::mzignore_vector::iterator miit, miit_end; |
61 |
|
62 |
/* Grab args */ |
63 |
char *target = parv[0]; |
64 |
char *m = parv[1]; |
65 |
|
66 |
/* Arg validation */ |
67 |
if (!target || !m) |
68 |
{ |
69 |
command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "SENDOPS"); |
70 |
|
71 |
command_fail (si, fault::needmoreparams, "Syntax: SENDOPS <channel> <memo>"); |
72 |
|
73 |
return; |
74 |
} |
75 |
|
76 |
/* user logged in? */ |
77 |
if (!si->smu) |
78 |
{ |
79 |
command_fail (si, fault::noprivs, _("You are not logged in.")); |
80 |
return; |
81 |
} |
82 |
|
83 |
if (si->smu->flags & MU_WAITAUTH) |
84 |
{ |
85 |
command_fail (si, fault::notverified, _("You need to verify your email address before you may send memos.")); |
86 |
return; |
87 |
} |
88 |
|
89 |
/* rate limit it -- jilles */ |
90 |
if (NOW - si->smu->memo_ratelimit_time > MEMO_MAX_TIME) |
91 |
si->smu->memo_ratelimit_num = 0; |
92 |
if (si->smu->memo_ratelimit_num > MEMO_MAX_NUM && !has_priv (si, PRIV_FLOOD)) |
93 |
{ |
94 |
command_fail (si, fault::toomany, _("You have used this command too many times; please wait a while and try again.")); |
95 |
return; |
96 |
} |
97 |
si->smu->memo_ratelimit_num++; |
98 |
si->smu->memo_ratelimit_time = NOW; |
99 |
|
100 |
/* Check for memo text length -- includes/common.h */ |
101 |
if (strlen (m) >= MEMOLEN) |
102 |
{ |
103 |
command_fail (si, fault::badparams, "Please make sure your memo is less than %d characters", MEMOLEN); |
104 |
|
105 |
return; |
106 |
} |
107 |
|
108 |
/* Check to make sure the memo doesn't contain hostile CTCP responses. |
109 |
* realistically, we'll probably want to check the _entire_ message for this... --nenolod |
110 |
*/ |
111 |
if (*m == '\001') |
112 |
{ |
113 |
command_fail (si, fault::badparams, _("Your memo contains invalid characters.")); |
114 |
return; |
115 |
} |
116 |
|
117 |
mc = mychan_t::find (target); |
118 |
|
119 |
if (mc == NULL) |
120 |
{ |
121 |
command_fail (si, fault::nosuch_target, "\2%s\2 is not registered.", target); |
122 |
return; |
123 |
} |
124 |
|
125 |
if (!chanacs_user_has_flag (mc, si->su, CA_ACLVIEW)) |
126 |
{ |
127 |
command_fail (si, fault::noprivs, _("You are not authorized to perform this operation.")); |
128 |
return; |
129 |
} |
130 |
|
131 |
LIST_FOREACH (tn, mc->chanacs.head) |
132 |
{ |
133 |
chanacs_t *ca = (chanacs_t *) tn->data; |
134 |
tmu = ca->myuser; |
135 |
|
136 |
if (!(ca->level & (CA_OP | CA_AUTOOP)) || tmu == NULL || tmu == si->smu) |
137 |
continue; |
138 |
|
139 |
tried++; |
140 |
|
141 |
/* Does the user allow memos? --pfish */ |
142 |
if (tmu->flags & MU_NOMEMO) |
143 |
continue; |
144 |
|
145 |
/* Check to make sure target inbox not full */ |
146 |
if (tmu->memos.size () >= me.mdlimit) |
147 |
continue; |
148 |
|
149 |
/* As in SEND to a single user, make ignore fail silently */ |
150 |
sent++; |
151 |
|
152 |
/* Make sure we're not on ignore */ |
153 |
ignored = false; |
154 |
for (miit = tmu->memo_ignores.begin (), miit_end = tmu->memo_ignores.end (); miit != miit_end; ++miit) |
155 |
{ |
156 |
if (!strcasecmp (*miit, si->smu->name)) |
157 |
ignored = true; |
158 |
} |
159 |
if (ignored) |
160 |
continue; |
161 |
|
162 |
/* Malloc and populate struct */ |
163 |
memo = new mymemo_t; |
164 |
memo->sent = NOW; |
165 |
memo->status = MEMO_CHANNEL; |
166 |
strlcpy (memo->sender, si->smu->name, NICKLEN); |
167 |
snprintf (memo->text, MEMOLEN, "%s %s", mc->name, m); |
168 |
|
169 |
/* Create a linked list node and add to memos */ |
170 |
tmu->memos.insert (memo); |
171 |
tmu->memoct_new++; |
172 |
|
173 |
/* Should we email this? */ |
174 |
if (tmu->flags & MU_EMAILMEMOS) |
175 |
{ |
176 |
if (sendemail (si->su, EMAIL_MEMO, tmu, memo->text)) |
177 |
continue; |
178 |
} |
179 |
|
180 |
/* Is the user online? If so, tell them about the new memo. */ |
181 |
if (si->su == NULL || !irccasecmp (si->su->nick, si->smu->name)) |
182 |
tmu->notice (memosvs.nick, _("You have a new memo from %s."), si->smu->name); |
183 |
else |
184 |
tmu->notice (memosvs.nick, _("You have a new memo from %s (nick: %s)."), si->smu->name, si->su->nick); |
185 |
} |
186 |
|
187 |
/* Tell user memo sent, return */ |
188 |
logcommand (si, CMDLOG_SET, "SENDOPS to %s (%d/%d sent)", mc->name, sent, tried); |
189 |
command_success_nodata (si, _("The memo has been successfully sent to %d ops on \2%s\2."), sent, mc->name); |
190 |
return; |
191 |
} |