Support and use G-line lastmod timestamp.
authorMichael Poole <mdpoole@troilus.org>
Mon, 11 Sep 2006 01:03:14 +0000 (01:03 +0000)
committerMichael Poole <mdpoole@troilus.org>
Mon, 11 Sep 2006 01:03:14 +0000 (01:03 +0000)
src/gline.c (KEY_LASTMOD): New key string.
  (gline_add): Use new parameter to set lastmod.
  (gline_add_record): Look for KEY_LASTMOD values.
  (gline_write_entry): Set KEY_LASTMOD if lastmod is set.
  (gline_discrim_create): Allow specification of lastmod criteria.
  (gline_discrim_match): Check lastmod if appropriate.

src/gline.h (struct gline): Add lastmod field.
  (struct gline_discrim): Add lastmod fields.
  (gline_add): New parameter.

src/mod-sockcheck.c (sockcheck_issue_gline): Set lastmod.

src/opserv.c (OSMSG_NO_GLINE): New format string.
  (opserv_block): Set lastmod.
  (cmd_gline): Set lastmod.
  (cmd_stats_glines): Allow searching for a particular G-line (just like
    gtrace).
  (opserv_new_user_check): Set lastmod.
  (gtrace_print_func): Use intervals rather than fixed dates and show
    lastmod.

src/opserv.help (GTRACE CRITERIA): Mention lastmod criteria.

src/proto-p10.c (irc_gline): Send lastmod if it is set.
  (cmd_num_gline): Parse out lastmod if it is set.
  (cmd_gline): Parse out lastmod if it is set.
git-archimport-id: srvx@srvx.net--2006/srvx--devo--1.3--patch-32

ChangeLog
src/gline.c
src/gline.h
src/mod-sockcheck.c
src/opserv.c
src/opserv.help
src/proto-p10.c

index 8d2827e9b2613d53c9eb8ebf8befab1501fa814b..ff3f60910ac698f876388603c693be90af90fa86 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,46 @@
 # arch-tag: automatic-ChangeLog--srvx@srvx.net--2006/srvx--devo--1.3
 #
 
+2006-09-11 01:03:14 GMT        Michael Poole <mdpoole@troilus.org>     patch-32
+
+    Summary:
+      Support and use G-line lastmod timestamp.
+    Revision:
+      srvx--devo--1.3--patch-32
+
+    src/gline.c (KEY_LASTMOD): New key string.
+      (gline_add): Use new parameter to set lastmod.
+      (gline_add_record): Look for KEY_LASTMOD values.
+      (gline_write_entry): Set KEY_LASTMOD if lastmod is set.
+      (gline_discrim_create): Allow specification of lastmod criteria.
+      (gline_discrim_match): Check lastmod if appropriate.
+    
+    src/gline.h (struct gline): Add lastmod field.
+      (struct gline_discrim): Add lastmod fields.
+      (gline_add): New parameter.
+    
+    src/mod-sockcheck.c (sockcheck_issue_gline): Set lastmod.
+    
+    src/opserv.c (OSMSG_NO_GLINE): New format string.
+      (opserv_block): Set lastmod.
+      (cmd_gline): Set lastmod.
+      (cmd_stats_glines): Allow searching for a particular G-line (just like
+        gtrace).
+      (opserv_new_user_check): Set lastmod.
+      (gtrace_print_func): Use intervals rather than fixed dates and show
+        lastmod.
+    
+    src/opserv.help (GTRACE CRITERIA): Mention lastmod criteria.
+    
+    src/proto-p10.c (irc_gline): Send lastmod if it is set.
+      (cmd_num_gline): Parse out lastmod if it is set.
+      (cmd_gline): Parse out lastmod if it is set.
+
+    modified files:
+     ChangeLog src/gline.c src/gline.h src/mod-sockcheck.c
+     src/opserv.c src/opserv.help src/proto-p10.c
+
+
 2006-09-09 21:37:28 GMT        Michael Poole <mdpoole@troilus.org>     patch-31
 
     Summary:
