diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-10-07 11:26:10 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-10-07 12:26:14 +0200 |
commit | e287086b8aa2558356af225a12d9bfea8e7d61ca (patch) | |
tree | 934632ad37a839938f519a800a29c7541741a1b4 /src/basic/strv.c | |
parent | 0084360296429b2068c1a4d4d4263083a8963b02 (diff) |
ask-password: add support for caching passwords in the kernel keyring
This adds support for caching harddisk passwords in the kernel keyring
if it is available, thus supporting caching without Plymouth being
around.
This is also useful for hooking up "gdm-auto-login" with the collected
boot-time harddisk password, in order to support gnome keyring
passphrase unlocking via the HDD password, if it is the same.
Any passwords added to the kernel keyring this way have a timeout of
2.5min at which time they are purged from the kernel.
Diffstat (limited to 'src/basic/strv.c')
-rw-r--r-- | src/basic/strv.c | 88 |
1 files changed, 79 insertions, 9 deletions
diff --git a/src/basic/strv.c b/src/basic/strv.c index d5169467da..27cb540895 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -188,17 +188,48 @@ char **strv_new(const char *x, ...) { return r; } -int strv_extend_strv(char ***a, char **b) { - int r; - char **s; +int strv_extend_strv(char ***a, char **b, bool filter_duplicates) { + char **s, **t; + size_t p, q, i = 0, j; + + assert(a); + + if (strv_isempty(b)) + return 0; + + p = strv_length(*a); + q = strv_length(b); + + t = realloc(*a, sizeof(char*) * (p + q + 1)); + if (!t) + return -ENOMEM; + + t[p] = NULL; + *a = t; STRV_FOREACH(s, b) { - r = strv_extend(a, *s); - if (r < 0) - return r; + + if (filter_duplicates && strv_contains(t, *s)) + continue; + + t[p+i] = strdup(*s); + if (!t[p+i]) + goto rollback; + + i++; + t[p+i] = NULL; } - return 0; + assert(i <= q); + + return (int) i; + +rollback: + for (j = 0; j < i; j++) + free(t[p + j]); + + t[p] = NULL; + return -ENOMEM; } int strv_extend_strv_concat(char ***a, char **b, const char *suffix) { @@ -618,6 +649,41 @@ char **strv_split_nulstr(const char *s) { return r; } +int strv_make_nulstr(char **l, char **p, size_t *q) { + size_t n_allocated = 0, n = 0; + _cleanup_free_ char *m = NULL; + char **i; + + assert(p); + assert(q); + + STRV_FOREACH(i, l) { + size_t z; + + z = strlen(*i); + + if (!GREEDY_REALLOC(m, n_allocated, n + z + 1)) + return -ENOMEM; + + memcpy(m + n, *i, z + 1); + n += z + 1; + } + + if (!m) { + m = new0(char, 1); + if (!m) + return -ENOMEM; + n = 0; + } + + *p = m; + *q = n; + + m = NULL; + + return 0; +} + bool strv_overlap(char **a, char **b) { char **i; @@ -644,8 +710,12 @@ char **strv_sort(char **l) { } bool strv_equal(char **a, char **b) { - if (!a || !b) - return a == b; + + if (strv_isempty(a)) + return strv_isempty(b); + + if (strv_isempty(b)) + return false; for ( ; *a || *b; ++a, ++b) if (!streq_ptr(*a, *b)) |