Discussion:
[Patches] SF.net SVN: undernet-ircu:[1900] ircu2/branches/u2_10_12_branch
e***@users.sourceforge.net
2009-01-13 02:30:25 UTC
Permalink
Revision: 1900
http://undernet-ircu.svn.sourceforge.net/undernet-ircu/?rev=1900&view=rev
Author: entrope
Date: 2009-01-13 02:30:25 +0000 (Tue, 13 Jan 2009)

Log Message:
-----------
Author: Entrope <***@troilus.org>
Description:

Make G-line parsing considerably more robust for unusual input forms.
Fix affected-user counting for G-lines with CIDR host portions. Add
tests to exercise the new parsing behaviors.

Modified Paths:
--------------
ircu2/branches/u2_10_12_branch/ChangeLog
ircu2/branches/u2_10_12_branch/include/gline.h
ircu2/branches/u2_10_12_branch/ircd/gline.c
ircu2/branches/u2_10_12_branch/ircd/m_gline.c
ircu2/branches/u2_10_12_branch/tests/ircd-2.conf
ircu2/branches/u2_10_12_branch/tests/ircd.conf
ircu2/branches/u2_10_12_branch/tests/readme.txt
ircu2/branches/u2_10_12_branch/tests/test-driver.pl

Added Paths:
-----------
ircu2/branches/u2_10_12_branch/tests/glines.cmd

Modified: ircu2/branches/u2_10_12_branch/ChangeLog
===================================================================
--- ircu2/branches/u2_10_12_branch/ChangeLog 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/ChangeLog 2009-01-13 02:30:25 UTC (rev 1900)
@@ -1,3 +1,36 @@
+2009-01-12 Michael Poole <***@troilus.org>
+
+ * include/gline.h (gline_forward_deactivation): Declare.
+
+ * ircd/gline.c (count_users): Use ipmask-based checks too.
+ (gline_add): Require flags to have exactly one of the GLINE_GLOBAL
+ and GLINE_LOCAL bits set.
+ (gline_forward_deactivation): Implement new function.
+ (gline_find): Only require the GLINE_LOCAL flag to be set in the
+ gline structure; infer GLINE_GLOBAL when it is cleared. (This
+ matches the value and usage of GLINE_MASK.)
+
+ * ircd/m_gline.c (ms_gline): Default lastmod to the known lastmod
+ time for GLINE_LOCAL_{DE,}ACTIVATE.
+ (mo_gline): Check that expiration times parse as expected. Reject
+ "*" as a target for GLINE_LOCAL_{DE,}ACTIVATE. Require reason and
+ expiration time for new G-lines. Allow deactivation of an unknown
+ G-line without creating it ("so-and-so ... creating new G-line" is
+ a confusing message for a deactivation).
+
+ * tests/glines.cmd: New test script for G-line parsing tests.
+
+ * tests/ircd.conf: Enable CONFIG_OPERCMDS for glines.cmd.
+
+ * tests/ircd-2.conf: Likewise.
+
+ * tests/readme.txt: Add section on command syntax.
+
+ * tests/test-driver.pl: Report line numbers more clearly.
+ Fix (somewhat kludgily) the brokenness of consecutive "expect"
+ lines, as demonstrated by the numeric 219 and 281 expects in
+ glines.cmd.
+
2008-11-17 Michael Poole <***@troilus.org>

* ircd/m_kick.c (ms_kick): Properly handle crossing net rider and

