Anope IRC Services  Version 1.8
ms_set.c
Go to the documentation of this file.
1 /* MemoServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  *
11  *
12  */
13 /*************************************************************************/
14 
15 #include "module.h"
16 
17 static int do_set(User * u);
18 static int do_set_notify(User * u, MemoInfo * mi, char *param);
19 static int do_set_limit(User * u, MemoInfo * mi, char *param);
20 static int reload_config(int argc, char **argv);
21 static void myMemoServHelp(User * u);
22 
29 int AnopeInit(int argc, char **argv)
30 {
31  Command *c;
32  EvtHook *hook;
33 
34  moduleAddAuthor("Anope");
35  moduleAddVersion(VERSION_STRING);
37 
38  c = createCommand("SET", do_set, NULL, MEMO_HELP_SET, -1, -1, -1, -1);
40 
41  c = createCommand("SET NOTIFY", NULL, NULL, MEMO_HELP_SET_NOTIFY, -1,
42  -1, -1, -1);
44 
45  c = createCommand("SET LIMIT", NULL, NULL, -1, MEMO_HELP_SET_LIMIT,
46  MEMO_SERVADMIN_HELP_SET_LIMIT,
47  MEMO_SERVADMIN_HELP_SET_LIMIT,
48  MEMO_SERVADMIN_HELP_SET_LIMIT);
49  c->help_param1 = (char *) (long) MSMaxMemos;
51 
53 
55  if (moduleAddEventHook(hook) != MOD_ERR_OK) {
56  alog("[\002ms_set\002] Can't hook to EVENT_RELOAD event");
57  return MOD_STOP;
58  }
59 
60  return MOD_CONT;
61 }
62 
66 void AnopeFini(void)
67 {
68 
69 }
70 
71 
72 
77 static void myMemoServHelp(User * u)
78 {
79  notice_lang(s_MemoServ, u, MEMO_HELP_CMD_SET);
80 }
81 
87 static int do_set(User * u)
88 {
89  char *cmd = strtok(NULL, " ");
90  char *param = strtok(NULL, "");
91  MemoInfo *mi = &u->na->nc->memos;
92 
93  if (readonly) {
94  notice_lang(s_MemoServ, u, MEMO_SET_DISABLED);
95  return MOD_CONT;
96  }
97  if (!param) {
98  syntax_error(s_MemoServ, u, "SET", MEMO_SET_SYNTAX);
99  } else if (!nick_identified(u)) {
100  notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
101  return MOD_CONT;
102  } else if (stricmp(cmd, "NOTIFY") == 0) {
103  do_set_notify(u, mi, param);
104  } else if (stricmp(cmd, "LIMIT") == 0) {
105  do_set_limit(u, mi, param);
106  } else {
107  notice_lang(s_MemoServ, u, MEMO_SET_UNKNOWN_OPTION, cmd);
108  notice_lang(s_MemoServ, u, MORE_INFO, s_MemoServ, "SET");
109  }
110  return MOD_CONT;
111 }
112 
118 static int do_set_notify(User * u, MemoInfo * mi, char *param)
119 {
120  if (stricmp(param, "ON") == 0) {
122  alog("%s: %s!%s@%s set notify to ON",
123  s_MemoServ, u->nick, u->username, u->host);
124  notice_lang(s_MemoServ, u, MEMO_SET_NOTIFY_ON, s_MemoServ);
125  } else if (stricmp(param, "LOGON") == 0) {
126  u->na->nc->flags |= NI_MEMO_SIGNON;
127  u->na->nc->flags &= ~NI_MEMO_RECEIVE;
128  alog("%s: %s!%s@%s set notify to LOGON",
129  s_MemoServ, u->nick, u->username, u->host);
130  notice_lang(s_MemoServ, u, MEMO_SET_NOTIFY_LOGON, s_MemoServ);
131  } else if (stricmp(param, "NEW") == 0) {
132  u->na->nc->flags &= ~NI_MEMO_SIGNON;
133  u->na->nc->flags |= NI_MEMO_RECEIVE;
134  alog("%s: %s!%s@%s set notify to NEW",
135  s_MemoServ, u->nick, u->username, u->host);
136  notice_lang(s_MemoServ, u, MEMO_SET_NOTIFY_NEW, s_MemoServ);
137  } else if (stricmp(param, "MAIL") == 0) {
138  if (u->na->nc->email) {
139  u->na->nc->flags |= NI_MEMO_MAIL;
140  alog("%s: %s!%s@%s set notify to MAIL",
141  s_MemoServ, u->nick, u->username, u->host);
142  notice_lang(s_MemoServ, u, MEMO_SET_NOTIFY_MAIL);
143  } else {
144  notice_lang(s_MemoServ, u, MEMO_SET_NOTIFY_INVALIDMAIL);
145  }
146  } else if (stricmp(param, "NOMAIL") == 0) {
147  u->na->nc->flags &= ~NI_MEMO_MAIL;
148  alog("%s: %s!%s@%s set notify to NOMAIL",
149  s_MemoServ, u->nick, u->username, u->host);
150  notice_lang(s_MemoServ, u, MEMO_SET_NOTIFY_NOMAIL);
151  } else if (stricmp(param, "OFF") == 0) {
153  alog("%s: %s!%s@%s set notify to OFF",
154  s_MemoServ, u->nick, u->username, u->host);
155  notice_lang(s_MemoServ, u, MEMO_SET_NOTIFY_OFF, s_MemoServ);
156  } else {
157  syntax_error(s_MemoServ, u, "SET NOTIFY", MEMO_SET_NOTIFY_SYNTAX);
158  }
159  return MOD_CONT;
160 }
161 
167 static int do_set_limit(User * u, MemoInfo * mi, char *param)
168 {
169  char *p1 = strtok(param, " ");
170  char *p2 = strtok(NULL, " ");
171  char *p3 = strtok(NULL, " ");
172  char *user = NULL, *chan = NULL;
173  int32 limit;
174  NickAlias *na = u->na;
175  ChannelInfo *ci = NULL;
176  int is_servadmin = is_services_admin(u);
177 
178  if (p1 && *p1 == '#') {
179  chan = p1;
180  p1 = p2;
181  p2 = p3;
182  p3 = strtok(NULL, " ");
183  if (!(ci = cs_findchan(chan))) {
184  notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan);
185  return MOD_CONT;
186  } else if (ci->flags & CI_VERBOTEN) {
187  notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, chan);
188  return MOD_CONT;
189  } else if (!is_servadmin && !check_access(u, ci, CA_MEMO)) {
190  notice_lang(s_MemoServ, u, ACCESS_DENIED);
191  return MOD_CONT;
192  }
193  mi = &ci->memos;
194  }
195  if (is_servadmin) {
196  if (p2 && stricmp(p2, "HARD") != 0 && !chan) {
197  if (!(na = findnick(p1))) {
198  notice_lang(s_MemoServ, u, NICK_X_NOT_REGISTERED, p1);
199  return MOD_CONT;
200  }
201  user = p1;
202  mi = &na->nc->memos;
203  p1 = p2;
204  p2 = p3;
205  } else if (!p1) {
206  syntax_error(s_MemoServ, u, "SET LIMIT",
207  MEMO_SET_LIMIT_SERVADMIN_SYNTAX);
208  return MOD_CONT;
209  }
210  if ((!isdigit(*p1) && stricmp(p1, "NONE") != 0) ||
211  (p2 && stricmp(p2, "HARD") != 0)) {
212  syntax_error(s_MemoServ, u, "SET LIMIT",
213  MEMO_SET_LIMIT_SERVADMIN_SYNTAX);
214  return MOD_CONT;
215  }
216  if (chan) {
217  if (p2)
218  ci->flags |= CI_MEMO_HARDMAX;
219  else
220  ci->flags &= ~CI_MEMO_HARDMAX;
221  } else {
222  if (p2)
223  na->nc->flags |= NI_MEMO_HARDMAX;
224  else
225  na->nc->flags &= ~NI_MEMO_HARDMAX;
226  }
227  limit = atoi(p1);
228  if (limit < 0 || limit > 32767) {
229  notice_lang(s_MemoServ, u, MEMO_SET_LIMIT_OVERFLOW, 32767);
230  limit = 32767;
231  }
232  if (stricmp(p1, "NONE") == 0)
233  limit = -1;
234  } else {
235  if (!p1 || p2 || !isdigit(*p1)) {
236  syntax_error(s_MemoServ, u, "SET LIMIT",
237  MEMO_SET_LIMIT_SYNTAX);
238  return MOD_CONT;
239  }
240  if (chan && (ci->flags & CI_MEMO_HARDMAX)) {
241  notice_lang(s_MemoServ, u, MEMO_SET_LIMIT_FORBIDDEN, chan);
242  return MOD_CONT;
243  } else if (!chan && (na->nc->flags & NI_MEMO_HARDMAX)) {
244  notice_lang(s_MemoServ, u, MEMO_SET_YOUR_LIMIT_FORBIDDEN);
245  return MOD_CONT;
246  }
247  limit = atoi(p1);
248  /* The first character is a digit, but we could still go negative
249  * from overflow... watch out! */
250  if (limit < 0 || (MSMaxMemos > 0 && limit > MSMaxMemos)) {
251  if (chan) {
252  notice_lang(s_MemoServ, u, MEMO_SET_LIMIT_TOO_HIGH,
253  chan, MSMaxMemos);
254  } else {
255  notice_lang(s_MemoServ, u, MEMO_SET_YOUR_LIMIT_TOO_HIGH,
256  MSMaxMemos);
257  }
258  return MOD_CONT;
259  } else if (limit > 32767) {
260  notice_lang(s_MemoServ, u, MEMO_SET_LIMIT_OVERFLOW, 32767);
261  limit = 32767;
262  }
263  }
264  mi->memomax = limit;
265  if (limit > 0) {
266  if (!chan && na->nc == u->na->nc) {
267  alog("%s: %s!%s@%s set their memo limit to %d",
268  s_MemoServ, u->nick, u->username, u->host, limit);
269  notice_lang(s_MemoServ, u, MEMO_SET_YOUR_LIMIT, limit);
270  } else {
271  alog("%s: %s!%s@%s set the memo limit for %s to %d",
272  s_MemoServ, u->nick, u->username, u->host,
273  chan ? chan : user, limit);
274  notice_lang(s_MemoServ, u, MEMO_SET_LIMIT,
275  chan ? chan : user, limit);
276  }
277  } else if (limit == 0) {
278  if (!chan && na->nc == u->na->nc) {
279  alog("%s: %s!%s@%s set their memo limit to 0",
280  s_MemoServ, u->nick, u->username, u->host);
281  notice_lang(s_MemoServ, u, MEMO_SET_YOUR_LIMIT_ZERO);
282  } else {
283  alog("%s: %s!%s@%s set the memo limit for %s to 0",
284  s_MemoServ, u->nick, u->username, u->host,
285  chan ? chan : user);
286  notice_lang(s_MemoServ, u, MEMO_SET_LIMIT_ZERO,
287  chan ? chan : user);
288  }
289  } else {
290  if (!chan && na->nc == u->na->nc) {
291  alog("%s: %s!%s@%s unset their memo limit",
292  s_MemoServ, u->nick, u->username, u->host);
293  notice_lang(s_MemoServ, u, MEMO_UNSET_YOUR_LIMIT);
294  } else {
295  alog("%s: %s!%s@%s unset the memo limit for %s",
296  s_MemoServ, u->nick, u->username, u->host,
297  chan ? chan : user);
298  notice_lang(s_MemoServ, u, MEMO_UNSET_LIMIT,
299  chan ? chan : user);
300  }
301  }
302  return MOD_CONT;
303 }
304 
308 static int reload_config(int argc, char **argv) {
309  Command *c;
310 
311  if (argc >= 1 && !stricmp(argv[0], EVENT_START))
312  if ((c = findCommand(MEMOSERV, "SET LIMIT")))
313  c->help_param1 = (char *) (long) MSMaxMemos;
314 
315  return MOD_CONT;
316 }
E int readonly
Definition: extern.h:776
char nick[NICKMAX]
Definition: services.h:875
E NickAlias * findnick(const char *nick)
Definition: db-merger.c:1857
void AnopeFini(void)
Definition: ms_set.c:66
E int nick_identified(User *u)
Definition: nickserv.c:1111
E int check_access(User *user, ChannelInfo *ci, int what)
Definition: chanserv.c:1974
#define NI_MEMO_RECEIVE
Definition: services.h:1295
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
static void myMemoServHelp(User *u)
Definition: ms_set.c:77
#define EVENT_RELOAD
Definition: events.h:40
#define CI_VERBOTEN
Definition: services.h:725
char * host
Definition: services.h:878
MemoInfo memos
Definition: services.h:552
#define CI_MEMO_HARDMAX
Definition: services.h:731
MDE void moduleAddAuthor(const char *author)
Definition: modules.c:1772
E void syntax_error(char *service, User *u, const char *command, int msgnum)
Definition: language.c:295
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
MDE void moduleSetType(MODType type)
Definition: modules.c:818
char * help_param1
Definition: modules.h:187
NickCore * nc
Definition: services.h:533
static int reload_config(int argc, char **argv)
Definition: ms_set.c:308
MDE void moduleSetMemoHelp(void(*func)(User *u))
Definition: modules.c:2102
E char * s_MemoServ
Definition: extern.h:286
#define MOD_STOP
Definition: modules.h:53
uint32 flags
Definition: services.h:669
int16 memomax
Definition: services.h:505
#define NI_MEMO_SIGNON
Definition: services.h:1294
int32_t int32
Definition: db-merger.c:122
MDE void moduleAddVersion(const char *version)
Definition: modules.c:1760
MDE EvtHook * createEventHook(char *name, int(*func)(int argc, char **argv))
Definition: events.c:305
Command * c
Definition: ns_recover.c:17
E void alog(const char *fmt,...) FORMAT(printf
#define MOD_ERR_OK
Definition: modules.h:71
#define MOD_CONT
Definition: modules.h:54
#define EVENT_START
Definition: events.h:14
E int is_services_admin(User *u)
Definition: operserv.c:591
char * username
Definition: services.h:877
MDE Command * findCommand(CommandHash *cmdTable[], const char *name)
Definition: modules.c:1442
#define MEMOSERV
Definition: modules.h:58
#define NI_MEMO_HARDMAX
Definition: services.h:1293
Definition: modules.h:99
MDE Command * createCommand(const char *name, int(*func)(User *u), int(*has_priv)(User *u), int help_all, int help_reg, int help_oper, int help_admin, int help_root)
Definition: modules.c:987
#define CA_MEMO
Definition: services.h:761
static int do_set(User *u)
Definition: ms_set.c:87
MemoInfo memos
Definition: services.h:690
int AnopeInit(int argc, char **argv)
Definition: ms_set.c:29
E ChannelInfo * cs_findchan(const char *chan)
Definition: db-merger.c:2000
uint32 flags
Definition: services.h:548
static int do_set_notify(User *u, MemoInfo *mi, char *param)
Definition: ms_set.c:118
static int do_set_limit(User *u, MemoInfo *mi, char *param)
Definition: ms_set.c:167
E char * s_NickServ
Definition: extern.h:284
E int MSMaxMemos
Definition: extern.h:415
MDE int moduleAddCommand(CommandHash *cmdTable[], Command *c, int pos)
Definition: modules.c:1082
MDE int moduleAddEventHook(EvtHook *evh)
Definition: events.c:528
#define NI_MEMO_MAIL
Definition: services.h:1306
NickAlias * na
Definition: services.h:892
#define MOD_UNIQUE
Definition: module.h:11
char * email
Definition: services.h:544