index 559541340ea58aa1da4bec3540023910494ba1b1..dab6954ca58076ab159181f2c585e0f1988ee9c4 100644 (file)
@@ -40,6 +40,7 @@
 
 #define KEY_REASON "reason"
 #define KEY_EXPIRES "expires"
+#define KEY_LASTMOD "lastmod"
 #define KEY_ISSUER "issuer"
 #define KEY_ISSUED "issued"
 
@@ -134,7 +135,7 @@ gline_remove(const char *target, int announce)
 }
 
 struct gline *
-gline_add(const char *issuer, const char *target, unsigned long duration, const char *reason, time_t issued, int announce)
+gline_add(const char *issuer, const char *target, unsigned long duration, const char *reason, time_t issued, time_t lastmod, int announce)
 {
     struct gline *ent;
     struct gline *prev_first;
@@ -147,9 +148,12 @@ gline_add(const char *issuer, const char *target, unsigned long duration, const
         heap_remove_pred(gline_heap, gline_for_p, (char*)target);
         if (ent->expires < (time_t)(now + duration))
             ent->expires = now + duration;
+        if (ent->lastmod < lastmod)
+            ent->lastmod = lastmod;
     } else {
         ent = malloc(sizeof(*ent));
         ent->issued = issued;
+        ent->lastmod = lastmod;
         ent->issuer = strdup(issuer);
         ent->target = strdup(target);
         ent->expires = now + duration;
@@ -251,7 +255,7 @@ gline_add_record(const char *key, void *data, UNUSED_ARG(void *extra))
 {
     struct record_data *rd = data;
     const char *issuer, *reason, *dstr;
-    time_t issued, expiration;
+    time_t issued, expiration, lastmod;
 
     if (!(reason = database_get_data(rd->d.object, KEY_REASON, RECDB_QSTRING))) {
        log_module(MAIN_LOG, LOG_ERROR, "Missing reason for gline %s", key);
@@ -262,6 +266,8 @@ gline_add_record(const char *key, void *data, UNUSED_ARG(void *extra))
        return 0;
     }
     expiration = strtoul(dstr, NULL, 0);
+    dstr = database_get_data(rd->d.object, KEY_LASTMOD, RECDB_QSTRING);
+    lastmod = dstr ? strtoul(dstr, NULL, 0) : 0;
     if ((dstr = database_get_data(rd->d.object, KEY_ISSUED, RECDB_QSTRING))) {
         issued = strtoul(dstr, NULL, 0);
     } else {
@@ -271,7 +277,7 @@ gline_add_record(const char *key, void *data, UNUSED_ARG(void *extra))
         issuer = "<unknown>";
     }
     if (expiration > now)
-        gline_add(issuer, key, expiration - now, reason, issued, 0);
+        gline_add(issuer, key, expiration - now, reason, issued, lastmod, 0);
     return 0;
 }
 
@@ -290,6 +296,8 @@ gline_write_entry(UNUSED_ARG(void *key), void *data, void *extra)
     saxdb_start_record(ctx, ent->target, 0);
     saxdb_write_int(ctx, KEY_EXPIRES, ent->expires);
     saxdb_write_int(ctx, KEY_ISSUED, ent->issued);
+    if (ent->lastmod)
+        saxdb_write_int(ctx, KEY_LASTMOD, ent->lastmod);
     saxdb_write_string(ctx, KEY_REASON, ent->reason);
     saxdb_write_string(ctx, KEY_ISSUER, ent->issuer);
     saxdb_end_record(ctx);
@@ -327,8 +335,9 @@ gline_discrim_create(struct userNode *user, struct userNode *src, unsigned int a
     struct gline_discrim *discrim;
 
     discrim = calloc(1, sizeof(*discrim));
-    discrim->max_issued = now;
     discrim->limit = 50;
+    discrim->max_issued = INT_MAX;
+    discrim->max_lastmod = INT_MAX;
 
     for (i=0; i<argc; i++) {
         if (i + 2 > argc) {
@@ -363,7 +372,24 @@ gline_discrim_create(struct userNode *user, struct userNode *src, unsigned int a
             discrim->min_expire = now + ParseInterval(argv[++i]);
         else if (!irccasecmp(argv[i], "before"))
             discrim->max_issued = now - ParseInterval(argv[++i]);
-        else {
+        else if (!irccasecmp(argv[i], "lastmod")) {
+            const char *cmp = argv[++i];
+            if (cmp[0] == '<') {
+                if (cmp[1] == '=') {
+                    discrim->min_lastmod = now - ParseInterval(cmp + 2);
+                } else {
+                    discrim->min_lastmod = now - (ParseInterval(cmp + 1) - 1);
+                }
+            } else if (cmp[0] == '>') {
+                if (cmp[1] == '=') {
+                    discrim->max_lastmod = now - ParseInterval(cmp + 2);
+                } else {
+                    discrim->max_lastmod = now - (ParseInterval(cmp + 1) - 1);
+                }
+            } else {
+                discrim->min_lastmod = now - ParseInterval(cmp + 2);
+            }
+        } else {
             send_message(user, src, "MSG_INVALID_CRITERIA", argv[i]);
             goto fail;
         }
@@ -401,7 +427,9 @@ gline_discrim_match(struct gline *gline, struct gline_discrim *discrim)
                     && (!discrim->alt_target_mask
                         || !match_ircglobs(discrim->alt_target_mask, gline->target)))))
         || (discrim->max_issued < gline->issued)
-        || (discrim->min_expire > gline->expires)) {
+        || (discrim->min_expire > gline->expires)
+        || (discrim->min_lastmod > gline->lastmod)
+        || (discrim->max_lastmod < gline->lastmod)) {
         return 0;
     }
     return 1;
index 2824bdebd4dbd5790cb9706de85bb79e07672966..9ad30feb01d6db7a7638d1874f5bcd3108473745 100644 (file)
@@ -25,6 +25,7 @@
 
 struct gline {
     time_t issued;
+    time_t lastmod;
     time_t expires;
     char *issuer;
     char *target;
@@ -40,10 +41,12 @@ struct gline_discrim {
     char *reason_mask;
     time_t max_issued;
     time_t min_expire;
+    time_t min_lastmod;
+    time_t max_lastmod;
 };
 
 void gline_init(void);
-struct gline *gline_add(const char *issuer, const char *target, unsigned long duration, const char *reason, time_t issued, int announce);
+struct gline *gline_add(const char *issuer, const char *target, unsigned long duration, const char *reason, time_t issued, time_t lastmod, int announce);
 struct gline *gline_find(const char *target);
 int gline_remove(const char *target, int announce);
 void gline_refresh_server(struct server *srv);
index 4788e13f2f5ee4cd9fe1e0b64020110393728d96..08ce625e14b65a527d43943e00c7a99d8376542e 100644 (file)
@@ -206,7 +206,7 @@ sockcheck_issue_gline(sockcheck_cache_info sci)
     char addr[IRC_NTOP_MAX_SIZE + 2] = {'*', '@', '\0'};
     irc_ntop(addr + 2, sizeof(addr) - 2, &sci->addr);
     log_module(PC_LOG, LOG_INFO, "Issuing gline for client at %s: %s", addr + 2, sci->reason);
-    gline_add("ProxyCheck", addr, sockcheck_conf.gline_duration, sci->reason, now, 1);
+    gline_add("ProxyCheck", addr, sockcheck_conf.gline_duration, sci->reason, now, now, 1);
 }
 
 static struct sockcheck_client *
index 3c0c683c20e0749846b38364c053edc12516a006..5751df13402f722df6218e6220c41349a226fe81 100644 (file)
@@ -151,6 +151,7 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_BADWORD_LIST", "Bad words: %s" },
     { "OSMSG_EXEMPTED_LIST", "Exempted channels: %s" },
     { "OSMSG_GLINE_COUNT", "There are %d glines active on the network." },
+    { "OSMSG_NO_GLINE", "$b%s$b is not a known G-line." },
     { "OSMSG_LINKS_SERVER", "%s%s (%u clients; %s)" },
     { "OSMSG_MAX_CLIENTS", "Max clients: %d at %s" },
     { "OSMSG_NETWORK_INFO", "Total users: %d (%d invisible, %d opers)" },
@@ -195,7 +196,7 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_GLINE_SEARCH_RESULTS", "The following glines were found:" },
     { "OSMSG_LOG_SEARCH_RESULTS", "The following log entries were found:" },
     { "OSMSG_GSYNC_RUNNING", "Synchronizing glines from %s." },
-    { "OSMSG_GTRACE_FORMAT", "%s (issued %s by %s, expires %s): %s" },
+    { "OSMSG_GTRACE_FORMAT", "%s (issued %s by %s, lastmod %s, expires %s): %s" },
     { "OSMSG_GAG_APPLIED", "Gagged $b%s$b, affecting %d users." },
     { "OSMSG_GAG_ADDED", "Gagged $b%s$b." },
     { "OSMSG_REDUNDANT_GAG", "Gag $b%s$b is redundant." },
@@ -758,7 +759,7 @@ opserv_block(struct userNode *target, char *src_handle, char *reason, unsigned l
                  "G-line requested by %s.", src_handle);
     if (!duration)
         duration = opserv_conf.block_gline_duration;
-    return gline_add(src_handle, mask, duration, reason, now, 1);
+    return gline_add(src_handle, mask, duration, reason, now, now, 1);
 }
 
 static MODCMD_FUNC(cmd_block)
@@ -802,7 +803,7 @@ static MODCMD_FUNC(cmd_gline)
         reply("MSG_INVALID_DURATION", argv[2]);
         return 0;
     }
-    gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, 1);
+    gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, now, 1);
     reply("OSMSG_GLINE_ISSUED", gline->target);
     return 1;
 }