Modified: ircu2/branches/u2_10_12_branch/include/gline.h
===================================================================
--- ircu2/branches/u2_10_12_branch/include/gline.h 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/include/gline.h 2009-01-13 02:30:25 UTC (rev 1900)
@@ -128,6 +128,9 @@
extern int gline_deactivate(struct Client *cptr, struct Client *sptr,
struct Gline *gline, time_t lastmod,
unsigned int flags);
+extern int gline_forward_deactivation(struct Client *cptr, struct Client *sptr,
+ char *userhost, time_t expire, time_t lastmod,
+ time_t lifetime, unsigned int flags);
extern int gline_modify(struct Client *cptr, struct Client *sptr,
struct Gline *gline, enum GlineAction action,
char *reason, time_t expire, time_t lastmod,

Modified: ircu2/branches/u2_10_12_branch/ircd/gline.c
===================================================================
--- ircu2/branches/u2_10_12_branch/ircd/gline.c 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/ircd/gline.c 2009-01-13 02:30:25 UTC (rev 1900)
@@ -354,11 +354,15 @@
static int
count_users(char *mask)
{
+ struct irc_in_addr ipmask;
struct Client *acptr;
int count = 0;
+ int ipmask_valid;
char namebuf[USERLEN + HOSTLEN + 2];
char ipbuf[USERLEN + SOCKIPLEN + 2];
+ unsigned char ipmask_len;

+ ipmask_valid = ipmask_parse(mask, &ipmask, &ipmask_len);
for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) {
if (!IsUser(acptr))
continue;
@@ -368,7 +372,9 @@
ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s@%s", cli_user(acptr)->username,
ircd_ntoa(&cli_ip(acptr)));

- if (!match(mask, namebuf) || !match(mask, ipbuf))
+ if (!match(mask, namebuf)
+ || !match(mask, ipbuf)
+ || (ipmask_valid && ipmask_check(&cli_ip(acptr), &ipmask, ipmask_len)))
count++;
}

@@ -429,6 +435,8 @@

assert(0 != userhost);
assert(0 != reason);
+ assert(((flags & (GLINE_GLOBAL | GLINE_LOCAL)) == GLINE_GLOBAL) ||
+ ((flags & (GLINE_GLOBAL | GLINE_LOCAL)) == GLINE_LOCAL));

