duration = durationtolong(cargv[1]);
- if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+ if (duration <= 0) {
+ controlreply(sender, "Invalid duration specified.");
+ return CMD_ERROR;
+ }
+
+ if (duration > MAXUSERGLINEDURATION) {
controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
return CMD_ERROR;
}
return CMD_OK;
}
-static int glines_cmdrawgline(void *source, int cargc, char **cargv) {
+static int glines_cmdgline(void *source, int cargc, char **cargv) {
nick *sender = source;
int duration, users, channels;
- char *mask, *reason;
+ char *mask, *reason, *pos;
char creator[32];
+ int coff, sanitychecks, operlimit;
glinebuf gbuf;
-#ifdef SNIRCD_13
+#if SNIRCD_VERSION < 140
gline *gl;
#endif
- if (cargc < 3)
+ if (cargc < 1)
return CMD_USAGE;
- mask = cargv[0];
+ coff = 0;
+ sanitychecks = 1;
+ operlimit = 1;
+
+ if (cargv[0][0] == '-') {
+ coff = 1;
+
+ for (pos = &(cargv[0][1]); *pos; pos++) {
+ switch (*pos) {
+ case 'S':
+ sanitychecks = 0;
+ break;
+ case 'l':
+ operlimit = 0;
+ break;
+ default:
+ controlreply(sender, "Invalid flag specified: %c", *pos);
+ return CMD_ERROR;
+ }
+ }
+ }
- duration = durationtolong(cargv[1]);
+ if (cargc < 3 + coff)
+ return CMD_USAGE;
- if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+ mask = cargv[coff];
+
+ duration = durationtolong(cargv[coff + 1]);
+
+ if (duration <= 0) {
+ controlreply(sender, "Invalid duration specified.");
+ return CMD_ERROR;
+ }
+
+ if (duration > MAXUSERGLINEDURATION) {
controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
return CMD_ERROR;
}
- reason = cargv[2];
+ rejoinline(cargv[coff + 2], cargc - coff - 2);
+ reason = cargv[coff + 2];
if (strlen(reason) < MINUSERGLINEREASON) {
controlreply(sender, "Please specify a proper gline reason.");
return CMD_ERROR;
}
-#ifdef SNIRCD_13
+#if SNIRCD_VERSION < 140
gl = findgline(mask);
if (gl) {
- /* snircd 1.3: warn opers that they can't modify this gline */
+ /* warn opers that they can't modify this gline */
if (gl->flags & GLINE_ACTIVE) {
- controlreply(sender, "Active G-Line already exists on %s - unable to modify", cargv[0]);
+ controlreply(sender, "Active G-Line already exists on %s - unable to modify", mask);
return CMD_ERROR;
}
snprintf(creator, sizeof(creator), "#%s", sender->authname);
glinebufinit(&gbuf, 1);
- glinebufadd(&gbuf, mask, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration);
- glinebufcounthits(&gbuf, &users, &channels);
- if (channels > MAXUSERGLINECHANNELHITS) {
- glinebufabandon(&gbuf);
- controlreply(sender, "G-Line on '%s' would hit %d channels. Limit is %d. Not setting G-Lines.", mask, channels, MAXUSERGLINECHANNELHITS);
+ if (!glinebufadd(&gbuf, mask, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration)) {
+ controlreply(sender, "Invalid G-Line mask.");
return CMD_ERROR;
- } else if (users > MAXUSERGLINEUSERHITS) {
+ }
+
+ if (operlimit) {
+ glinebufcounthits(&gbuf, &users, &channels);
+
+ if (channels > MAXUSERGLINECHANNELHITS) {
+ glinebufabandon(&gbuf);
+ controlreply(sender, "G-Line on '%s' would hit %d channels. Limit is %d. Not setting G-Line.", mask, channels, MAXUSERGLINECHANNELHITS);
+ return CMD_ERROR;
+ } else if (users > MAXUSERGLINEUSERHITS) {
+ glinebufabandon(&gbuf);
+ controlreply(sender, "G-Line on '%s' would hit %d users. Limit is %d. Not setting G-Line.", mask, users, MAXUSERGLINEUSERHITS);
+ return CMD_ERROR;
+ }
+ }
+
+ if (sanitychecks && glinebufsanitize(&gbuf) > 0) {
glinebufabandon(&gbuf);
- controlreply(sender, "G-Line on '%s' would hit %d users. Limit is %d. Not setting G-Lines.", mask, users, MAXUSERGLINEUSERHITS);
+ controlreply(sender, "G-Line failed sanity checks. Not setting G-Line.");
return CMD_ERROR;
}
-
+
glinebufflush(&gbuf, 1);
- controlwall(NO_OPER, NL_GLINES, "%s RAWGLINE'd mask '%s' for %s with reason '%s' (hits %d users/%d channels)", controlid(sender), mask, longtoduration(duration, 0), reason, users, channels);
+ controlwall(NO_OPER, NL_GLINES, "%s GLINE'd mask '%s' for %s with reason '%s' (hits %d users/%d channels)",
+ controlid(sender), mask, longtoduration(duration, 0), reason, users, channels);
controlreply(sender, "Done.");
return CMD_OK;
}
-static int glines_cmdrawglinesimulate(void *source, int cargc, char **cargv) {
+static int glines_cmdglinesimulate(void *source, int cargc, char **cargv) {
nick *sender = source;
char *mask;
glinebuf gbuf;
- gline *gl;
int users, channels;
char creator[32];
snprintf(creator, sizeof(creator), "#%s", sender->authname);
glinebufinit(&gbuf, 0);
- gl = glinebufadd(&gbuf, mask, creator, "Simulate", getnettime(), getnettime(), getnettime());
- if (!gl) {
+ if (!glinebufadd(&gbuf, mask, creator, "Simulate", getnettime(), getnettime(), getnettime())) {
+ glinebufabandon(&gbuf);
controlreply(sender, "Invalid G-Line mask.");
return CMD_ERROR;
}
return CMD_OK;
}
-static int glines_cmdgline(void *source, int cargc, char **cargv) {
+static int glines_cmdsmartgline(void *source, int cargc, char **cargv) {
nick *sender = source;
char *origmask;
char mask[512];
origmask = cargv[0];
if (origmask[0] == '#' || origmask[0] == '&') {
- controlreply(sender, "Please use rawgline for badchans and regex glines.");
+ controlreply(sender, "Please use \"gline\" for badchans and regex glines.");
return CMD_ERROR;
}
duration = durationtolong(cargv[1]);
- if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+ if (duration <= 0) {
+ controlreply(sender, "Invalid duration specified.");
+ return CMD_ERROR;
+ }
+
+ if (duration > MAXUSERGLINEDURATION) {
controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
return CMD_ERROR;
}
strncpy(mask, origmask, sizeof(mask));
if (strchr(mask, '!')) {
- controlreply(sender, "Use rawgline to place nick glines.");
+ controlreply(sender, "Use \"gline\" to place nick glines.");
return CMD_ERROR;
}
duration = durationtolong(cargv[2]);
- if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+ if (duration <= 0) {
+ controlreply(sender, "Invalid duration specified.");
+ return CMD_ERROR;
+ }
+
+ if (duration > MAXUSERGLINEDURATION) {
controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
return CMD_ERROR;
}
return CMD_OK;
}
+static int glines_cmdcleanupglines(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ gline **pnext, *gl;
+ int count;
+
+ count = 0;
+
+ for (pnext = &glinelist; *pnext; pnext = &((*pnext)->next)) {
+ gl = *pnext;
+
+ if (!(gl->flags & GLINE_ACTIVE)) {
+ gline_destroy(gl, 0, 1);
+ count++;
+ }
+
+ 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;
commandsregistered = 1;
registercontrolhelpcmd("block", NO_OPER, 3, glines_cmdblock, "Usage: block <nick> <duration> <reason>\nSets a gline using an appropriate mask given the user's nickname.");
- registercontrolhelpcmd("rawgline", NO_OPER, 3, glines_cmdrawgline, "Usage: rawgline <mask> <duration> <reason>\nSets a gline.");
- registercontrolhelpcmd("rawglinesimulate", NO_OPER, 1, glines_cmdrawglinesimulate, "Usage: rawglinesimulate <mask>\nSimulates what happens when a gline is set.");
- registercontrolhelpcmd("gline", NO_OPER, 3, glines_cmdgline, "Usage: gline <user@host> <duration> <reason>\nSets a gline. Automatically adjusts the mask so as not to hit unrelated trusted users.");
+ registercontrolhelpcmd("gline", NO_OPER, 4, glines_cmdgline, "Usage: gline ?flags? <mask> <duration> <reason>\nSets a gline. Flags can be one or more of:\n-S - bypass sanity checks\n-l - bypass hit limits");
+ registercontrolhelpcmd("glinesimulate", NO_OPER, 1, glines_cmdglinesimulate, "Usage: glinesimulate <mask>\nSimulates what happens when a gline is set.");
+ registercontrolhelpcmd("smartgline", NO_OPER, 3, glines_cmdsmartgline, "Usage: gline <user@host> <duration> <reason>\nSets a gline. Automatically adjusts the mask so as not to hit unrelated trusted users.");
registercontrolhelpcmd("ungline", NO_OPER, 1, glines_cmdungline, "Usage: ungline <mask>\nDeactivates a gline.");
registercontrolhelpcmd("clearchan", NO_OPER, 4, glines_cmdclearchan, "Usage: clearchan <#channel> <how> <duration> ?reason?\nClears a channel.\nhow can be one of:\nkick - Kicks users.\nkill - Kills users.\ngline - Glines non-authed users (using an appropriate mask).\nglineall - Glines users.\nDuration is only valid when glining users. Reason defaults to \"Clearing channel.\".");
registercontrolhelpcmd("trustgline", NO_OPER, 4, glines_cmdtrustgline, "Usage: trustgline <#id|name> <user> <duration> <reason>\nSets a gline on the specified username for each host in the specified trust group. The username may contain wildcards.");
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("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.");
commandsregistered = 0;
deregistercontrolcmd("block", glines_cmdblock);
- deregistercontrolcmd("rawgline", glines_cmdrawgline);
- deregistercontrolcmd("rawglinesimulate", glines_cmdrawglinesimulate);
deregistercontrolcmd("gline", glines_cmdgline);
+ deregistercontrolcmd("glinesimulate", glines_cmdglinesimulate);
+ deregistercontrolcmd("smartgline", glines_cmdsmartgline);
deregistercontrolcmd("ungline", glines_cmdungline);
deregistercontrolcmd("clearchan", glines_cmdclearchan);
deregistercontrolcmd("trustgline", glines_cmdtrustgline);
deregistercontrolcmd("trustungline", glines_cmdtrustungline);
deregistercontrolcmd("glstats", glines_cmdglstats);
deregistercontrolcmd("glist", glines_cmdglist);
+ deregistercontrolcmd("cleanupglines", glines_cmdcleanupglines);
deregistercontrolcmd("syncglines", glines_cmdsyncglines);
deregistercontrolcmd("loadglines", glines_cmdloadglines);
deregistercontrolcmd("saveglines", glines_cmdsaveglines);