aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-06-21 19:04:30 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-06-21 19:04:30 +0300
commit54574861db3f7c02cd5e347f243d119b992232d2 (patch)
treee0bedabc8e33876848e6a192ed6e9bce76833c37
parent7d63e9e21b74f3b0ca3a87714e19ef1bbfeb7fbf (diff)
downloadsmap-54574861db3f7c02cd5e347f243d119b992232d2.tar.gz
smap-54574861db3f7c02cd5e347f243d119b992232d2.tar.bz2
Change transformation syntax and method calling convention.
* include/smap/module.h (smap_module)<smap_xform>: Change signature. * modules/guile/getpw.scm (smap-xform): Change signature. * modules/guile/guile.c (guile_xform): Change signature. * src/query.c: Change transform syntax. New syntax is: "transform" "key"|"map" dbname. * src/smapd.cfin [GUILE]: Add sample transform entries.
-rw-r--r--include/smap/module.h4
-rw-r--r--modules/guile/getpw.scm4
-rw-r--r--modules/guile/guile.c24
-rw-r--r--src/query.c116
-rw-r--r--src/smapd.cfin2
5 files changed, 90 insertions, 60 deletions
diff --git a/include/smap/module.h b/include/smap/module.h
index 27befad..c8cd5e7 100644
--- a/include/smap/module.h
+++ b/include/smap/module.h
@@ -51,9 +51,9 @@ struct smap_module {
const char *map, const char *key,
struct smap_conninfo const *conninfo);
int (*smap_xform)(smap_database_t dbp,
- const char *map, const char *key,
+ const char *arg,
struct smap_conninfo const *conninfo,
- char **newmap, char **newkey);
+ char **output);
};
#endif
diff --git a/modules/guile/getpw.scm b/modules/guile/getpw.scm
index 88bd724..9029e96 100644
--- a/modules/guile/getpw.scm
+++ b/modules/guile/getpw.scm
@@ -107,11 +107,11 @@
"NOTFOUND")))
(newline)))
-(define-public (smap-xform handle map arg . rest)
+(define-public (smap-xform handle arg . rest)
(let ((arg-parts (string-split arg #\@)))
(if (null? (cdr arg-parts))
#f
- (cons #f (car arg-parts)))))
+ (car arg-parts))))
;;; Module initialization function returns an associative list
;;; of methods implemented by the module. Each method is represented
diff --git a/modules/guile/guile.c b/modules/guile/guile.c
index 510cd7d..cdfa9bc 100644
--- a/modules/guile/guile.c
+++ b/modules/guile/guile.c
@@ -620,9 +620,9 @@ guile_query(smap_database_t dbp,
int
guile_xform(smap_database_t dbp,
- const char *map, const char *key,
+ const char *input,
struct smap_conninfo const *conninfo,
- char **newmap, char **newkey)
+ char **output)
{
struct _guile_database *db = (struct _guile_database *)dbp;
SCM res, arg;
@@ -630,26 +630,14 @@ guile_xform(smap_database_t dbp,
if (!db->vtab[xform_proc])
return 1;
- arg = scm_append(scm_list_2(scm_list_3(db->handle,
- scm_from_locale_string(map),
- scm_from_locale_string(key)),
+ arg = scm_append(scm_list_2(scm_list_2(db->handle,
+ scm_from_locale_string(input)),
scm_from_smap_conninfo(conninfo)));
if (guile_call_proc(&res, db->vtab[xform_proc], arg))
return 1;
- if (!scm_is_pair(res))
+ if (!scm_is_string(res))
return 1;
-
- arg = scm_car(res);
- if (!scm_is_string(arg))
- *newmap = NULL;
- else
- *newmap = scm_to_locale_string(arg);
- arg = scm_cdr(res);
- if (!scm_is_string(arg))
- *newkey = NULL;
- else
- *newkey = scm_to_locale_string(arg);
-
+ *output = scm_to_locale_string(res);
return 0;
}
diff --git a/src/query.c b/src/query.c
index a2ee1f5..238a797 100644
--- a/src/query.c
+++ b/src/query.c
@@ -56,6 +56,10 @@ struct query_cond {
} v;
};
+#define XFORM_NONE 0
+#define XFORM_MAP 1
+#define XFORM_KEY 2
+
struct dispatch_rule {
struct dispatch_rule *prev, *next;
char *file;
@@ -434,11 +438,11 @@ parse_complex_dispatch()
struct query_cond *head = NULL, *tail = NULL;
char *dbname = NULL;
struct dispatch_rule *rp;
- int xform;
+ int xform = XFORM_NONE;
while (*input && rc == 0) {
char *s = *input++;
- int tok;
+ int tok, subtok;
struct query_cond *cond = NULL;
if (smap_kwtab_nametotok(query_kwtab, s, &tok)) {
@@ -469,9 +473,21 @@ parse_complex_dispatch()
rc = parse_dispatch_comp(&cond, query_cond_key);
break;
- case T_DB:
case T_TRANSFORM:
s = nextarg();
+ if (!s) {
+ rc = 1;
+ break;
+ }
+ if (smap_kwtab_nametotok(query_kwtab, s, &subtok)) {
+ smap_error("%s:%lu: unknown keyword: %s",
+ cfg_file_name, cfg_line, s);
+ rc = 1;
+ break;
+ }
+
+ case T_DB:
+ s = nextarg();
if (!s)
rc = 1;
else if (dbname) {
@@ -480,7 +496,18 @@ parse_complex_dispatch()
rc = 1;
} else
dbname = estrdup(s);
- xform = tok == T_TRANSFORM;
+ if (tok == T_TRANSFORM) {
+ if (subtok == T_MAP)
+ xform = XFORM_MAP;
+ else if (subtok == T_KEY)
+ xform = XFORM_KEY;
+ else {
+ smap_error("%s:%lu: unexpected keyword"
+ "; expected map or key",
+ cfg_file_name, cfg_line);
+ rc = 1;
+ }
+ }
}
if (rc == 1)
break;
@@ -616,6 +643,7 @@ struct query_pack {
struct smap_conninfo const *conninfo;
const char *map;
const char *key;
+ char *storage[2];
};
static int
@@ -682,26 +710,19 @@ find_dispatch_rule(struct query_pack *qp, struct dispatch_rule *start)
return p;
}
-void
-dispatch_query(const char *id, struct smap_conninfo const *conninfo,
- smap_stream_t ostr, const char *map, const char *key)
+static void
+dispatch_query_pack(struct query_pack *qp,
+ struct smap_conninfo const *conninfo, smap_stream_t ostr)
{
+ struct dispatch_rule *next = NULL;
struct smap_database_instance *dbi;
struct smap_module *mod;
- struct query_pack query;
- struct dispatch_rule *next = NULL;
- char *alloc_map = NULL, *alloc_key = NULL;
-
- debug(DBG_QUERY, 1, ("dispatching query %s %s", map, key));
- query.server_id = id;
- query.conninfo = conninfo;
- query.map = map;
- query.key = key;
+ debug(DBG_QUERY, 1, ("dispatching query %s %s", qp->map, qp->key));
do {
struct dispatch_rule *qr;
- qr = find_dispatch_rule(&query, next);
+ qr = find_dispatch_rule(qp, next);
if (qr)
debug(DBG_QUERY, 1, ("rule at %s:%u, database %s",
qr->file, qr->line, qr->dbname));
@@ -727,35 +748,54 @@ dispatch_query(const char *id, struct smap_conninfo const *conninfo,
}
if (qr->xform) {
- char *nmap = NULL;
- char *nkey = NULL;
- if (mod->smap_xform(dbi->dbh, map, key, conninfo,
- &nmap, &nkey) == 0) {
- if (nmap) {
- if (alloc_map)
- free(alloc_map);
- alloc_map = nmap;
- query.map = nmap;
- }
- if (nkey) {
- if (alloc_key)
- free(alloc_key);
- alloc_key = nkey;
- query.key = nkey;
+ const char **parg;
+ char *narg = NULL;
+ static const char *what[]= { "map", "key" };
+
+ if (qr->xform == XFORM_KEY)
+ parg = &qp->key;
+ else
+ parg = &qp->map;
+ if (mod->smap_xform(dbi->dbh, *parg,
+ conninfo, &narg) == 0) {
+ if (narg) {
+ if (qp->storage[qr->xform-1])
+ free(qp->storage[qr->xform-1]);
+ qp->storage[qr->xform-1] = narg;
+ debug(DBG_QUERY, 1,
+ ("rule at %s:%u, transformed %s: %s => %s",
+ qr->file, qr->line, what[qr->xform - 1],
+ *parg, narg));
+ *parg = narg;
}
- debug(DBG_QUERY, 1,
- ("rule at %s:%u, transformed query: %s %s",
- qr->file, qr->line, query.map, query.key));
- }
+ } else
+ smap_error("%s:%u: transformation failed",
+ qr->file, qr->line);
next = qr->next;
} else {
if (mod->smap_query(dbi->dbh, ostr,
- query.map, query.key,
+ qp->map, qp->key,
conninfo))
break;
return;
}
} while (next);
- smap_error("no database matches %s %s", map, key);
+ smap_error("no database matches %s %s", qp->map, qp->key);
smap_stream_printf(ostr, "NOTFOUND\n");
}
+
+void
+dispatch_query(const char *id, struct smap_conninfo const *conninfo,
+ smap_stream_t ostr, const char *map, const char *key)
+{
+ struct query_pack query;
+
+ query.server_id = id;
+ query.conninfo = conninfo;
+ query.map = map;
+ query.key = key;
+ query.storage[0] = query.storage[1] = NULL;
+ dispatch_query_pack(&query, conninfo, ostr);
+ free(query.storage[0]);
+ free(query.storage[1]);
+}
diff --git a/src/smapd.cfin b/src/smapd.cfin
index 4057e09..aea7d7c 100644
--- a/src/smapd.cfin
+++ b/src/smapd.cfin
@@ -179,6 +179,8 @@ dispatch map getpwnam server privileged database auth
dispatch server privileged database default')
ifdef(`GUILE',`dnl
+dispatch server local key like *@* transform key getpw
+dispatch server loopback key like *@* transform key getpw
dispatch server local database getpw
dispatch server loopback database getpw
')

Return to:

Send suggestions and report system problems to the System administrator.