LibC: Implement fgetspent(3)

This commit is contained in:
implicitfield authored and Nico Weber committed 2025-08-07 21:34:32 -04:00
1 parent 59911d8da3
commit c19feacccf
2 files changed
+23 -21

No files matched your search

+22 -21
View File
@@ -17,7 +17,6 @@
extern "C" {
static FILE* s_stream = nullptr;
static unsigned s_line_number = 0;
static struct spwd s_shadow_entry;
static ByteString s_name;
@@ -25,7 +24,6 @@ static ByteString s_pwdp;
void setspent()
{
s_line_number = 0;
if (s_stream) {
rewind(s_stream);
} else {
@@ -38,7 +36,6 @@ void setspent()
void endspent()
{
s_line_number = 0;
if (s_stream) {
fclose(s_stream);
s_stream = nullptr;
@@ -65,7 +62,7 @@ static bool parse_shadow_entry(ByteString const& line)
{
auto parts = line.split_view(':', SplitBehavior::KeepEmpty);
if (parts.size() != 9) {
dbgln("getspent(): Malformed entry on line {}", s_line_number);
dbgln("getspent(): Malformed entry ({})", line);
return false;
}
@@ -81,7 +78,7 @@ static bool parse_shadow_entry(ByteString const& line)
auto lstchg = lstchg_string.to_number<int>();
if (!lstchg.has_value()) {
dbgln("getspent(): Malformed lstchg on line {}", s_line_number);
dbgln("getspent(): Malformed lstchg ({})", line);
return false;
}
@@ -89,7 +86,7 @@ static bool parse_shadow_entry(ByteString const& line)
min_string = "-1"sv;
auto min_value = min_string.to_number<int>();
if (!min_value.has_value()) {
dbgln("getspent(): Malformed min value on line {}", s_line_number);
dbgln("getspent(): Malformed min value ({})", line);
return false;
}
@@ -97,7 +94,7 @@ static bool parse_shadow_entry(ByteString const& line)
max_string = "-1"sv;
auto max_value = max_string.to_number<int>();
if (!max_value.has_value()) {
dbgln("getspent(): Malformed max value on line {}", s_line_number);
dbgln("getspent(): Malformed max value ({})", line);
return false;
}
@@ -105,7 +102,7 @@ static bool parse_shadow_entry(ByteString const& line)
warn_string = "-1"sv;
auto warn = warn_string.to_number<int>();
if (!warn.has_value()) {
dbgln("getspent(): Malformed warn on line {}", s_line_number);
dbgln("getspent(): Malformed warn ({})", line);
return false;
}
@@ -113,7 +110,7 @@ static bool parse_shadow_entry(ByteString const& line)
inact_string = "-1"sv;
auto inact = inact_string.to_number<int>();
if (!inact.has_value()) {
dbgln("getspent(): Malformed inact on line {}", s_line_number);
dbgln("getspent(): Malformed inact ({})", line);
return false;
}
@@ -121,7 +118,7 @@ static bool parse_shadow_entry(ByteString const& line)
expire_string = "-1"sv;
auto expire = expire_string.to_number<int>();
if (!expire.has_value()) {
dbgln("getspent(): Malformed expire on line {}", s_line_number);
dbgln("getspent(): Malformed expire ({})", line);
return false;
}
@@ -129,7 +126,7 @@ static bool parse_shadow_entry(ByteString const& line)
flag_string = "0"sv;
auto flag = flag_string.to_number<int>();
if (!flag.has_value()) {
dbgln("getspent(): Malformed flag on line {}", s_line_number);
dbgln("getspent(): Malformed flag ({})", line);
return false;
}
@@ -146,26 +143,22 @@ static bool parse_shadow_entry(ByteString const& line)
return true;
}
struct spwd* getspent()
struct spwd* fgetspent(FILE* stream)
{
if (!s_stream)
setspent();
while (true) {
if (!s_stream || feof(s_stream))
if (!stream || feof(stream))
return nullptr;
if (ferror(s_stream)) {
dbgln("getspent(): Read error: {}", strerror(ferror(s_stream)));
if (ferror(stream)) {
dbgln("getspent(): Read error: {}", strerror(ferror(stream)));
return nullptr;
}
char buffer[1024];
++s_line_number;
char* s = fgets(buffer, sizeof(buffer), s_stream);
char* s = fgets(buffer, sizeof(buffer), stream);
// Silently tolerate an empty line at the end.
if ((!s || !s[0]) && feof(s_stream))
if ((!s || !s[0]) && feof(stream))
return nullptr;
ByteString line(s, Chomp);
@@ -175,6 +168,14 @@ struct spwd* getspent()
}
}
struct spwd* getspent()
{
if (!s_stream)
setspent();
return fgetspent(s_stream);
}
static void construct_spwd(struct spwd* sp, char* buf, struct spwd** result)
{
auto* buf_name = &buf[0];
+1
View File
@@ -25,6 +25,7 @@ struct spwd {
};
struct spwd* getspent(void);
struct spwd* fgetspent(FILE* stream);
void setspent(void);
void endspent(void);
struct spwd* getspnam(char const* name);