]> jfr.im git - solanum.git/blobdiff - modules/m_trace.c
extensions/umode_hide_idle_time: mask times for hidden sources (#373)
[solanum.git] / modules / m_trace.c
index 1c0122939e73c709dbad8b4ae9a816d174dce4a2..ae9a0057829e96d71b7574c6680164873a60f63a 100644 (file)
@@ -20,8 +20,6 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
- *
- *  $Id: m_trace.c 3183 2007-02-01 01:07:42Z jilles $
  */
 
 #include "stdinc.h"
@@ -29,7 +27,6 @@
 #include "hook.h"
 #include "client.h"
 #include "hash.h"
-#include "common.h"
 #include "hash.h"
 #include "match.h"
 #include "ircd.h"
 #include "parse.h"
 #include "modules.h"
 
-static int m_trace(struct Client *, struct Client *, int, const char **);
+static const char trace_desc[] =
+       "Provides the TRACE command to trace the route to a client or server";
+
+static void m_trace(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
 
 static void trace_spy(struct Client *, struct Client *);
 
 struct Message trace_msgtab = {
-       "TRACE", 0, 0, 0, MFLG_SLOW,
+       "TRACE", 0, 0, 0, 0,
        {mg_unreg, {m_trace, 0}, {m_trace, 0}, mg_ignore, mg_ignore, {m_trace, 0}}
 };
 
 int doing_trace_hook;
+int doing_trace_show_idle_hook;
 
 mapi_clist_av1 trace_clist[] = { &trace_msgtab, NULL };
 mapi_hlist_av1 trace_hlist[] = {
        { "doing_trace",        &doing_trace_hook },
+       { "doing_trace_show_idle", &doing_trace_show_idle_hook },
        { NULL, NULL }
 };
-DECLARE_MODULE_AV1(trace, NULL, NULL, trace_clist, trace_hlist, NULL, "$Revision: 3183 $");
+DECLARE_MODULE_AV2(trace, NULL, NULL, trace_clist, trace_hlist, NULL, NULL, NULL, trace_desc);
 
 static void count_downlinks(struct Client *server_p, int *pservcount, int *pusercount);
 static int report_this_status(struct Client *source_p, struct Client *target_p);
 
+static const char *empty_sockhost = "255.255.255.255";
+
 /*
  * m_trace
- *      parv[0] = sender prefix
  *      parv[1] = servername
  */
-static int
-m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+static void
+m_trace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
 {
        struct Client *target_p = NULL;
        struct Class *cltmp;
        const char *tname;
-       int doall = 0;
-       int cnt = 0, wilds, dow;
+       bool doall = false, wilds, dow;
+       int cnt = 0;
        rb_dlink_node *ptr;
 
        if(parc > 1)
@@ -86,7 +89,7 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                {
                        if(hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv) !=
                                        HUNTED_ISME)
-                               return 0;
+                               return;
                }
        }
        else
@@ -110,7 +113,7 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
 
                        if(ac2ptr == NULL)
                        {
-                               RB_DLINK_FOREACH(ptr, global_client_list.head)
+                               RB_DLINK_FOREACH(ptr, global_serv_list.head)
                                {
                                        ac2ptr = ptr->data;
 
@@ -124,35 +127,35 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                        /* giving this out with flattened links defeats the
                         * object --fl
                         */
-                       if(IsOper(source_p) || IsExemptShide(source_p) ||
+                       if(IsOperGeneral(source_p) || IsExemptShide(source_p) ||
                           !ConfigServerHide.flatten_links)
-                               sendto_one_numeric(source_p, RPL_TRACELINK, 
+                               sendto_one_numeric(source_p, RPL_TRACELINK,
                                                   form_str(RPL_TRACELINK),
-                                                  ircd_version, 
+                                                  ircd_version,
                                                   ac2ptr ? ac2ptr->name : tname,
                                                   ac2ptr ? ac2ptr->from->name : "EEK!");
 
-                       return 0;
+                       return;
                }
 
                case HUNTED_ISME:
                        break;
 
                default:
-                       return 0;
+                       return;
                }
        }
 
        if(match(tname, me.name))
        {
-               doall = 1;
+               doall = true;
        }
        /* if theyre tracing our SID, we need to move tname to our name so
         * we dont give the sid in ENDOFTRACE
         */
        else if(!MyClient(source_p) && !strcmp(tname, me.id))
        {
-               doall = 1;
+               doall = true;
                tname = me.name;
        }
 
@@ -160,7 +163,7 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
        dow = wilds || doall;
 
        /* specific trace */
-       if(dow == 0)
+       if(!dow)
        {
                if(MyClient(source_p) || parc > 2)
                        target_p = find_named_person(tname);
@@ -172,20 +175,20 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                 */
                if(target_p != NULL)
                {
-                       report_this_status(source_p, target_p, 0);
+                       report_this_status(source_p, target_p);
                        tname = target_p->name;
                }
 
                trace_spy(source_p, target_p);
 
-               sendto_one_numeric(source_p, RPL_ENDOFTRACE, 
+               sendto_one_numeric(source_p, RPL_ENDOFTRACE,
                                   form_str(RPL_ENDOFTRACE), tname);
-               return 0;
+               return;
        }
 
        trace_spy(source_p, NULL);
 
-       /* give non-opers a limited trace output of themselves (if local), 
+       /* give non-opers a limited trace output of themselves (if local),
         * opers and servers (if no shide) --fl
         */
        if(!IsOper(source_p))
@@ -193,7 +196,7 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                if(MyClient(source_p))
                {
                        if(doall || (wilds && match(tname, source_p->name)))
-                               report_this_status(source_p, source_p, 0);
+                               report_this_status(source_p, source_p);
                }
 
                RB_DLINK_FOREACH(ptr, local_oper_list.head)
@@ -203,7 +206,10 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                        if(!doall && wilds && (match(tname, target_p->name) == 0))
                                continue;
 
-                       report_this_status(source_p, target_p, 0);
+                       if(!SeesOper(target_p, source_p))
+                               continue;
+
+                       report_this_status(source_p, target_p);
                }
 
                if (IsExemptShide(source_p) || !ConfigServerHide.flatten_links)
@@ -215,13 +221,13 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                                if(!doall && wilds && !match(tname, target_p->name))
                                        continue;
 
-                               report_this_status(source_p, target_p, 0);
+                               report_this_status(source_p, target_p);
                        }
                }
 
