From cde7910993b08f7fe605457d69c2d28b2510c756 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 28 Mar 2019 17:28:48 +0100 Subject: [PATCH] =?utf8?q?sysusers,strv:=20export=20the=20hash=20ops=20to?= =?utf8?q?=20map=20char*=20=E2=86=92=20strv?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Also make string_strv_hashmap_put return 0 only if the entry already existed. --- src/basic/strv.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ src/basic/strv.h | 5 +++++ src/sysusers/sysusers.c | 37 ++---------------------------- 3 files changed, 67 insertions(+), 35 deletions(-) diff --git a/src/basic/strv.c b/src/basic/strv.c index 2ae685f..88b8586 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -889,3 +889,63 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space) { return 0; } + +static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) { + char **l; + int r; + + l = hashmap_get(h, key); + if (l) { + /* A list for this key already exists, let's append to it if it is not listed yet */ + if (strv_contains(l, value)) + return 0; + + r = strv_extend(&l, value); + if (r < 0) + return r; + + assert_se(hashmap_update(h, key, l) >= 0); + } else { + /* No list for this key exists yet, create one */ + _cleanup_strv_free_ char **l2 = NULL; + _cleanup_free_ char *t = NULL; + + t = strdup(key); + if (!t) + return -ENOMEM; + + r = strv_extend(&l2, value); + if (r < 0) + return r; + + r = hashmap_put(h, t, l2); + if (r < 0) + return r; + TAKE_PTR(t); + TAKE_PTR(l2); + } + + return 1; +} + +int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value) { + int r; + + r = hashmap_ensure_allocated(h, &string_strv_hash_ops); + if (r < 0) + return r; + + return string_strv_hashmap_put_internal(*h, key, value); +} + +int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value) { + int r; + + r = ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops); + if (r < 0) + return r; + + return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h), key, value); +} + +DEFINE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free); diff --git a/src/basic/strv.h b/src/basic/strv.h index aa5f95a..e80964a 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -9,6 +9,7 @@ #include "alloc-util.h" #include "extract-word.h" +#include "hashmap.h" #include "macro.h" #include "string-util.h" @@ -188,3 +189,7 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space); (b) = NULL; \ 0; \ }) + +extern const struct hash_ops string_strv_hash_ops; +int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value); +int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 990a2f9..5f12ef1 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1358,8 +1358,6 @@ static bool item_equal(Item *a, Item *b) { return true; } -DEFINE_PRIVATE_HASH_OPS_FULL(members_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free); - static int parse_line(const char *fname, unsigned line, const char *buffer) { static const Specifier specifier_table[] = { @@ -1511,8 +1509,6 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { return 0; case ADD_MEMBER: { - char **l; - /* Try to extend an existing member or group item */ if (!name) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -1535,38 +1531,9 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { fname, line, action[0], description ? "GECOS" : home ? "home directory" : "login shell"); - r = ordered_hashmap_ensure_allocated(&members, &members_hash_ops); + r = string_strv_ordered_hashmap_put(&members, resolved_id, resolved_name); if (r < 0) - return log_oom(); - - l = ordered_hashmap_get(members, resolved_id); - if (l) { - /* A list for this group name already exists, let's append to it */ - r = strv_push(&l, resolved_name); - if (r < 0) - return log_oom(); - - resolved_name = NULL; - - assert_se(ordered_hashmap_update(members, resolved_id, l) >= 0); - } else { - /* No list for this group name exists yet, create one */ - - l = new0(char *, 2); - if (!l) - return -ENOMEM; - - l[0] = resolved_name; - l[1] = NULL; - - r = ordered_hashmap_put(members, resolved_id, l); - if (r < 0) { - free(l); - return log_oom(); - } - - resolved_id = resolved_name = NULL; - } + return log_error_errno(r, "Failed to store mapping for %s: %m", resolved_id); return 0; } -- 2.7.4