Anope IRC Services  Version 1.8
messages.c
Go to the documentation of this file.
1 /* Definitions of IRC message functions and list of messages.
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 #include "services.h"
15 #include "messages.h"
16 #include "language.h"
17 
18 /*************************************************************************/
19 
20 int m_nickcoll(char *user)
21 {
22  if (!skeleton && !readonly)
23  introduce_user(user);
24  return MOD_CONT;
25 }
26 
27 /*************************************************************************/
28 
29 int m_away(char *source, char *msg)
30 {
31  User *u;
32 
33  /* When using TS6, we get a UID. ~ Viper */
34  if (UseTS6 && ircd->ts6) {
35  u = find_byuid(source);
36  if (!u)
37  u = finduser(source);
38  } else {
39  u = finduser(source);
40  }
41 
42  if (u && msg == 0) /* un-away */
43  check_memos(u);
44  return MOD_CONT;
45 }
46 
47 /*************************************************************************/
48 
49 int m_kill(char *nick, char *msg)
50 {
51  BotInfo *bi;
52 
53  /* Recover if someone kills us. */
54  /* use nickIsServices() to reduce the number of lines of code - TSL */
55  if (nickIsServices(nick, 0)) {
56  if (!readonly && !skeleton)
57  introduce_user(nick);
58  } else if (s_BotServ && (bi = findbot(nick))) {
59  if (!readonly && !skeleton) {
60  introduce_user(nick);
61  bot_rejoin_all(bi);
62  }
63  } else {
64  do_kill(nick, msg);
65  }
66  return MOD_CONT;
67 }
68 
69 /*************************************************************************/
70 
71 int m_time(char *source, int ac, char **av)
72 {
73  User *u;
74  time_t t;
75  struct tm *tm;
76  char buf[64];
77 
78  /* When using TS6, we get a UID. ~ Viper */
79  if (UseTS6 && ircd->ts6) {
80  u = find_byuid(source);
81  if (!u)
82  u = finduser(source);
83  } else {
84  u = finduser(source);
85  }
86  if (!u) return MOD_CONT;
87 
88  time(&t);
89  tm = localtime(&t);
90  strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm);
91  anope_cmd_391(u->nick, buf);
92  return MOD_CONT;
93 }
94 
95 /*************************************************************************/
96 
97 int m_motd(char *source)
98 {
99  User *u;
100  FILE *f;
101  char buf[BUFSIZE];
102 
103  /* When using TS6, we get a UID. ~ Viper */
104  if (UseTS6 && ircd->ts6) {
105  u = find_byuid(source);
106  if (!u)
107  u = finduser(source);
108  } else {
109  u = finduser(source);
110  }
111  if (!u) return MOD_CONT;
112 
113  f = fopen(MOTDFilename, "r");
114  if (f) {
115  anope_cmd_375(u->nick);
116  while (fgets(buf, sizeof(buf), f)) {
117  buf[strlen(buf) - 1] = 0;
118  anope_cmd_372(u->nick, buf);
119  }
120  fclose(f);
121  anope_cmd_376(u->nick);
122  } else {
124  }
125  return MOD_CONT;
126 }
127 
128 /*************************************************************************/
129 
130 int m_privmsg(char *source, char *receiver, char *msg)
131 {
132  char *s, *target;
133  time_t starttime, stoptime; /* When processing started and finished */
134 
135  BotInfo *bi;
136  ChannelInfo *ci;
137  User *u;
138 
139  if (!source || !*source || !*receiver || !receiver || !msg) {
140  return MOD_CONT;
141  }
142 
143  /* We always get the nick.. the protocol module translates for us.. ~ Viper */
144  u = finduser(source);
145 
146  if (!u) {
147  alog("%s: user record for %s not found", msg, source);
148  anope_cmd_notice(receiver, source,
149  getstring(NULL, USER_RECORD_NOT_FOUND));
150  return MOD_CONT;
151  }
152 
153  if (*receiver == '#') {
154  if (s_BotServ && (ci = cs_findchan(receiver))) {
155  /* Some paranoia checks */
156  if (!(ci->flags & CI_VERBOTEN) && ci->c && ci->bi) {
157  botchanmsgs(u, ci, msg);
158  }
159  }
160  } else {
161  /* Check if we should ignore. Operators always get through. */
162  if (allow_ignore && !is_oper(u)) {
163  IgnoreData *ign = get_ignore(source);
164  if (ign) {
165  target = myStrGetToken(msg, ' ', 0);
166  alog("Ignored message from %s to %s using command %s", source, receiver, target);
167  free(target);
168  return MOD_CONT;
169  }
170  }
171 
172  /* If a server is specified (nick@server format), make sure it matches
173  * us, and strip it off. */
174  s = strchr(receiver, '@');
175  if (s) {
176  *s++ = 0;
177  if (stricmp(s, ServerName) != 0)
178  return MOD_CONT;
179  } else if (UseStrictPrivMsg) {
180  if (debug) {
181  alog("Ignored PRIVMSG without @ from %s", source);
182  }
183  notice_lang(receiver, u, INVALID_TARGET, receiver, receiver,
184  ServerName, receiver);
185  return MOD_CONT;
186  }
187 
188  starttime = time(NULL);
189 
190  if ((stricmp(receiver, s_OperServ) == 0)
191  || (s_OperServAlias
192  && (stricmp(receiver, s_OperServAlias) == 0))) {
193  if (!is_oper(u) && OSOpersOnly) {
194  notice_lang(s_OperServ, u, ACCESS_DENIED);
195  if (WallBadOS) {
197  "Denied access to %s from %s!%s@%s (non-oper)",
198  s_OperServ, u->nick, u->username,
199  u->host);
200  alog("%s: %s (DENIED): %s", s_OperServ, u->nick, msg);
201  }
202  } else {
203  operserv(u, msg);
204  }
205  } else if ((stricmp(receiver, s_NickServ) == 0)
206  || (s_NickServAlias
207  && (stricmp(receiver, s_NickServAlias) == 0))) {
208  nickserv(u, msg);
209  } else if ((stricmp(receiver, s_ChanServ) == 0)
210  || (s_ChanServAlias
211  && (stricmp(receiver, s_ChanServAlias) == 0))) {
212  if (!is_oper(u) && CSOpersOnly)
213  notice_lang(s_ChanServ, u, ACCESS_DENIED);
214  else
215  chanserv(u, msg);
216  } else if ((stricmp(receiver, s_MemoServ) == 0)
217  || (s_MemoServAlias
218  && (stricmp(receiver, s_MemoServAlias) == 0))) {
219  memoserv(u, msg);
220  } else if (s_HostServ && ((stricmp(receiver, s_HostServ) == 0)
221  || (s_HostServAlias
222  &&
223  (stricmp(receiver, s_HostServAlias)
224  == 0)))) {
225  hostserv(u, msg);
226  } else if (s_HelpServ && ((stricmp(receiver, s_HelpServ) == 0)
227  || (s_HelpServAlias
228  &&
229  (stricmp(receiver, s_HelpServAlias)
230  == 0)))) {
231  helpserv(u, msg);
232  } else if (s_BotServ && ((stricmp(receiver, s_BotServ) == 0)
233  || (s_BotServAlias
234  && (stricmp(receiver, s_BotServAlias)
235  == 0)))) {
236  botserv(u, msg);
237  } else if (s_BotServ && (bi = findbot(receiver))) {
238  botmsgs(u, bi, msg);
239  }
240 
241  /* Add to ignore list if the command took a significant amount of time. */
242  if (allow_ignore) {
243  stoptime = time(NULL);
244  if (stoptime > starttime && *source && !strchr(source, '.'))
245  add_ignore(source, stoptime - starttime);
246  }
247  }
248  return MOD_CONT;
249 }
250 
251 /*************************************************************************/
252 
253 int m_stats(char *source, int ac, char **av)
254 {
255  int i;
256  User *u;
257  NickCore *nc;
258 
259  if (ac < 1)
260  return MOD_CONT;
261 
262  /* When using TS6, we get a UID. ~ Viper */
263  if (UseTS6 && ircd->ts6) {
264  u = find_byuid(source);
265  if (!u)
266  u = finduser(source);
267  } else {
268  u = finduser(source);
269  }
270  if (!u) return MOD_CONT;
271 
272  switch (*av[0]) {
273  case 'l':
274  if (is_oper(u)) {
275  if (servernum == 1) {
277  ("%s Server SendBuf SentBytes SentMsgs RecvBuf "
278  "RecvBytes RecvMsgs ConnTime", u->nick);
279  anope_cmd_211("%s %s %d %d %d %d %d %d %ld", u->nick,
282  total_read, -1, time(NULL) - start_time);
283  } else if (servernum == 2) {
285  ("%s Server SendBuf SentBytes SentMsgs RecvBuf "
286  "RecvBytes RecvMsgs ConnTime", u->nick);
287  anope_cmd_211("%s %s %d %d %d %d %d %d %ld", u->nick,
290  total_read, -1, time(NULL) - start_time);
291  } else if (servernum == 3) {
293  ("%s Server SendBuf SentBytes SentMsgs RecvBuf "
294  "RecvBytes RecvMsgs ConnTime", u->nick);
295  anope_cmd_211("%s %s %d %d %d %d %d %d %ld", u->nick,
298  total_read, -1, time(NULL) - start_time);
299  }
300  }
301 
302  anope_cmd_219(u->nick, av[0]);
303  break;
304  case 'o':
305  case 'O':
306  /* Check whether the user is an operator */
307  if (!is_oper(u) && HideStatsO) {
308  anope_cmd_219(u->nick, av[0]);
309  } else {
310  for (i = 0; i < RootNumber; i++)
311  anope_cmd_243("%s O * * %s Root 0", u->nick, ServicesRoots[i]);
312  for (i = 0; i < servadmins.count && (nc = servadmins.list[i]);
313  i++)
314  anope_cmd_243("%s O * * %s Admin 0", u->nick, nc->display);
315  for (i = 0; i < servopers.count && (nc = servopers.list[i]);
316  i++)
317  anope_cmd_243("%s O * * %s Oper 0", u->nick, nc->display);
318 
319  anope_cmd_219(u->nick, av[0]);
320  }
321  break;
322 
323  case 'u':{
324  int uptime = time(NULL) - start_time;
325  anope_cmd_242("%s :Services up %d day%s, %02d:%02d:%02d",
326  u->nick, uptime / 86400,
327  (uptime / 86400 == 1) ? "" : "s",
328  (uptime / 3600) % 24, (uptime / 60) % 60,
329  uptime % 60);
330  anope_cmd_250("%s :Current users: %d (%d ops); maximum %d",
331  u->nick, usercnt, opcnt, maxusercnt);
332  anope_cmd_219(u->nick, av[0]);
333  break;
334  } /* case 'u' */
335 
336  default:
337  anope_cmd_219(u->nick, av[0]);
338  break;
339  }
340  return MOD_CONT;
341 }
342 
343 /*************************************************************************/
344 
345 int m_version(char *source, int ac, char **av)
346 {
347  User *u;
348 
349  /* When using TS6, we get a UID. ~ Viper */
350  if (UseTS6 && ircd->ts6) {
351  u = find_byuid(source);
352  if (!u)
353  u = finduser(source);
354  } else {
355  u = finduser(source);
356  }
357  if (!u) return MOD_CONT;
358 
359  anope_cmd_351(u->nick);
360  return MOD_CONT;
361 }
362 
363 
364 /*************************************************************************/
365 
366 int m_whois(char *source, char *who)
367 {
368  User *u;
369  BotInfo *bi;
370  NickAlias *na;
371  const char *clientdesc;
372 
373  /* When using TS6, we get a UID. ~ Viper */
374  if (UseTS6 && ircd->ts6) {
375  u = find_byuid(source);
376  if (!u)
377  u = finduser(source);
378  } else {
379  u = finduser(source);
380  }
381  if (!u) return MOD_CONT;
382 
383  if (who) {
384  if (stricmp(who, s_NickServ) == 0)
385  clientdesc = desc_NickServ;
386  else if (stricmp(who, s_ChanServ) == 0)
387  clientdesc = desc_ChanServ;
388  else if (stricmp(who, s_MemoServ) == 0)
389  clientdesc = desc_MemoServ;
390  else if (s_BotServ && stricmp(who, s_BotServ) == 0)
391  clientdesc = desc_BotServ;
392  else if (s_HostServ && stricmp(who, s_HostServ) == 0)
393  clientdesc = desc_HostServ;
394  else if (stricmp(who, s_HelpServ) == 0)
395  clientdesc = desc_HelpServ;
396  else if (stricmp(who, s_OperServ) == 0)
397  clientdesc = desc_OperServ;
398  else if (stricmp(who, s_GlobalNoticer) == 0)
399  clientdesc = desc_GlobalNoticer;
400  else if (s_DevNull && stricmp(who, s_DevNull) == 0)
401  clientdesc = desc_DevNull;
402  else if (s_BotServ && (bi = findbot(who))) {
403  /* Bots are handled separately */
404  anope_cmd_311("%s %s %s %s * :%s", u->nick, bi->nick,
405  bi->user, bi->host, bi->real);
406  anope_cmd_307("%s %s :is a registered nick", u->nick, bi->nick);
407  anope_cmd_312("%s %s %s :%s", u->nick, bi->nick, ServerName,
408  ServerDesc);
409  anope_cmd_317("%s %s %ld %ld :seconds idle, signon time",
410  u->nick, bi->nick, time(NULL) - bi->lastmsg,
411  start_time);
412  anope_cmd_318(u->nick, bi->nick);
413  return MOD_CONT;
414  } else if (!(ircd->svshold && UseSVSHOLD) && (na = findnick(who))
415  && (na->status & NS_KILL_HELD)) {
416  /* We have a nick enforcer client here that we need to respond to.
417  * We can't just say it doesn't exist here, even tho it does for
418  * other servers :) -GD
419  */
420  anope_cmd_311("%s %s %s %s * :Services Enforcer", u->nick,
422  anope_cmd_312("%s %s %s :%s", u->nick, na->nick, ServerName,
423  ServerDesc);
424  anope_cmd_318(u->nick, na->nick);
425  return MOD_CONT;
426  } else {
427  anope_cmd_401(u->nick, who);
428  return MOD_CONT;
429  }
430  anope_cmd_311("%s %s %s %s * :%s", u->nick, who,
431  ServiceUser, ServiceHost, clientdesc);
432  anope_cmd_312("%s %s %s :%s", u->nick, who, ServerName, ServerDesc);
433  anope_cmd_317("%s %s %ld %ld :seconds idle, signon time", u->nick,
434  who, time(NULL) - start_time, start_time);
435  anope_cmd_318(u->nick, who);
436  }
437  return MOD_CONT;
438 }
439 
440 /* NULL route messages */
441 int anope_event_null(char *source, int ac, char **av)
442 {
443  return MOD_CONT;
444 }
445 
446 /* *INDENT-OFF* */
447 void moduleAddMsgs(void) {
448  Message *m;
449  m = createMessage("STATS", m_stats); addCoreMessage(IRCD,m);
450  m = createMessage("TIME", m_time); addCoreMessage(IRCD,m);
451  m = createMessage("VERSION", m_version); addCoreMessage(IRCD,m);
452 }
453 
454 /*************************************************************************/
455 
456 Message *find_message(const char *name)
457 {
458  Message *m;
459  m = findMessage(IRCD, name);
460  return m;
461 }
462 
463 /*************************************************************************/
E int is_oper(User *user)
Definition: users.c:937
E int32 usercnt
Definition: extern.h:1140
E int32 opcnt
Definition: extern.h:1140
E void anope_cmd_211(const char *fmt,...)
Definition: ircd.c:493
E char * desc_NickServ
Definition: extern.h:292
E char * desc_GlobalNoticer
Definition: extern.h:298
E int readonly
Definition: extern.h:776
#define NS_KILL_HELD
Definition: services.h:1278
char nick[NICKMAX]
Definition: services.h:875
E NickAlias * findnick(const char *nick)
Definition: db-merger.c:1857
int m_whois(char *source, char *who)
Definition: messages.c:366
E void anope_cmd_243(const char *fmt,...)
Definition: ircd.c:480
E char * s_HelpServAlias
Definition: extern.h:315
E char * RemoteServer2
Definition: extern.h:265
E void operserv(User *u, char *buf)
Definition: operserv.c:129
E char * s_BotServ
Definition: extern.h:287
E IRCDVar * ircd
Definition: extern.h:39
E uint32 maxusercnt
Definition: extern.h:1141
E char * desc_ChanServ
Definition: extern.h:293
MDE int addCoreMessage(MessageHash *msgTable[], Message *m)
Definition: modules.c:1597
E void helpserv(User *u, char *buf)
Definition: helpserv.c:50
E void botserv(User *u, char *buf)
Definition: botserv.c:82
E SList servadmins
Definition: extern.h:971
Message * find_message(const char *name)
Definition: messages.c:456
E char * MOTDFilename
Definition: extern.h:331
E time_t start_time
Definition: extern.h:797
E char * desc_OperServ
Definition: extern.h:297
E int allow_ignore
Definition: extern.h:1021
E char * RemoteServer
Definition: extern.h:262
E char * desc_DevNull
Definition: extern.h:299
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
E void botchanmsgs(User *u, ChannelInfo *ci, char *buf)
Definition: botserv.c:130
E char * NSEnforcerUser
Definition: extern.h:386
int m_version(char *source, int ac, char **av)
Definition: messages.c:345
E void botmsgs(User *u, BotInfo *bi, char *buf)
Definition: botserv.c:107
E char * ServerDesc
Definition: extern.h:275
#define CI_VERBOTEN
Definition: services.h:725
#define getstring(na, index)
Definition: extern.h:731
E User * find_byuid(const char *uid)
Definition: users.c:378
E void chanserv(User *u, char *buf)
Definition: chanserv.c:389
char * host
Definition: services.h:878
MDE Message * createMessage(const char *name, int(*func)(char *source, int ac, char **av))
Definition: modules.c:1470
#define IRCD
Definition: modules.h:63
E void check_memos(User *u)
Definition: memoserv.c:86
E void anope_cmd_242(const char *fmt,...)
Definition: ircd.c:467
E void anope_cmd_250(const char *fmt,...)
Definition: ircd.c:387
E char * desc_HostServ
Definition: extern.h:302
E char * desc_MemoServ
Definition: extern.h:294
E void anope_cmd_375(char *source)
Definition: ircd.c:190
E char * NSEnforcerHost
Definition: extern.h:387
void moduleAddMsgs(void)
Definition: messages.c:447
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
E char * s_OperServAlias
Definition: extern.h:316
E void anope_cmd_372(char *source, char *msg)
Definition: ircd.c:180
int m_nickcoll(char *user)
Definition: messages.c:20
int m_privmsg(char *source, char *receiver, char *msg)
Definition: messages.c:130
E void bot_rejoin_all(BotInfo *bi)
Definition: botserv.c:814
E int OSOpersOnly
Definition: extern.h:1014
char * display
Definition: services.h:542
E void anope_cmd_401(char *source, char *who)
Definition: ircd.c:457
E int WallBadOS
Definition: extern.h:449
E void introduce_user(const char *user)
Definition: init.c:23
E int32 read_buffer_len(void)
Definition: sockutil.c:37
E void anope_cmd_391(char *source, char *timestr)
Definition: ircd.c:382
void ** list
Definition: slist.h:21
E char * s_OperServ
Definition: extern.h:289
E char * s_MemoServ
Definition: extern.h:286
uint32 flags
Definition: services.h:669
E char * ServiceHost
Definition: extern.h:277
int16 count
Definition: slist.h:23
E int nickIsServices(char *nick, int bot)
Definition: misc.c:857
E void anope_cmd_318(char *source, char *who)
Definition: ircd.c:462
E User * finduser(const char *nick)
Definition: users.c:323
E char * s_ChanServAlias
Definition: extern.h:312
uint16 status
Definition: services.h:532
E BotInfo * findbot(char *nick)
Definition: db-merger.c:1989
E char * s_HelpServ
Definition: extern.h:288
struct channel_ * c
Definition: services.h:692
E char * s_BotServAlias
Definition: extern.h:314
E void memoserv(User *u, char *buf)
Definition: memoserv.c:54
char * real
Definition: services.h:576
Message * findMessage(MessageHash *msgTable[], const char *name)
Definition: modules.c:1494
E void anope_cmd_351(char *source)
Definition: ircd.c:329
E void alog(const char *fmt,...) FORMAT(printf
E int servernum
Definition: extern.h:615
E void add_ignore(const char *nick, time_t delta)
Definition: process.c:33
time_t lastmsg
Definition: services.h:581
int svshold
Definition: services.h:338
E int CSOpersOnly
Definition: extern.h:413
#define MOD_CONT
Definition: modules.h:54
E int32 total_written
Definition: extern.h:1123
E int UseTS6
Definition: extern.h:364
E void anope_cmd_376(char *source)
Definition: ircd.c:195
E void anope_cmd_317(const char *fmt,...)
Definition: ircd.c:439
E int debug
Definition: extern.h:775
E void hostserv(User *u, char *buf)
Definition: hostserv.c:88
E char * s_HostServ
Definition: extern.h:303
char * nick
Definition: services.h:526
char * username
Definition: services.h:877
int anope_event_null(char *source, int ac, char **av)
Definition: messages.c:441
E int skeleton
Definition: extern.h:778
E int32 total_read
Definition: extern.h:1123
E char * RemoteServer3
Definition: extern.h:268
E char * s_HostServAlias
Definition: extern.h:319
E int32 write_buffer_len(void)
Definition: sockutil.c:191
E char * desc_BotServ
Definition: extern.h:295
E void anope_cmd_312(const char *fmt,...)
Definition: ircd.c:426
E void do_kill(char *source, char *reason)
Definition: users.c:889
E char ** ServicesRoots
Definition: extern.h:434
char * host
Definition: services.h:575
int m_motd(char *source)
Definition: messages.c:97
E void nickserv(User *u, char *buf)
Definition: nickserv.c:244
E int UseSVSHOLD
Definition: extern.h:357
E char * myStrGetToken(const char *str, const char dilim, int token_number)
Definition: misc.c:654
E void anope_cmd_307(const char *fmt,...)
Definition: ircd.c:400
E void anope_cmd_notice(char *source, char *dest, const char *fmt,...)
Definition: ircd.c:257
E int HideStatsO
Definition: extern.h:429
E IgnoreData * get_ignore(const char *nick)
Definition: process.c:106
E char * s_MemoServAlias
Definition: extern.h:313
char * nick
Definition: services.h:573
E ChannelInfo * cs_findchan(const char *chan)
Definition: db-merger.c:2000
E char * desc_HelpServ
Definition: extern.h:296
int m_stats(char *source, int ac, char **av)
Definition: messages.c:253
E char * ServerName
Definition: extern.h:274
int ts6
Definition: services.h:366
E char * s_ChanServ
Definition: extern.h:285
int m_time(char *source, int ac, char **av)
Definition: messages.c:71
E char * s_NickServ
Definition: extern.h:284
int m_away(char *source, char *msg)
Definition: messages.c:29
BotInfo * bi
Definition: services.h:699
E SList servopers
Definition: extern.h:972
E char * ServiceUser
Definition: extern.h:276
E int UseStrictPrivMsg
Definition: extern.h:353
int m_kill(char *nick, char *msg)
Definition: messages.c:49
char * user
Definition: services.h:574
#define BUFSIZE
Definition: config.h:47
E void anope_cmd_372_error(char *source)
Definition: ircd.c:185
E int RootNumber
Definition: extern.h:435
E char * s_GlobalNoticer
Definition: extern.h:290
E void anope_cmd_219(char *source, char *who)
Definition: ircd.c:452
E char * s_NickServAlias
Definition: extern.h:311
E char * s_DevNull
Definition: extern.h:291
E void anope_cmd_global(char *source, const char *fmt,...)
Definition: ircd.c:506
E void anope_cmd_311(const char *fmt,...)
Definition: ircd.c:413