util.c revision ca92350db6ad6ac344181f7b8ec695eda29da675
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor Simo Sorce <ssorce@redhat.com>
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor Copyright (C) 2009 Red Hat
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor This program is free software; you can redistribute it and/or modify
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor it under the terms of the GNU General Public License as published by
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor the Free Software Foundation; either version 3 of the License, or
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor (at your option) any later version.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen This program is distributed in the hope that it will be useful,
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen but WITHOUT ANY WARRANTY; without even the implied warranty of
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor GNU General Public License for more details.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor You should have received a copy of the GNU General Public License
d229f940abfb2490dee17979e9a5ff31b7012eb5rbowen along with this program. If not, see <http://www.gnu.org/licenses/>.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/* split a string into an allocated array of strings.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * the separator is a string, and is case-sensitive.
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung * optionally single values can be trimmed of of spaces and tabs */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorint split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor const char *t, *p, *n;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor char **list, **r;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* trim leading whitespace */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (isspace(*t)) t++;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* find substrings separated by the separator */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* strip whitespace after the separator
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * so it's not in the next token */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (isspace(*t)) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (len == 0) break;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* strip whitespace before the separator
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * so it's not in the current token */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* Add the token to the array, +2 b/c of the trailing NULL */
cae0359c9286c8e34cbccd15eee2da90562c1ee2sf if (len == 0) {
cae0359c9286c8e34cbccd15eee2da90562c1ee2sf if (!list[l]) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor t = n; /* move to next string */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* Handle the last remaining token */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* trim leading whitespace */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (isspace(*t)) {
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen if (len == 0) break;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* trim trailing whitespace */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (len == 0) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/* parse a string into arguments.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * arguments are separated by a space
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * '\' is an escape character and can be used only to escape
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * itself or the white space.
ba543b319188dc1887607f6d59feddc00e38eee2humbedooh const char *p;
ba543b319188dc1887607f6d59feddc00e38eee2humbedooh char **ret, **r;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (*p) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor switch (*p) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* check if this was the last char */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (*p == '\0') {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* check next char and skip multiple spaces */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (!r) goto fail;
cae0359c9286c8e34cbccd15eee2da90562c1ee2sfchar **dup_string_list(TALLOC_CTX *memctx, const char **str_list)
cae0359c9286c8e34cbccd15eee2da90562c1ee2sf int i = 0;
cae0359c9286c8e34cbccd15eee2da90562c1ee2sf int j = 0;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* Find the size of the list */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (str_list[i]) i++;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* Copy the elements */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor for (j = 0; j < i; j++) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* NULL-terminate the list */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/* Take two string lists (terminated on a NULL char*)
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * and return up to three arrays of strings based on
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * shared ownership.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Pass NULL to any return type you don't care about
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor unsigned long count;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* Add all entries from list 1 into a hash table */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (list1[i]) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* Iterate through list 2 and remove matching items */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (list2[i]) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* String was present in both lists */
ba543b319188dc1887607f6d59feddc00e38eee2humbedooh both_lists = talloc_realloc(tmp_ctx, both_lists, char *, i12+1);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor both_lists[i12-1] = talloc_strdup(both_lists, list2[i]);
ba543b319188dc1887607f6d59feddc00e38eee2humbedooh /* String was present only in list2 */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor list2_only[i2-1] = talloc_strdup(list2_only, list2[i]);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* An error occurred */
ba543b319188dc1887607f6d59feddc00e38eee2humbedooh /* Get the leftover entries in the hash table */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor for (i = 0; i < count; i++) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor list1_only[i] = talloc_strdup(list1_only, keys[i].str);
ba543b319188dc1887607f6d59feddc00e38eee2humbedoohstatic void *hash_talloc(const size_t size, void *pvt)
ba543b319188dc1887607f6d59feddc00e38eee2humbedooh unsigned long count,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /* Steal the table pointer onto the mem_ctx,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * then make the internal_ctx a child of
cae0359c9286c8e34cbccd15eee2da90562c1ee2sf * This way, we can clean up the values when
cae0359c9286c8e34cbccd15eee2da90562c1ee2sf * we talloc_free() the table
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh const char *input,
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh /* Assume the worst-case. We'll resize it later, once */
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1);
5effc8b39fae5cd169d17f342bfc265705840014rbowen while (input[i]) {
d229f940abfb2490dee17979e9a5ff31b7012eb5rbowen switch(input[i]) {
if (!*sanitized) {
return ENOMEM;
return EOK;