summaryrefslogtreecommitdiffstats
path: root/pwcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'pwcache.c')
-rw-r--r--pwcache.c293
1 files changed, 0 insertions, 293 deletions
diff --git a/pwcache.c b/pwcache.c
deleted file mode 100644
index 7812b50..0000000
--- a/pwcache.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/****************************************************************************
- * bfs *
- * Copyright (C) 2020 Tavian Barnes <tavianator@tavianator.com> *
- * *
- * Permission to use, copy, modify, and/or distribute this software for any *
- * purpose with or without fee is hereby granted. *
- * *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF *
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR *
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES *
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN *
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
- ****************************************************************************/
-
-#include "pwcache.h"
-#include "darray.h"
-#include "trie.h"
-#include <errno.h>
-#include <grp.h>
-#include <pwd.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct bfs_users {
- /** The array of passwd entries. */
- struct passwd *entries;
- /** A map from usernames to entries. */
- struct trie by_name;
- /** A map from UIDs to entries. */
- struct trie by_uid;
-};
-
-struct bfs_users *bfs_users_parse(void) {
- int error;
-
- struct bfs_users *users = malloc(sizeof(*users));
- if (!users) {
- return NULL;
- }
-
- users->entries = NULL;
- trie_init(&users->by_name);
- trie_init(&users->by_uid);
-
- setpwent();
-
- while (true) {
- errno = 0;
- struct passwd *ent = getpwent();
- if (!ent) {
- if (errno) {
- error = errno;
- goto fail_end;
- } else {
- break;
- }
- }
-
- if (DARRAY_PUSH(&users->entries, ent) != 0) {
- error = errno;
- goto fail_end;
- }
-
- ent = users->entries + darray_length(users->entries) - 1;
- ent->pw_name = strdup(ent->pw_name);
- ent->pw_dir = strdup(ent->pw_dir);
- ent->pw_shell = strdup(ent->pw_shell);
- if (!ent->pw_name || !ent->pw_dir || !ent->pw_shell) {
- error = ENOMEM;
- goto fail_end;
- }
- }
-
- endpwent();
-
- for (size_t i = 0; i < darray_length(users->entries); ++i) {
- struct passwd *entry = users->entries + i;
- struct trie_leaf *leaf = trie_insert_str(&users->by_name, entry->pw_name);
- if (leaf) {
- if (!leaf->value) {
- leaf->value = entry;
- }
- } else {
- error = errno;
- goto fail_free;
- }
-
- leaf = trie_insert_mem(&users->by_uid, &entry->pw_uid, sizeof(entry->pw_uid));
- if (leaf) {
- if (!leaf->value) {
- leaf->value = entry;
- }
- } else {
- error = errno;
- goto fail_free;
- }
- }
-
- return users;
-
-fail_end:
- endpwent();
-fail_free:
- bfs_users_free(users);
- errno = error;
- return NULL;
-}
-
-const struct passwd *bfs_getpwnam(const struct bfs_users *users, const char *name) {
- const struct trie_leaf *leaf = trie_find_str(&users->by_name, name);
- if (leaf) {
- return leaf->value;
- } else {
- return NULL;
- }
-}
-
-const struct passwd *bfs_getpwuid(const struct bfs_users *users, uid_t uid) {
- const struct trie_leaf *leaf = trie_find_mem(&users->by_uid, &uid, sizeof(uid));
- if (leaf) {
- return leaf->value;
- } else {
- return NULL;
- }
-}
-
-void bfs_users_free(struct bfs_users *users) {
- if (users) {
- trie_destroy(&users->by_uid);
- trie_destroy(&users->by_name);
-
- for (size_t i = 0; i < darray_length(users->entries); ++i) {
- struct passwd *entry = users->entries + i;
- free(entry->pw_shell);
- free(entry->pw_dir);
- free(entry->pw_name);
- }
- darray_free(users->entries);
-
- free(users);
- }
-}
-
-struct bfs_groups {
- /** The array of group entries. */
- struct group *entries;
- /** A map from group names to entries. */
- struct trie by_name;
- /** A map from GIDs to entries. */
- struct trie by_gid;
-};
-
-/**
- * struct group::gr_mem isn't properly aligned on macOS, so do this to avoid
- * ASAN warnings.
- */
-static char *next_gr_mem(void **gr_mem) {
- char *mem;
- memcpy(&mem, *gr_mem, sizeof(mem));
- *gr_mem = (char *)*gr_mem + sizeof(mem);
- return mem;
-}
-
-struct bfs_groups *bfs_groups_parse(void) {
- int error;
-
- struct bfs_groups *groups = malloc(sizeof(*groups));
- if (!groups) {
- return NULL;
- }
-
- groups->entries = NULL;
- trie_init(&groups->by_name);
- trie_init(&groups->by_gid);
-
- setgrent();
-
- while (true) {
- errno = 0;
- struct group *ent = getgrent();
- if (!ent) {
- if (errno) {
- error = errno;
- goto fail_end;
- } else {
- break;
- }
- }
-
- if (DARRAY_PUSH(&groups->entries, ent) != 0) {
- error = errno;
- goto fail_end;
- }
- ent = groups->entries + darray_length(groups->entries) - 1;
-
- void *members = ent->gr_mem;
- ent->gr_mem = NULL;
-
- ent->gr_name = strdup(ent->gr_name);
- if (!ent->gr_name) {
- error = errno;
- goto fail_end;
- }
-
- for (char *mem = next_gr_mem(&members); mem; mem = next_gr_mem(&members)) {
- char *dup = strdup(mem);
- if (!dup) {
- error = errno;
- goto fail_end;
- }
-
- if (DARRAY_PUSH(&ent->gr_mem, &dup) != 0) {
- error = errno;
- free(dup);
- goto fail_end;
- }
- }
- }
-
- endgrent();
-
- for (size_t i = 0; i < darray_length(groups->entries); ++i) {
- struct group *entry = groups->entries + i;
- struct trie_leaf *leaf = trie_insert_str(&groups->by_name, entry->gr_name);
- if (leaf) {
- if (!leaf->value) {
- leaf->value = entry;
- }
- } else {
- error = errno;
- goto fail_free;
- }
-
- leaf = trie_insert_mem(&groups->by_gid, &entry->gr_gid, sizeof(entry->gr_gid));
- if (leaf) {
- if (!leaf->value) {
- leaf->value = entry;
- }
- } else {
- error = errno;
- goto fail_free;
- }
- }
-
- return groups;
-
-fail_end:
- endgrent();
-fail_free:
- bfs_groups_free(groups);
- errno = error;
- return NULL;
-}
-
-const struct group *bfs_getgrnam(const struct bfs_groups *groups, const char *name) {
- const struct trie_leaf *leaf = trie_find_str(&groups->by_name, name);
- if (leaf) {
- return leaf->value;
- } else {
- return NULL;
- }
-}
-
-const struct group *bfs_getgrgid(const struct bfs_groups *groups, gid_t gid) {
- const struct trie_leaf *leaf = trie_find_mem(&groups->by_gid, &gid, sizeof(gid));
- if (leaf) {
- return leaf->value;
- } else {
- return NULL;
- }
-}
-
-void bfs_groups_free(struct bfs_groups *groups) {
- if (groups) {
- trie_destroy(&groups->by_gid);
- trie_destroy(&groups->by_name);
-
- for (size_t i = 0; i < darray_length(groups->entries); ++i) {
- struct group *entry = groups->entries + i;
- for (size_t j = 0; j < darray_length(entry->gr_mem); ++j) {
- free(entry->gr_mem[j]);
- }
- darray_free(entry->gr_mem);
- free(entry->gr_name);
- }
- darray_free(groups->entries);
-
- free(groups);
- }
-}