diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-21 19:04:30 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-21 19:04:30 +0300 |
commit | 54574861db3f7c02cd5e347f243d119b992232d2 (patch) | |
tree | e0bedabc8e33876848e6a192ed6e9bce76833c37 | |
parent | 7d63e9e21b74f3b0ca3a87714e19ef1bbfeb7fbf (diff) | |
download | smap-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.h | 4 | ||||
-rw-r--r-- | modules/guile/getpw.scm | 4 | ||||
-rw-r--r-- | modules/guile/guile.c | 24 | ||||
-rw-r--r-- | src/query.c | 116 | ||||
-rw-r--r-- | src/smapd.cfin | 2 |
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 ') |