#include "../localuser/localuserchannel.h"
#include "glines.h"
+//#define DEBUG
+
+#ifdef DEBUG
+#define Debug(...) Error("debuggline", ERR_DEBUG, ##__VA_ARGS__)
+#else
+#define Debug(...)
+#endif
+
/*
<prefix> GL <target> [!][+|-|>|<]<mask> [<expiration>] [<lastmod>] [<lifetime>] [:<reason>]
*/
int handleglinemsg(void *source, int cargc, char **cargv) {
char *sender = (char *)source;
- char *target;
char *mask;
char *reason;
char *creator;
long creatornum;
gline *agline;
nick *np;
+ glinebuf gbuf;
/**
* Valid GL tokens have X params:
* 2: Local modification to a local gline - ignored by services
+ * 4: ulined GL
* 5: 1.3.x GL Token
* 6: 1.4.x GL Token - adds lifetime parameter
*/
case 2:
/* local modification which we reject later */
break;
+ case 4:
+ /* ulined GL */
+ break;
case 5:
/* 1.3.x GL Token */
break;
Error("gline", ERR_WARNING, "Received gline from non-existant server");
return CMD_ERROR;
} else {
- creator = serverlist[(int)creatornum].name->content, HOSTLEN;
+ creator = serverlist[(int)creatornum].name->content;
}
break;
case 5:
return CMD_ERROR;
}
- /* 1st param is target */
- target = cargv[0];
-
- /* anything other than a global G-Line is irrelevant */
- if (strcmp(target, "*") != 0) {
- Error("gline", ERR_WARNING, "Received local g-line from %s - do they realise we're a service?", sender);
- return CMD_ERROR;
- }
-
/* 2nd param is mask */
mask = cargv[1];
+ if (*mask == '%') {
+ flags |= GLINE_DESTROY;
+ mask++;
+ }
+
switch (*mask) {
case '+':
flags |= GLINE_ACTIVATE;
switch (cargc) {
case 4:
/* asuka U:d, no lastmod */
+ lastmod = 0;
+ lifetime = expire;
reason = cargv[3];
break;
case 5:
return CMD_ERROR;
}
- Error("debuggline", ERR_WARNING, "GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator, mask, reason, expire, lastmod, lifetime);
+ Debug("GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator, mask, reason, expire, lastmod, lifetime);
agline = findgline(mask);
if (agline) {
- if (agline->flags & GLINE_ACTIVE) {
- Error("debuggline", ERR_WARNING, "Duplicate Gline recieved for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expire, agline->lifetime, agline->reason->content, agline->creator->content);
+ Debug("Update for existing gline received for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expire, agline->lifetime, agline->reason ? agline->reason->content : "", agline->creator->content);
+
+ agline->flags |= GLINE_ACTIVE;
+
+ /* check lastmod then assume the new gline is authoritive */
+ if (lastmod > agline->lastmod) {
+ agline->lastmod = lastmod;
+ agline->expire = expire;
+ agline->lifetime = lifetime;
+ freesstring(agline->creator);
+ agline->creator = getsstring(creator, 255);
+ freesstring(agline->reason);
+ agline->reason = getsstring(reason, 255);
} else {
- /* we're reactivating a gline - check lastmod then assume the new gline is authoritive */
- if (lastmod > agline->lastmod) {
- agline->lastmod = lastmod;
- agline->expire = expire;
- agline->lifetime = lifetime;
- agline->creator = getsstring(creator, 255);
- freesstring(agline->reason);
- agline->reason = getsstring(reason, 255);
- agline->flags |= GLINE_ACTIVE;
- } else {
- Error("debuggline", ERR_WARNING, "received a gline with a lower lastmod");
- /* @@@TODO resend our gline ? */
- }
- }
- /* TODO */
- return CMD_ERROR;
+ Debug("received a gline with a lower lastmod");
+ /* Don't send our gline as that might cause loops in case we don't understand the gline properly. */
+ }
+
+ return CMD_OK;
} else {
- gline_add(creator, mask, reason, expire, lastmod, lifetime);
+ glinebufinit(&gbuf, 0);
+ glinebufadd(&gbuf, mask, creator, reason, expire, lastmod, lifetime);
+ glinebufcommit(&gbuf, 0);
}
} else if (flags & GLINE_DEACTIVATE) {
/* deactivate gline */
case 5:
/* asuka last mod */
lastmod = atoi(cargv[3]);
- gline_deactivate(agline, lastmod, 0);
+
+ if (flags & GLINE_DESTROY)
+ gline_destroy(agline, lastmod, 0);
+ else
+ gline_deactivate(agline, lastmod, 0);
+
break;
case 6:
/* snircd */
lastmod = atoi(cargv[3]);
- gline_deactivate(agline, lastmod, 0);
+
+ if (flags & GLINE_DESTROY)
+ gline_destroy(agline, lastmod, 0);
+ else
+ gline_deactivate(agline, lastmod, 0);
+
break;
default:
Error("gline", ERR_WARNING, "Gline Deactivate with invalid number (%d) of arguments", cargc);
return CMD_OK;
} else {
+ if (cargc < 5)
+ return; /* U:lined gline, we're done */
Error("gline", ERR_WARNING, "Gline addition - adding deactivated gline - mask not found (%s)", mask);
expire = abs_expire(atoi(cargv[2]));
switch (cargc) {
- case 4:
- /* asuka U:d, no lastmod */
- reason = cargv[3];
- break;
case 5:
/*asuka lastmod */
lastmod = atoi(cargv[3]);
return CMD_ERROR;
}
- agline = gline_add(creator, mask, reason, expire, lastmod, lifetime);
+ glinebufinit(&gbuf, 0);
+ agline = glinebufadd(&gbuf, mask, creator, reason, expire, lastmod, lifetime);
if (!agline) {
+ glinebufabort(&gbuf);
Error("gline", ERR_WARNING, "gline_add failed");
return CMD_ERROR;
}
gline_deactivate(agline, lastmod, 0);
+ glinebufcommit(&gbuf, 0);
return CMD_OK;
}
freesstring(agline->reason);
agline->reason = getsstring(reason, 255);
} else {
- Error("debuggline", ERR_WARNING, "received a gline modification with a lower lastmod");
- /* @@@TODO resend our gline ? */
+ Debug("received a gline modification with a lower lastmod");
}
return CMD_OK;
} else {
- Error("gline", ERR_WARNING, "Received modification for G-Line that does not exist for mask %s", mask);
+ Debug("Received modification for G-Line that does not exist for mask %s", mask);
return CMD_ERROR;
}
}