@@ -1303,11 +1304,6 @@ static MODCMD_FUNC(cmd_stats_bad) {
     return 1;
 }
 
-static MODCMD_FUNC(cmd_stats_glines) {
-    reply("OSMSG_GLINE_COUNT", gline_count());
-    return 1;
-}
-
 static void
 trace_links(struct userNode *bot, struct userNode *user, struct server *server, unsigned int depth) {
     unsigned int nn, pos;
@@ -1780,7 +1776,7 @@ opserv_new_user_check(struct userNode *user)
         } else if (ohi->clients.used > limit) {
             char target[IRC_NTOP_MAX_SIZE + 3] = { '*', '@', '\0' };
             strcpy(target + 2, addr);
-            gline_add(opserv->nick, target, opserv_conf.clone_gline_duration, "AUTO Excessive connections from a single host.", now, 1);
+            gline_add(opserv->nick, target, opserv_conf.clone_gline_duration, "AUTO Excessive connections from a single host.", now, now, 1);
         }
     }
 
@@ -3644,11 +3640,38 @@ static void
 gtrace_print_func(struct gline *gline, void *extra)
 {
     struct gline_extra *xtra = extra;
-    char *when_text, set_text[20];
-    strftime(set_text, sizeof(set_text), "%Y-%m-%d", localtime(&gline->issued));
-    when_text = asctime(localtime(&gline->expires));
-    when_text[strlen(when_text)-1] = 0; /* strip lame \n */
-    send_message(xtra->user, opserv, "OSMSG_GTRACE_FORMAT", gline->target, set_text, gline->issuer, when_text, gline->reason);
+    char issued[INTERVALLEN];
+    char lastmod[INTERVALLEN];
+    char expires[INTERVALLEN];
+
+    intervalString(issued, now - gline->issued, xtra->user->handle_info);
+    if (gline->lastmod)
+        intervalString(lastmod, now - gline->lastmod, xtra->user->handle_info);
+    else
+        strcpy(lastmod, "<unknown>");
+    if (gline->expires)
+        intervalString(expires, gline->expires - now, xtra->user->handle_info);
+    else
+        strcpy(expires, "never");
+    send_message(xtra->user, opserv, "OSMSG_GTRACE_FORMAT", gline->target, issued, gline->issuer, lastmod, expires, gline->reason);
+}
+
+static MODCMD_FUNC(cmd_stats_glines) {
+    if (argc < 2) {
+        reply("OSMSG_GLINE_COUNT", gline_count());
+        return 1;
+    } else if (argc < 3) {
+        struct gline_extra extra;
+        struct gline *gl;
+
+        extra.user = user;
+        gl = gline_find(argv[1]);
+        if (!gl)
+            reply("OSMSG_NO_GLINE", argv[1]);
+        else
+            gtrace_print_func(gl, &extra);
+        return 1;
+    } else return 0;
 }
 
 static void
