messages.c

Go to the documentation of this file.
00001 /* Definitions of IRC message functions and list of messages.
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  *
00011  *
00012  */
00013 
00014 #include "services.h"
00015 #include "messages.h"
00016 #include "language.h"
00017 
00018 /*************************************************************************/
00019 
00020 int m_nickcoll(char *user)
00021 {
00022     if (!skeleton && !readonly)
00023         introduce_user(user);
00024     return MOD_CONT;
00025 }
00026 
00027 /*************************************************************************/
00028 
00029 int m_away(char *source, char *msg)
00030 {
00031     User *u;
00032 
00033     /* When using TS6, we get a UID. ~ Viper */
00034     if (UseTS6 && ircd->ts6) {
00035         u = find_byuid(source);
00036         if (!u)
00037             u = finduser(source);
00038     } else {
00039         u = finduser(source);
00040     }
00041 
00042     if (u && msg == 0)          /* un-away */
00043         check_memos(u);
00044     return MOD_CONT;
00045 }
00046 
00047 /*************************************************************************/
00048 
00049 int m_kill(char *nick, char *msg)
00050 {
00051     BotInfo *bi;
00052 
00053     /* Recover if someone kills us. */
00054     /* use nickIsServices() to reduce the number of lines of code  - TSL */
00055     if (nickIsServices(nick, 0)) {
00056         if (!readonly && !skeleton)
00057             introduce_user(nick);
00058     } else if (s_BotServ && (bi = findbot(nick))) {
00059         if (!readonly && !skeleton) {
00060             introduce_user(nick);
00061             bot_rejoin_all(bi);
00062         }
00063     } else {
00064         do_kill(nick, msg);
00065     }
00066     return MOD_CONT;
00067 }
00068 
00069 /*************************************************************************/
00070 
00071 int m_time(char *source, int ac, char **av)
00072 {
00073     User *u;
00074     time_t t;
00075     struct tm *tm;
00076     char buf[64];
00077 
00078     /* When using TS6, we get a UID. ~ Viper */
00079     if (UseTS6 && ircd->ts6) {
00080         u = find_byuid(source);
00081         if (!u)
00082             u = finduser(source);
00083     } else {
00084         u = finduser(source);
00085     }
00086     if (!u) return MOD_CONT;
00087 
00088     time(&t);
00089     tm = localtime(&t);
00090     strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm);
00091     anope_cmd_391(u->nick, buf);
00092     return MOD_CONT;
00093 }
00094 
00095 /*************************************************************************/
00096 
00097 int m_motd(char *source)
00098 {
00099     User *u;
00100     FILE *f;
00101     char buf[BUFSIZE];
00102 
00103     /* When using TS6, we get a UID. ~ Viper */
00104     if (UseTS6 && ircd->ts6) {
00105         u = find_byuid(source);
00106         if (!u)
00107             u = finduser(source);
00108     } else {
00109         u = finduser(source);
00110     }
00111     if (!u) return MOD_CONT;
00112 
00113     f = fopen(MOTDFilename, "r");
00114     if (f) {
00115         anope_cmd_375(u->nick);
00116         while (fgets(buf, sizeof(buf), f)) {
00117             buf[strlen(buf) - 1] = 0;
00118             anope_cmd_372(u->nick, buf);
00119         }
00120         fclose(f);
00121         anope_cmd_376(u->nick);
00122     } else {
00123         anope_cmd_372_error(u->nick);
00124     }
00125     return MOD_CONT;
00126 }
00127 
00128 /*************************************************************************/
00129 
00130 int m_privmsg(char *source, char *receiver, char *msg)
00131 {
00132     char *s, *target;
00133     time_t starttime, stoptime; /* When processing started and finished */
00134 
00135     BotInfo *bi;
00136     ChannelInfo *ci;
00137     User *u;
00138 
00139     if (!source || !*source || !*receiver || !receiver || !msg) {
00140         return MOD_CONT;
00141     }
00142 
00143     /* We always get the nick.. the protocol module translates for us.. ~ Viper */
00144     u = finduser(source);
00145 
00146     if (!u) {
00147         alog("%s: user record for %s not found", msg, source);
00148         anope_cmd_notice(receiver, source,
00149                          getstring(NULL, USER_RECORD_NOT_FOUND));
00150         return MOD_CONT;
00151     }
00152 
00153     if (*receiver == '#') {
00154         if (s_BotServ && (ci = cs_findchan(receiver))) {
00155             /* Some paranoia checks */
00156             if (!(ci->flags & CI_VERBOTEN) && ci->c && ci->bi) {
00157                 botchanmsgs(u, ci, msg);
00158             }
00159         }
00160     } else {
00161         /* Check if we should ignore.  Operators always get through. */
00162         if (allow_ignore && !is_oper(u)) {
00163             IgnoreData *ign = get_ignore(source);
00164             if (ign) {
00165                 target = myStrGetToken(msg, ' ', 0);
00166                 alog("Ignored message from %s to %s using command %s", source, receiver, target);
00167                 free(target);
00168                 return MOD_CONT;
00169             }
00170         }
00171 
00172         /* If a server is specified (nick@server format), make sure it matches
00173          * us, and strip it off. */
00174         s = strchr(receiver, '@');
00175         if (s) {
00176             *s++ = 0;
00177             if (stricmp(s, ServerName) != 0)
00178                 return MOD_CONT;
00179         } else if (UseStrictPrivMsg) {
00180             if (debug) {
00181                 alog("Ignored PRIVMSG without @ from %s", source);
00182             }
00183             notice_lang(receiver, u, INVALID_TARGET, receiver, receiver,
00184                         ServerName, receiver);
00185             return MOD_CONT;
00186         }
00187 
00188         starttime = time(NULL);
00189 
00190         if ((stricmp(receiver, s_OperServ) == 0)
00191             || (s_OperServAlias
00192                 && (stricmp(receiver, s_OperServAlias) == 0))) {
00193             if (!is_oper(u) && OSOpersOnly) {
00194                 notice_lang(s_OperServ, u, ACCESS_DENIED);
00195                 if (WallBadOS) {
00196                     anope_cmd_global(s_OperServ,
00197                                      "Denied access to %s from %s!%s@%s (non-oper)",
00198                                      s_OperServ, u->nick, u->username,
00199                                      u->host);
00200                     alog("%s: %s (DENIED): %s", s_OperServ, u->nick, msg);
00201                 }
00202             } else {
00203                 operserv(u, msg);
00204             }
00205         } else if ((stricmp(receiver, s_NickServ) == 0)
00206                    || (s_NickServAlias
00207                        && (stricmp(receiver, s_NickServAlias) == 0))) {
00208             nickserv(u, msg);
00209         } else if ((stricmp(receiver, s_ChanServ) == 0)
00210                    || (s_ChanServAlias
00211                        && (stricmp(receiver, s_ChanServAlias) == 0))) {
00212             if (!is_oper(u) && CSOpersOnly)
00213                 notice_lang(s_ChanServ, u, ACCESS_DENIED);
00214             else
00215                 chanserv(u, msg);
00216         } else if ((stricmp(receiver, s_MemoServ) == 0)
00217                    || (s_MemoServAlias
00218                        && (stricmp(receiver, s_MemoServAlias) == 0))) {
00219             memoserv(u, msg);
00220         } else if (s_HostServ && ((stricmp(receiver, s_HostServ) == 0)
00221                                   || (s_HostServAlias
00222                                       &&
00223                                       (stricmp(receiver, s_HostServAlias)
00224                                        == 0)))) {
00225             hostserv(u, msg);
00226         } else if (s_HelpServ && ((stricmp(receiver, s_HelpServ) == 0)
00227                                   || (s_HelpServAlias
00228                                       &&
00229                                       (stricmp(receiver, s_HelpServAlias)
00230                                        == 0)))) {
00231             helpserv(u, msg);
00232         } else if (s_BotServ && ((stricmp(receiver, s_BotServ) == 0)
00233                                  || (s_BotServAlias
00234                                      && (stricmp(receiver, s_BotServAlias)
00235                                          == 0)))) {
00236             botserv(u, msg);
00237         } else if (s_BotServ && (bi = findbot(receiver))) {
00238             botmsgs(u, bi, msg);
00239         }
00240 
00241         /* Add to ignore list if the command took a significant amount of time. */
00242         if (allow_ignore) {
00243             stoptime = time(NULL);
00244             if (stoptime > starttime && *source && !strchr(source, '.'))
00245                 add_ignore(source, stoptime - starttime);
00246         }
00247     }
00248     return MOD_CONT;
00249 }
00250 
00251 /*************************************************************************/
00252 
00253 int m_stats(char *source, int ac, char **av)
00254 {
00255     int i;
00256     User *u;
00257     NickCore *nc;
00258 
00259     if (ac < 1)
00260         return MOD_CONT;
00261 
00262     /* When using TS6, we get a UID. ~ Viper */
00263     if (UseTS6 && ircd->ts6) {
00264         u = find_byuid(source);
00265         if (!u)
00266             u = finduser(source);
00267     } else {
00268         u = finduser(source);
00269     }
00270     if (!u) return MOD_CONT;
00271 
00272     switch (*av[0]) {
00273     case 'l':
00274         if (is_oper(u)) {
00275             if (servernum == 1) {
00276                 anope_cmd_211
00277                     ("%s Server SendBuf SentBytes SentMsgs RecvBuf "
00278                      "RecvBytes RecvMsgs ConnTime", u->nick);
00279                 anope_cmd_211("%s %s %d %d %d %d %d %d %ld", u->nick,
00280                               RemoteServer, write_buffer_len(),
00281                               total_written, -1, read_buffer_len(),
00282                               total_read, -1, time(NULL) - start_time);
00283             } else if (servernum == 2) {
00284                 anope_cmd_211
00285                     ("%s Server SendBuf SentBytes SentMsgs RecvBuf "
00286                      "RecvBytes RecvMsgs ConnTime", u->nick);
00287                 anope_cmd_211("%s %s %d %d %d %d %d %d %ld", u->nick,
00288                               RemoteServer2, write_buffer_len(),
00289                               total_written, -1, read_buffer_len(),
00290                               total_read, -1, time(NULL) - start_time);
00291             } else if (servernum == 3) {
00292                 anope_cmd_211
00293                     ("%s Server SendBuf SentBytes SentMsgs RecvBuf "
00294                      "RecvBytes RecvMsgs ConnTime", u->nick);
00295                 anope_cmd_211("%s %s %d %d %d %d %d %d %ld", u->nick,
00296                               RemoteServer3, write_buffer_len(),
00297                               total_written, -1, read_buffer_len(),
00298                               total_read, -1, time(NULL) - start_time);
00299             }
00300         }
00301 
00302         anope_cmd_219(u->nick, av[0]);
00303         break;
00304     case 'o':
00305     case 'O':
00306         /* Check whether the user is an operator */
00307         if (!is_oper(u) && HideStatsO) {
00308             anope_cmd_219(u->nick, av[0]);
00309         } else {
00310             for (i = 0; i < RootNumber; i++)
00311                 anope_cmd_243("%s O * * %s Root 0", u->nick, ServicesRoots[i]);
00312             for (i = 0; i < servadmins.count && (nc = servadmins.list[i]);
00313                  i++)
00314                 anope_cmd_243("%s O * * %s Admin 0", u->nick, nc->display);
00315             for (i = 0; i < servopers.count && (nc = servopers.list[i]);
00316                  i++)
00317                 anope_cmd_243("%s O * * %s Oper 0", u->nick, nc->display);
00318 
00319             anope_cmd_219(u->nick, av[0]);
00320         }
00321         break;
00322 
00323     case 'u':{
00324             int uptime = time(NULL) - start_time;
00325             anope_cmd_242("%s :Services up %d day%s, %02d:%02d:%02d",
00326                           u->nick, uptime / 86400,
00327                           (uptime / 86400 == 1) ? "" : "s",
00328                           (uptime / 3600) % 24, (uptime / 60) % 60,
00329                           uptime % 60);
00330             anope_cmd_250("%s :Current users: %d (%d ops); maximum %d",
00331                           u->nick, usercnt, opcnt, maxusercnt);
00332             anope_cmd_219(u->nick, av[0]);
00333             break;
00334         }                       /* case 'u' */
00335 
00336     default:
00337         anope_cmd_219(u->nick, av[0]);
00338         break;
00339     }
00340     return MOD_CONT;
00341 }
00342 
00343 /*************************************************************************/
00344 
00345 int m_version(char *source, int ac, char **av)
00346 {
00347     User *u; 
00348 
00349     /* When using TS6, we get a UID. ~ Viper */
00350     if (UseTS6 && ircd->ts6) {
00351         u = find_byuid(source);
00352         if (!u)
00353             u = finduser(source);
00354     } else {
00355         u = finduser(source);
00356     }
00357     if (!u) return MOD_CONT;
00358 
00359     anope_cmd_351(u->nick);
00360     return MOD_CONT;
00361 }
00362 
00363 
00364 /*************************************************************************/
00365 
00366 int m_whois(char *source, char *who)
00367 {
00368     User *u; 
00369     BotInfo *bi;
00370     NickAlias *na;
00371     const char *clientdesc;
00372 
00373     /* When using TS6, we get a UID. ~ Viper */
00374     if (UseTS6 && ircd->ts6) {
00375         u = find_byuid(source);
00376         if (!u)
00377             u = finduser(source);
00378     } else {
00379         u = finduser(source);
00380     }
00381     if (!u) return MOD_CONT;
00382 
00383     if (who) {
00384         if (stricmp(who, s_NickServ) == 0)
00385             clientdesc = desc_NickServ;
00386         else if (stricmp(who, s_ChanServ) == 0)
00387             clientdesc = desc_ChanServ;
00388         else if (stricmp(who, s_MemoServ) == 0)
00389             clientdesc = desc_MemoServ;
00390         else if (s_BotServ && stricmp(who, s_BotServ) == 0)
00391             clientdesc = desc_BotServ;
00392         else if (s_HostServ && stricmp(who, s_HostServ) == 0)
00393             clientdesc = desc_HostServ;
00394         else if (stricmp(who, s_HelpServ) == 0)
00395             clientdesc = desc_HelpServ;
00396         else if (stricmp(who, s_OperServ) == 0)
00397             clientdesc = desc_OperServ;
00398         else if (stricmp(who, s_GlobalNoticer) == 0)
00399             clientdesc = desc_GlobalNoticer;
00400         else if (s_DevNull && stricmp(who, s_DevNull) == 0)
00401             clientdesc = desc_DevNull;
00402         else if (s_BotServ && (bi = findbot(who))) {
00403             /* Bots are handled separately */
00404             anope_cmd_311("%s %s %s %s * :%s", u->nick, bi->nick,
00405                           bi->user, bi->host, bi->real);
00406             anope_cmd_307("%s %s :is a registered nick", u->nick, bi->nick);
00407             anope_cmd_312("%s %s %s :%s", u->nick, bi->nick, ServerName,
00408                           ServerDesc);
00409             anope_cmd_317("%s %s %ld %ld :seconds idle, signon time",
00410                           u->nick, bi->nick, time(NULL) - bi->lastmsg,
00411                           start_time);
00412             anope_cmd_318(u->nick, bi->nick);
00413             return MOD_CONT;
00414         } else if (!(ircd->svshold && UseSVSHOLD) && (na = findnick(who))
00415                    && (na->status & NS_KILL_HELD)) {
00416             /* We have a nick enforcer client here that we need to respond to.
00417              * We can't just say it doesn't exist here, even tho it does for
00418              * other servers :) -GD
00419              */
00420             anope_cmd_311("%s %s %s %s * :Services Enforcer", u->nick,
00421                           na->nick, NSEnforcerUser, NSEnforcerHost);
00422             anope_cmd_312("%s %s %s :%s", u->nick, na->nick, ServerName,
00423                           ServerDesc);
00424             anope_cmd_318(u->nick, na->nick);
00425             return MOD_CONT;
00426         } else {
00427             anope_cmd_401(u->nick, who);
00428             return MOD_CONT;
00429         }
00430         anope_cmd_311("%s %s %s %s * :%s", u->nick, who,
00431                       ServiceUser, ServiceHost, clientdesc);
00432         anope_cmd_312("%s %s %s :%s", u->nick, who, ServerName, ServerDesc);
00433         anope_cmd_317("%s %s %ld %ld :seconds idle, signon time", u->nick,
00434                       who, time(NULL) - start_time, start_time);
00435         anope_cmd_318(u->nick, who);
00436     }
00437     return MOD_CONT;
00438 }
00439 
00440 /* NULL route messages */
00441 int anope_event_null(char *source, int ac, char **av)
00442 {
00443     return MOD_CONT;
00444 }
00445 
00446 /* *INDENT-OFF* */
00447 void moduleAddMsgs(void) {
00448     Message *m;
00449     m = createMessage("STATS",     m_stats); addCoreMessage(IRCD,m);
00450     m = createMessage("TIME",      m_time); addCoreMessage(IRCD,m);
00451     m = createMessage("VERSION",   m_version); addCoreMessage(IRCD,m);
00452 }
00453 
00454 /*************************************************************************/
00455 
00456 Message *find_message(const char *name)
00457 {
00458     Message *m;
00459     m = findMessage(IRCD, name);
00460     return m;
00461 }
00462 
00463 /*************************************************************************/