From e8498810dc7eb20ea4a652b75e2da194b604f740 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 9 Dec 2009 04:00:09 +0100 Subject: Consolidate code for splitting strings by separator There were two functions for parsing strings by a separator. This patch consolidates on the one previously used in confdb. This also allows stripping the tokens of whitespace. Fixes: #319 --- server/confdb/confdb.c | 106 +-------------------------- server/providers/ipa/ipa_common.c | 5 +- server/providers/krb5/krb5_common.c | 8 +- server/providers/ldap/ldap_common.c | 5 +- server/util/util.c | 141 +++++++++++++++++++++++++----------- server/util/util.h | 5 +- 6 files changed, 107 insertions(+), 163 deletions(-) diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c index ad354e5b..6ba57a56 100644 --- a/server/confdb/confdb.c +++ b/server/confdb/confdb.c @@ -103,110 +103,6 @@ done: return ret; } -/* split a string into an allocated array of strings. - * the separator is a string, and is case-sensitive. - * optionally single values can be trimmed of of spaces and tabs */ -static int split_on_separator(TALLOC_CTX *mem_ctx, const char *str, - const char *sep, bool trim, char ***_list, int *size) -{ - const char *t, *p, *n; - size_t l, s, len; - char **list, **r; - - if (!str || !*str || !sep || !*sep || !_list) return EINVAL; - - s = strlen(sep); - t = str; - - list = NULL; - l = 0; - - if (trim) - while (*t == ' ' || *t == '\t') t++; - - while (t && (p = strstr(t, sep))) { - len = p - t; - n = p + s; /* save next string starting point */ - if (trim) { - while (*t == ' ' || *t == '\t') { - t++; - len--; - if (len == 0) break; - } - p--; - while (len > 0 && (*p == ' ' || *p == '\t')) { - len--; - p--; - } - } - - r = talloc_realloc(mem_ctx, list, char *, l + 2); - if (!r) { - talloc_free(list); - return ENOMEM; - } else { - list = r; - } - - if (len == 0) { - list[l] = talloc_strdup(list, ""); - } else { - list[l] = talloc_strndup(list, t, len); - } - if (!list[l]) { - talloc_free(list); - return ENOMEM; - } - l++; - - t = n; /* move to next string */ - } - - if (t) { - r = talloc_realloc(mem_ctx, list, char *, l + 2); - if (!r) { - talloc_free(list); - return ENOMEM; - } else { - list = r; - } - - if (trim) { - len = strlen(t); - while (*t == ' ' || *t == '\t') { - t++; - len--; - if (len == 0) break; - } - p = t + len - 1; - while (len > 0 && (*p == ' ' || *p == '\t')) { - len--; - p--; - } - - if (len == 0) { - list[l] = talloc_strdup(list, ""); - } else { - list[l] = talloc_strndup(list, t, len); - } - } else { - list[l] = talloc_strdup(list, t); - } - if (!list[l]) { - talloc_free(list); - return ENOMEM; - } - l++; - } - - list[l] = NULL; /* terminate list */ - - if (size) *size = l + 1; - *_list = list; - - return EOK; -} - int confdb_add_param(struct confdb_ctx *cdb, bool replace, const char *section, @@ -608,7 +504,7 @@ int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx, goto done; } - ret = split_on_separator(ctx, values[0], ",", true, result, NULL); + ret = split_on_separator(ctx, values[0], ',', true, result, NULL); done: talloc_free(values); diff --git a/server/providers/ipa/ipa_common.c b/server/providers/ipa/ipa_common.c index 0b0eb489..5ef19da7 100644 --- a/server/providers/ipa/ipa_common.c +++ b/server/providers/ipa/ipa_common.c @@ -508,7 +508,6 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, struct ipa_service *service; char **list = NULL; char *realm; - int count = 0; int ret; int i; @@ -562,14 +561,14 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, service->krb5_service->realm = realm; /* split server parm into a list */ - ret = sss_split_list(tmp_ctx, servers, ", ", &list, &count); + ret = split_on_separator(tmp_ctx, servers, ',', true, &list, NULL); if (ret != EOK) { DEBUG(1, ("Failed to parse server list!\n")); goto done; } /* now for each one add a new server to the failover service */ - for (i = 0; i < count; i++) { + for (i = 0; list[i]; i++) { talloc_steal(service, list[i]); diff --git a/server/providers/krb5/krb5_common.c b/server/providers/krb5/krb5_common.c index 6817d650..b1cf4201 100644 --- a/server/providers/krb5/krb5_common.c +++ b/server/providers/krb5/krb5_common.c @@ -49,7 +49,6 @@ errno_t check_and_export_options(struct dp_option *opts, const char *dummy; struct stat stat_buf; char **list; - int count; realm = dp_opt_get_cstring(opts, KRB5_REALM); if (realm == NULL) { @@ -71,7 +70,7 @@ errno_t check_and_export_options(struct dp_option *opts, if (dummy == NULL) { DEBUG(1, ("No KDC expicitly configured, using defaults")); } else { - ret = sss_split_list(opts, dummy, ", ", &list, &count); + ret = split_on_separator(opts, dummy, ',', true, &list, NULL); if (ret != EOK) { DEBUG(1, ("Failed to parse server list!\n")); return ret; @@ -287,7 +286,6 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, TALLOC_CTX *tmp_ctx; struct krb5_service *service; char **list = NULL; - int count = 0; int ret; int i; @@ -320,13 +318,13 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, goto done; } - ret = sss_split_list(tmp_ctx, servers, ", ", &list, &count); + ret = split_on_separator(tmp_ctx, servers, ',', true, &list, NULL); if (ret != EOK) { DEBUG(1, ("Failed to parse server list!\n")); goto done; } - for (i = 0; i < count; i++) { + for (i = 0; list[i]; i++) { talloc_steal(service, list[i]); diff --git a/server/providers/ldap/ldap_common.c b/server/providers/ldap/ldap_common.c index e4f3f6bb..74b478cc 100644 --- a/server/providers/ldap/ldap_common.c +++ b/server/providers/ldap/ldap_common.c @@ -503,7 +503,6 @@ int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, struct sdap_service *service; LDAPURLDesc *lud; char **list = NULL; - int count = 0; int ret; int i; @@ -531,14 +530,14 @@ int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, } /* split server parm into a list */ - ret = sss_split_list(tmp_ctx, urls, ", ", &list, &count); + ret = split_on_separator(tmp_ctx, urls, ',', true, &list, NULL); if (ret != EOK) { DEBUG(1, ("Failed to parse server list!\n")); goto done; } /* now for each URI add a new server to the failover service */ - for (i = 0; i < count; i++) { + for (i = 0; list[i]; i++) { ret = ldap_url_parse(list[i], &lud); if (ret != LDAP_SUCCESS) { DEBUG(0, ("Failed to parse ldap URI (%s)!\n", list[i])); diff --git a/server/util/util.c b/server/util/util.c index 9049602c..57ceb597 100644 --- a/server/util/util.c +++ b/server/util/util.c @@ -18,68 +18,121 @@ along with this program. If not, see . */ +#include + #include "talloc.h" #include "util/util.h" -/* Split string in a list using a set of legal seprators */ - -int sss_split_list(TALLOC_CTX *memctx, const char *string, - const char *sep, char ***_list, int *c) +/* split a string into an allocated array of strings. + * the separator is a string, and is case-sensitive. + * optionally single values can be trimmed of of spaces and tabs */ +int split_on_separator(TALLOC_CTX *mem_ctx, const char *str, + const char sep, bool trim, char ***_list, int *size) { - const char *p; - const char *s; - char **list; - char **t; - int i; + const char *t, *p, *n; + size_t l, len; + char **list, **r; + const char sep_str[2] = { sep, '\0'}; + + if (!str || !*str || !_list) return EINVAL; + + t = str; - /* split server parm into a list */ list = NULL; - s = string; - i = 0; - - while (s) { - p = strpbrk(s, sep); - if (p) { - if (p - s == 1) { - s++; - continue; - } + l = 0; - t = talloc_realloc(memctx, list, char *, i + 1); - if (!t) { - talloc_zfree(list); - return ENOMEM; + /* trim leading whitespace */ + if (trim) + while (isspace(*t)) t++; + + /* find substrings separated by the separator */ + while (t && (p = strpbrk(t, sep_str))) { + len = p - t; + n = p + 1; /* save next string starting point */ + if (trim) { + /* strip whitespace after the separator + * so it's not in the next token */ + while (isspace(*t)) { + t++; + len--; + if (len == 0) break; } - list = t; - list[i] = talloc_asprintf(list, "%.*s", (int)(p - s), s); - if (!list[i]) { - talloc_zfree(list); - return ENOMEM; + p--; + /* strip whitespace before the separator + * so it's not in the current token */ + while (len > 0 && (isspace(*p))) { + len--; + p--; } - i++; + } + + /* Add the token to the array, +2 b/c of the trailing NULL */ + r = talloc_realloc(mem_ctx, list, char *, l + 2); + if (!r) { + talloc_free(list); + return ENOMEM; + } else { + list = r; + } - s = p + 1; + if (len == 0) { + list[l] = talloc_strdup(list, ""); + } else { + list[l] = talloc_strndup(list, t, len); + } + if (!list[l]) { + talloc_free(list); + return ENOMEM; + } + l++; + + t = n; /* move to next string */ + } + + /* Handle the last remaining token */ + if (t) { + r = talloc_realloc(mem_ctx, list, char *, l + 2); + if (!r) { + talloc_free(list); + return ENOMEM; + } else { + list = r; } - else { - t = talloc_realloc(memctx, list, char *, i + 1); - if (!t) { - talloc_zfree(list); - return ENOMEM; + if (trim) { + /* trim leading whitespace */ + len = strlen(t); + while (isspace(*t)) { + t++; + len--; + if (len == 0) break; } - list = t; - list[i] = talloc_strdup(list, s); - if (!list[i]) { - talloc_zfree(list); - return ENOMEM; + /* trim trailing whitespace */ + p = t + len - 1; + while (len > 0 && (isspace(*p))) { + len--; + p--; } - i++; - s = NULL; + if (len == 0) { + list[l] = talloc_strdup(list, ""); + } else { + list[l] = talloc_strndup(list, t, len); + } + } else { + list[l] = talloc_strdup(list, t); + } + if (!list[l]) { + talloc_free(list); + return ENOMEM; } + l++; } + list[l] = NULL; /* terminate list */ + + if (size) *size = l + 1; *_list = list; - *c = i; + return EOK; } diff --git a/server/util/util.h b/server/util/util.h index 1c583e23..a639b192 100644 --- a/server/util/util.h +++ b/server/util/util.h @@ -229,7 +229,6 @@ errno_t check_and_open_readonly(const char *filename, int *fd, const uid_t uid, const gid_t gid, const mode_t mode); /* from util.c */ -int sss_split_list(TALLOC_CTX *memctx, const char *string, - const char *sep, char ***_list, int *c); - +int split_on_separator(TALLOC_CTX *mem_ctx, const char *str, + const char sep, bool trim, char ***_list, int *size); #endif /* __SSSD_UTIL_H__ */ -- cgit