<table class="bordered"><tr class="header"><th>Name</th><th>Description</th></tr>
<tr><td><code>-n</code></td>
- <td>String is not empty</td></tr>
+ <td>True if string is not empty</td></tr>
<tr class="odd"><td><code>-z</code></td>
- <td>String is empty</td></tr>
-<tr><td><code>-R</code></td>
+ <td>True if string is empty</td></tr>
+<tr><td><code>-T</code></td>
+ <td>False if string is empty, "<code>0</code>", "<code>off</code>",
+ "<code>false</code>", or "<code>no</code>" (case insensitive).
+ True otherwise.</td></tr>
+<tr class="odd"><td><code>-R</code></td>
<td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more efficient
</td></tr>
</table>
<tr><th>Name</th><th>Description</th></tr>
<tr><td><code>-n</code></td>
- <td>String is not empty</td></tr>
+ <td>True if string is not empty</td></tr>
<tr><td><code>-z</code></td>
- <td>String is empty</td></tr>
+ <td>True if string is empty</td></tr>
+ <tr><td><code>-T</code></td>
+ <td>False if string is empty, "<code>0</code>", "<code>off</code>",
+ "<code>false</code>", or "<code>no</code>" (case insensitive).
+ True otherwise.</td></tr>
<tr><td><code>-R</code></td>
<td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more efficient
</td></tr>
return apr_ipsubnet_test(subnet, ctx->c->remote_addr);
}
+static int op_T(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
+{
+ switch (arg[0]) {
+ case '\0':
+ return FALSE;
+ case 'o':
+ case 'O':
+ return strcasecmp(arg, "off") == 0 ? FALSE : TRUE;
+ case 'n':
+ case 'N':
+ return strcasecmp(arg, "no") == 0 ? FALSE : TRUE;
+ case 'f':
+ case 'F':
+ return strcasecmp(arg, "false") == 0 ? FALSE : TRUE;
+ case '0':
+ return arg[1] == '\0' ? FALSE : TRUE;
+ default:
+ return TRUE;
+ }
+}
+
static int op_fnmatch(ap_expr_eval_ctx_t *ctx, const void *data,
const char *arg1, const char *arg2)
{
{ op_nz, "n", NULL },
{ op_nz, "z", NULL },
{ op_R, "R", subnet_parse_arg },
+ { op_T, "T", NULL },
{ NULL, NULL, NULL }
};