aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-06-17 13:24:19 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-06-17 13:24:19 +0300
commitc81c5df1da0ec4de29a13787b3b116bb71e66ddd (patch)
tree11f35326cb4dd1a1e9e6bc2f8fa29e88e8f711aa
parentc32cdcbb85fd6ee8d7808957f6312a5ffb3153b0 (diff)
downloadsmap-c81c5df1da0ec4de29a13787b3b116bb71e66ddd.tar.gz
smap-c81c5df1da0ec4de29a13787b3b116bb71e66ddd.tar.bz2
Further work on the documentation.
* src/query.c (parse_regexp): New function. (parse_query_map): Regular expressions must be prefixed with `regexp'. * doc/smap.texi: Update.
-rw-r--r--doc/smap.texi115
-rw-r--r--src/query.c116
2 files changed, 183 insertions, 48 deletions
diff --git a/doc/smap.texi b/doc/smap.texi
index a277238..5bf823c 100644
--- a/doc/smap.texi
+++ b/doc/smap.texi
@@ -736,6 +736,7 @@ when debugging @command{smapd}. @emph{Never use it in production
environment!}
@end deffn
+@anchor{config-server}
@deffn {Config} server name address [block]
Configure a server. The @var{name} argument gives its symbolic
name, which will be used in logs to identify it. The @var{address}
@@ -765,10 +766,12 @@ word @samp{begin} followed by a newline, one or more configuration
statements and the word @samp{end} alone on a line. For example:
@example
+@group
server main unix:///var/run/smap.sock begin
user smap
allgroups yes
end
+@end group
@end example
The statements within block apply only to that particular server.
@@ -812,17 +815,121 @@ Arguments to the module initialization function.
@end table
@end deffn
-@deffn {Config} database name modname [args...]
-Define a database @var{name} and associate it with the module
+@anchor{config-database}
+@deffn {Config} database dbname modname [args...]
+Define a database @var{dbname} and associate it with the module
@var{modname}, which must be loaded by a prior @code{module}
statement. Optional @var{args} are passed to the database
initialization function verbatim.
@end deffn
@deffn {Config} query cond target
-FIXME
+Route incoming queries.
+
+@var{Cond} is a list of conditions that must be satisfied in order to
+route this query to @var{target}. Conditions are separated by any
+amount of whitespace. They are evaluated from left to right and are
+joined using boolean @samp{AND} so that @var{cond} yields @samp{True}
+only if all conditions evaluate to @samp{True}. Supported conditions
+are:
+
+@deffn {Condition} from ipaddr
+Returns @samp{True} if the IP address of the client equals
+@var{ipaddr}. The latter may be given either as an IP address or
+as a host name, in which case it will be resolved and the first of
+its IP addresses will be used.
+@end deffn
+
+@deffn {Condition} from ipaddr/netmask
+Returns @samp{True} if the result of logical @samp{AND} between the
+client IP address and @var{netmask} equals to @var{ipaddr}. The
+network mask must be specified in ``dotted quad'' form, e.g.:
+
+@example
+from 10.1.10.1/255.255.255.224
+@end example
+@end deffn
+
+@deffn {Condition} from ipaddr/netlen
+Returns @samp{True} if first @var{netlen} bits from the client IP
+address equal to @var{ipaddr}. The network mask length, @var{netlen}
+must be an integer number in the range from 0 to 32. The address
+part, @var{ipaddr}, is as described above. For example:
+
+@example
+from 10.1.10.1/27
+@end example
+@end deffn
+
+@deffn {Condition} to name
+@samp{True} if this query is being served by the server @var{name}
+(@pxref{config-server, name}).
+@end deffn
+
+@deffn {Condition} map op string
+@samp{True} if the map name part of the query (@pxref{Protocol,map})
+matches @var{string}. The @var{op} part specifies the comparison
+algorithm:
+
+@table @asis
+@item eq
+@itemx is
+Literal equality. Map name must be exactly the same as @var{string}.
+
+@item like
+@itemx fnmatch
+Match using shell wildcard patterns (@pxref{glob,Globbing
+patterns,,glob(7), Glob(7) man page}).
+
+@item regexp
+Match using regular expressions. @var{String} must have the following
+form:
+
+@example
+/@var{expr}/@var{flags}
+@end example
+
+The slashes may be uniformly replaced with any other punctuation
+character. The @var{expr} must constitute a valid regular expression.
+The @var{flags} are optional. When given, they allow to control the
+type of the regular expression:
+
+@multitable @columnfractions 0.1 0.9
+@headitem Flag @tab Meaning
+@item i @tab Use case-insensitive matching
+@item x @tab @var{expr} is an @dfn{extended regular expression}. This
+is the default setting.
+@item b @tab @var{expr} is a @dfn{basic regular expression}.
+@end multitable
+
+@xref{Extended regexps, Extended regular expressions, Extended
+regular expressions, sed, GNU sed}, for a description of Extended
+regular expressions.
+@end table
+@end deffn
+
+@deffn {Condition} not cond
+Reverts the value returned by @var{cond}, which is one of the
+conditions described above. For example:
+
+@example
+not map like "local*"
+@end example
@end deffn
+@deffn {Condition} default
+Always @samp{True}. This must be the only condition in @var{cond}.
+It is useful to declare default query routing.
+@end deffn
+
+The @var{target} instructs the server to direct this query to a
+particular database. The syntax is:
+
+@deffn {Target} uses dbname
+@deffnx {Target} database dbname
+Pass this query to the database @var{dbname} (@pxref{config-database,dbname}).
+@end deffn
+@end deffn
@node exit codes
@section Smapd Exit Codes
@@ -830,7 +937,7 @@ FIXME
For each code it lists its decimal number, symbolic name from the
@file{sysexits.h} header file, and its meaning.
-@multitable @columnfractions 0.1 0.2 0.7
+@multitable @columnfractions 0.1 0.4 0.5
@headitem Code @tab Name @tab Meaning
@item 0 @tab EX_OK @tab Normal termination.
@item 64 @tab EX_USAGE @tab Command line usage error.
diff --git a/src/query.c b/src/query.c
index 2931b95..61779d7 100644
--- a/src/query.c
+++ b/src/query.c
@@ -126,6 +126,7 @@ enum query_tok {
T_MAP,
T_LIKE,
T_EQ,
+ T_REGEXP,
T_DB,
T_NOT
};
@@ -135,6 +136,8 @@ static struct smap_kwtab query_kwtab[] = {
{ "to", T_TO },
{ "map", T_MAP },
{ "like", T_LIKE },
+ { "fnmatch", T_LIKE },
+ { "regexp", T_REGEXP },
{ "eq", T_EQ },
{ "is", T_EQ },
{ "uses", T_DB },
@@ -221,6 +224,67 @@ parse_query_not(struct query_cond **pcond)
}
static int
+parse_regexp(const char *s, struct map_cond *mapcond)
+{
+ int rc;
+ char *buf;
+ size_t len;
+ int flags = REG_NOSUB | REG_EXTENDED;
+ char *p;
+
+ if (!ispunct(s[0])) {
+ smap_error("%s:%lu: regexp does not start with "
+ "a punctuation character: %s",
+ cfg_file_name, cfg_line, s);
+ return 1;
+ }
+
+ p = strrchr(s, s[0]);
+ if (p == s) {
+ smap_error("%s:%lu: unfinished regexp: %s",
+ cfg_file_name, cfg_line, s);
+ return 1;
+ }
+ if (p[1]) {
+ char *q;
+ for (q = p + 1; *q; q++) {
+ switch (*q) {
+ case 'i':
+ flags |= REG_ICASE;
+ break;
+ case 'b':
+ flags &= ~REG_EXTENDED;
+ break;
+ case 'x':
+ flags |= REG_EXTENDED;
+ break;
+ default:
+ smap_error("%s:%lu: uknown regexp "
+ "flag: %c",
+ cfg_file_name, cfg_line,
+ *q);
+ return 1;
+ }
+ }
+ }
+ len = p - s - 1;
+ buf = emalloc(len + 1);
+ memcpy(buf, s + 1, len);
+ buf[len] = 0;
+ rc = regcomp(&mapcond->re, buf, flags);
+ free(buf);
+ if (rc) {
+ char errbuf[512];
+ regerror(rc, &mapcond->re, errbuf, sizeof(errbuf));
+ smap_error("%s:%lu: regexp error: %s",
+ cfg_file_name, cfg_line, errbuf);
+ return 1;
+ }
+ mapcond->op = map_re;
+ return 0;
+}
+
+static int
parse_query_map(struct query_cond **pcond)
{
struct query_cond *cond;
@@ -247,53 +311,17 @@ parse_query_map(struct query_cond **pcond)
mapcond.op = map_eq;
break;
+ case T_REGEXP:
+ s = nextarg();
+ if (!s)
+ return 1;
+ if (parse_regexp(s, &mapcond))
+ return 1;
+ break;
+
default:
mapcond.op = map_eq;
}
- } else if (ispunct(s[0])) {
- int rc;
- char *buf;
- size_t len;
- int flags = REG_NOSUB | REG_EXTENDED;
- char *p = strrchr(s, s[0]);
- if (p == s) {
- smap_error("%s:%lu: unfinished regexp: %s",
- cfg_file_name, cfg_line, s);
- return 1;
- }
- if (p[1]) {
- char *q;
- for (q = p + 1; *q; q++) {
- switch (*q) {
- case 'i':
- flags |= REG_ICASE;
- break;
- case 'b':
- flags &= ~REG_EXTENDED;
- break;
- default:
- smap_error("%s:%lu: uknown regexp "
- "flag: %c",
- cfg_file_name, cfg_line,
- *q);
- return 1;
- }
- }
- }
- len = p - s - 1;
- buf = emalloc(len + 1);
- memcpy(buf, s + 1, len);
- buf[len] = 0;
- rc = regcomp(&mapcond.re, buf, flags);
- free(buf);
- if (rc) {
- char errbuf[512];
- regerror(rc, &mapcond.re, errbuf, sizeof(errbuf));
- smap_error("%s:%lu: regexp error: %s",
- cfg_file_name, cfg_line, errbuf);
- return 1;
- }
- mapcond.op = map_re;
} else
mapcond.op = map_eq;
mapcond.str = estrdup(s);

Return to:

Send suggestions and report system problems to the System administrator.