-               sendto_one_numeric(source_p, RPL_ENDOFTRACE, 
+               sendto_one_numeric(source_p, RPL_ENDOFTRACE,
                                   form_str(RPL_ENDOFTRACE), tname);
-               return 0;
+               return;
        }
 
        /* source_p is opered */
@@ -232,18 +238,18 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                target_p = ptr->data;
 
                /* dont show invisible users to remote opers */
-               if(IsInvisible(target_p) && dow && !MyConnect(source_p) && !IsOper(target_p))
+               if(IsInvisible(target_p) && dow && !MyConnect(source_p) && !SeesOper(target_p, source_p))
                        continue;
 
                if(!doall && wilds && !match(tname, target_p->name))
                        continue;
 
                /* remote opers may not see invisible normal users */
-               if(dow && !MyConnect(source_p) && !IsOper(target_p) &&
+               if(dow && !MyConnect(source_p) && !SeesOper(target_p, source_p) &&
                                IsInvisible(target_p))
                        continue;
 
-               cnt = report_this_status(source_p, target_p, dow);
+               cnt = report_this_status(source_p, target_p);
        }
 
        RB_DLINK_FOREACH(ptr, serv_list.head)
@@ -253,7 +259,7 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                if(!doall && wilds && !match(tname, target_p->name))
                        continue;
 
-               cnt = report_this_status(source_p, target_p, dow);
+               cnt = report_this_status(source_p, target_p);
        }
 
        if(MyConnect(source_p))
@@ -265,7 +271,7 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                        if(!doall && wilds && !match(tname, target_p->name))
                                continue;
 
-                       cnt = report_this_status(source_p, target_p, dow);
+                       cnt = report_this_status(source_p, target_p);
                }
        }
 
@@ -277,9 +283,9 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
                /* let the user have some idea that its at the end of the
                 * trace
                 */
-               sendto_one_numeric(source_p, RPL_ENDOFTRACE, 
+               sendto_one_numeric(source_p, RPL_ENDOFTRACE,
                                   form_str(RPL_ENDOFTRACE), tname);
-               return 0;
+               return;
        }
 
        if(doall)
