]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Add jupe support
authorPaul <redacted>
Sat, 26 May 2007 16:08:03 +0000 (16:08 +0000)
committerPaul <redacted>
Sat, 26 May 2007 16:08:03 +0000 (16:08 +0000)
jupe/Makefile [new file with mode: 0644]
jupe/jupe.c [new file with mode: 0644]
jupe/jupe.h [new file with mode: 0644]
jupe/jupe_commands.c [new file with mode: 0644]

diff --git a/jupe/Makefile b/jupe/Makefile
new file mode 100644 (file)
index 0000000..2b09cd4
--- /dev/null
@@ -0,0 +1,10 @@
+CFLAGS=-g
+
+.PHONY: all
+all: jupe.so jupe_commands.so
+
+jupe.so: jupe.o
+       ld -shared -Bdynamic -o $@ $^
+
+jupe_commands.so: jupe_commands.o
+       ld -shared -Bdynamic -o $@ $^
diff --git a/jupe/jupe.c b/jupe/jupe.c
new file mode 100644 (file)
index 0000000..0eb8c52
--- /dev/null
@@ -0,0 +1,227 @@
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "../core/hooks.h"
+#include "../lib/sstring.h"
+#include "../server/server.h"
+#include "../irc/irc.h"
+#include "../core/error.h"
+#include "../lib/irc_string.h"
+#include "jupe.h"
+
+jupe_t *jupes;
+
+int handlejupe(void *source, int cargc, char **cargv);
+void sendjupeburst(int hook, void *args);
+
+void _init() {
+       jupes = NULL;
+
+       registerhook(HOOK_IRC_SENDBURSTBURSTS, &sendjupeburst);
+       
+       registerserverhandler("JU", &handlejupe, 5);
+}
+
+void _fini() {
+       jupe_t *next;
+
+       while (jupes) {
+               /* keep a pointer to the next item */
+               next = jupes->ju_next;
+
+               free(jupes);
+
+               jupes = next;
+       }
+
+       deregisterhook(HOOK_IRC_SENDBURSTBURSTS, &sendjupeburst);
+       
+       deregisterserverhandler("JU", &handlejupe);
+}
+
+int handlejupe(void *source, int cargc, char **cargv) {
+       char *target, *server, *expire, *modtime, *reason;
+       jupe_t *jupe, *last_jupe;
+       unsigned int flags;
+
+       if (cargc < 5)
+               return CMD_OK; /* local jupe or not a valid.. we don't care */
+
+       target = cargv[0];
+       server = cargv[1];
+       expire = cargv[2];
+       modtime = cargv[3];
+       reason = cargv[4];
+
+       if (atoi(expire) > JUPE_MAX_EXPIRE || atoi(expire) <= 0)
+               return; /* jupe's expiry date is not valid */
+       
+       if (server[0] != '+' && server[0] != '-')
+               return CMD_OK; /* not a valid jupe either */
+       else {
+               flags = (server[0] == '+') ? JUPE_ACTIVE : 0;
+               server++;
+       }
+
+       jupe = jupe_find(server);
+
+       if (jupe != NULL && atoi(modtime) > jupe->ju_lastmod) {
+               jupe->ju_flags = flags;
+               jupe->ju_lastmod = atoi(modtime);
+
+               Error("jupe", ERR_WARNING, "jupe modified for %s (%s) expiring in %s,"
+                                                       " lastmod: %s, active: %s", server, reason, expire, modtime, flags ? "yes" : "no");
+
+               return CMD_OK;
+       }
+
+       jupe = make_jupe(server, reason, getnettime() + atoi(expire),
+                       atoi(modtime), flags);
+
+       if (jupe == NULL)
+               return CMD_ERROR;
+
+       Error("jupe", ERR_WARNING, "jupe added for %s (%s) expiring in %s,"
+                       " lastmod: %s, active: %s", server, reason, expire, modtime, flags ? "yes" : "no");
+
+       return CMD_OK;
+}
+
+void sendjupeburst(int hook, void *args) {
+       jupe_t *jupe = jupes;
+
+       if (hook != HOOK_IRC_SENDBURSTBURSTS)
+               return;
+
+       while (jupe) {
+               jupe_propagate(jupe);
+
+               jupe = jupe->ju_next;
+       }
+}
+
+jupe_t *make_jupe(char *server, char *reason, time_t expirets, time_t lastmod, unsigned int flags) {
+       jupe_t *jupe, *last_jupe;
+
+       jupe = (jupe_t*)malloc(sizeof(jupe_t));
+
+       if (jupe == NULL)
+               return NULL;
+
+       jupe->ju_server = getsstring(server, HOSTLEN);
+       jupe->ju_reason = getsstring(reason, TOPICLEN);
+       jupe->ju_expire = expirets;
+       jupe->ju_lastmod = lastmod;
+       jupe->ju_flags = flags;
+       jupe->ju_next = NULL;
+
+       /* add the jupe to our linked list */
+       if (jupes == NULL)
+               jupes = jupe;
+       else {
+               last_jupe = jupes;
+
+               while (last_jupe->ju_next)
+                       last_jupe = last_jupe->ju_next;
+
+               last_jupe->ju_next = jupe;
+       }
+
+       return jupe;
+}
+
+void jupe_propagate(jupe_t *jupe) {
+       irc_send("%s JU * %c%s %d %d :%s", mynumeric->content, 
+                       JupeIsRemActive(jupe) ? '+' : '-',
+                       JupeServer(jupe),
+                       jupe->ju_expire - getnettime(),
+                       JupeLastMod(jupe),
+                       JupeReason(jupe));
+}
+
+void jupe_expire(void) {
+       jupe_find(NULL);
+}
+
+jupe_t *jupe_find(char *server) {
+       jupe_t *jupe = jupes;
+
+       while (jupe) {
+               /* server == NULL if jupe_find() is used by jupe_expire */
+               if (server && ircd_strcmp(server, JupeServer(jupe)) == 0)
+                       return jupe;
+
+               if (jupe->ju_next && jupe->ju_next->ju_expire < getnettime())
+                       jupe_free(jupe->ju_next);
+               
+               jupe = jupe->ju_next;
+       }
+
+       if (jupes && jupes->ju_expire < getnettime())
+               jupe_free(jupes);
+
+       return NULL;
+}
+
+void jupe_free(jupe_t *jupe) {
+       jupe_t *next = jupe->ju_next;
+       jupe_t *trav = jupes;
+
+       if (jupe == jupes)
+               jupes = jupe->ju_next;
+       else {
+               while (trav) {
+                       if (trav->ju_next == jupe) {
+                               trav->ju_next = jupe->ju_next;
+
+                               break;
+                       }
+
+                       trav = trav->ju_next;
+               }
+       }
+
+       freesstring(jupe->ju_server);
+       freesstring(jupe->ju_reason);
+       free(jupe);
+}
+
+void jupe_activate(jupe_t *jupe) {
+       if (jupe->ju_flags & JUPE_ACTIVE)
+               return;
+
+       jupe->ju_flags |= JUPE_ACTIVE;
+       jupe->ju_lastmod = getnettime();
+
+       jupe_propagate(jupe);
+}
+
+void jupe_deactivate(jupe_t *jupe) {
+       if ((jupe->ju_flags & JUPE_ACTIVE) == 0)
+               return;
+
+       jupe->ju_flags &= ~JUPE_ACTIVE;
+       jupe->ju_lastmod = getnettime();
+
+       jupe_propagate(jupe);
+}
+
+int jupe_add(char *server, char *reason, time_t duration, unsigned int flags) {
+       jupe_t *jupe;
+
+       if (jupe_find(server) != NULL)
+               return 0;
+       
+       if (duration > JUPE_MAX_EXPIRE || duration <= 0)
+               return 0;
+
+       jupe = make_jupe(server, reason, getnettime() + duration,
+                       getnettime(), flags);
+       
+       if (jupe == NULL)
+               return 0;
+
+       jupe_propagate(jupe);
+
+       return 1;
+}
diff --git a/jupe/jupe.h b/jupe/jupe.h
new file mode 100644 (file)
index 0000000..1948899
--- /dev/null
@@ -0,0 +1,31 @@
+typedef struct jupe_s {
+       struct jupe_s*  ju_next;
+       sstring*        ju_server;
+       sstring*        ju_reason;
+       time_t          ju_expire;
+       time_t          ju_lastmod;
+       unsigned int    ju_flags;
+} jupe_t;
+
+extern jupe_t *jupes;
+
+#define JUPE_MAX_EXPIRE        604800
+
+#define JUPE_ACTIVE    0x0001
+
+#define JupeIsRemActive(j)     ((j)->ju_flags & JUPE_ACTIVE)
+
+#define JupeServer(j)          ((j)->ju_server->content)
+#define JupeReason(j)          ((j)->ju_reason->content)
+#define JupeLastMod(j)         ((j)->ju_lastmod)
+
+void jupe_propagate(jupe_t *jupe);
+jupe_t *make_jupe(char *server, char *reason, time_t expirets, time_t lastmod, unsigned int flags);
+void jupe_free(jupe_t *jupe);
+
+/* (public) functions for using/modifying jupes */
+jupe_t *jupe_find(char *server);
+void jupe_activate(jupe_t *jupe);
+void jupe_deactivate(jupe_t *jupe);
+int jupe_add(char *server, char *reason, time_t duration, unsigned int flags);
+void jupe_expire(void); /* call this before directly using the jupes list */
diff --git a/jupe/jupe_commands.c b/jupe/jupe_commands.c
new file mode 100644 (file)
index 0000000..0869dce
--- /dev/null
@@ -0,0 +1,135 @@
+#include "../control/control.h"
+#include "../nick/nick.h"
+#include "../channel/channel.h"
+#include "jupe.h"
+
+int ju_addjupe(void *source, int cargc, char **cargv) {
+       nick *np = (nick*)source;
+       int result, duration;
+       
+       if (cargc < 3) {
+               controlreply(np, "Syntax: addjupe <servername> <duration> <reason>");
+
+               return CMD_OK;
+       }
+
+       if (jupe_find(cargv[0]) != NULL) {
+               controlreply(np, "There is already a jupe for that server.");
+
+               return CMD_OK;
+       }
+
+       duration = durationtolong(cargv[1]);
+       
+       if (duration > JUPE_MAX_EXPIRE) {
+               controlreply(np, "A jupe's maximum duration is %s. Could not create jupe.", longtoduration(JUPE_MAX_EXPIRE));
+
+               return CMD_OK;
+       }
+
+       result = jupe_add(cargv[0], cargv[2], duration, JUPE_ACTIVE);
+
+       if (result)
+               controlreply(np, "Done.");
+       else
+               controlreply(np, "Jupe could not be created.");
+                       
+       return CMD_OK;
+}
+
+int ju_activatejupe(void *source, int cargc, char **cargv) {
+       nick *np = (nick*)source;
+       jupe_t *jupe;
+
+       if (cargc < 1) {
+               controlreply(np, "Syntax: activatejupe <servername>");
+
+               return CMD_OK;
+       }
+
+       jupe = jupe_find(cargv[0]);
+
+       if (jupe == NULL) {
+               controlreply(np, "There is no such jupe.");
+
+               return CMD_OK;
+       }
+
+       if (jupe->ju_flags & JUPE_ACTIVE) {
+               controlreply(np, "This jupe is already activated.");
+
+               return CMD_OK;
+       }
+
+       jupe_activate(jupe);
+
+       controlreply(np, "Done.");
+
+       return CMD_OK;
+}
+
+int ju_deactivatejupe(void *source, int cargc, char **cargv) {
+       nick *np = (nick*)source;
+       jupe_t *jupe;
+
+       if (cargc < 1) {
+               controlreply(np, "Syntax: deactivatejupe <servername>");
+
+               return CMD_OK;
+       }
+
+       jupe = jupe_find(cargv[0]);
+
+       if (jupe == NULL) {
+               controlreply(np, "There is no such jupe.");
+
+               return CMD_OK;
+       }
+
+       if ((jupe->ju_flags & JUPE_ACTIVE) == 0) {
+               controlreply(np, "This jupe is already deactivated.");
+
+               return CMD_OK;
+       }
+
+       jupe_deactivate(jupe);
+
+       controlreply(np, "Done.");
+       
+       return CMD_OK;
+}
+
+int ju_jupelist(void *source, int cargc, char **cargv) {
+       nick *np = (nick*)source;
+       jupe_t *jupe;
+
+       jupe_expire();
+
+       jupe = jupes;
+       
+       controlreply(np, "Server Reason Expires Status");
+
+       while (jupe) {
+               controlreply(np, "%s %s %s %s", JupeServer(jupe), JupeReason(jupe), longtoduration(jupe->ju_expire - getnettime()), (jupe->ju_flags & JUPE_ACTIVE) ? "activated" : "deactivated");
+               
+               jupe = jupe->ju_next;
+       }
+
+       controlreply(np, "--- End of JUPE list.");
+
+       return CMD_OK;
+}
+
+void _init(void) {
+       registercontrolcmd("addjupe", 10, 3, ju_addjupe);
+       registercontrolcmd("activatejupe", 10, 1, ju_activatejupe);
+       registercontrolcmd("deactivatejupe", 10, 1, ju_deactivatejupe);
+       registercontrolcmd("jupelist", 10, 0, ju_jupelist);
+}
+
+void _fini(void) {
+       deregistercontrolcmd("addjupe", ju_addjupe);
+       deregistercontrolcmd("activatejupe", ju_activatejupe);
+       deregistercontrolcmd("deactivatejupe", ju_deactivatejupe);
+       deregistercontrolcmd("jupelist", ju_jupelist);
+}