|
From: wasted <wa...@fi...> - 2003-12-24 08:30:05
|
wasted 2003/12/24 02:30:35 CST
Modified files:
src gline.c
Log:
revise gline system
Revision Changes Path
1.3 +181 -89 wStats/src/gline.c
Index: gline.c
===================================================================
RCS file: /home/cvs/wstats/wStats/src/gline.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gline.c 22 Dec 2003 08:54:21 -0000 1.2
+++ gline.c 24 Dec 2003 08:30:35 -0000 1.3
@@ -18,7 +18,7 @@
* wStats is derrived from srvx (http://srvx.net), everything in here that's
* original srvx code, Copyrighted 2000-2003 srvx Development Team.
*
- * $Id: gline.c,v 1.2 2003/12/22 08:54:21 wasted Exp $
+ * $Id: gline.c,v 1.3 2003/12/24 08:30:35 wasted Exp $
*/
#include "heap.h"
@@ -28,93 +28,185 @@
#include "gline.h"
#include "mysql.h"
-static dict_t gline_dict; /* key: target, data: struct gline* */
-
-static void
-free_gline_from_dict(void *data)
-{
- struct gline *ent = data;
- free(ent->issuer);
- free(ent->target);
- free(ent->reason);
- free(ent);
-}
-
-static void
-expire_gline(void *data)
-{
- struct gline *ex_gline = data;
-
- if(dict_find(gline_dict, ex_gline->target, NULL))
- {
- dict_remove(gline_dict, ex_gline->target);
- free(ex_gline);
- }
-}
-
-int
-gline_remove(const char *target)
-{
- struct gline *ex_gline;
-
- if((ex_gline = dict_find(gline_dict, target, NULL)))
- {
- dict_remove(gline_dict, target);
- timeq_del(0, expire_gline, ex_gline, TIMEQ_IGNORE_WHEN);
- free(ex_gline);
- return 1;
- }
-
- return 0;
-}
-
-struct gline *
-gline_add(const char *issuer, const char *target, unsigned long duration, const char *reason, time_t issued)
-{
- struct gline *newgline;
-
- if(dict_find(gline_dict, target, NULL))
- {
- dict_remove(gline_dict, target);
- }
-
- /* If the duration is in the minus, stop */
- if(duration <= 0) return NULL;
-
- newgline = calloc(1, sizeof(*newgline));
- newgline->expires = now + duration;
- newgline->issued = issued;
- newgline->issuer = strdup(issuer);
- newgline->reason = strdup(reason);
- newgline->target = strdup(target);
-
- dict_insert(gline_dict, newgline->target, newgline);
-
- if(duration) {
- timeq_add(newgline->expires, expire_gline, newgline);
- }
-
- return newgline;
-}
-
-unsigned int
-gline_count(void)
-{
- return dict_size(gline_dict);
-}
-
-static void
-gline_db_cleanup(void)
-{
- dict_delete(gline_dict);
-}
-
-void
-gline_init(void)
-{
- gline_dict = dict_new();
- dict_set_free_data(gline_dict, free_gline_from_dict);
- reg_exit_func(gline_db_cleanup);
+static heap_t gline_heap; /* key: expiry time, data: struct gline_entry* */
+static dict_t gline_dict; /* key: target, data: struct gline_entry* */
+
+static int
+gline_comparator(const void *a, const void *b)
+{
+ const struct gline *ga=a, *gb=b;
+ return ga->expires - gb->expires;
+}
+
+static void
+free_gline_from_dict(void *data)
+{
+ struct gline *ent = data;
+ free(ent->issuer);
+ free(ent->target);
+ free(ent->reason);
+ free(ent);
+}
+
+static void
+free_gline(struct gline *ent)
+{
+ dict_remove(gline_dict, ent->target);
+}
+
+static int
+gline_for_p(UNUSED_ARG(void *key), void *data, void *extra)
+{
+ struct gline *ge = data;
+ return !irccasecmp(ge->target, extra);
+}
+
+static int
+delete_gline_for_p(UNUSED_ARG(void *key), void *data, void *extra)
+{
+ struct gline *ge = data;
+
+ if (!irccasecmp(ge->target, extra))
+ {
+ free_gline(ge);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+static void
+gline_expire(UNUSED_ARG(void *data))
+{
+ time_t stopped;
+ void *wraa;
+
+ stopped = 0;
+ while (heap_size(gline_heap))
+ {
+ heap_peek(gline_heap, 0, &wraa);
+ stopped = ((struct gline*)wraa)->expires;
+ if (stopped > now)
+ {
+ break;
+ }
+ heap_pop(gline_heap);
+ free_gline(wraa);
+ }
+ if (heap_size(gline_heap))
+ {
+ timeq_add(stopped, gline_expire, NULL);
+ }
+}
+
+int
+gline_remove(const char *target)
+{
+ int res = dict_find(gline_dict, target, NULL) ? 1 : 0;
+ if (heap_remove_pred(gline_heap, delete_gline_for_p, (char*)target))
+ {
+ void *argh;
+ struct gline *new_first;
+ heap_peek(gline_heap, 0, &argh);
+ if (argh)
+ {
+ new_first = argh;
+ timeq_del(0, gline_expire, 0, TIMEQ_IGNORE_WHEN|TIMEQ_IGNORE_DATA);
+ timeq_add(new_first->expires, gline_expire, 0);
+ }
+ }
+
+ return res;
+}
+
+struct gline *
+gline_add(const char *issuer, const char *target, unsigned long duration, const char *reason, time_t issued)
+{
+ struct gline *ent;
+ struct gline *prev_first;
+ void *argh;
+
+ heap_peek(gline_heap, 0, &argh);
+ prev_first = argh;
+ ent = dict_find(gline_dict, target, NULL);
+ if (ent)
+ {
+ heap_remove_pred(gline_heap, gline_for_p, (char*)target);
+ if (ent->expires < (time_t)(now + duration))
+ {
+ ent->expires = now + duration;
+ }
+ }
+ else {
+ ent = malloc(sizeof(*ent));
+ ent->issued = issued;
+ ent->issuer = strdup(issuer);
+ ent->target = strdup(target);
+ ent->expires = now + duration;
+ ent->reason = strdup(reason);
+ dict_insert(gline_dict, ent->target, ent);
+ }
+ heap_insert(gline_heap, ent, ent);
+ if (!prev_first || (ent->expires < prev_first->expires))
+ {
+ timeq_del(0, gline_expire, 0, TIMEQ_IGNORE_WHEN|TIMEQ_IGNORE_DATA);
+ timeq_add(ent->expires, gline_expire, 0);
+ }
+
+ return ent;
+}
+
+struct gline *
+gline_find(const char *target)
+{
+ struct gline *res;
+ dict_iterator_t it;
+
+ res = dict_find(gline_dict, target, NULL);
+ if (res)
+ {
+ return res;
+ }
+ /* Stock ircu requires BADCHANs to match exactly. */
+ if ((target[0] == '#') || (target[0] == '&'))
+ {
+ return NULL;
+ }
+ else {
+ /* Otherwise, do an obnoxiously long search. */
+ for (it = dict_first(gline_dict); it; it = iter_next(it))
+ {
+ res = iter_data(it);
+ if (match_ircglob(target, res->target))
+ {
+ return res;
+ }
+ }
+ }
+ return NULL;
+}
+
+unsigned int
+gline_count(void)
+{
+ return dict_size(gline_dict);
+}
+
+static void
+gline_db_cleanup(void)
+{
+ heap_delete(gline_heap);
+ dict_delete(gline_dict);
+}
+
+void
+gline_init(void)
+{
+ gline_heap = heap_new(gline_comparator);
+ gline_dict = dict_new();
+ dict_set_free_data(gline_dict, free_gline_from_dict);
+ reg_exit_func(gline_db_cleanup);
}
static int
@@ -142,4 +234,4 @@
next = iter_next(it);
mysql_insert_gline(target);
}
-}
\ No newline at end of file
+}
|