mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 09:22:44 +00:00 
			
		
		
		
	
							parent
							
								
									288d75fdab
								
							
						
					
					
						commit
						7442cfb507
					
				
					 2 changed files with 54 additions and 25 deletions
				
			
		|  | @ -19,7 +19,6 @@ extern "C" { | ||||||
| 
 | 
 | ||||||
| static FILE* s_stream = nullptr; | static FILE* s_stream = nullptr; | ||||||
| static unsigned s_line_number = 0; | static unsigned s_line_number = 0; | ||||||
| static struct passwd s_passwd_entry; |  | ||||||
| 
 | 
 | ||||||
| static String s_name; | static String s_name; | ||||||
| static String s_passwd; | static String s_passwd; | ||||||
|  | @ -71,21 +70,30 @@ struct passwd* getpwnam(char const* name) | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool parse_pwddb_entry(String const& line) | static bool parse_pwddb_entry(char* raw_line, struct passwd& passwd_entry) | ||||||
| { | { | ||||||
|     auto parts = line.split_view(':', SplitBehavior::KeepEmpty); |     size_t line_length = strlen(raw_line); | ||||||
|  |     for (size_t i = 0; i < line_length; ++i) { | ||||||
|  |         auto& ch = raw_line[i]; | ||||||
|  |         if (ch == '\r' || ch == '\n') | ||||||
|  |             line_length = i; | ||||||
|  |         if (ch == ':' || ch == '\r' || ch == '\n') | ||||||
|  |             ch = '\0'; | ||||||
|  |     } | ||||||
|  |     auto line = StringView { raw_line, line_length }; | ||||||
|  |     auto parts = line.split_view('\0', SplitBehavior::KeepEmpty); | ||||||
|     if (parts.size() != 7) { |     if (parts.size() != 7) { | ||||||
|         dbgln("getpwent(): Malformed entry on line {}", s_line_number); |         dbgln("getpwent(): Malformed entry on line {}", s_line_number); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     s_name = parts[0]; |     auto& name = parts[0]; | ||||||
|     s_passwd = parts[1]; |     auto& passwd = parts[1]; | ||||||
|     auto& uid_string = parts[2]; |     auto& uid_string = parts[2]; | ||||||
|     auto& gid_string = parts[3]; |     auto& gid_string = parts[3]; | ||||||
|     s_gecos = parts[4]; |     auto& gecos = parts[4]; | ||||||
|     s_dir = parts[5]; |     auto& dir = parts[5]; | ||||||
|     s_shell = parts[6]; |     auto& shell = parts[6]; | ||||||
| 
 | 
 | ||||||
|     auto uid = uid_string.to_uint(); |     auto uid = uid_string.to_uint(); | ||||||
|     if (!uid.has_value()) { |     if (!uid.has_value()) { | ||||||
|  | @ -98,42 +106,62 @@ static bool parse_pwddb_entry(String const& line) | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     s_passwd_entry.pw_name = const_cast<char*>(s_name.characters()); |     passwd_entry.pw_name = const_cast<char*>(name.characters_without_null_termination()); | ||||||
|     s_passwd_entry.pw_passwd = const_cast<char*>(s_passwd.characters()); |     passwd_entry.pw_passwd = const_cast<char*>(passwd.characters_without_null_termination()); | ||||||
|     s_passwd_entry.pw_uid = uid.value(); |     passwd_entry.pw_uid = uid.value(); | ||||||
|     s_passwd_entry.pw_gid = gid.value(); |     passwd_entry.pw_gid = gid.value(); | ||||||
|     s_passwd_entry.pw_gecos = const_cast<char*>(s_gecos.characters()); |     passwd_entry.pw_gecos = const_cast<char*>(gecos.characters_without_null_termination()); | ||||||
|     s_passwd_entry.pw_dir = const_cast<char*>(s_dir.characters()); |     passwd_entry.pw_dir = const_cast<char*>(dir.characters_without_null_termination()); | ||||||
|     s_passwd_entry.pw_shell = const_cast<char*>(s_shell.characters()); |     passwd_entry.pw_shell = const_cast<char*>(shell.characters_without_null_termination()); | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct passwd* getpwent() | struct passwd* getpwent() | ||||||
|  | { | ||||||
|  |     static struct passwd passwd_entry; | ||||||
|  |     static char buffer[1024]; | ||||||
|  |     struct passwd* result; | ||||||
|  |     if (getpwent_r(&passwd_entry, buffer, sizeof(buffer), &result) < 0) | ||||||
|  |         return nullptr; | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int getpwent_r(struct passwd* passwd_buf, char* buffer, size_t buffer_size, struct passwd** passwd_entry_ptr) | ||||||
| { | { | ||||||
|     if (!s_stream) |     if (!s_stream) | ||||||
|         setpwent(); |         setpwent(); | ||||||
| 
 | 
 | ||||||
|     while (true) { |     while (true) { | ||||||
|         if (!s_stream || feof(s_stream)) |         if (!s_stream || feof(s_stream)) { | ||||||
|             return nullptr; |             errno = EIO; | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (ferror(s_stream)) { |         if (ferror(s_stream)) { | ||||||
|             dbgln("getpwent(): Read error: {}", strerror(ferror(s_stream))); |             dbgln("getpwent(): Read error: {}", strerror(ferror(s_stream))); | ||||||
|             return nullptr; |             errno = EIO; | ||||||
|  |             return -1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         char buffer[1024]; |  | ||||||
|         ++s_line_number; |         ++s_line_number; | ||||||
|         char* s = fgets(buffer, sizeof(buffer), s_stream); |         char* s = fgets(buffer, buffer_size, s_stream); | ||||||
| 
 | 
 | ||||||
|         // Silently tolerate an empty line at the end.
 |         // Silently tolerate an empty line at the end.
 | ||||||
|         if ((!s || !s[0]) && feof(s_stream)) |         if ((!s || !s[0]) && feof(s_stream)) { | ||||||
|             return nullptr; |             *passwd_entry_ptr = nullptr; | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         String line(s, Chomp); |         if (strlen(s) == buffer_size - 1) { | ||||||
|         if (parse_pwddb_entry(line)) |             errno = ERANGE; | ||||||
|             return &s_passwd_entry; |             return -1; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (parse_pwddb_entry(buffer, *passwd_buf)) { | ||||||
|  |             *passwd_entry_ptr = passwd_buf; | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|         // Otherwise, proceed to the next line.
 |         // Otherwise, proceed to the next line.
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ struct passwd { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct passwd* getpwent(void); | struct passwd* getpwent(void); | ||||||
|  | int getpwent_r(struct passwd*, char*, size_t, struct passwd**); | ||||||
| void setpwent(void); | void setpwent(void); | ||||||
| void endpwent(void); | void endpwent(void); | ||||||
| struct passwd* getpwnam(char const* name); | struct passwd* getpwnam(char const* name); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gunnar Beutner
						Gunnar Beutner