JSON: avoid recent library version usage
[exim.git] / src / src / lookups / json.c
CommitLineData
854bd65f
JH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
5/* Copyright (c) Jeremy Harris 2019 */
6/* See the file NOTICE for conditions of use and distribution. */
7
8#include "../exim.h"
9#include "lf_functions.h"
10#include <jansson.h>
11
12
13
14/*************************************************
15* Open entry point *
16*************************************************/
17
18/* See local README for interface description */
19
20static void *
21json_open(uschar *filename, uschar **errmsg)
22{
23FILE *f = Ufopen(filename, "rb");
24if (f == NULL)
25 {
26 int save_errno = errno;
27 *errmsg = string_open_failed(errno, "%s for json search", filename);
28 errno = save_errno;
29 return NULL;
30 }
31return f;
32}
33
34
35
36/*************************************************
37* Check entry point *
38*************************************************/
39
40static BOOL
41json_check(void *handle, uschar *filename, int modemask, uid_t *owners,
42 gid_t *owngroups, uschar **errmsg)
43{
44return lf_check_file(fileno((FILE *)handle), filename, S_IFREG, modemask,
45 owners, owngroups, "json", errmsg) == 0;
46}
47
48
49
50/*************************************************
51* Find entry point for lsearch *
52*************************************************/
53
54/* See local README for interface description */
55
56static int
57json_find(void *handle, uschar *filename, const uschar *keystring, int length,
58 uschar **result, uschar **errmsg, uint *do_cache)
59{
60FILE * f = handle;
61json_t * j, * j0;
62json_error_t jerr;
63uschar * key;
64int sep = 0;
65
66length = length; /* Keep picky compilers happy */
67do_cache = do_cache; /* Keep picky compilers happy */
68
69rewind(f);
70if (!(j = json_loadf(f, 0, &jerr)))
71 {
9669c6e0
JH
72 *errmsg = string_sprintf("json error on open: %.*s\n",
73 JSON_ERROR_TEXT_LENGTH, jerr.text);
854bd65f
JH
74 return FAIL;
75 }
76j0 = j;
77
78for (int k = 1; (key = string_nextinlist(&keystring, &sep, NULL, 0)); k++)
79 {
80 BOOL numeric = TRUE;
81 for (uschar * s = key; *s; s++) if (!isdigit(*s)) { numeric = FALSE; break; }
82
83 if (!(j = numeric
84 ? json_array_get(j, (size_t) strtoul(CS key, NULL, 10))
85 : json_object_get(j, CCS key)
86 ) )
87 {
88 DEBUG(D_lookup) debug_printf("%s, for key %d: '%s'\n",
89 numeric
90 ? US"bad index, or not json array"
91 : US"no such key, or not json object",
92 k, key);
93 json_decref(j0);
94 return FAIL;
95 }
96 }
97
98switch (json_typeof(j))
99 {
100 case JSON_STRING:
101 *result = string_copyn(CUS json_string_value(j), json_string_length(j));
102 break;
103 case JSON_INTEGER:
104 *result = string_sprintf("%" JSON_INTEGER_FORMAT, json_integer_value(j));
105 break;
106 case JSON_REAL:
107 *result = string_sprintf("%f", json_real_value(j));
108 break;
109 case JSON_TRUE: *result = US"true"; break;
110 case JSON_FALSE: *result = US"false"; break;
111 case JSON_NULL: *result = NULL; break;
112 default: *result = US json_dumps(j, 0); break;
113 }
114json_decref(j0);
115return OK;
116}
117
118
119
120/*************************************************
121* Close entry point *
122*************************************************/
123
124/* See local README for interface description */
125
126static void
127json_close(void *handle)
128{
129(void)fclose((FILE *)handle);
130}
131
132
133
134/*************************************************
135* Version reporting entry point *
136*************************************************/
137
138/* See local README for interface description. */
139
140#include "../version.h"
141
142void
143json_version_report(FILE *f)
144{
145fprintf(f, "Library version: json: Jansonn version %s\n", JANSSON_VERSION);
146}
147
148
149static lookup_info json_lookup_info = {
150 US"json", /* lookup name */
151 lookup_absfile, /* uses absolute file name */
152 json_open, /* open function */
153 json_check, /* check function */
154 json_find, /* find function */
155 json_close, /* close function */
156 NULL, /* no tidy function */
157 NULL, /* no quoting function */
158 json_version_report /* version reporting */
159};
160
161
162#ifdef DYNLOOKUP
163#define json_lookup_module_info _lookup_module_info
164#endif
165
166static lookup_info *_lookup_list[] = { &json_lookup_info };
167lookup_module_info json_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
168
169/* End of lookups/json.c */