Debug((DEBUG_DEBUG, "gline_add(\"%s\", \"%s\", \"%s\", \"%s\", %Tu, %Tu "
"%Tu, 0x%04x)", cli_name(cptr), cli_name(sptr), userhost, reason,
@@ -664,6 +672,42 @@
return 0;
}

+/** Send a deactivation request for a locally unknown G-line.
+ * @param[in] cptr Client that sent us the G-line modification.
+ * @param[in] sptr Client that originated the G-line modification.
+ * @param[in] userhost Text representation of G-line target.
+ * @param[in] expire Expiration time of G-line.
+ * @param[in] lastmod Last modification time of G-line.
+ * @param[in] lifetime Lifetime of G-line.
+ * @param[in] flags Bitwise combination of GLINE_* flags.
+ * @return Zero.
+ */
+int
+gline_forward_deactivation(struct Client *cptr, struct Client *sptr,
+ char *userhost, time_t expire, time_t lastmod,
+ time_t lifetime, unsigned int flags)
+{
+ char *msg = "deactivating unknown global";
+
+ if (!lifetime)
+ lifetime = expire;
+
+ /* Inform ops and log it */
+ sendto_opmask_butone(0, SNO_GLINE, "%s %s GLINE for %s, expiring at %Tu",
+ (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
+ cli_name(sptr) : cli_name((cli_user(sptr))->server),
+ msg, userhost, expire + TSoffset);
+
+ log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE,
+ "%#C %s GLINE for %s, expiring at %Tu", sptr, msg, userhost,
+ expire);
+
+ sendcmdto_serv_butone(sptr, CMD_GLINE, cptr, "* -%s %Tu %Tu %Tu",
+ userhost, expire, lastmod, lifetime);
+
+ return 0;
+}
+
/** Modify a global G-line.
* @param[in] cptr Client that sent us the G-line modification.
* @param[in] sptr Client that originated the G-line modification.
@@ -918,8 +962,7 @@

if (flags & (GLINE_BADCHAN | GLINE_ANY)) {
gliter(BadChanGlineList, gline, sgline) {
- if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) ||
- (flags & GLINE_LOCAL && gline->gl_flags & GLINE_GLOBAL) ||
+ if ((flags & (GlineIsLocal(gline) ? GLINE_GLOBAL : GLINE_LOCAL)) ||
(flags & GLINE_LASTMOD && !gline->gl_lastmod))
continue;
else if ((flags & GLINE_EXACT ? ircd_strcmp(gline->gl_user, userhost) :
@@ -936,8 +979,7 @@
canon_userhost(t_uh, &user, &host, "*");

gliter(GlobalGlineList, gline, sgline) {
- if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) ||
- (flags & GLINE_LOCAL && gline->gl_flags & GLINE_GLOBAL) ||
+ if ((flags & (GlineIsLocal(gline) ? GLINE_GLOBAL : GLINE_LOCAL)) ||
(flags & GLINE_LASTMOD && !gline->gl_lastmod))
continue;
else if (flags & GLINE_EXACT) {

Modified: ircu2/branches/u2_10_12_branch/ircd/m_gline.c
===================================================================
--- ircu2/branches/u2_10_12_branch/ircd/m_gline.c 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/ircd/m_gline.c 2009-01-13 02:30:25 UTC (rev 1900)
@@ -279,6 +279,7 @@
case GLINE_LOCAL_DEACTIVATE: /* locally deactivating a G-line */
if (!agline) /* no G-line to locally activate or deactivate? */
return send_reply(sptr, ERR_NOSUCHGLINE, mask);
+ lastmod = agline->gl_lastmod;
break; /* no additional parameters to manipulate */

case GLINE_ACTIVATE: /* activating a G-line */
@@ -379,7 +380,7 @@
unsigned int flags = 0;
enum GlineAction action = GLINE_MODIFY;
time_t expire = 0;
- char *mask = parv[1], *target = 0, *reason = 0;
+ char *mask = parv[1], *target = 0, *reason = 0, *end;

if (parc < 2)
return gline_list(sptr, 0);
@@ -422,7 +423,9 @@
return need_more_params(sptr, "GLINE");

target = parv[2]; /* get the target... */
- expire = atoi(parv[3]) + CurrentTime; /* and the expiration */
+ expire = strtol(parv[3], &end, 10) + CurrentTime; /* and the expiration */
+ if (*end != '\0')
+ return send_reply(sptr, SND_EXPLICIT | ERR_BADEXPIRE, "%s :Bad expire time", parv[3]);

flags |= GLINE_EXPIRE; /* remember that we got an expire time */

@@ -442,8 +445,11 @@

case GLINE_LOCAL_ACTIVATE: /* locally activate a G-line */
case GLINE_LOCAL_DEACTIVATE: /* locally deactivate a G-line */
- if (parc > 2) /* if target is available, pick it */
+ if (parc > 2) { /* if target is available, pick it */
target = parv[2];
+ if (target[0] == '*' && target[1] == '\0')
+ return send_reply(sptr, ERR_NOSUCHSERVER, target);
+ }
break;

case GLINE_ACTIVATE: /* activating/adding a G-line */
@@ -453,8 +459,10 @@

if (parc > 3) {
/* get expiration and target */
- expire = atoi(parv[parc - 2]) + CurrentTime;
reason = parv[parc - 1];
+ expire = strtol(parv[parc - 2], &end, 10) + CurrentTime;
+ if (*end != '\0')
+ return send_reply(sptr, SND_EXPLICIT | ERR_BADEXPIRE, "%s :Bad expire time", parv[parc - 2]);

flags |= GLINE_EXPIRE | GLINE_REASON; /* remember that we got 'em */

@@ -499,8 +507,8 @@
action == GLINE_LOCAL_ACTIVATE ? '>' : '<'));

sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s", acptr,
- flags & GLINE_OPERFORCE ? "!" : "",
- action == GLINE_LOCAL_ACTIVATE ? '>' : '<', mask);
+ flags & GLINE_OPERFORCE ? "!" : "",
+ action == GLINE_LOCAL_ACTIVATE ? '>' : '<', mask);

return 0; /* all done */
}
@@ -582,10 +590,12 @@
}
}

- /* can't modify a G-line that doesn't exist... */
+ /* can't modify a G-line that doesn't exist...
+ * (and if we are creating a new one, we need a reason and expiration)
+ */
if (!agline &&
(action == GLINE_MODIFY || action == GLINE_LOCAL_ACTIVATE ||
- action == GLINE_LOCAL_DEACTIVATE))
+ action == GLINE_LOCAL_DEACTIVATE || !reason || !expire))
return send_reply(sptr, ERR_NOSUCHGLINE, mask);

/* check for G-line permissions... */
@@ -600,6 +610,12 @@
return send_reply(sptr, ERR_NOPRIVILEGES);
}