@@ -290,14 +296,12 @@ m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *
 
                        if(CurrUsers(cltmp) > 0)
                                sendto_one_numeric(source_p, RPL_TRACECLASS,
-                                                  form_str(RPL_TRACECLASS), 
+                                                  form_str(RPL_TRACECLASS),
                                                   ClassName(cltmp), CurrUsers(cltmp));
                }
        }
 
        sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), tname);
-
-       return 0;
 }
 
 /*
@@ -330,7 +334,7 @@ count_downlinks(struct Client *server_p, int *pservcount, int *pusercount)
  * side effects - NONE
  */
 static int
-report_this_status(struct Client *source_p, struct Client *target_p, int dow)
+report_this_status(struct Client *source_p, struct Client *target_p)
 {
        const char *name;
        const char *class_name;
@@ -373,31 +377,32 @@ report_this_status(struct Client *source_p, struct Client *target_p, int dow)
                sendto_one_numeric(source_p, RPL_TRACEUNKNOWN,
                                   form_str(RPL_TRACEUNKNOWN),
                                   class_name, name, ip,
-                                  rb_current_time() - target_p->localClient->firsttime);
+                                  (unsigned long)(rb_current_time() - target_p->localClient->firsttime));
                cnt++;
                break;
 
        case STAT_CLIENT:
-                /* Only opers see users if there is a wildcard
-                 * but anyone can see all the opers.
-                 */
-                if((IsOper(source_p) &&
-                    (MyClient(source_p) || !(dow && IsInvisible(target_p))))
-                   || !dow || IsOper(target_p) || (source_p == target_p))
-                {
-                        int tnumeric = RPL_TRACEUSER;
-                        if(IsOper(target_p))
-                                tnumeric = RPL_TRACEOPERATOR;
-                        
-                        sendto_one_numeric(source_p, tnumeric, form_str(tnumeric),
-                                        class_name, name,
-                                        show_ip(source_p, target_p) ? ip : empty_sockhost,
-                                        rb_current_time() - target_p->localClient->lasttime,
-                                        rb_current_time() - target_p->localClient->last);
-                        cnt++;
-                }
-                break;
+               {
+                       /* fire the doing_trace_show_idle hook to allow modules to tell us whether to show the idle time */
+                       hook_data_client_approval hdata_showidle;
+
+                       hdata_showidle.client = source_p;
+                       hdata_showidle.target = target_p;
+                       hdata_showidle.approved = WHOIS_IDLE_SHOW;
+
+                       call_hook(doing_trace_show_idle_hook, &hdata_showidle);
 
+                       sendto_one_numeric(source_p,
+                                       SeesOper(target_p, source_p) ? RPL_TRACEOPERATOR : RPL_TRACEUSER,
+                                       SeesOper(target_p, source_p) ? form_str(RPL_TRACEOPERATOR) : form_str(RPL_TRACEUSER),
+                                       class_name, name,
+                                       show_ip(source_p, target_p) ? ip : empty_sockhost,
+                                       hdata_showidle.approved ? (unsigned long)(rb_current_time() - target_p->localClient->lasttime) : 0,
+                                       hdata_showidle.approved ? (unsigned long)(rb_current_time() - target_p->localClient->last) : 0);
+
+                       cnt++;
+               }
+               break;
 
        case STAT_SERVER:
                {
@@ -409,16 +414,16 @@ report_this_status(struct Client *source_p, struct Client *target_p, int dow)
                        sendto_one_numeric(source_p, RPL_TRACESERVER, form_str(RPL_TRACESERVER),
                                   class_name, servcount, usercount, name,
                                   *(target_p->serv->by) ? target_p->serv->by : "*", "*",
-                                  me.name, rb_current_time() - target_p->localClient->lasttime);
+                                  me.name,
+                                  (unsigned long)(rb_current_time() - target_p->localClient->lasttime));
                        cnt++;
 
                }
                break;
 
        default:                /* ...we actually shouldn't come here... --msa */
-               sendto_one_numeric(source_p, RPL_TRACENEWTYPE, 
-                                  form_str(RPL_TRACENEWTYPE), 
-                                  me.name, source_p->name, name);
+               sendto_one_numeric(source_p, RPL_TRACENEWTYPE,
+                                  form_str(RPL_TRACENEWTYPE), name);
                cnt++;
                break;
        }