index 297e8b984552597c03783c17401ba6f033c91288..f2e4329a9251a81e23dcdc515a9995cdde55ef52 100644 (file)
         "$bLIMIT$b count            Limits the number of matching glines.",
         "$bREASON$b reason          Looks for glines with the given reason.",
         "$bISSUER$b account         Looks for glines issued by the given account.",
+        "$BLASTMOD$b interval       Looks for glines last modified in the specified time.",
         "$bAFTER$b interval         Looks for glines that expire more than $binterval$b in the future.");
 "GSYNC" ("/msg $O GSYNC [server]",
        "Requests a list of GLINES from its uplink or the specified server.  This can be used in the event srvx is down for period and becomes desynced.",
index 35e5a0928c3753b2859410a2ff51ec1ed6ed7240..75f9e2b4ecda2e34cb1ce55bf6937a09dd9eb764 100644 (file)
@@ -636,8 +636,12 @@ irc_introduce(const char *passwd)
 void
 irc_gline(struct server *srv, struct gline *gline)
 {
-    putsock("%s " P10_GLINE " %s +%s %ld :%s",
-            self->numeric, (srv ? srv->numeric : "*"), gline->target, gline->expires-now, gline->reason);
+    if (gline->lastmod)
+        putsock("%s " P10_GLINE " %s +%s %ld %ld :%s",
+                self->numeric, (srv ? srv->numeric : "*"), gline->target, gline->expires-now, gline->lastmod, gline->reason);
+    else
+        putsock("%s " P10_GLINE " %s +%s %ld :%s",
+                self->numeric, (srv ? srv->numeric : "*"), gline->target, gline->expires-now, gline->reason);
 }
 
 void
@@ -1344,9 +1348,11 @@ static CMD_FUNC(cmd_num_topic)
 
 static CMD_FUNC(cmd_num_gline)
 {
+    time_t lastmod;
     if (argc < 6)
         return 0;
-    gline_add(origin, argv[3], atoi(argv[4])-now, argv[5], now, 0);
+    lastmod = (argc > 5) ? strtoul(argv[5], NULL, 0) : 0;
+    gline_add(origin, argv[3], atoi(argv[4])-now, argv[argc - 1], now, lastmod, 0);
     return 1;
 }
 
@@ -1461,12 +1467,15 @@ static CMD_FUNC(cmd_away)
 
 static CMD_FUNC(cmd_gline)
 {
+    time_t lastmod;
+
     if (argc < 3)
         return 0;
     if (argv[2][0] == '+') {
         if (argc < 5)
             return 0;
-        gline_add(origin, argv[2]+1, strtoul(argv[3], NULL, 0), argv[argc-1], now, 0);
+        lastmod = (argc > 5) ? strtoul(argv[5], NULL, 0) : 0;
+        gline_add(origin, argv[2]+1, strtoul(argv[3], NULL, 0), argv[argc-1], now, lastmod, 0);
         return 1;
     } else if (argv[2][0] == '-') {
         gline_remove(argv[2]+1, 0);