2 * prof_get.c --- routines that expose the public interfaces for
3 * querying items from the profile.
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
)
37 list
->list
= malloc(list
->max
* sizeof(char *));
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
)
56 *ret_list
= list
->list
;
59 for (cp
= list
->list
; *cp
; cp
++)
63 list
->num
= list
->max
= 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
;
75 if (list
->num
+1 >= list
->max
) {
76 newmax
= list
->max
+ 10;
77 newlist
= realloc(list
->list
, newmax
* sizeof(char *));
83 newstr
= malloc(strlen(str
)+1);
88 list
->list
[list
->num
++] = newstr
;
89 list
->list
[list
->num
] = 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
)
103 for (cpp
= list
->list
; *cpp
; cpp
++) {
104 if (!strcmp(*cpp
, str
))
111 * This function frees a null-terminated list as returned by
112 * profile_get_values.
114 void KRB5_CALLCONV
profile_free_list(char **list
)
121 for (cp
= list
; *cp
; cp
++)
126 errcode_t KRB5_CALLCONV
127 profile_get_values(profile_t profile
, const char *const *names
,
133 struct profile_string_list values
;
135 if ((retval
= profile_node_iterator_create(profile
, names
,
136 PROFILE_ITER_RELATIONS_ONLY
,
140 if ((retval
= init_list(&values
)))
144 if ((retval
= profile_node_iterator(&state
, 0, 0, &value
)))
147 add_to_list(&values
, value
);
150 if (values
.num
== 0) {
151 retval
= PROF_NO_RELATION
;
155 end_list(&values
, ret_values
);
159 end_list(&values
, 0);
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
)
174 if ((retval
= profile_node_iterator_create(profile
, names
,
175 PROFILE_ITER_RELATIONS_ONLY
,
179 if ((retval
= profile_node_iterator(&state
, 0, 0, &value
)))
185 retval
= PROF_NO_RELATION
;
188 profile_node_iterator_free(&state
);
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
,
199 const char *names
[4];
204 names
[2] = subsubname
;
206 retval
= profile_get_value(profile
, names
, &value
);
207 if (retval
== PROF_NO_SECTION
|| retval
== PROF_NO_RELATION
)
215 *ret_string
= malloc(strlen(value
)+1);
216 if (*ret_string
== 0)
218 strcpy(*ret_string
, value
);
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
)
230 const char *names
[4];
240 names
[2] = subsubname
;
242 retval
= profile_get_value(profile
, names
, &value
);
243 if (retval
== PROF_NO_SECTION
|| retval
== PROF_NO_RELATION
) {
250 /* Empty string is no good. */
251 return PROF_BAD_INTEGER
;
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
;
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",
281 profile_parse_boolean(const char *s
, int *ret_boolean
)
283 const char *const *p
;
285 if (ret_boolean
== NULL
)
288 for(p
=conf_yes
; *p
; p
++) {
289 if (!strcasecmp(*p
,s
)) {
295 for(p
=conf_no
; *p
; p
++) {
296 if (!strcasecmp(*p
,s
)) {
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
)
311 const char *names
[4];
314 *ret_boolean
= def_val
;
320 names
[2] = subsubname
;
322 retval
= profile_get_value(profile
, names
, &value
);
323 if (retval
== PROF_NO_SECTION
|| retval
== PROF_NO_RELATION
) {
324 *ret_boolean
= def_val
;
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
,
343 struct profile_string_list values
;
345 if ((retval
= profile_node_iterator_create(profile
, names
,
346 PROFILE_ITER_LIST_SECTION
| PROFILE_ITER_SECTIONS_ONLY
,
350 if ((retval
= init_list(&values
)))
354 if ((retval
= profile_node_iterator(&state
, 0, &name
, 0)))
357 add_to_list(&values
, name
);
360 end_list(&values
, ret_names
);
364 end_list(&values
, 0);
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
,
379 struct profile_string_list values
;
381 if ((retval
= profile_node_iterator_create(profile
, names
,
382 PROFILE_ITER_LIST_SECTION
| PROFILE_ITER_RELATIONS_ONLY
,
386 if ((retval
= init_list(&values
)))
390 if ((retval
= profile_node_iterator(&state
, 0, &name
, 0)))
392 if (name
&& !is_list_member(&values
, name
))
393 add_to_list(&values
, name
);
396 end_list(&values
, ret_names
);
400 end_list(&values
, 0);
404 errcode_t KRB5_CALLCONV
405 profile_iterator_create(profile_t profile
, const char *const *names
, int flags
,
408 return profile_node_iterator_create(profile
, names
, flags
, ret_iter
);
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
)
423 retval
= profile_node_iterator(iter_p
, 0, &name
, &value
);
429 *ret_name
= malloc(strlen(name
)+1);
432 strcpy(*ret_name
, name
);
438 *ret_value
= malloc(strlen(value
)+1);
446 strcpy(*ret_value
, value
);
454 profile_release_string(char *str
)