diff options
Diffstat (limited to 'lib/mlibc/options/posix/generic/pwd-stubs.cpp')
-rw-r--r-- | lib/mlibc/options/posix/generic/pwd-stubs.cpp | 284 |
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(); -} |