]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/subr_dnvlist.c
MFV ntp 4.2.8p1 (r258945, r275970, r276091, r276092, r276093, r278284)
[FreeBSD/FreeBSD.git] / sys / kern / subr_dnvlist.c
1 /*-
2  * Copyright (c) 2013 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Pawel Jakub Dawidek under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #ifdef _KERNEL
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/kernel.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
40
41 #include <machine/stdarg.h>
42
43 #else
44 #include <stdarg.h>
45 #include <stdbool.h>
46 #include <stdint.h>
47 #include <stdlib.h>
48 #endif
49
50 #include <sys/nv.h>
51 #include <sys/nv_impl.h>
52
53 #include <sys/dnv.h>
54
55 #define DNVLIST_GET(ftype, type)                                        \
56 ftype                                                                   \
57 dnvlist_get_##type(const nvlist_t *nvl, const char *name, ftype defval) \
58 {                                                                       \
59                                                                         \
60         if (nvlist_exists_##type(nvl, name))                            \
61                 return (nvlist_get_##type(nvl, name));                  \
62         else                                                            \
63                 return (defval);                                        \
64 }
65
66 DNVLIST_GET(bool, bool)
67 DNVLIST_GET(uint64_t, number)
68 DNVLIST_GET(const char *, string)
69 DNVLIST_GET(const nvlist_t *, nvlist)
70 #ifndef _KERNEL
71 DNVLIST_GET(int, descriptor)
72 #endif
73
74 #undef  DNVLIST_GET
75
76 const void *
77 dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep,
78     const void *defval, size_t defsize)
79 {
80         const void *value;
81
82         if (nvlist_exists_binary(nvl, name))
83                 value = nvlist_get_binary(nvl, name, sizep);
84         else {
85                 if (sizep != NULL)
86                         *sizep = defsize;
87                 value = defval;
88         }
89         return (value);
90 }
91
92 #ifndef _KERNEL
93 #define DNVLIST_GETF(ftype, type)                                       \
94 ftype                                                                   \
95 dnvlist_getf_##type(const nvlist_t *nvl, ftype defval,                  \
96     const char *namefmt, ...)                                           \
97 {                                                                       \
98         va_list nameap;                                                 \
99         ftype value;                                                    \
100                                                                         \
101         va_start(nameap, namefmt);                                      \
102         value = dnvlist_getv_##type(nvl, defval, namefmt, nameap);      \
103         va_end(nameap);                                                 \
104                                                                         \
105         return (value);                                                 \
106 }
107
108 DNVLIST_GETF(bool, bool)
109 DNVLIST_GETF(uint64_t, number)
110 DNVLIST_GETF(const char *, string)
111 DNVLIST_GETF(const nvlist_t *, nvlist)
112 DNVLIST_GETF(int, descriptor)
113
114 #undef  DNVLIST_GETF
115
116 const void *
117 dnvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
118     size_t defsize, const char *namefmt, ...)
119 {
120         va_list nameap;
121         const void *value;
122
123         va_start(nameap, namefmt);
124         value = dnvlist_getv_binary(nvl, sizep, defval, defsize, namefmt,
125             nameap);
126         va_end(nameap);
127
128         return (value);
129 }
130
131 #define DNVLIST_GETV(ftype, type)                                       \
132 ftype                                                                   \
133 dnvlist_getv_##type(const nvlist_t *nvl, ftype defval,                  \
134     const char *namefmt, va_list nameap)                                \
135 {                                                                       \
136         char *name;                                                     \
137         ftype value;                                                    \
138                                                                         \
139         vasprintf(&name, namefmt, nameap);                              \
140         if (name == NULL)                                               \
141                 return (defval);                                        \
142         value = dnvlist_get_##type(nvl, name, defval);                  \
143         free(name);                                                     \
144         return (value);                                                 \
145 }
146
147 DNVLIST_GETV(bool, bool)
148 DNVLIST_GETV(uint64_t, number)
149 DNVLIST_GETV(const char *, string)
150 DNVLIST_GETV(const nvlist_t *, nvlist)
151 DNVLIST_GETV(int, descriptor)
152
153 #undef  DNVLIST_GETV
154
155 const void *
156 dnvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
157     size_t defsize, const char *namefmt, va_list nameap)
158 {
159         char *name;
160         const void *value;
161
162         nv_vasprintf(&name, namefmt, nameap);
163         if (name != NULL) {
164                 value = dnvlist_get_binary(nvl, name, sizep, defval, defsize);
165                 nv_free(name);
166         } else {
167                 if (sizep != NULL)
168                         *sizep = defsize;
169                 value = defval;
170         }
171         return (value);
172 }
173 #endif
174
175 #define DNVLIST_TAKE(ftype, type)                                       \
176 ftype                                                                   \
177 dnvlist_take_##type(nvlist_t *nvl, const char *name, ftype defval)      \
178 {                                                                       \
179                                                                         \
180         if (nvlist_exists_##type(nvl, name))                            \
181                 return (nvlist_take_##type(nvl, name));                 \
182         else                                                            \
183                 return (defval);                                        \
184 }
185
186 DNVLIST_TAKE(bool, bool)
187 DNVLIST_TAKE(uint64_t, number)
188 DNVLIST_TAKE(char *, string)
189 DNVLIST_TAKE(nvlist_t *, nvlist)
190 #ifndef _KERNEL
191 DNVLIST_TAKE(int, descriptor)
192 #endif
193
194 #undef  DNVLIST_TAKE
195
196 void *
197 dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep,
198     void *defval, size_t defsize)
199 {
200         void *value;
201
202         if (nvlist_exists_binary(nvl, name))
203                 value = nvlist_take_binary(nvl, name, sizep);
204         else {
205                 if (sizep != NULL)
206                         *sizep = defsize;
207                 value = defval;
208         }
209         return (value);
210 }
211
212 #ifndef _KERNEL
213 #define DNVLIST_TAKEF(ftype, type)                                      \
214 ftype                                                                   \
215 dnvlist_takef_##type(nvlist_t *nvl, ftype defval,                       \
216     const char *namefmt, ...)                                           \
217 {                                                                       \
218         va_list nameap;                                                 \
219         ftype value;                                                    \
220                                                                         \
221         va_start(nameap, namefmt);                                      \
222         value = dnvlist_takev_##type(nvl, defval, namefmt, nameap);     \
223         va_end(nameap);                                                 \
224                                                                         \
225         return (value);                                                 \
226 }
227
228 DNVLIST_TAKEF(bool, bool)
229 DNVLIST_TAKEF(uint64_t, number)
230 DNVLIST_TAKEF(char *, string)
231 DNVLIST_TAKEF(nvlist_t *, nvlist)
232 DNVLIST_TAKEF(int, descriptor)
233
234 #undef  DNVLIST_TAKEF
235
236 void *
237 dnvlist_takef_binary(nvlist_t *nvl, size_t *sizep, void *defval,
238     size_t defsize, const char *namefmt, ...)
239 {
240         va_list nameap;
241         void *value;
242
243         va_start(nameap, namefmt);
244         value = dnvlist_takev_binary(nvl, sizep, defval, defsize, namefmt,
245             nameap);
246         va_end(nameap);
247
248         return (value);
249 }
250
251 #define DNVLIST_TAKEV(ftype, type)                                      \
252 ftype                                                                   \
253 dnvlist_takev_##type(nvlist_t *nvl, ftype defval, const char *namefmt,  \
254     va_list nameap)                                                     \
255 {                                                                       \
256         char *name;                                                     \
257         ftype value;                                                    \
258                                                                         \
259         vasprintf(&name, namefmt, nameap);                              \
260         if (name == NULL)                                               \
261                 return (defval);                                        \
262         value = dnvlist_take_##type(nvl, name, defval);                 \
263         free(name);                                                     \
264         return (value);                                                 \
265 }
266
267 DNVLIST_TAKEV(bool, bool)
268 DNVLIST_TAKEV(uint64_t, number)
269 DNVLIST_TAKEV(char *, string)
270 DNVLIST_TAKEV(nvlist_t *, nvlist)
271 DNVLIST_TAKEV(int, descriptor)
272
273 #undef  DNVLIST_TAKEV
274
275 void *
276 dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval,
277     size_t defsize, const char *namefmt, va_list nameap)
278 {
279         char *name;
280         void *value;
281
282         nv_vasprintf(&name, namefmt, nameap);
283         if (name != NULL) {
284                 value = dnvlist_take_binary(nvl, name, sizep, defval, defsize);
285                 nv_free(name);
286         } else {
287                 if (sizep != NULL)
288                         *sizep = defsize;
289                 value = defval;
290         }
291
292         return (value);
293 }
294 #endif