+ /* If globally disabling a G-line that we do not already have, avoid
+ * creating a temporary one. */
+ if (!agline && action == GLINE_DEACTIVATE) {
+ return gline_forward_deactivation(cptr, sptr, mask, expire, CurrentTime, 0, flags);
+ }
+
Debug((DEBUG_DEBUG, "I have a global G-line I am acting upon now; "
"target %s, mask %s, operforce %s, action %s, expire %Tu, "
"reason: %s; gline %s! (fields present: %s %s)", target,

Added: ircu2/branches/u2_10_12_branch/tests/glines.cmd
===================================================================
--- ircu2/branches/u2_10_12_branch/tests/glines.cmd (rev 0)
+++ ircu2/branches/u2_10_12_branch/tests/glines.cmd 2009-01-13 02:30:25 UTC (rev 1900)
@@ -0,0 +1,330 @@
+define srv1 localhost:7601
+define srv1-name irc.example.net
+define srv2 localhost:7611
+define srv2-name irc-2.example.net
+define cl1-nick Op3rm4n
+define cl2-nick Monitor
+
+# Connect a client, oper it up and force G-line server notices on (0x8200).
+connect cl1 %cl1-nick% oper %srv1% :Some IRC Operator
+:cl1 oper oper oper
+:cl1 mode %cl1-nick% +s +33280
+
+# Do the same for the second server, for monitoring snotices.
+# This is useful while debugging the remote operations in this script.
+connect cl2 %cl2-nick% oper %srv2% :Some IRC Operator
+:cl2 oper oper oper
+:cl2 mode %cl2-nick% +s +33280
+
+# For an operator, the syntax is:
+# GLINE [[!][+|-|>|<]<mask> [<target>] [<expiration> [:<reason>]]]
+# By itself, that's 2 * 5 * 3 (target missing/self, other or global)
+# * 3 = 90 possibilities.
+#
+# In each case, we would want to try it with various combinations:
+# - Local gline for <mask> absent or present
+# - Global gline for <mask> absent, or present but locally and/or globally activated or deactivated (5 combinations)
+# So ten pre-existing states for each syntax variant.
+# For sanity's sake, we don't do all 900 combinations.
+#
+# Perl code to generate a fairly complete list:
+# foreach my $operator (split(//, ' +-><')) {
+# foreach my $mask ('***@example.com') {
+# foreach my $target ('', '%srv1-name%', '%srv2-name%', '*') {
+# foreach my $expiration ('', '100000') {
+# foreach my $reason ('', ':foo') {
+# my $str = "GLINE ${operator}${mask} ${target} ${expiration} ${reason}";
+# $str =~ s/ +/ /g;
+# $str =~ s/ +$//;
+# print "$str\n";
+# }
+# }
+# }
+# print "\n";
+# }
+# }
+
+# Initial query: verify that our target G-line does not exist.
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+
+# Try a bunch of operations, only one of which should generate an actual G-line.
+:cl1 raw :GLINE ***@example.com :foo
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE ***@example.com 100000
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE ***@example.com 100000 :foo
+:cl1 expect %srv1-name% 515 foo :Bad expire time
+:cl1 raw :GLINE ***@example.com %srv1-name%
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE ***@example.com %srv1-name% :foo
+:cl1 expect %srv1-name% 515 foo :Bad expire time
+:cl1 raw :GLINE ***@example.com %srv1-name% 100000
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+
+# Check that we still have no G-line, and that we create it as expected.
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+:cl1 raw :GLINE ***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% adding local GLINE for ***@example.com, expiring at \\d+: foo
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 280 ***@example.com \\d+ 0 \\d+ %srv1-name% \\+ :foo
+:cl1 expect %srv1-name% 281 :End of G-line List
+# Now remove it (and verify removal).
+:cl1 raw :GLINE -***@example.com 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% removing local GLINE for ***@example.com
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+
+# Try doing remote operations.
+:cl1 raw :GLINE ***@example.com %srv2-name%
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE ***@example.com %srv2-name% :foo
+:cl1 expect %srv1-name% 515 foo :Bad expire time
+:cl1 raw :GLINE ***@example.com %srv2-name% 100000
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+:cl1 raw :GLINE ***@example.com %srv2-name% 100000 :foo
+# No response expected for remote commands; do a remote stats query to check.
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ 0 \\d+ \\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+:cl1 raw :GLINE -***@example.com %srv2-name% 100000 :foo
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+
+# Try doing network-wide operations.
+:cl1 raw :GLINE ***@example.com *
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+# These should fail because no existing G-line matches.
+:cl1 raw :GLINE ***@example.com * :foo
+:cl1 expect %srv1-name% 515 foo :Bad expire time
+:cl1 raw :GLINE ***@example.com * 100000
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+:cl1 raw :GLINE ***@example.com * 100000 :foo
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+
+# Try explicit create/activate operations.
+:cl1 raw :GLINE +***@example.com
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE +***@example.com :foo
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE +***@example.com 100000
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+# This next one should create the G-line.
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+:cl1 raw :GLINE +***@example.com 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% adding local GLINE for ***@example.com, expiring at \\d+: foo
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 280 ***@example.com \\d+ 0 \\d+ %srv1-name% \\+ :foo
+:cl1 expect %srv1-name% 281 :End of G-line List
+:cl1 raw :GLINE -***@example.com 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% removing local GLINE for ***@example.com
+
+# Local create/activate operations?
+:cl1 raw :GLINE +***@example.com %srv1-name%
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE +***@example.com %srv1-name% :foo
+:cl1 expect %srv1-name% 515 .+ :Bad expire time
+:cl1 raw :GLINE +***@example.com %srv1-name% 100000
+:cl1 expect %srv1-name% 515 .+ :Bad expire time
+:cl1 raw :GLINE +***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% adding local GLINE for ***@example.com, expiring at \\d+: foo
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 280 ***@example.com \\d+ 0 \\d+ %srv1-name% \\+ :foo
+:cl1 expect %srv1-name% 281 :End of G-line List
+:cl1 raw :GLINE -***@example.com 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% removing local GLINE for ***@example.com
+:cl1 raw :GLINE +***@example.com %srv1-name% 100000 :foo
+:cl1 raw :GLINE -***@example.com 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% removing local GLINE for ***@example.com
+:cl1 raw :GLINE +***@example.com %srv1-name% 100000 :foo
+:cl1 raw :GLINE -***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% removing local GLINE for ***@example.com
+
+# Remote create/activate operations?
+:cl1 raw :GLINE +***@example.com %srv2-name%
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE +***@example.com %srv2-name% :foo
+:cl1 expect %srv1-name% 515 .+ :Bad expire time
+:cl1 raw :GLINE +***@example.com %srv2-name% 100000
+:cl1 expect %srv1-name% 515 .+ :Bad expire time
+:cl1 raw :GLINE +***@example.com %srv2-name% 100000 :foo
+# No response expected for remote commands; do a remote stats query to check.
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ 0 \\d+ \\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+:cl1 raw :GLINE -***@example.com %srv2-name% 100000 :foo
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+
+# Global create/activate operations?
+:cl1 raw :GLINE +***@example.com *
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+:cl1 raw :GLINE +***@example.com * :foo
+:cl1 expect %srv1-name% 515 .+ :Bad expire time
+:cl1 raw :GLINE +***@example.com * 100000
+:cl1 expect %srv1-name% 515 .+ :Bad expire time
+
+# Local G-line deactivation?
+:cl1 raw :GLINE -***@example.com
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE -***@example.com :foo
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE -***@example.com 100000
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE -***@example.com 100000 :foo
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+
+# .. with a specified server?
+:cl1 raw :GLINE -***@example.com %srv1-name%
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE -***@example.com %srv1-name% :foo
+:cl1 expect %srv1-name% 515 %srv1-name% :Bad expire time
+:cl1 raw :GLINE -***@example.com %srv1-name% 100000
+:cl1 expect %srv1-name% 515 %srv1-name% :Bad expire time
+:cl1 raw :GLINE -***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+:cl1 raw :GLINE -***@example.com %srv2-name%
+:cl1 expect %srv1-name% 461 GLINE :Not enough parameters
+:cl1 raw :GLINE -***@example.com %srv2-name% :foo
+:cl1 expect %srv1-name% 515 %srv2-name% :Bad expire time
+:cl1 raw :GLINE -***@example.com %srv2-name% 100000
+:cl1 expect %srv1-name% 515 %srv2-name% :Bad expire time
+:cl1 raw :GLINE -***@example.com %srv2-name% 100000 :foo
+:cl1 expect %srv2-name% 512 ***@example.com :No such gline
+
+# Global deactivations?
+:cl1 raw :GLINE -***@example.com *
+:cl1 expect %srv1-name% 512 ***@example.com :No such gline
+:cl1 raw :GLINE -***@example.com * :foo
+:cl1 expect %srv1-name% 515 \\* :Bad expire time
+:cl1 raw :GLINE -***@example.com * 100000
+:cl1 expect %srv1-name% 515 \\* :Bad expire time
+:cl1 raw :GLINE -***@example.com * 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% deactivating unknown global GLINE for ***@example.com
+
+# Now start with the operations that create or need a global G-line.
+
+# Global activations and deactivations?
+:cl1 raw :GLINE +***@example.com * 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% adding global GLINE for ***@example.com
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 280 ***@example.com \\d+ \\d+ \\d+ \\* \\+ :foo
+:cl1 raw :GLINE ***@example.com * 100000
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: changing expiration time to \\d+; and extending record lifetime to \\d+
+:cl1 raw :GLINE ***@example.com * 100000 :food
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: changing expiration time to \\d+; extending record lifetime to \\d+; and changing reason to "food"
+:cl1 raw :GLINE -***@example.com *
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: globally deactivating G-line
+:cl1 raw :GLINE -***@example.com * 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: changing expiration time to \\d+; extending record lifetime to \\d+; and changing reason to "foo"
+:cl1 raw :GLINE ***@example.com
+:cl1 expect %srv1-name% 280 ***@example.com \\d+ \\d+ \\d+ \\* - :foo
+
+# Failed local activations and deactivations?
+:cl1 raw :GLINE >***@example.com
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally activating G-line
+:cl1 raw :GLINE <***@example.com
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally deactivating G-line
+:cl1 raw :GLINE >***@example.com :foo
+:cl1 expect %srv1-name% 402 foo :No such server
+:cl1 raw :GLINE <***@example.com :foo
+:cl1 expect %srv1-name% 402 foo :No such server
+:cl1 raw :GLINE >***@example.com 100000
+:cl1 expect %srv1-name% 402 100000 :No such server
+:cl1 raw :GLINE <***@example.com 100000 :foo
+:cl1 expect %srv1-name% 402 100000 :No such server
+:cl1 raw :GLINE <***@example.com 100000 :foo
+:cl1 expect %srv1-name% 402 100000 :No such server
+:cl1 raw :GLINE >***@2.example.com
+:cl1 expect %srv1-name% 512 ***@2.example.com :No such gline
+:cl1 raw :GLINE >***@example.com %srv1-name%
+
+# What about successes for the local server?
+# (For simplicity, single-server activations and deactivations are not
+# allowed to change any other parameters.)
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally activating G-line
+:cl1 raw :GLINE <***@example.com %srv1-name%
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally deactivating G-line
+:cl1 raw :GLINE >***@example.com %srv1-name% :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally activating G-line
+:cl1 raw :GLINE <***@example.com %srv1-name% :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally deactivating G-line
+:cl1 raw :GLINE >***@example.com %srv1-name% 100000
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally activating G-line
+:cl1 raw :GLINE <***@example.com %srv1-name% 100000
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally deactivating G-line
+:cl1 raw :GLINE >***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally activating G-line
+:cl1 raw :GLINE <***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally deactivating G-line
+:cl1 raw :GLINE >***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally activating G-line
+:cl1 raw :GLINE <***@example.com %srv1-name% 100000 :foo
+:cl1 expect %srv1-name% NOTICE :\\*\\*\\* Notice -- %cl1-nick% modifying global GLINE for ***@example.com: locally deactivating G-line
+
+# And successful activations/deactiations for a (single) remote server?
+# First make sure the global G-line is globally activated.
+:cl1 raw :GLINE +***@example.com * 100000 :foo
+# Form: "GLINE <***@mask server.name"
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ \\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+:cl1 raw :GLINE <***@example.com %srv2-name%
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ <\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+:cl1 raw :GLINE >***@example.com %srv2-name%
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ >\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+# Form: "GLINE <***@mask server.name :foo"
+:cl1 raw :GLINE <***@example.com %srv2-name% :foo
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ <\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+:cl1 raw :GLINE >***@example.com %srv2-name% :foo
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ >\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+# Form: "GLINE <***@mask server.name 100000"
+:cl1 raw :GLINE <***@example.com %srv2-name% 100000
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ <\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+:cl1 raw :GLINE >***@example.com %srv2-name% 100000
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ >\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+# Form: "GLINE <***@mask server.name 100000 :foo"
+:cl1 raw :GLINE <***@example.com %srv2-name% 100000 :foo
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ <\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+:cl1 raw :GLINE >***@example.com %srv2-name% 100000 :foo
+:cl1 raw :STATS g %srv2-name%
+:cl1 expect %srv2-name% 247 G ***@example.com \\d+ \\d+ \\d+ >\\+ :foo
+:cl1 expect %srv2-name% 219 g :End of /STATS report
+
+# What about activations/deactivations that might go across the whole network?
+# (These are not permitted because "global local [de]activation" does not
+# make sense: just globally [de]activate the G-line.)
+:cl1 raw :GLINE >***@example.com *
+:cl1 expect %srv1-name% 402 \\* :No such server
+:cl1 raw :GLINE <***@example.com *
+:cl1 expect %srv1-name% 402 \\* :No such server
+:cl1 raw :GLINE >***@example.com * :foo
+:cl1 expect %srv1-name% 402 \\* :No such server
+:cl1 raw :GLINE <***@example.com * :foo
+:cl1 expect %srv1-name% 402 \\* :No such server
+:cl1 raw :GLINE >***@example.com * 100000
+:cl1 expect %srv1-name% 402 \\* :No such server
+:cl1 raw :GLINE <***@example.com * 100000
+:cl1 expect %srv1-name% 402 \\* :No such server
+:cl1 raw :GLINE >***@example.com * 100000 :foo
+:cl1 expect %srv1-name% 402 \\* :No such server
+:cl1 raw :GLINE <***@example.com * 100000 :foo
+:cl1 expect %srv1-name% 402 \\* :No such server

Modified: ircu2/branches/u2_10_12_branch/tests/ircd-2.conf
===================================================================
--- ircu2/branches/u2_10_12_branch/tests/ircd-2.conf 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/tests/ircd-2.conf 2009-01-13 02:30:25 UTC (rev 1900)
@@ -35,4 +35,5 @@

Features {
"PPATH" = "ircd-2.pid";
+ "CONFIG_OPERCMDS" = "TRUE";
};

Modified: ircu2/branches/u2_10_12_branch/tests/ircd.conf
===================================================================
--- ircu2/branches/u2_10_12_branch/tests/ircd.conf 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/tests/ircd.conf 2009-01-13 02:30:25 UTC (rev 1900)
@@ -37,4 +37,5 @@

Features {
"HUB" = "TRUE";
+ "CONFIG_OPERCMDS" = "TRUE";
};

Modified: ircu2/branches/u2_10_12_branch/tests/readme.txt
===================================================================
--- ircu2/branches/u2_10_12_branch/tests/readme.txt 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/tests/readme.txt 2009-01-13 02:30:25 UTC (rev 1900)
@@ -19,3 +19,89 @@

The normal output is one dot for each line that is executed. Using
the -D and -V options generates much more output.
+
+Command Syntax
+==============
+
+A test script typically starts with a set of variable definitions for
+strings that are used throughout the script or that may be changed to
+match changes ircu's configuration file. These have the syntax:
+ define <variable> <replacement text>
+
+A variable is expanded by writing %variablename% in later commands.
+If a variable is dereferenced without a definition, the test will
+abort.
+
+Following the variable definitions is usually one or more "connect"
+statements. These have the syntax:
+ connect <tag> <nickname> <username> <server:port> :<Real Name or GECOS>
+This creates a client and starts a connection to an IRC server. The
+tag is used to issue commands for that client in the rest of the file.
+The remaining fields have their usual meanings for IRC.
+
+A number of IRC commands are supported natively, including:
+ :<tag> join <channel>
+ :<tag> mode <nick/channel> [<modes> ...]
+ :<tag> nick <nickname>
+ :<tag> notice <target> :<text>
+ :<tag> oper <name> <password>
+ :<tag> part <channel> [:<message>]
+ :<tag> privmsg <target> :<text>
+ :<tag> quit [:<message>]
+ :<tag> raw :<irc line to send>
+
+Other commands are used to implement tests:
+ :<tag> expect <irc line contents>
+ :<tag> sleep <seconds>
+ :<tag> wait <tag2,tag3>
+
+The test commands are discussed at more length below.
+
+expect Syntax
+=============
+
+The command to look for data coming from the irc server is "expect":
+ :<tag> expect <irc line contents>
+
+The contents are treated as a regular expression and matched against
+the start of the line. If the line from the IRC server began with
+':', that is removed before the match is performed.
+
+Because the contents are a regular expression, and because \ is used
+as an escape character both in parsing both the script line and the
+regular expression, some common things become awkward to match:
+ :cl1 mode %channel% +D
+ :cl1 expect %cl1-nick% mode %channel% \\+D
+or a more drastic example:
+ :cl1 mode %channel% +b *!*@*.bar.example.*
+ :cl1 mode %channel% +b
+ :cl1 expect %srv1-name% 367 %channel% \\*!\\*@\\*\\.bar\\.example\\.* %cl1-nick% \\d+
+
+sleep Syntax
+============
+
+The command to make a client stop operating for a fixed period of time
+is "sleep":
+ :<tag> sleep <seconds>
+
+This will deactivate the identified client for at least <seconds>
+seconds (which may be a floating point number). Other clients will
+continue to process commands, but if another command for the
+identified client is encountered, it will block execution until the
+time expires.
+
+wait Syntax
+===========
+
+The command to synchronize one client to another is "wait":
+ :<tag> wait <tag2[,tag3...]>
+
+This is syntactic sugar for something like this:
+ :<tag> expect <nick2> NOTICE <nick> :SYNC
+ :<nick2> notice <nick> :SYNC
+ :<tag> expect <nick3> NOTICE <nick> :SYNC
+ :<nick3> notice <nick> :SYNC
+
+In other words, the wait command uses in-IRC messages to make sure
+that other clients have already executed commands up to a certain
+point in the test script.

Modified: ircu2/branches/u2_10_12_branch/tests/test-driver.pl
===================================================================
--- ircu2/branches/u2_10_12_branch/tests/test-driver.pl 2008-12-21 03:44:55 UTC (rev 1899)
+++ ircu2/branches/u2_10_12_branch/tests/test-driver.pl 2009-01-13 02:30:25 UTC (rev 1900)
@@ -164,7 +164,7 @@

# expand any macros in the line
$line =~ s/(?<=[^\\])%(\S+?)%/$heap->{macros}->{$1}
- or die "Use of undefined macro $1 at $heap->{lineno}\n"/eg;
+ or die "Use of undefined macro $1 at line $heap->{lineno}\n"/eg;
# remove any \-escapes
$line =~ s/\\(.)/$1/g;
# figure out the type of line
@@ -235,7 +235,7 @@
my $client = $heap->{clients}->{$c};
if (not $client) {
print "ERROR: Unknown session name $c (line $heap->{lineno}; ignoring)\n";
- } elsif (($used->{$c} and not $zero_time->{$cmd}) or not $client->{ready}) {
+ } elsif (($used->{$c} and not $zero_time->{$cmd}) or ($cmd ne 'expect' and not $client->{ready})) {
push @unavail, $c;
} else {
push @avail, $c;
@@ -276,8 +276,8 @@
}

sub drv_timeout_expect {
- my ($kernel, $session, $client) = @_[KERNEL, SESSION, ARG0];
- print "ERROR: Dropping timed-out expectation by $client->{name}: ".join(',', @{$client->{expect}->[0]})."\n";
+ my ($kernel, $session, $client, $heap) = @_[KERNEL, SESSION, ARG0, HEAP];
+ print "\nERROR: Dropping timed-out expectation by $client->{name} (line $heap->{expect_lineno}): ".join(',', @{$client->{expect}->[0]})."\n";
$client->{expect_alarms}->[0] = undef;
unexpect($kernel, $session, $client);
}
@@ -370,6 +370,7 @@
sub cmd_expect {
my ($kernel, $session, $heap, $client, $args) = @_[KERNEL, SESSION, HEAP, ARG0, ARG1];
die "Missing argument" unless $#$args >= 0;
+ $heap->{expect_lineno} = $heap->{lineno};
push @{$client->{expect}}, $args;
push @{$client->{expect_alarms}}, $kernel->delay_set('timeout_expect', EXPECT_TIMEOUT, $client);
$kernel->call($session, 'disable_client', $client);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Loading...