return CMD_OK;
}
+static int glines_cmdsyncglines(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ gline *gl;
+ int count;
+
+ count = 0;
+
+ for (gl = glinelist; gl; gl = gl->next) {
+ gline_propagate(gl);
+ count++;
+ }
+
+ controlwall(NO_OPER, NL_GLINES, "%s SYNCGLINE'd %d G-Lines.",
+ controlid(sender), count);
+
+ controlreply(sender, "Done.");
+
+ return CMD_OK;
+}
+
+static int glines_cmdcleanupglines(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ gline **pnext, *gl;
+ int count;
+ time_t now;
+
+ count = 0;
+ time(&now);
+
+ for (pnext = &glinelist; *pnext;) {
+ gl = *pnext;
+
+ /* Remove inactivate glines that have been last changed more than a week ago */
+ if (1) { /*!(gl->flags & GLINE_ACTIVE) && gl->lastmod < now - 7 * 24 * 60 * 60) {*/
+ gline_destroy(gl, 0, 1);
+ count++;
+ } else {
+ pnext = &((*pnext)->next);
+ }
+
+ if (!*pnext)
+ break;
+ }
+
+ controlwall(NO_OPER, NL_GLINES, "%s CLEANUPGLINES'd %d G-Lines.",
+ controlid(sender), count);
+
+ controlreply(sender, "Done.");
+
+ return CMD_OK;
+}
+
static int commandsregistered;
static void registercommands(int hooknum, void *arg) {
registercontrolhelpcmd("trustungline", NO_OPER, 2, glines_cmdtrustungline, "Usage: trustungline <#id|name> <user>\nRemoves a gline that was previously set with trustgline.");
registercontrolhelpcmd("glstats", NO_OPER, 0, glines_cmdglstats, "Usage: glstat\nShows statistics about G-Lines.");
registercontrolhelpcmd("glist", NO_OPER, 2, glines_cmdglist, "Usage: glist [-flags] <mask>\nLists matching G-Lines.\nValid flags are:\n-c: Count G-Lines.\n-f: Find G-Lines active on <mask>.\n-x: Find G-Lines matching <mask> exactly.\n-R: Find G-lines on realnames.\n-o: Search for glines by owner.\n-r: Search for glines by reason.\n-i: Include inactive glines.");
+ registercontrolhelpcmd("syncglines", NO_DEVELOPER, 0, glines_cmdsyncglines, "Usage: syncglines\nSends all G-Lines to all other servers.");
+ registercontrolhelpcmd("cleanupglines", NO_OPER, 0, glines_cmdcleanupglines, "Usage: cleanupglines\nDestroys all deactivated G-Lines.");
}
static void deregistercommands(int hooknum, void *arg) {
deregistercontrolcmd("trustungline", glines_cmdtrustungline);
deregistercontrolcmd("glstats", glines_cmdglstats);
deregistercontrolcmd("glist", glines_cmdglist);
+ deregistercontrolcmd("syncglines", glines_cmdsyncglines);
+ deregistercontrolcmd("cleanupglines", glines_cmdcleanupglines);
}
void _init(void) {
#include "../control/control.h"
#include "glines.h"
+/** Find canonical user and host for a string.
+ * If \a userhost starts with '$', assign \a userhost to *user_p and NULL to *host_p.
+ * Otherwise, if \a userhost contains '@', assign the earlier part of it to *user_p and the rest to *host_p.
+ * Otherwise, assign \a def_user to *user_p and \a userhost to *host_p.
+ *
+ * @param[in] userhost Input string from user.
+ * @param[out] nick_p Gets pointer to nick part of hostmask.
+ * @param[out] user_p Gets pointer to user (or channel/realname) part of hostmask.
+ * @param[out] host_p Gets point to host part of hostmask (may be assigned NULL).
+ * @param[in] def_user Default value for user part.
+ */
+static void
+canon_userhost(char *userhost, char **nick_p, char **user_p, char **host_p, char *def_user) {
+ char *tmp, *s;
+
+ if (*userhost == '$') {
+ *user_p = userhost;
+ *host_p = NULL;
+ *nick_p = NULL;
+ return;
+ }
+
+ if ((tmp = strchr(userhost, '!'))) {
+ *nick_p = userhost;
+ *(tmp++) = '\0';
+ } else {
+ *nick_p = def_user;
+ tmp = userhost;
+ }
+
+ if (!(s = strchr(tmp, '@'))) {
+ *user_p = def_user;
+ *host_p = tmp;
+ } else {
+ *user_p = tmp;
+ *(s++) = '\0';
+ *host_p = s;
+ }
+}
+
gline *makegline(const char *mask) {
/* populate gl-> user,host,node,nick and set appropriate flags */
gline *gl;
- char nick[512], user[512], host[512];
- const char *pnick = NULL, *puser = NULL, *phost = NULL;
+ char dupmask[512];
+ char *nick, *user, *host;
const char *pos;
int count;
- /* Make sure there are no spaces in the mask, glstore_* depends on this */
+ /* Make sure there are no spaces in the mask */
if (strchr(mask, ' ') != NULL)
return NULL;
Error("gline", ERR_ERROR, "Failed to allocate new gline");
return NULL;
}
-
+
if (mask[0] == '#' || mask[0] == '&') {
gl->flags |= GLINE_BADCHAN;
gl->user = getsstring(mask, CHANNELLEN);
return gl;
}
- if (sscanf(mask, "%[^!]!%[^@]@%s", nick, user, host) == 3) {
- pnick = nick;
- puser = user;
- phost = host;
- } else if (sscanf(mask, "%[^@]@%s", user, host) == 2) {
- puser = user;
- phost = host;
- } else {
- phost = mask;
- }
+ strncpy(dupmask, mask, sizeof(dupmask));
+ canon_userhost(dupmask, &nick, &user, &host, "*");
- /* validate length of the mask components */
- if ((pnick && (pnick[0] == '\0' || strlen(pnick) > NICKLEN)) ||
- (puser && (puser[0] == '\0' || strlen(puser) > USERLEN)) ||
- (phost && (phost[0] == '\0' || strlen(phost) > HOSTLEN))) {
- freegline(gl);
- return NULL;
- }
-
- /* ! and @ are not allowed in the mask components */
- if ((pnick && (strchr(pnick, '!') || strchr(pnick, '@'))) ||
- (puser && (strchr(puser, '!') || strchr(puser, '@'))) ||
- (phost && (strchr(phost, '!') || strchr(phost, '@')))) {
- freegline(gl);
- return NULL;
- }
-
- if (phost && ipmask_parse(phost, &gl->ip, &gl->bits))
+ if (ipmask_parse(host, &gl->ip, &gl->bits))
gl->flags |= GLINE_IPMASK;
else
gl->flags |= GLINE_HOSTMASK;
- /* Don't allow invalid IPv6 bans as those match * on snircd 1.3.4 */
- if (phost) {
- count = 0;
+ /* Don't allow invalid IPv6 bans as those might match * on snircd 1.3.4 */
+ count = 0;
- for (pos = phost; *pos; pos++)
- if (*pos == ':')
- count++;
+ for (pos = host; *pos; pos++)
+ if (*pos == ':')
+ count++;
- if (count >= 8) {
- controlwall(NO_OPER, NL_GLINES, "Warning: Parsed invalid IPv6 G-Line: %s", mask);
- freegline(gl);
- return NULL;
- }
+ if (count >= 8) {
+ controlwall(NO_OPER, NL_GLINES, "Warning: Parsed invalid IPv6 G-Line: %s", mask);
+ freegline(gl);
+ return NULL;
}
- if (pnick && strcmp(pnick, "*") != 0)
- gl->nick = getsstring(pnick, NICKLEN);
+ if (strcmp(nick, "*") != 0)
+ gl->nick = getsstring(nick, 512);
- if (puser && strcmp(puser, "*") != 0)
- gl->user = getsstring(puser, USERLEN);
+ if (strcmp(user, "*") != 0)
+ gl->user = getsstring(user, 512);
- if (phost && strcmp(phost, "*") != 0)
- gl->host = getsstring(phost, HOSTLEN);
+ if (strcmp(host, "*") != 0)
+ gl->host = getsstring(host, 512);
return gl;
}
return glstore_loadfile(path);
}
-static int glines_cmdcleanupglines(void *source, int cargc, char **cargv) {
- nick *sender = source;
- gline **pnext, *gl;
- int count;
- time_t now;
-
- count = 0;
- time(&now);
-
- for (pnext = &glinelist; *pnext;) {
- gl = *pnext;
-
- /* Remove inactivate glines that have been last changed more than a week ago */
- if (!(gl->flags & GLINE_ACTIVE) && gl->lastmod < now - 7 * 24 * 60 * 60) {
- gline_destroy(gl, 0, 1);
- count++;
- } else {
- pnext = &((*pnext)->next);
- }
-
- if (!*pnext)
- break;
- }
-
- controlwall(NO_OPER, NL_GLINES, "%s CLEANUPGLINES'd %d G-Lines.",
- controlid(sender), count);
-
- controlreply(sender, "Done.");
-
- return CMD_OK;
-}
-
-static int glines_cmdsyncglines(void *source, int cargc, char **cargv) {
- nick *sender = source;
- gline *gl;
- int count;
-
- count = 0;
-
- for (gl = glinelist; gl; gl = gl->next) {
- gline_propagate(gl);
- count++;
- }
-
- controlwall(NO_OPER, NL_GLINES, "%s SYNCGLINE'd %d G-Lines.",
- controlid(sender), count);
-
- controlreply(sender, "Done.");
-
- return CMD_OK;
-}
-
static int glines_cmdsaveglines(void *source, int cargc, char **cargv) {
nick *sender = source;
int count;
}
void _init() {
- registercontrolhelpcmd("cleanupglines", NO_OPER, 0, glines_cmdcleanupglines, "Usage: cleanupglines\nDestroys all deactivated G-Lines.");
- registercontrolhelpcmd("syncglines", NO_DEVELOPER, 0, glines_cmdsyncglines, "Usage: syncglines\nSends all G-Lines to all other servers.");
registercontrolhelpcmd("loadglines", NO_DEVELOPER, 0, glines_cmdloadglines, "Usage: loadglines\nForce load of glines.");
registercontrolhelpcmd("saveglines", NO_DEVELOPER, 0, glines_cmdsaveglines, "Usage: saveglines\nForce save of glines.");
}
void _fini() {
- deregistercontrolcmd("cleanupglines", glines_cmdcleanupglines);
- deregistercontrolcmd("syncglines", glines_cmdsyncglines);
deregistercontrolcmd("loadglines", glines_cmdloadglines);
deregistercontrolcmd("saveglines", glines_cmdsaveglines);