19a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
29a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * profile_helpers.c -- Helper functions for the profile library
39a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o *
49a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * These functions are not part of the "core" profile library, and do
59a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * not require access to the internal functions and data structures of
69a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * the profile library.  They are mainly convenience functions for
79a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * programs that want to do something unusual such as obtaining the
89a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * list of sections or relations, or accessing multiple values from a
99a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * relation that is listed more than once.  This functionality can all
109a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * be done using the profile_iterator abstraction, but it is less
119a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * convenient.
12efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
139a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Copyright (C) 2006 by Theodore Ts'o.
149a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o *
159a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * %Begin-Header%
169a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * This file may be redistributed under the terms of the GNU Public
179a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * License.
189a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * %End-Header%
199a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
209a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
21d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h"
229a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <stdlib.h>
239a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <string.h>
249a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <errno.h>
259a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
269a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <et/com_err.h>
279a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include "profile.h"
28a701823a31505c5765d327d02bb14aa43fc34ae5Theodore Ts'o#include "profile_helpers.h"
299a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include "prof_err.h"
309a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
319a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
329a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * These functions --- init_list(), end_list(), and add_to_list() are
339a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * internal functions used to build up a null-terminated char ** list
349a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * of strings to be returned by functions like profile_get_values.
359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o *
369a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * The profile_string_list structure is used for internal booking
379a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * purposes to build up the list, which is returned in *ret_list by
389a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * the end_list() function.
399a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o *
409a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * The publicly exported interface for freeing char** list is
419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * profile_free_list().
429a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
439a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
449a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostruct profile_string_list {
459a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char	**list;
469a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int	num;
479a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int	max;
489a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o};
499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
509a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
519a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Initialize the string list abstraction.
529a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
539a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostatic errcode_t init_list(struct profile_string_list *list)
549a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
559a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->num = 0;
569a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->max = 10;
579a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list = malloc(list->max * sizeof(char *));
589a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (list->list == 0)
599a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return ENOMEM;
609a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list[0] = 0;
619a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
629a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
639a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
659a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Free any memory left over in the string abstraction, returning the
669a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * built up list in *ret_list if it is non-null.
679a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
689a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostatic void end_list(struct profile_string_list *list, char ***ret_list)
699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
709a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char	**cp;
719a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (list == 0)
739a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return;
749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
759a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (ret_list) {
769a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		*ret_list = list->list;
779a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return;
789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} else {
799a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		for (cp = list->list; *cp; cp++)
809a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			free(*cp);
819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		free(list->list);
829a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
839a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->num = list->max = 0;
849a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list = 0;
859a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
869a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
879a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
889a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Add a string to the list.
899a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
90d673582241d9970e96b56caa0fd79ff95871c39bTheodore Ts'ostatic errcode_t add_to_list(struct profile_string_list *list, char *str)
919a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
929a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char 	**newlist;
939a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int	newmax;
94efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
959a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (list->num+1 >= list->max) {
969a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		newmax = list->max + 10;
979a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		newlist = realloc(list->list, newmax * sizeof(char *));
989a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (newlist == 0)
999a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			return ENOMEM;
1009a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		list->max = newmax;
1019a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		list->list = newlist;
1029a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
1039a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1049a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list[list->num++] = str;
1059a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list[list->num] = 0;
1069a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
1079a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
1089a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1099a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
1109a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Return TRUE if the string is already a member of the list.
1119a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
1129a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostatic int is_list_member(struct profile_string_list *list, const char *str)
1139a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1149a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char **cpp;
1159a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1169a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (!list->list)
1179a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return 0;
1189a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1199a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	for (cpp = list->list; *cpp; cpp++) {
1209a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (!strcmp(*cpp, str))
1219a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			return 1;
1229a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
1239a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
124efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o}
125efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1269a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
1279a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * This function frees a null-terminated list as returned by
1289a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * profile_get_values.
1299a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
1309a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ovoid profile_free_list(char **list)
1319a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1329a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    char	**cp;
1339a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1349a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    if (list == 0)
1359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	    return;
136efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1379a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    for (cp = list; *cp; cp++)
1389a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	free(*cp);
1399a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    free(list);
1409a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
1419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1429a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oerrcode_t
1439a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_get_values(profile_t profile, const char *const *names,
1449a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   char ***ret_values)
1459a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1469a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t		retval;
1479a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	void			*state;
1489a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char			*value;
1499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	struct profile_string_list values;
1509a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1519a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = profile_iterator_create(profile, names,
1529a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o					      PROFILE_ITER_RELATIONS_ONLY,
1539a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o					      &state)))
1549a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
1559a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1569a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = init_list(&values)))
15737000b024574d78b1313168443fd110b09c6d85bTheodore Ts'o		goto cleanup_iterator;
1589a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1599a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	do {
1609a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if ((retval = profile_iterator(&state, 0, &value)))
1619a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			goto cleanup;
1629a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (value)
1639a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			add_to_list(&values, value);
1649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} while (state);
1659a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1669a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (values.num == 0) {
1679a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		retval = PROF_NO_RELATION;
1689a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		goto cleanup;
1699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
1709a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1719a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, ret_values);
1729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
173efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ocleanup:
1759a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, 0);
17637000b024574d78b1313168443fd110b09c6d85bTheodore Ts'ocleanup_iterator:
17737000b024574d78b1313168443fd110b09c6d85bTheodore Ts'o	profile_iterator_free(&state);
1789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
1799a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
1809a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
1829a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * This function will return the list of the names of subections in the
1839a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * under the specified section name.
1849a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
185efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t
1869a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_get_subsection_names(profile_t profile, const char **names,
1879a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			     char ***ret_names)
1889a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1899a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t		retval;
1909a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	void			*state;
1919a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char			*name;
1929a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	struct profile_string_list values;
1939a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1949a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = profile_iterator_create(profile, names,
1959a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   PROFILE_ITER_LIST_SECTION | PROFILE_ITER_SECTIONS_ONLY,
1969a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   &state)))
1979a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
1989a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1999a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = init_list(&values)))
20037000b024574d78b1313168443fd110b09c6d85bTheodore Ts'o		goto cleanup_iterator;
2019a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2029a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	do {
2039a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if ((retval = profile_iterator(&state, &name, 0)))
2049a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			goto cleanup;
2059a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (name)
2069a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			add_to_list(&values, name);
2079a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} while (state);
2089a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2099a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, ret_names);
2109a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
211efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2129a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ocleanup:
2139a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, 0);
21437000b024574d78b1313168443fd110b09c6d85bTheodore Ts'ocleanup_iterator:
21537000b024574d78b1313168443fd110b09c6d85bTheodore Ts'o	profile_iterator_free(&state);
2169a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
2179a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
2189a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2199a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
2209a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * This function will return the list of the names of relations in the
2219a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * under the specified section name.
2229a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
223efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t
2249a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_get_relation_names(profile_t profile, const char **names,
2259a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			   char ***ret_names)
2269a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
2279a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t		retval;
2289a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	void			*state;
2299a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char			*name;
2309a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	struct profile_string_list values;
2319a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2329a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = profile_iterator_create(profile, names,
2339a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   PROFILE_ITER_LIST_SECTION | PROFILE_ITER_RELATIONS_ONLY,
2349a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   &state)))
2359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
2369a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2379a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = init_list(&values)))
23837000b024574d78b1313168443fd110b09c6d85bTheodore Ts'o		goto cleanup_iterator;
2399a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2409a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	do {
2419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if ((retval = profile_iterator(&state, &name, 0)))
2429a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			goto cleanup;
2439a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (name) {
2449a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			if (is_list_member(&values, name))
2459a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o				free(name);
2469a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			else
2479a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o				add_to_list(&values, name);
2489a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		}
2499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} while (state);
2509a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2519a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, ret_names);
2529a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
253efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2549a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ocleanup:
2559a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, 0);
25637000b024574d78b1313168443fd110b09c6d85bTheodore Ts'ocleanup_iterator:
25737000b024574d78b1313168443fd110b09c6d85bTheodore Ts'o	profile_iterator_free(&state);
2589a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
2599a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
2609a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2619a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
262efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ovoid
2639a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_release_string(char *str)
2649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
2659a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	free(str);
2669a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
2679a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
268efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t
2699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_init_path(const char * filepath,
2709a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		  profile_t *ret_profile)
2719a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
2729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int n_entries, i;
2739a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	unsigned int ent_len;
2749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	const char *s, *t;
2759a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char **filenames;
2769a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t retval;
2779a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* count the distinct filename components */
2799a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	for(s = filepath, n_entries = 1; *s; s++) {
2809a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (*s == ':')
2819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			n_entries++;
2829a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
283efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2849a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* the array is NULL terminated */
2859a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	filenames = (char **) malloc((n_entries+1) * sizeof(char*));
2869a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (filenames == 0)
2879a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return ENOMEM;
2889a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2899a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* measure, copy, and skip each one */
2909a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	for(s = filepath, i=0; (t = strchr(s, ':')) || (t=s+strlen(s)); s=t+1, i++) {
2919a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		ent_len = t-s;
2929a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		filenames[i] = (char*) malloc(ent_len + 1);
2939a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (filenames[i] == 0) {
2949a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			/* if malloc fails, free the ones that worked */
2959a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			while(--i >= 0) free(filenames[i]);
2969a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o                        free(filenames);
2979a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			return ENOMEM;
2989a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		}
2999a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		strncpy(filenames[i], s, ent_len);
3009a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		filenames[i][ent_len] = 0;
3019a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (*t == 0) {
3029a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			i++;
3039a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			break;
3049a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		}
3059a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
3069a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* cap the array */
3079a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	filenames[i] = 0;
3089a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
309a701823a31505c5765d327d02bb14aa43fc34ae5Theodore Ts'o	retval = profile_init((const char * const *) filenames,
3109a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			      ret_profile);
3119a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
3129a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* count back down and free the entries */
3139a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	while(--i >= 0) free(filenames[i]);
3149a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	free(filenames);
3159a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
3169a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
3179a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
318