1 |
/** |
2 |
* send.C: This file contains code for the Memoserv SEND 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 Atheme Development Group |
10 |
* Rights to this code are as documented in doc/pod/license.pod. |
11 |
* |
12 |
* $Id: send.C,v 1.7 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/myuser.h> |
19 |
#include <account/mymemo.h> |
20 |
|
21 |
static char const rcsid[] = "$Id: send.C,v 1.7 2007-09-16 18:54:43 pippijn Exp $"; |
22 |
|
23 |
REGISTER_MODULE ("memoserv/send", false, "The Ermyth Team <http://ermyth.xinutec.org>"); |
24 |
|
25 |
static void ms_cmd_send (sourceinfo_t *si, int parc, char *parv[]); |
26 |
|
27 |
command_t const ms_send = { "SEND", N_("Sends a memo to a user."), AC_NONE, 2, ms_cmd_send }; |
28 |
|
29 |
E cmdvec ms_cmdtree; |
30 |
E helpvec ms_helptree; |
31 |
|
32 |
bool |
33 |
_modinit (module *m) |
34 |
{ |
35 |
ms_cmdtree << ms_send; |
36 |
help_addentry (ms_helptree, "SEND", "help/memoserv/send", NULL); |
37 |
|
38 |
return true; |
39 |
} |
40 |
|
41 |
void |
42 |
_moddeinit () |
43 |
{ |
44 |
ms_cmdtree >> ms_send; |
45 |
help_delentry (ms_helptree, "SEND"); |
46 |
} |
47 |
|
48 |
static void |
49 |
ms_cmd_send (sourceinfo_t *si, int parc, char *parv[]) |
50 |
{ |
51 |
/* misc structs etc */ |
52 |
user_t *tu; |
53 |
myuser_t *tmu; |
54 |
mymemo_t *memo; |
55 |
command_t const *cmd; |
56 |
myuser_t::mzignore_vector::iterator miit, miit_end; |
57 |
|
58 |
/* Grab args */ |
59 |
char *target = parv[0]; |
60 |
char *m = parv[1]; |
61 |
|
62 |
/* Arg validation */ |
63 |
if (!target || !m) |
64 |
{ |
65 |
command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "SEND"); |
66 |
|
67 |
command_fail (si, fault::needmoreparams, "Syntax: SEND <user> <memo>"); |
68 |
|
69 |
return; |
70 |
} |
71 |
|
72 |
/* user logged in? */ |
73 |
if (!si->smu) |
74 |
{ |
75 |
command_fail (si, fault::noprivs, _("You are not logged in.")); |
76 |
return; |
77 |
} |
78 |
|
79 |
if (si->smu->flags & MU_WAITAUTH) |
80 |
{ |
81 |
command_fail (si, fault::notverified, _("You need to verify your email address before you may send memos.")); |
82 |
return; |
83 |
} |
84 |
|
85 |
/* rate limit it -- jilles */ |
86 |
if (NOW - si->smu->memo_ratelimit_time > MEMO_MAX_TIME) |
87 |
si->smu->memo_ratelimit_num = 0; |
88 |
if (si->smu->memo_ratelimit_num > MEMO_MAX_NUM && !has_priv (si, PRIV_FLOOD)) |
89 |
{ |
90 |
command_fail (si, fault::toomany, _("You have used this command too many times; please wait a while and try again.")); |
91 |
return; |
92 |
} |
93 |
si->smu->memo_ratelimit_num++; |
94 |
si->smu->memo_ratelimit_time = NOW; |
95 |
|
96 |
/* Check for memo text length -- includes/common.h */ |
97 |
if (strlen (m) >= MEMOLEN) |
98 |
{ |
99 |
command_fail (si, fault::badparams, "Please make sure your memo is less than %d characters", MEMOLEN); |
100 |
|
101 |
return; |
102 |
} |
103 |
|
104 |
/* Check to make sure the memo doesn't contain hostile CTCP responses. |
105 |
* realistically, we'll probably want to check the _entire_ message for this... --nenolod |
106 |
*/ |
107 |
if (*m == '\001') |
108 |
{ |
109 |
command_fail (si, fault::badparams, _("Your memo contains invalid characters.")); |
110 |
return; |
111 |
} |
112 |
|
113 |
if (*target != '#') |
114 |
{ |
115 |
/* See if target is valid */ |
116 |
if (!(tmu = myuser_t::find_ext (target))) |
117 |
{ |
118 |
command_fail (si, fault::nosuch_target, "\2%s\2 is not registered.", target); |
119 |
|
120 |
return; |
121 |
} |
122 |
|
123 |
/* Does the user allow memos? --pfish */ |
124 |
if (tmu->flags & MU_NOMEMO) |
125 |
{ |
126 |
command_fail (si, fault::noprivs, "\2%s\2 does not wish to receive memos.", target); |
127 |
|
128 |
return; |
129 |
} |
130 |
|
131 |
/* Check to make sure target inbox not full */ |
132 |
if (tmu->memos.size () >= me.mdlimit) |
133 |
{ |
134 |
command_fail (si, fault::toomany, _("%s's inbox is full"), target); |
135 |
logcommand (si, CMDLOG_SET, "failed SEND to %s (target inbox full)", tmu->name); |
136 |
return; |
137 |
} |
138 |
|
139 |
|
140 |
/* Make sure we're not on ignore */ |
141 |
for (miit = tmu->memo_ignores.begin (), miit_end = tmu->memo_ignores.end (); miit != miit_end; ++miit) |
142 |
{ |
143 |
if (!strcasecmp (*miit, si->smu->name)) |
144 |
{ |
145 |
logcommand (si, CMDLOG_SET, "failed SEND to %s (on ignore list)", tmu->name); |
146 |
command_success_nodata (si, _("The memo has been successfully sent to \2%s\2."), target); |
147 |
return; |
148 |
} |
149 |
} |
150 |
logcommand (si, CMDLOG_SET, "SEND to %s", tmu->name); |
151 |
|
152 |
/* Malloc and populate struct */ |
153 |
memo = new mymemo_t; |
154 |
memo->sent = NOW; |
155 |
memo->status = 0; |
156 |
strlcpy (memo->sender, si->smu->name, NICKLEN); |
157 |
strlcpy (memo->text, m, MEMOLEN); |
158 |
|
159 |
/* Create a linked list node and add to memos */ |
160 |
tmu->memos.insert (memo); |
161 |
tmu->memoct_new++; |
162 |
|
163 |
/* Should we email this? */ |
164 |
if (tmu->flags & MU_EMAILMEMOS) |
165 |
{ |
166 |
if (sendemail (si->su, EMAIL_MEMO, tmu, memo->text)) |
167 |
{ |
168 |
command_success_nodata (si, _("Your memo has been emailed to \2%s\2."), target); |
169 |
return; |
170 |
} |
171 |
} |
172 |
|
173 |
/* Is the user online? If so, tell them about the new memo. */ |
174 |
/* Note: do not disclose other nicks they're logged in with |
175 |
* -- jilles |
176 |
* |
177 |
* Actually, I don't see the point in this at all. If they want this information, |
178 |
* they should use WHOIS. --nenolod |
179 |
*/ |
180 |
tu = user_find_named (target); |
181 |
if (tu != NULL && tu->myuser == tmu) |
182 |
command_success_nodata (si, _("%s is currently online, and you may talk directly, by sending a private message."), target); |
183 |
|
184 |
if (si->su == NULL || !irccasecmp (si->su->nick, si->smu->name)) |
185 |
tmu->notice (memosvs.nick, "You have a new memo from %s.", si->smu->name); |
186 |
else |
187 |
tmu->notice (memosvs.nick, "You have a new memo from %s (nick: %s).", si->smu->name, si->su->nick); |
188 |
|
189 |
/* Tell user memo sent */ |
190 |
command_success_nodata (si, _("The memo has been successfully sent to \2%s\2."), target); |
191 |
} |
192 |
else |
193 |
{ |
194 |
cmd = si->service->cmdtree->find ("SENDOPS"); |
195 |
if (cmd != NULL) |
196 |
cmd->exec (si->service, si, parc, parv); |
197 |
else |
198 |
command_fail (si, fault::nosuch_target, _("Channel memos are administratively disabled.")); |
199 |
} |
200 |
|
201 |
return; |
202 |
} |