zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/e2fsck/profile_helpers.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/e2fsck/profile_helpers.c
new file mode 100644
index 0000000..9c9080a
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/e2fsck/profile_helpers.c
@@ -0,0 +1,310 @@
+/*
+ * profile_helpers.c -- Helper functions for the profile library
+ *
+ * These functions are not part of the "core" profile library, and do
+ * not require access to the internal functions and data structures of
+ * the profile library.  They are mainly convenience functions for
+ * programs that want to do something unusual such as obtaining the
+ * list of sections or relations, or accessing multiple values from a
+ * relation that is listed more than once.  This functionality can all
+ * be done using the profile_iterator abstraction, but it is less
+ * convenient.
+ *
+ * Copyright (C) 2006 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <et/com_err.h>
+#include "profile.h"
+#include "prof_err.h"
+
+/*
+ * These functions --- init_list(), end_list(), and add_to_list() are
+ * internal functions used to build up a null-terminated char ** list
+ * of strings to be returned by functions like profile_get_values.
+ *
+ * The profile_string_list structure is used for internal booking
+ * purposes to build up the list, which is returned in *ret_list by
+ * the end_list() function.
+ *
+ * The publicly exported interface for freeing char** list is
+ * profile_free_list().
+ */
+
+struct profile_string_list {
+	char	**list;
+	int	num;
+	int	max;
+};
+
+/*
+ * Initialize the string list abstraction.
+ */
+static errcode_t init_list(struct profile_string_list *list)
+{
+	list->num = 0;
+	list->max = 10;
+	list->list = malloc(list->max * sizeof(char *));
+	if (list->list == 0)
+		return ENOMEM;
+	list->list[0] = 0;
+	return 0;
+}
+
+/*
+ * Free any memory left over in the string abstraction, returning the
+ * built up list in *ret_list if it is non-null.
+ */
+static void end_list(struct profile_string_list *list, char ***ret_list)
+{
+	char	**cp;
+
+	if (list == 0)
+		return;
+
+	if (ret_list) {
+		*ret_list = list->list;
+		return;
+	} else {
+		for (cp = list->list; *cp; cp++)
+			free(*cp);
+		free(list->list);
+	}
+	list->num = list->max = 0;
+	list->list = 0;
+}
+
+/*
+ * Add a string to the list.
+ */
+static errcode_t add_to_list(struct profile_string_list *list, char *str)
+{
+	char 	**newlist;
+	int	newmax;
+
+	if (list->num+1 >= list->max) {
+		newmax = list->max + 10;
+		newlist = realloc(list->list, newmax * sizeof(char *));
+		if (newlist == 0)
+			return ENOMEM;
+		list->max = newmax;
+		list->list = newlist;
+	}
+
+	list->list[list->num++] = str;
+	list->list[list->num] = 0;
+	return 0;
+}
+
+/*
+ * Return TRUE if the string is already a member of the list.
+ */
+static int is_list_member(struct profile_string_list *list, const char *str)
+{
+	char **cpp;
+
+	if (!list->list)
+		return 0;
+
+	for (cpp = list->list; *cpp; cpp++) {
+		if (!strcmp(*cpp, str))
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * This function frees a null-terminated list as returned by
+ * profile_get_values.
+ */
+void profile_free_list(char **list)
+{
+    char	**cp;
+
+    if (list == 0)
+	    return;
+
+    for (cp = list; *cp; cp++)
+	free(*cp);
+    free(list);
+}
+
+errcode_t
+profile_get_values(profile_t profile, const char *const *names,
+		   char ***ret_values)
+{
+	errcode_t		retval;
+	void			*state;
+	char			*value;
+	struct profile_string_list values;
+
+	if ((retval = profile_iterator_create(profile, names,
+					      PROFILE_ITER_RELATIONS_ONLY,
+					      &state)))
+		return retval;
+
+	if ((retval = init_list(&values)))
+		return retval;
+
+	do {
+		if ((retval = profile_iterator(&state, 0, &value)))
+			goto cleanup;
+		if (value)
+			add_to_list(&values, value);
+	} while (state);
+
+	if (values.num == 0) {
+		retval = PROF_NO_RELATION;
+		goto cleanup;
+	}
+
+	end_list(&values, ret_values);
+	return 0;
+
+cleanup:
+	end_list(&values, 0);
+	return retval;
+}
+
+/*
+ * This function will return the list of the names of subections in the
+ * under the specified section name.
+ */
+errcode_t
+profile_get_subsection_names(profile_t profile, const char **names,
+			     char ***ret_names)
+{
+	errcode_t		retval;
+	void			*state;
+	char			*name;
+	struct profile_string_list values;
+
+	if ((retval = profile_iterator_create(profile, names,
+		   PROFILE_ITER_LIST_SECTION | PROFILE_ITER_SECTIONS_ONLY,
+		   &state)))
+		return retval;
+
+	if ((retval = init_list(&values)))
+		return retval;
+
+	do {
+		if ((retval = profile_iterator(&state, &name, 0)))
+			goto cleanup;
+		if (name)
+			add_to_list(&values, name);
+	} while (state);
+
+	end_list(&values, ret_names);
+	return 0;
+
+cleanup:
+	end_list(&values, 0);
+	return retval;
+}
+
+/*
+ * This function will return the list of the names of relations in the
+ * under the specified section name.
+ */
+errcode_t
+profile_get_relation_names(profile_t profile, const char **names,
+			   char ***ret_names)
+{
+	errcode_t		retval;
+	void			*state;
+	char			*name;
+	struct profile_string_list values;
+
+	if ((retval = profile_iterator_create(profile, names,
+		   PROFILE_ITER_LIST_SECTION | PROFILE_ITER_RELATIONS_ONLY,
+		   &state)))
+		return retval;
+
+	if ((retval = init_list(&values)))
+		return retval;
+
+	do {
+		if ((retval = profile_iterator(&state, &name, 0)))
+			goto cleanup;
+		if (name) {
+			if (is_list_member(&values, name))
+				free(name);
+			else
+				add_to_list(&values, name);
+		}
+	} while (state);
+
+	end_list(&values, ret_names);
+	return 0;
+
+cleanup:
+	end_list(&values, 0);
+	return retval;
+}
+
+
+void
+profile_release_string(char *str)
+{
+	free(str);
+}
+
+errcode_t
+profile_init_path(const char * filepath,
+		  profile_t *ret_profile)
+{
+	int n_entries, i;
+	unsigned int ent_len;
+	const char *s, *t;
+	char **filenames;
+	errcode_t retval;
+
+	/* count the distinct filename components */
+	for(s = filepath, n_entries = 1; *s; s++) {
+		if (*s == ':')
+			n_entries++;
+	}
+
+	/* the array is NULL terminated */
+	filenames = (char **) malloc((n_entries+1) * sizeof(char*));
+	if (filenames == 0)
+		return ENOMEM;
+
+	/* measure, copy, and skip each one */
+	for(s = filepath, i=0; (t = strchr(s, ':')) || (t=s+strlen(s)); s=t+1, i++) {
+		ent_len = t-s;
+		filenames[i] = (char*) malloc(ent_len + 1);
+		if (filenames[i] == 0) {
+			/* if malloc fails, free the ones that worked */
+			while(--i >= 0) free(filenames[i]);
+                        free(filenames);
+			return ENOMEM;
+		}
+		strncpy(filenames[i], s, ent_len);
+		filenames[i][ent_len] = 0;
+		if (*t == 0) {
+			i++;
+			break;
+		}
+	}
+	/* cap the array */
+	filenames[i] = 0;
+
+	retval = profile_init((const char **) filenames,
+			      ret_profile);
+
+	/* count back down and free the entries */
+	while(--i >= 0) free(filenames[i]);
+	free(filenames);
+
+	return retval;
+}