8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / gss_mechs / mech_krb5 / profile / prof_get.c
blobc58594d5a12ca35c38695c09eba90630dcf22e5f
1 /*
2 * prof_get.c --- routines that expose the public interfaces for
3 * querying items from the profile.
5 */
7 #include "prof_int.h"
8 #include <stdio.h>
9 #include <string.h>
10 #ifdef HAVE_STDLIB_H
11 #include <stdlib.h>
12 #endif
13 #include <errno.h>
14 #include <limits.h>
17 * Solaris Kerberos: The following functions are made public so that other
18 * profile functions can call upon these basic routines:
19 * init_list(), end_list(), and add_to_list().
20 * Note: That profile_string_list is moved to prof_int.h as a result.
22 * These functions --- init_list(), end_list(), and add_to_list() are
23 * publicy exported functions used to build up a null-terminated char ** list
24 * of strings to be returned by functions like profile_get_values.
26 * The publicly exported interface for freeing char** list is
27 * profile_free_list().
31 * Initialize the string list abstraction.
33 errcode_t init_list(struct profile_string_list *list)
35 list->num = 0;
36 list->max = 10;
37 list->list = malloc(list->max * sizeof(char *));
38 if (list->list == 0)
39 return ENOMEM;
40 list->list[0] = 0;
41 return 0;
45 * Free any memory left over in the string abstraction, returning the
46 * built up list in *ret_list if it is non-null.
48 void end_list(struct profile_string_list *list, char ***ret_list)
50 char **cp;
52 if (list == 0)
53 return;
55 if (ret_list) {
56 *ret_list = list->list;
57 return;
58 } else {
59 for (cp = list->list; *cp; cp++)
60 free(*cp);
61 free(list->list);
63 list->num = list->max = 0;
64 list->list = 0;
68 * Add a string to the list.
70 errcode_t add_to_list(struct profile_string_list *list, const char *str)
72 char *newstr, **newlist;
73 int newmax;
75 if (list->num+1 >= list->max) {
76 newmax = list->max + 10;
77 newlist = realloc(list->list, newmax * sizeof(char *));
78 if (newlist == 0)
79 return ENOMEM;
80 list->max = newmax;
81 list->list = newlist;
83 newstr = malloc(strlen(str)+1);
84 if (newstr == 0)
85 return ENOMEM;
86 strcpy(newstr, str);
88 list->list[list->num++] = newstr;
89 list->list[list->num] = 0;
90 return 0;
94 * Return TRUE if the string is already a member of the list.
96 static int is_list_member(struct profile_string_list *list, const char *str)
98 char **cpp;
100 if (!list->list)
101 return 0;
103 for (cpp = list->list; *cpp; cpp++) {
104 if (!strcmp(*cpp, str))
105 return 1;
107 return 0;
111 * This function frees a null-terminated list as returned by
112 * profile_get_values.
114 void KRB5_CALLCONV profile_free_list(char **list)
116 char **cp;
118 if (list == 0)
119 return;
121 for (cp = list; *cp; cp++)
122 free(*cp);
123 free(list);
126 errcode_t KRB5_CALLCONV
127 profile_get_values(profile_t profile, const char *const *names,
128 char ***ret_values)
130 errcode_t retval;
131 void *state;
132 char *value;
133 struct profile_string_list values;
135 if ((retval = profile_node_iterator_create(profile, names,
136 PROFILE_ITER_RELATIONS_ONLY,
137 &state)))
138 return retval;
140 if ((retval = init_list(&values)))
141 return retval;
143 do {
144 if ((retval = profile_node_iterator(&state, 0, 0, &value)))
145 goto cleanup;
146 if (value)
147 add_to_list(&values, value);
148 } while (state);
150 if (values.num == 0) {
151 retval = PROF_NO_RELATION;
152 goto cleanup;
155 end_list(&values, ret_values);
156 return 0;
158 cleanup:
159 end_list(&values, 0);
160 return retval;
164 * This function only gets the first value from the file; it is a
165 * helper function for profile_get_string, profile_get_integer, etc.
167 errcode_t profile_get_value(profile_t profile, const char **names,
168 const char **ret_value)
170 errcode_t retval;
171 void *state;
172 char *value;
174 if ((retval = profile_node_iterator_create(profile, names,
175 PROFILE_ITER_RELATIONS_ONLY,
176 &state)))
177 return retval;
179 if ((retval = profile_node_iterator(&state, 0, 0, &value)))
180 goto cleanup;
182 if (value)
183 *ret_value = value;
184 else
185 retval = PROF_NO_RELATION;
187 cleanup:
188 profile_node_iterator_free(&state);
189 return retval;
192 errcode_t KRB5_CALLCONV
193 profile_get_string(profile_t profile, const char *name, const char *subname,
194 const char *subsubname, const char *def_val,
195 char **ret_string)
197 const char *value;
198 errcode_t retval;
199 const char *names[4];
201 if (profile) {
202 names[0] = name;
203 names[1] = subname;
204 names[2] = subsubname;
205 names[3] = 0;
206 retval = profile_get_value(profile, names, &value);
207 if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION)
208 value = def_val;
209 else if (retval)
210 return retval;
211 } else
212 value = def_val;
214 if (value) {
215 *ret_string = malloc(strlen(value)+1);
216 if (*ret_string == 0)
217 return ENOMEM;
218 strcpy(*ret_string, value);
219 } else
220 *ret_string = 0;
221 return 0;
224 errcode_t KRB5_CALLCONV
225 profile_get_integer(profile_t profile, const char *name, const char *subname,
226 const char *subsubname, int def_val, int *ret_int)
228 const char *value;
229 errcode_t retval;
230 const char *names[4];
231 char *end_value;
232 long ret_long;
234 *ret_int = def_val;
235 if (profile == 0)
236 return 0;
238 names[0] = name;
239 names[1] = subname;
240 names[2] = subsubname;
241 names[3] = 0;
242 retval = profile_get_value(profile, names, &value);
243 if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION) {
244 *ret_int = def_val;
245 return 0;
246 } else if (retval)
247 return retval;
249 if (value[0] == 0)
250 /* Empty string is no good. */
251 return PROF_BAD_INTEGER;
252 errno = 0;
253 ret_long = strtol (value, &end_value, 10);
255 /* Overflow or underflow. */
256 if ((ret_long == LONG_MIN || ret_long == LONG_MAX) && errno != 0)
257 return PROF_BAD_INTEGER;
258 /* Value outside "int" range. */
259 if ((long) (int) ret_long != ret_long)
260 return PROF_BAD_INTEGER;
261 /* Garbage in string. */
262 if (end_value != value + strlen (value))
263 return PROF_BAD_INTEGER;
266 *ret_int = ret_long;
267 return 0;
270 static const char *const conf_yes[] = {
271 "y", "yes", "true", "t", "1", "on",
275 static const char *const conf_no[] = {
276 "n", "no", "false", "nil", "0", "off",
280 static errcode_t
281 profile_parse_boolean(const char *s, int *ret_boolean)
283 const char *const *p;
285 if (ret_boolean == NULL)
286 return PROF_EINVAL;
288 for(p=conf_yes; *p; p++) {
289 if (!strcasecmp(*p,s)) {
290 *ret_boolean = 1;
291 return 0;
295 for(p=conf_no; *p; p++) {
296 if (!strcasecmp(*p,s)) {
297 *ret_boolean = 0;
298 return 0;
302 return PROF_BAD_BOOLEAN;
305 errcode_t KRB5_CALLCONV
306 profile_get_boolean(profile_t profile, const char *name, const char *subname,
307 const char *subsubname, int def_val, int *ret_boolean)
309 const char *value;
310 errcode_t retval;
311 const char *names[4];
313 if (profile == 0) {
314 *ret_boolean = def_val;
315 return 0;
318 names[0] = name;
319 names[1] = subname;
320 names[2] = subsubname;
321 names[3] = 0;
322 retval = profile_get_value(profile, names, &value);
323 if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION) {
324 *ret_boolean = def_val;
325 return 0;
326 } else if (retval)
327 return retval;
329 return profile_parse_boolean (value, ret_boolean);
333 * This function will return the list of the names of subections in the
334 * under the specified section name.
336 errcode_t KRB5_CALLCONV
337 profile_get_subsection_names(profile_t profile, const char **names,
338 char ***ret_names)
340 errcode_t retval;
341 void *state;
342 char *name;
343 struct profile_string_list values;
345 if ((retval = profile_node_iterator_create(profile, names,
346 PROFILE_ITER_LIST_SECTION | PROFILE_ITER_SECTIONS_ONLY,
347 &state)))
348 return retval;
350 if ((retval = init_list(&values)))
351 return retval;
353 do {
354 if ((retval = profile_node_iterator(&state, 0, &name, 0)))
355 goto cleanup;
356 if (name)
357 add_to_list(&values, name);
358 } while (state);
360 end_list(&values, ret_names);
361 return 0;
363 cleanup:
364 end_list(&values, 0);
365 return retval;
369 * This function will return the list of the names of relations in the
370 * under the specified section name.
372 errcode_t KRB5_CALLCONV
373 profile_get_relation_names(profile_t profile, const char **names,
374 char ***ret_names)
376 errcode_t retval;
377 void *state;
378 char *name;
379 struct profile_string_list values;
381 if ((retval = profile_node_iterator_create(profile, names,
382 PROFILE_ITER_LIST_SECTION | PROFILE_ITER_RELATIONS_ONLY,
383 &state)))
384 return retval;
386 if ((retval = init_list(&values)))
387 return retval;
389 do {
390 if ((retval = profile_node_iterator(&state, 0, &name, 0)))
391 goto cleanup;
392 if (name && !is_list_member(&values, name))
393 add_to_list(&values, name);
394 } while (state);
396 end_list(&values, ret_names);
397 return 0;
399 cleanup:
400 end_list(&values, 0);
401 return retval;
404 errcode_t KRB5_CALLCONV
405 profile_iterator_create(profile_t profile, const char *const *names, int flags,
406 void **ret_iter)
408 return profile_node_iterator_create(profile, names, flags, ret_iter);
411 void KRB5_CALLCONV
412 profile_iterator_free(void **iter_p)
414 profile_node_iterator_free(iter_p);
417 errcode_t KRB5_CALLCONV
418 profile_iterator(void **iter_p, char **ret_name, char **ret_value)
420 char *name, *value;
421 errcode_t retval;
423 retval = profile_node_iterator(iter_p, 0, &name, &value);
424 if (retval)
425 return retval;
427 if (ret_name) {
428 if (name) {
429 *ret_name = malloc(strlen(name)+1);
430 if (!*ret_name)
431 return ENOMEM;
432 strcpy(*ret_name, name);
433 } else
434 *ret_name = 0;
436 if (ret_value) {
437 if (value) {
438 *ret_value = malloc(strlen(value)+1);
439 if (!*ret_value) {
440 if (ret_name) {
441 free(*ret_name);
442 *ret_name = 0;
444 return ENOMEM;
446 strcpy(*ret_value, value);
447 } else
448 *ret_value = 0;
450 return 0;
453 void KRB5_CALLCONV
454 profile_release_string(char *str)
456 free(str);