diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2019-01-08 19:15:29 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2019-01-08 23:11:30 +0000 |
commit | 854bd65fa7f6a97b04680fb090423c27b19077a2 (patch) | |
tree | ce46b4041022ffcb148048b174ee0fcc989c6e1e /src | |
parent | 57a7b15ed9a35f447c05c7c6b80eb8b2a5836fbb (diff) |
JSON lookup
Diffstat (limited to 'src')
-rwxr-xr-x | src/scripts/MakeLinks | 2 | ||||
-rwxr-xr-x | src/scripts/lookups-Makefile | 2 | ||||
-rw-r--r-- | src/src/config.h.defaults | 1 | ||||
-rw-r--r-- | src/src/drtables.c | 7 | ||||
-rw-r--r-- | src/src/exim.c | 3 | ||||
-rw-r--r-- | src/src/lookups/Makefile | 2 | ||||
-rw-r--r-- | src/src/lookups/json.c | 169 |
7 files changed, 184 insertions, 2 deletions
diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index f69bde437..b71736797 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -30,7 +30,7 @@ echo ">>> Creating links to source files..." mkdir lookups cd lookups # Makefile is generated -for f in README cdb.c dbmdb.c dnsdb.c dsearch.c ibase.c ldap.h ldap.c \ +for f in README cdb.c dbmdb.c dnsdb.c dsearch.c ibase.c json.c ldap.h ldap.c \ lmdb.c lsearch.c mysql.c redis.c nis.c nisplus.c oracle.c passwd.c \ pgsql.c spf.c sqlite.c testdb.c whoson.c \ lf_functions.h lf_check_file.c lf_quote.c lf_sqlperform.c diff --git a/src/scripts/lookups-Makefile b/src/scripts/lookups-Makefile index db2d184a7..498184ff6 100755 --- a/src/scripts/lookups-Makefile +++ b/src/scripts/lookups-Makefile @@ -160,7 +160,7 @@ exec > "$target" sed -n "1,/$tag_marker/p" < "$input" for name_mod in \ - CDB DBM:dbmdb DNSDB DSEARCH IBASE LSEARCH MYSQL NIS NISPLUS ORACLE \ + CDB DBM:dbmdb DNSDB DSEARCH IBASE JSON LSEARCH MYSQL NIS NISPLUS ORACLE \ PASSWD PGSQL REDIS SQLITE TESTDB WHOSON do emit_module_rule $name_mod diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 74ec3f4df..55688295d 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -93,6 +93,7 @@ Do not put spaces between # and the 'define'. #define LOOKUP_DNSDB #define LOOKUP_DSEARCH #define LOOKUP_IBASE +#define LOOKUP_JSON #define LOOKUP_LDAP #define LOOKUP_LSEARCH #define LOOKUP_MYSQL diff --git a/src/src/drtables.c b/src/src/drtables.c index 54d03edab..b7024297d 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -564,6 +564,9 @@ extern lookup_module_info dsearch_lookup_module_info; #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2 extern lookup_module_info ibase_lookup_module_info; #endif +#if defined(LOOKUP_JSON) +extern lookup_module_info json_lookup_module_info; +#endif #if defined(LOOKUP_LDAP) extern lookup_module_info ldap_lookup_module_info; #endif @@ -649,6 +652,10 @@ init_lookup_list(void) addlookupmodule(NULL, &ldap_lookup_module_info); #endif +#ifdef LOOKUP_JSON + addlookupmodule(NULL, &json_lookup_module_info); +#endif + #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2 addlookupmodule(NULL, &lsearch_lookup_module_info); #endif diff --git a/src/src/exim.c b/src/src/exim.c index 5c9d4ee16..32bd3968f 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -930,6 +930,9 @@ fprintf(fp, "Lookups (built-in):"); #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2 fprintf(fp, " ibase"); #endif +#if defined(LOOKUP_JSON) && LOOKUP_JSON!=2 + fprintf(fp, " json"); +#endif #if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2 fprintf(fp, " ldap ldapdn ldapm"); #endif diff --git a/src/src/lookups/Makefile b/src/src/lookups/Makefile index 7c9700690..01910d542 100644 --- a/src/src/lookups/Makefile +++ b/src/src/lookups/Makefile @@ -35,6 +35,7 @@ dsearch.o: $(PHDRS) dsearch.c ibase.o: $(PHDRS) ibase.c ldap.o: $(PHDRS) ldap.c lmdb.o: $(PHDRS) lmdb.c +json.o: $(PHDRS) json.c lsearch.o: $(PHDRS) lsearch.c mysql.o: $(PHDRS) mysql.c nis.o: $(PHDRS) nis.c @@ -53,6 +54,7 @@ dbmdb.so: $(PHDRS) dbmdb.c dnsdb.so: $(PHDRS) dnsdb.c dsearch.so: $(PHDRS) dsearch.c ibase.so: $(PHDRS) ibase.c +json.so: $(PHDRS) json.c ldap.so: $(PHDRS) ldap.c lmdb.so: $(PHDRS) lmdb.c lsearch.so: $(PHDRS) lsearch.c diff --git a/src/src/lookups/json.c b/src/src/lookups/json.c new file mode 100644 index 000000000..013013ae8 --- /dev/null +++ b/src/src/lookups/json.c @@ -0,0 +1,169 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) Jeremy Harris 2019 */ +/* See the file NOTICE for conditions of use and distribution. */ + +#include "../exim.h" +#include "lf_functions.h" +#include <jansson.h> + + + +/************************************************* +* Open entry point * +*************************************************/ + +/* See local README for interface description */ + +static void * +json_open(uschar *filename, uschar **errmsg) +{ +FILE *f = Ufopen(filename, "rb"); +if (f == NULL) + { + int save_errno = errno; + *errmsg = string_open_failed(errno, "%s for json search", filename); + errno = save_errno; + return NULL; + } +return f; +} + + + +/************************************************* +* Check entry point * +*************************************************/ + +static BOOL +json_check(void *handle, uschar *filename, int modemask, uid_t *owners, + gid_t *owngroups, uschar **errmsg) +{ +return lf_check_file(fileno((FILE *)handle), filename, S_IFREG, modemask, + owners, owngroups, "json", errmsg) == 0; +} + + + +/************************************************* +* Find entry point for lsearch * +*************************************************/ + +/* See local README for interface description */ + +static int +json_find(void *handle, uschar *filename, const uschar *keystring, int length, + uschar **result, uschar **errmsg, uint *do_cache) +{ +FILE * f = handle; +json_t * j, * j0; +json_error_t jerr; +uschar * key; +int sep = 0; + +length = length; /* Keep picky compilers happy */ +do_cache = do_cache; /* Keep picky compilers happy */ + +rewind(f); +if (!(j = json_loadf(f, 0, &jerr))) + { + enum json_error_code je = json_error_code(&jerr); + *errmsg = string_sprintf("json err %d on open", je); + return FAIL; + } +j0 = j; + +for (int k = 1; (key = string_nextinlist(&keystring, &sep, NULL, 0)); k++) + { + BOOL numeric = TRUE; + for (uschar * s = key; *s; s++) if (!isdigit(*s)) { numeric = FALSE; break; } + + if (!(j = numeric + ? json_array_get(j, (size_t) strtoul(CS key, NULL, 10)) + : json_object_get(j, CCS key) + ) ) + { + DEBUG(D_lookup) debug_printf("%s, for key %d: '%s'\n", + numeric + ? US"bad index, or not json array" + : US"no such key, or not json object", + k, key); + json_decref(j0); + return FAIL; + } + } + +switch (json_typeof(j)) + { + case JSON_STRING: + *result = string_copyn(CUS json_string_value(j), json_string_length(j)); + break; + case JSON_INTEGER: + *result = string_sprintf("%" JSON_INTEGER_FORMAT, json_integer_value(j)); + break; + case JSON_REAL: + *result = string_sprintf("%f", json_real_value(j)); + break; + case JSON_TRUE: *result = US"true"; break; + case JSON_FALSE: *result = US"false"; break; + case JSON_NULL: *result = NULL; break; + default: *result = US json_dumps(j, 0); break; + } +json_decref(j0); +return OK; +} + + + +/************************************************* +* Close entry point * +*************************************************/ + +/* See local README for interface description */ + +static void +json_close(void *handle) +{ +(void)fclose((FILE *)handle); +} + + + +/************************************************* +* Version reporting entry point * +*************************************************/ + +/* See local README for interface description. */ + +#include "../version.h" + +void +json_version_report(FILE *f) +{ +fprintf(f, "Library version: json: Jansonn version %s\n", JANSSON_VERSION); +} + + +static lookup_info json_lookup_info = { + US"json", /* lookup name */ + lookup_absfile, /* uses absolute file name */ + json_open, /* open function */ + json_check, /* check function */ + json_find, /* find function */ + json_close, /* close function */ + NULL, /* no tidy function */ + NULL, /* no quoting function */ + json_version_report /* version reporting */ +}; + + +#ifdef DYNLOOKUP +#define json_lookup_module_info _lookup_module_info +#endif + +static lookup_info *_lookup_list[] = { &json_lookup_info }; +lookup_module_info json_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 }; + +/* End of lookups/json.c */ |