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
219a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <stdlib.h>
229a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <string.h>
239a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <errno.h>
249a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
259a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include <et/com_err.h>
269a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include "profile.h"
279a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include "prof_err.h"
289a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
299a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
309a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * These functions --- init_list(), end_list(), and add_to_list() are
319a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * internal functions used to build up a null-terminated char ** list
329a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * of strings to be returned by functions like profile_get_values.
339a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o *
349a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * The profile_string_list structure is used for internal booking
359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * purposes to build up the list, which is returned in *ret_list by
369a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * the end_list() function.
379a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o *
389a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * The publicly exported interface for freeing char** list is
399a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * profile_free_list().
409a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
429a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostruct profile_string_list {
439a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char	**list;
449a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int	num;
459a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int	max;
469a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o};
479a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
489a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Initialize the string list abstraction.
509a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
519a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostatic errcode_t init_list(struct profile_string_list *list)
529a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
539a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->num = 0;
549a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->max = 10;
559a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list = malloc(list->max * sizeof(char *));
569a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (list->list == 0)
579a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return ENOMEM;
589a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list[0] = 0;
599a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
609a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
619a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
629a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
639a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Free any memory left over in the string abstraction, returning the
649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * built up list in *ret_list if it is non-null.
659a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
669a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostatic void end_list(struct profile_string_list *list, char ***ret_list)
679a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
689a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char	**cp;
699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
709a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (list == 0)
719a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return;
729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
739a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (ret_list) {
749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		*ret_list = list->list;
759a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return;
769a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} else {
779a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		for (cp = list->list; *cp; cp++)
789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			free(*cp);
799a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		free(list->list);
809a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->num = list->max = 0;
829a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list = 0;
839a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
849a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
859a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
869a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Add a string to the list.
879a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
88d673582241d9970e96b56caa0fd79ff95871c39bTheodore Ts'ostatic errcode_t add_to_list(struct profile_string_list *list, char *str)
899a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
909a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char 	**newlist;
919a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int	newmax;
92efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
939a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (list->num+1 >= list->max) {
949a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		newmax = list->max + 10;
959a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		newlist = realloc(list->list, newmax * sizeof(char *));
969a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (newlist == 0)
979a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			return ENOMEM;
989a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		list->max = newmax;
999a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		list->list = newlist;
1009a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
1019a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1029a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list[list->num++] = str;
1039a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	list->list[list->num] = 0;
1049a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
1059a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
1069a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1079a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
1089a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * Return TRUE if the string is already a member of the list.
1099a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
1109a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostatic int is_list_member(struct profile_string_list *list, const char *str)
1119a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1129a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char **cpp;
1139a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1149a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (!list->list)
1159a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return 0;
1169a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1179a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	for (cpp = list->list; *cpp; cpp++) {
1189a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (!strcmp(*cpp, str))
1199a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			return 1;
1209a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
1219a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
122efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o}
123efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1249a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
1259a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * This function frees a null-terminated list as returned by
1269a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * profile_get_values.
1279a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
1289a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ovoid profile_free_list(char **list)
1299a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1309a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    char	**cp;
1319a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1329a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    if (list == 0)
1339a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	    return;
134efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    for (cp = list; *cp; cp++)
1369a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	free(*cp);
1379a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o    free(list);
1389a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
1399a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1409a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oerrcode_t
1419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_get_values(profile_t profile, const char *const *names,
1429a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   char ***ret_values)
1439a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1449a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t		retval;
1459a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	void			*state;
1469a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char			*value;
1479a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	struct profile_string_list values;
1489a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = profile_iterator_create(profile, names,
1509a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o					      PROFILE_ITER_RELATIONS_ONLY,
1519a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o					      &state)))
1529a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
1539a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1549a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = init_list(&values)))
1559a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
1569a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1579a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	do {
1589a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if ((retval = profile_iterator(&state, 0, &value)))
1599a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			goto cleanup;
1609a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (value)
1619a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			add_to_list(&values, value);
1629a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} while (state);
1639a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (values.num == 0) {
1659a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		retval = PROF_NO_RELATION;
1669a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		goto cleanup;
1679a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
1689a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, ret_values);
1709a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
171efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ocleanup:
1739a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, 0);
1749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
1759a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
1769a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1779a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
1789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * This function will return the list of the names of subections in the
1799a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * under the specified section name.
1809a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
181efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t
1829a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_get_subsection_names(profile_t profile, const char **names,
1839a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			     char ***ret_names)
1849a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
1859a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t		retval;
1869a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	void			*state;
1879a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char			*name;
1889a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	struct profile_string_list values;
1899a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1909a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = profile_iterator_create(profile, names,
1919a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   PROFILE_ITER_LIST_SECTION | PROFILE_ITER_SECTIONS_ONLY,
1929a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   &state)))
1939a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
1949a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1959a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = init_list(&values)))
1969a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
1979a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
1989a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	do {
1999a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if ((retval = profile_iterator(&state, &name, 0)))
2009a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			goto cleanup;
2019a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (name)
2029a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			add_to_list(&values, name);
2039a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} while (state);
2049a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2059a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, ret_names);
2069a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
207efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2089a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ocleanup:
2099a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, 0);
2109a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
2119a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
2129a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2139a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o/*
2149a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * This function will return the list of the names of relations in the
2159a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o * under the specified section name.
2169a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o */
217efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t
2189a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_get_relation_names(profile_t profile, const char **names,
2199a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			   char ***ret_names)
2209a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
2219a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t		retval;
2229a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	void			*state;
2239a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char			*name;
2249a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	struct profile_string_list values;
2259a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2269a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = profile_iterator_create(profile, names,
2279a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   PROFILE_ITER_LIST_SECTION | PROFILE_ITER_RELATIONS_ONLY,
2289a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		   &state)))
2299a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
2309a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2319a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if ((retval = init_list(&values)))
2329a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return retval;
2339a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2349a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	do {
2359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if ((retval = profile_iterator(&state, &name, 0)))
2369a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			goto cleanup;
2379a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (name) {
2389a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			if (is_list_member(&values, name))
2399a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o				free(name);
2409a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			else
2419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o				add_to_list(&values, name);
2429a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		}
2439a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	} while (state);
2449a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2459a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, ret_names);
2469a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return 0;
247efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2489a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ocleanup:
2499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	end_list(&values, 0);
2509a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
2519a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
2529a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2539a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
254efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ovoid
2559a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_release_string(char *str)
2569a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
2579a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	free(str);
2589a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
2599a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
260efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t
2619a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_init_path(const char * filepath,
2629a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		  profile_t *ret_profile)
2639a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o{
2649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	int n_entries, i;
2659a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	unsigned int ent_len;
2669a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	const char *s, *t;
2679a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	char **filenames;
2689a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	errcode_t retval;
2699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2709a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* count the distinct filename components */
2719a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	for(s = filepath, n_entries = 1; *s; s++) {
2729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (*s == ':')
2739a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			n_entries++;
2749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
275efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2769a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* the array is NULL terminated */
2779a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	filenames = (char **) malloc((n_entries+1) * sizeof(char*));
2789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	if (filenames == 0)
2799a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		return ENOMEM;
2809a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
2819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* measure, copy, and skip each one */
2829a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	for(s = filepath, i=0; (t = strchr(s, ':')) || (t=s+strlen(s)); s=t+1, i++) {
2839a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		ent_len = t-s;
2849a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		filenames[i] = (char*) malloc(ent_len + 1);
2859a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (filenames[i] == 0) {
2869a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			/* if malloc fails, free the ones that worked */
2879a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			while(--i >= 0) free(filenames[i]);
2889a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o                        free(filenames);
2899a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			return ENOMEM;
2909a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		}
2919a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		strncpy(filenames[i], s, ent_len);
2929a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		filenames[i][ent_len] = 0;
2939a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		if (*t == 0) {
2949a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			i++;
2959a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			break;
2969a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o		}
2979a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	}
2989a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* cap the array */
2999a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	filenames[i] = 0;
3009a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
301efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	retval = profile_init((const char **) filenames,
3029a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o			      ret_profile);
3039a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
3049a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	/* count back down and free the entries */
3059a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	while(--i >= 0) free(filenames[i]);
3069a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	free(filenames);
3079a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o
3089a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o	return retval;
3099a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}
310