aboutsummaryrefslogtreecommitdiff
path: root/src/json/json_gnsrecord.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/json/json_gnsrecord.c')
-rw-r--r--src/json/json_gnsrecord.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/json/json_gnsrecord.c b/src/json/json_gnsrecord.c
new file mode 100644
index 000000000..7bdf97f06
--- /dev/null
+++ b/src/json/json_gnsrecord.c
@@ -0,0 +1,177 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/**
20 * @file json/json_gnsrecord.c
21 * @brief JSON handling of GNS record data
22 * @author Philippe Buschmann
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_json_lib.h"
27
28#define GNUNET_JSON_GNSRECORD_VALUE "value"
29#define GNUNET_JSON_GNSRECORD_TYPE "type"
30#define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time"
31#define GNUNET_JSON_GNSRECORD_FLAG "flag"
32#define GNUNET_JSON_GNSRECORD_LABEL "label"
33#define GNUNET_JSON_GNSRECORD_NEVER "never"
34
35
36/**
37 * Parse given JSON object to gns record
38 *
39 * @param cls closure, NULL
40 * @param root the json object representing data
41 * @param spec where to write the data
42 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
43 */
44static int
45parse_gnsrecordobject (void *cls,
46 json_t *root,
47 struct GNUNET_JSON_Specification *spec)
48{
49 struct GNUNET_GNSRECORD_Data *gnsrecord_object;
50 struct GNUNET_TIME_Absolute abs_expiration_time;
51 int unpack_state=0;
52 const char *value;
53 const char *expiration_time;
54 const char *record_type;
55 const char *label;
56 int flag;
57 void *rdata = NULL;
58 size_t rdata_size;
59
60 GNUNET_assert(NULL != root);
61 if(!json_is_object(root))
62 {
63 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
64 "Error json is not array nor object!\n");
65 return GNUNET_SYSERR;
66 }
67 //interpret single gns record
68 unpack_state = json_unpack(root,
69 "{s:s, s:s, s:s, s?:i, s:s!}",
70 GNUNET_JSON_GNSRECORD_VALUE, &value,
71 GNUNET_JSON_GNSRECORD_TYPE, &record_type,
72 GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, &expiration_time,
73 GNUNET_JSON_GNSRECORD_FLAG, &flag,
74 GNUNET_JSON_GNSRECORD_LABEL, &label);
75 if (0 != unpack_state)
76 {
77 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
78 "Error json object has a wrong format!\n");
79 return GNUNET_SYSERR;
80 }
81 gnsrecord_object = GNUNET_new (struct GNUNET_GNSRECORD_Data);
82 gnsrecord_object->record_type = GNUNET_GNSRECORD_typename_to_number(record_type);
83 if (UINT32_MAX == gnsrecord_object->record_type)
84 {
85 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Unsupported type\n");
86 GNUNET_free(gnsrecord_object);
87 return GNUNET_SYSERR;
88 }
89 if (GNUNET_OK
90 != GNUNET_GNSRECORD_string_to_value (gnsrecord_object->record_type,
91 value,
92 &rdata,
93 &rdata_size))
94 {
95 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Value invalid for record type\n");
96 GNUNET_free(gnsrecord_object);
97 return GNUNET_SYSERR;
98 }
99
100 gnsrecord_object->data = rdata;
101 gnsrecord_object->data_size = rdata_size;
102
103 if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER))
104 {
105 gnsrecord_object->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
106 }
107 else if (GNUNET_OK
108 == GNUNET_STRINGS_fancy_time_to_absolute (expiration_time,
109 &abs_expiration_time))
110 {
111 gnsrecord_object->expiration_time = abs_expiration_time.abs_value_us;
112 }
113 else
114 {
115 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Expiration time invalid\n");
116 GNUNET_free_non_null(rdata);
117 GNUNET_free(gnsrecord_object);
118 return GNUNET_SYSERR;
119 }
120 // check if flag is a valid enum value
121 if ((GNUNET_GNSRECORD_RF_NONE != flag)
122 && (GNUNET_GNSRECORD_RF_PRIVATE != flag)
123 && (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION != flag)
124 && (GNUNET_GNSRECORD_RF_SHADOW_RECORD) != flag)
125 {
126 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Flag invalid\n");
127 GNUNET_free_non_null(rdata);
128 GNUNET_free(gnsrecord_object);
129 return GNUNET_SYSERR;
130 }
131 gnsrecord_object->flags = (enum GNUNET_GNSRECORD_Flags)flag;
132 *(struct GNUNET_GNSRECORD_Data **) spec->ptr = gnsrecord_object;
133 return GNUNET_OK;
134}
135
136/**
137 * Cleanup data left from parsing RSA public key.
138 *
139 * @param cls closure, NULL
140 * @param[out] spec where to free the data
141 */
142static void
143clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec)
144{
145 struct GNUNET_GNSRECORD_Data **gnsrecord_object;
146 gnsrecord_object = (struct GNUNET_GNSRECORD_Data **) spec->ptr;
147 if (NULL != *gnsrecord_object)
148 {
149 if (NULL != (*gnsrecord_object)->data)
150 GNUNET_free((char*)(*gnsrecord_object)->data);
151
152 GNUNET_free(*gnsrecord_object);
153 *gnsrecord_object = NULL;
154 }
155}
156
157/**
158 * JSON Specification for GNS Records.
159 *
160 * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill
161 * @return JSON Specification
162 */
163struct GNUNET_JSON_Specification
164GNUNET_JSON_spec_gnsrecord_data (struct GNUNET_GNSRECORD_Data **gnsrecord_object)
165{
166 struct GNUNET_JSON_Specification ret = {
167 .parser = &parse_gnsrecordobject,
168 .cleaner = &clean_gnsrecordobject,
169 .cls = NULL,
170 .field = NULL,
171 .ptr = gnsrecord_object,
172 .ptr_size = 0,
173 .size_ptr = NULL
174 };
175 *gnsrecord_object = NULL;
176 return ret;
177}