aboutsummaryrefslogtreecommitdiff
path: root/lib/mlibc/options/posix/generic/pwd-stubs.cpp
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-03-07 17:28:52 -0500
committerIan Moffett <ian@osmora.org>2024-03-07 18:24:51 -0500
commitf5e48e94a2f4d4bbd6e5628c7f2afafc6dbcc459 (patch)
tree93b156621dc0303816b37f60ba88051b702d92f6 /lib/mlibc/options/posix/generic/pwd-stubs.cpp
parentbd5969fc876a10b18613302db7087ef3c40f18e1 (diff)
build: Build mlibc + add distclean target
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/posix/generic/pwd-stubs.cpp')
-rw-r--r--lib/mlibc/options/posix/generic/pwd-stubs.cpp284
1 files changed, 0 insertions, 284 deletions
diff --git a/lib/mlibc/options/posix/generic/pwd-stubs.cpp b/lib/mlibc/options/posix/generic/pwd-stubs.cpp
deleted file mode 100644
index 5d8f618..0000000
--- a/lib/mlibc/options/posix/generic/pwd-stubs.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-
-#include <errno.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <bits/ensure.h>
-
-#include <mlibc/debug.hpp>
-
-namespace {
- FILE *global_file; // Used by setpwent/getpwent/endpwent.
-
- bool open_global_file() {
- if(!global_file) {
- global_file = fopen("/etc/passwd", "r");
- if(!global_file) {
- errno = EIO;
- return false;
- }
- }
-
- return true;
- }
-
- void close_global_file() {
- if(global_file) {
- fclose(global_file);
- global_file = nullptr;
- }
- }
-
- bool extract_entry(frg::string_view line, passwd *entry) {
- frg::string_view segments[8];
-
- // Parse the line into 7 or 8 segments.
- size_t s = 0;
- int n;
- for(n = 0; n < 7; n++) {
- size_t d = line.find_first(':', s);
- if(d == size_t(-1))
- break;
- segments[n] = line.sub_string(s, d - s);
- s = d + 1;
- }
- if(line.find_first(':', s) != size_t(-1))
- return false;
- segments[n] = line.sub_string(s, line.size() - s);
- n++;
-
- if(n < 7)
- return false;
-
- // TODO: Handle strndup() failure.
- auto name = strndup(segments[0].data(), segments[0].size());
- __ensure(name);
-
- auto passwd = strndup(segments[1].data(), segments[1].size());
- __ensure(passwd);
-
- auto uid = segments[2].to_number<int>();
- if(!uid)
- return false;
- auto gid = segments[3].to_number<int>();
- if(!gid)
- return false;
-
- auto real_name = strndup(segments[4].data(), segments[4].size());
- __ensure(real_name);
- auto dir = strndup(segments[5].data(), segments[5].size());
- __ensure(dir);
- auto shell = strndup(segments[6].data(), segments[6].size());
- __ensure(shell);
-
- // Chop the newline off the end of shell
- __ensure(strlen(shell) > 0);
- shell[strlen(shell) - 1] = '\0';
-
- entry->pw_name = name;
- entry->pw_passwd = passwd;
- entry->pw_uid = *uid;
- entry->pw_gid = *gid;
- entry->pw_dir = dir;
- entry->pw_shell = shell;
- entry->pw_gecos = real_name;
- return true;
- }
-
- void copy_to_buffer(passwd *pwd, char *buffer, size_t size) {
- char *pw_dir = stpcpy(buffer, pwd->pw_name) + 1;
- free(pwd->pw_name);
- pwd->pw_name = buffer;
-
- char *pw_shell = stpcpy(pw_dir, pwd->pw_dir) + 1;
- free(pwd->pw_dir);
- pwd->pw_dir = pw_dir;
-
- char *pw_passwd = stpcpy(pw_shell, pwd->pw_shell) + 1;
- free(pwd->pw_shell);
- pwd->pw_shell = pw_shell;
-
- char *end = stpcpy(pw_passwd, pwd->pw_passwd);
- __ensure(end <= buffer + size);
- free(pwd->pw_passwd);
- pwd->pw_passwd = pw_passwd;
- }
-
- void clear_entry(passwd *entry) {
- free(entry->pw_name);
- free(entry->pw_dir);
- free(entry->pw_passwd);
- free(entry->pw_shell);
- entry->pw_name = nullptr;
- entry->pw_dir = nullptr;
- entry->pw_passwd = nullptr;
- entry->pw_shell = nullptr;
- }
-}
-
-struct passwd *getpwent(void) {
- static passwd entry;
- char line[NSS_BUFLEN_PASSWD];
-
- if(!open_global_file()) {
- return nullptr;
- }
-
- if (fgets(line, NSS_BUFLEN_PASSWD, global_file)) {
- clear_entry(&entry);
- if(!extract_entry(line, &entry)) {
- errno = EINVAL; // I suppose this can be a valid errno?
- return nullptr;
- }
- return &entry;
- }
-
- if(ferror(global_file)) {
- errno = EIO;
- }
-
- return nullptr;
-}
-
-struct passwd *getpwnam(const char *name) {
- static passwd entry;
- auto file = fopen("/etc/passwd", "r");
- if(!file)
- return nullptr;
-
- char line[NSS_BUFLEN_PASSWD];
- while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
- clear_entry(&entry);
- if(!extract_entry(line, &entry))
- continue;
- if(!strcmp(entry.pw_name, name)) {
- fclose(file);
- return &entry;
- }
- }
-
- int err = errno;
- if(ferror(file)) {
- err = EIO;
- }
-
- fclose(file);
- errno = err;
- return nullptr;
-}
-
-int getpwnam_r(const char *name, struct passwd *pwd, char *buffer, size_t size, struct passwd **result) {
- *result = nullptr;
- auto file = fopen("/etc/passwd", "r");
- if(!file) {
- return EIO;
- }
-
- char line[NSS_BUFLEN_PASSWD];
- while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
- if(!extract_entry(line, pwd))
- continue;
- if(!strcmp(pwd->pw_name, name)) {
- fclose(file);
-
- size_t required_size = strlen(pwd->pw_name) + strlen(pwd->pw_dir)
- + strlen(pwd->pw_shell) + strlen(pwd->pw_passwd) + 4;
- if (size < required_size)
- return ERANGE;
-
- copy_to_buffer(pwd, buffer, size);
- *result = pwd;
- return 0;
- }
- }
-
- int ret = 0;
- if(ferror(file)) {
- ret = EIO;
- }
-
- fclose(file);
- return ret;
-}
-
-struct passwd *getpwuid(uid_t uid) {
- static passwd entry;
- auto file = fopen("/etc/passwd", "r");
- if(!file)
- return nullptr;
-
- char line[NSS_BUFLEN_PASSWD];
- while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
- clear_entry(&entry);
- if(!extract_entry(line, &entry))
- continue;
- if(entry.pw_uid == uid) {
- fclose(file);
- return &entry;
- }
- }
-
- int err = ESRCH;
- if(ferror(file)) {
- err = EIO;
- }
-
- fclose(file);
- errno = err;
- return nullptr;
-}
-
-int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, size_t size, struct passwd **result) {
- *result = nullptr;
- auto file = fopen("/etc/passwd", "r");
- if(!file) {
- return EIO;
- }
-
- char line[NSS_BUFLEN_PASSWD];
- while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
- if(!extract_entry(line, pwd))
- continue;
- if(pwd->pw_uid == uid) {
- fclose(file);
-
- size_t required_size = strlen(pwd->pw_name) + strlen(pwd->pw_dir)
- + strlen(pwd->pw_shell) + + strlen(pwd->pw_passwd) + 4;
- if (size < required_size)
- return ERANGE;
-
- copy_to_buffer(pwd, buffer, size);
- *result = pwd;
- return 0;
- }
- }
-
- int ret = 0;
- if(ferror(file)) {
- ret = EIO;
- }
-
- fclose(file);
- return ret;
-}
-
-void setpwent(void) {
- if(!open_global_file()) {
- return;
- }
- rewind(global_file);
-}
-
-void endpwent(void) {
- close_global_file();
-}
-
-int putpwent(const struct passwd *, FILE *) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
-}
-
-struct passwd *fgetpwent(FILE *) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
-}