libpwdgrp: use getpwent() instead of getpwent_r()
No binary (build failed)
—
(log yok)
| @@ -36,7 +36,6 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |
| #define getpwent bb_internal_getpwent | |
| #define getpwuid bb_internal_getpwuid | |
| #define getpwnam bb_internal_getpwnam | |
| - | #define getpwent_r bb_internal_getpwent_r |
| #define getpwnam_r bb_internal_getpwnam_r | |
| /* All function names below should be remapped by #defines above | |
| @@ -48,10 +47,8 @@ void FAST_FUNC setpwent(void); | |
| /* Close the password-file stream. */ | |
| void FAST_FUNC endpwent(void); | |
| - | #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS |
| /* Read an entry from the password-file stream, opening it if necessary. */ | |
| struct passwd* FAST_FUNC getpwent(void); | |
| - | #endif |
| /* Search for an entry with a matching user ID. */ | |
| struct passwd* FAST_FUNC getpwuid(uid_t __uid); | |
| @@ -59,18 +56,7 @@ struct passwd* FAST_FUNC getpwuid(uid_t __uid); | |
| /* Search for an entry with a matching username. */ | |
| struct passwd* FAST_FUNC getpwnam(const char *__name); | |
| - | /* Reentrant versions of some of the functions above. |
| - | |
| - | PLEASE NOTE: the `getpwent_r' function is not (yet) standardized. |
| - | The interface may change in later versions of this library. But |
| - | the interface is designed following the principals used for the |
| - | other reentrant functions so the chances are good this is what the |
| - | POSIX people would choose. */ |
| - | |
| - | int FAST_FUNC getpwent_r(struct passwd *__restrict __resultbuf, |
| - | char *__restrict __buffer, size_t __buflen, |
| - | struct passwd **__restrict __result); |
| - | |
| + | /* Reentrant versions of some of the functions above. */ |
| int FAST_FUNC getpwnam_r(const char *__restrict __name, | |
| struct passwd *__restrict __resultbuf, | |
| char *__restrict __buffer, size_t __buflen, | |
| @@ -672,23 +672,20 @@ static char *username_path_completion(char *ud) | |
| */ | |
| static NOINLINE unsigned complete_username(const char *ud) | |
| { | |
| - | /* Using _r function to avoid pulling in static buffers */ |
| - | char line_buff[256]; |
| - | struct passwd pwd; |
| - | struct passwd *result; |
| + | struct passwd *pw; |
| unsigned userlen; | |
| ud++; /* skip ~ */ | |
| userlen = strlen(ud); | |
| setpwent(); | |
| - | while (!getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) { |
| + | while ((pw = getpwent()) != NULL) { |
| /* Null usernames should result in all users as possible completions. */ | |
| - | if (/*!userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) { |
| - | add_match(xasprintf("~%s/", pwd.pw_name)); |
| + | if (/*!userlen || */ strncmp(ud, pw->pw_name, userlen) == 0) { |
| + | add_match(xasprintf("~%s/", pw->pw_name)); |
| } | |
| } | |
| - | endpwent(); |
| + | endpwent(); /* don't keep password file open */ |
| return 1 + userlen; | |
| } | |
| @@ -336,6 +336,22 @@ static int massage_data_for_r_func(struct passdb *db, | |
| return errno; | |
| } | |
| + | static void* massage_data_for_non_r_func(struct passdb *db, char *buf) |
| + | { |
| + | if (!buf) |
| + | return NULL; |
| + | |
| + | free(db->malloced); |
| + | /* We enlarge buf and move string data up, freeing space |
| + | * for struct passwd/group/spwd at the beginning. This way, |
| + | * entire result of getXXnam is in a single malloced block. |
| + | * This enables easy creation of xmalloc_getpwnam() API. |
| + | */ |
| + | db->malloced = buf = xrealloc(buf, db->size_of + S.string_size); |
| + | memmove(buf + db->size_of, buf, S.string_size); |
| + | return convert_to_struct(db, buf + db->size_of, buf); |
| + | } |
| + | |
| /****** getXXnam/id_r */ | |
| static int FAST_FUNC getXXnam_r(const char *name, uintptr_t db_and_field_pos, | |
| @@ -372,6 +388,7 @@ int FAST_FUNC getspnam_r(const char *name, struct spwd *struct_buf, char *buffer | |
| } | |
| #endif | |
| + | #ifdef UNUSED |
| /****** getXXent_r */ | |
| static int FAST_FUNC getXXent_r(uintptr_t db_idx, char *buffer, size_t buflen, | |
| @@ -400,17 +417,39 @@ int FAST_FUNC getpwent_r(struct passwd *struct_buf, char *buffer, size_t buflen, | |
| *result = struct_buf; | |
| return getXXent_r(0, buffer, buflen, result); | |
| } | |
| + | #endif |
| + | |
| + | /****** getXXent */ |
| + | |
| + | static void* FAST_FUNC getXXent(uintptr_t db_idx) |
| + | { |
| + | char *buf; |
| + | struct passdb *db = &get_S()->db[db_idx]; |
| + | |
| + | if (!db->fp) { |
| + | db->fp = fopen_for_read(db->filename); |
| + | if (!db->fp) { |
| + | return NULL; |
| + | } |
| + | close_on_exec_on(fileno(db->fp)); |
| + | } |
| + | |
| + | buf = parse_common(db->fp, db, /*no search key:*/ NULL, -1); |
| + | return massage_data_for_non_r_func(db, buf); |
| + | } |
| + | |
| + | struct passwd* FAST_FUNC getpwent(void) |
| + | { |
| + | return getXXent(0); |
| + | } |
| /****** getXXnam/id */ | |
| static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos) | |
| { | |
| char *buf; | |
| - | void *result; |
| struct passdb *db = &get_S()->db[db_and_field_pos >> 2]; | |
| - | result = NULL; |
| - | |
| if (!db->fp) { | |
| db->fp = fopen_for_read(db->filename); | |
| if (!db->fp) { | |
| @@ -420,18 +459,7 @@ static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos) | |
| } | |
| buf = parse_common(db->fp, db, name, db_and_field_pos & 3); | |
| - | if (buf) { |
| - | free(db->malloced); |
| - | /* We enlarge buf and move string data up, freeing space |
| - | * for struct passwd/group/spwd at the beginning. This way, |
| - | * entire result of getXXnam is in a single malloced block. |
| - | * This enables easy creation of xmalloc_getpwnam() API. |
| - | */ |
| - | db->malloced = buf = xrealloc(buf, db->size_of + S.string_size); |
| - | memmove(buf + db->size_of, buf, S.string_size); |
| - | result = convert_to_struct(db, buf + db->size_of, buf); |
| - | } |
| - | return result; |
| + | return massage_data_for_non_r_func(db, buf); |
| } | |
| struct passwd* FAST_FUNC getpwnam(const char *name) | |
| @@ -91,12 +91,11 @@ int deluser_main(int argc, char **argv) | |
| if (!member) { | |
| /* "delgroup GROUP" */ | |
| struct passwd *pw; | |
| - | struct passwd pwent; |
| /* Check if the group is in use */ | |
| - | #define passwd_buf bb_common_bufsiz1 |
| - | while (!getpwent_r(&pwent, passwd_buf, sizeof(passwd_buf), &pw)) { |
| - | if (pwent.pw_gid == gr->gr_gid) |
| - | bb_error_msg_and_die("'%s' still has '%s' as their primary group!", pwent.pw_name, name); |
| + | while ((pw = getpwent()) != NULL) { |
| + | if (pw->pw_gid == gr->gr_gid) |
| + | bb_error_msg_and_die("'%s' still has '%s' as their primary group!", |
| + | pw->pw_name, name); |
| } | |
| //endpwent(); | |
| } | |