From 894aead8fcecffd99339f2825ce71bede7ec9695 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 22 Apr 2020 09:01:48 -0400 Subject: pwcache: Rename from passwd.[ch] --- Makefile | 2 +- eval.c | 2 +- main.c | 2 +- parse.c | 2 +- passwd.c | 280 -------------------------------------------------------------- passwd.h | 117 -------------------------- printf.c | 2 +- pwcache.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pwcache.h | 117 ++++++++++++++++++++++++++ 9 files changed, 402 insertions(+), 402 deletions(-) delete mode 100644 passwd.c delete mode 100644 passwd.h create mode 100644 pwcache.c create mode 100644 pwcache.h diff --git a/Makefile b/Makefile index 94e9d0c..3163ab0 100644 --- a/Makefile +++ b/Makefile @@ -104,8 +104,8 @@ bfs: \ mtab.o \ opt.o \ parse.o \ - passwd.o \ printf.o \ + pwcache.o \ spawn.o \ stat.o \ time.o \ diff --git a/eval.c b/eval.c index bdf4d99..a4cb8f3 100644 --- a/eval.c +++ b/eval.c @@ -28,8 +28,8 @@ #include "exec.h" #include "fsade.h" #include "mtab.h" -#include "passwd.h" #include "printf.h" +#include "pwcache.h" #include "stat.h" #include "time.h" #include "trie.h" diff --git a/main.c b/main.c index 442f66a..b8063d8 100644 --- a/main.c +++ b/main.c @@ -40,7 +40,7 @@ * - dstring.[ch] (a dynamic string library) * - fsade.[ch] (a facade over non-standard filesystem features) * - mtab.[ch] (parses the system's mount table) - * - passwd.[ch] (a cache for the user/group tables) + * - pwcache.[ch] (a cache for the user/group tables) * - spawn.[ch] (spawns processes) * - stat.[ch] (wraps stat(), or statx() on Linux) * - time.[ch] (date/time handling utilities) diff --git a/parse.c b/parse.c index 7f4da32..d5c0128 100644 --- a/parse.c +++ b/parse.c @@ -31,8 +31,8 @@ #include "expr.h" #include "fsade.h" #include "mtab.h" -#include "passwd.h" #include "printf.h" +#include "pwcache.h" #include "spawn.h" #include "stat.h" #include "time.h" diff --git a/passwd.c b/passwd.c deleted file mode 100644 index 2640c70..0000000 --- a/passwd.c +++ /dev/null @@ -1,280 +0,0 @@ -/**************************************************************************** - * bfs * - * Copyright (C) 2020 Tavian Barnes * - * * - * 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 "passwd.h" -#include "darray.h" -#include "trie.h" -#include -#include -#include -#include -#include - -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_parse_users(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_free_users(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_free_users(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 bfs_groups *bfs_parse_groups(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; - ent->gr_name = strdup(ent->gr_name); - if (!ent->gr_name) { - error = errno; - goto fail_end; - } - - char **members = ent->gr_mem; - ent->gr_mem = NULL; - for (char **mem = members; *mem; ++mem) { - 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_free_groups(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_free_groups(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); - } -} diff --git a/passwd.h b/passwd.h deleted file mode 100644 index a0b8c6b..0000000 --- a/passwd.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** - * bfs * - * Copyright (C) 2020 Tavian Barnes * - * * - * 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. * - ****************************************************************************/ - -/** - * A caching wrapper for /etc/{passwd,group}. - */ - -#ifndef BFS_PASSWD_H -#define BFS_PASSWD_H - -#include -#include - -/** - * The user table. - */ -struct bfs_users; - -/** - * Parse the user table. - * - * @return - * The parsed user table, or NULL on failure. - */ -struct bfs_users *bfs_parse_users(void); - -/** - * Get a user entry by name. - * - * @param users - * The user table. - * @param name - * The username to look up. - * @return - * The matching user, or NULL if not found. - */ -const struct passwd *bfs_getpwnam(const struct bfs_users *users, const char *name); - -/** - * Get a user entry by ID. - * - * @param users - * The user table. - * @param uid - * The ID to look up. - * @return - * The matching user, or NULL if not found. - */ -const struct passwd *bfs_getpwuid(const struct bfs_users *users, uid_t uid); - -/** - * Free a user table. - * - * @param users - * The user table to free. - */ -void bfs_free_users(struct bfs_users *users); - -/** - * The group table. - */ -struct bfs_groups; - -/** - * Parse the group table. - * - * @return - * The parsed group table, or NULL on failure. - */ -struct bfs_groups *bfs_parse_groups(void); - -/** - * Get a group entry by name. - * - * @param groups - * The group table. - * @param name - * The group name to look up. - * @return - * The matching group, or NULL if not found. - */ -const struct group *bfs_getgrnam(const struct bfs_groups *groups, const char *name); - -/** - * Get a group entry by ID. - * - * @param groups - * The group table. - * @param uid - * The ID to look up. - * @return - * The matching group, or NULL if not found. - */ -const struct group *bfs_getgrgid(const struct bfs_groups *groups, gid_t gid); - -/** - * Free a group table. - * - * @param groups - * The group table to free. - */ -void bfs_free_groups(struct bfs_groups *groups); - -#endif // BFS_PASSWD_H diff --git a/printf.c b/printf.c index 7bee795..18ea5ff 100644 --- a/printf.c +++ b/printf.c @@ -21,7 +21,7 @@ #include "dstring.h" #include "expr.h" #include "mtab.h" -#include "passwd.h" +#include "pwcache.h" #include "stat.h" #include "time.h" #include "util.h" diff --git a/pwcache.c b/pwcache.c new file mode 100644 index 0000000..4fca134 --- /dev/null +++ b/pwcache.c @@ -0,0 +1,280 @@ +/**************************************************************************** + * bfs * + * Copyright (C) 2020 Tavian Barnes * + * * + * 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 +#include +#include +#include +#include + +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_parse_users(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_free_users(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_free_users(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 bfs_groups *bfs_parse_groups(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; + ent->gr_name = strdup(ent->gr_name); + if (!ent->gr_name) { + error = errno; + goto fail_end; + } + + char **members = ent->gr_mem; + ent->gr_mem = NULL; + for (char **mem = members; *mem; ++mem) { + 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_free_groups(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_free_groups(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); + } +} diff --git a/pwcache.h b/pwcache.h new file mode 100644 index 0000000..23f8c9f --- /dev/null +++ b/pwcache.h @@ -0,0 +1,117 @@ +/**************************************************************************** + * bfs * + * Copyright (C) 2020 Tavian Barnes * + * * + * 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. * + ****************************************************************************/ + +/** + * A caching wrapper for /etc/{passwd,group}. + */ + +#ifndef BFS_PWCACHE_H +#define BFS_PWCACHE_H + +#include +#include + +/** + * The user table. + */ +struct bfs_users; + +/** + * Parse the user table. + * + * @return + * The parsed user table, or NULL on failure. + */ +struct bfs_users *bfs_parse_users(void); + +/** + * Get a user entry by name. + * + * @param users + * The user table. + * @param name + * The username to look up. + * @return + * The matching user, or NULL if not found. + */ +const struct passwd *bfs_getpwnam(const struct bfs_users *users, const char *name); + +/** + * Get a user entry by ID. + * + * @param users + * The user table. + * @param uid + * The ID to look up. + * @return + * The matching user, or NULL if not found. + */ +const struct passwd *bfs_getpwuid(const struct bfs_users *users, uid_t uid); + +/** + * Free a user table. + * + * @param users + * The user table to free. + */ +void bfs_free_users(struct bfs_users *users); + +/** + * The group table. + */ +struct bfs_groups; + +/** + * Parse the group table. + * + * @return + * The parsed group table, or NULL on failure. + */ +struct bfs_groups *bfs_parse_groups(void); + +/** + * Get a group entry by name. + * + * @param groups + * The group table. + * @param name + * The group name to look up. + * @return + * The matching group, or NULL if not found. + */ +const struct group *bfs_getgrnam(const struct bfs_groups *groups, const char *name); + +/** + * Get a group entry by ID. + * + * @param groups + * The group table. + * @param uid + * The ID to look up. + * @return + * The matching group, or NULL if not found. + */ +const struct group *bfs_getgrgid(const struct bfs_groups *groups, gid_t gid); + +/** + * Free a group table. + * + * @param groups + * The group table to free. + */ +void bfs_free_groups(struct bfs_groups *groups); + +#endif // BFS_PWCACHE_H -- cgit v1.2.3