#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
/* 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);
/* 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,
*/
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;
}
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,
}
#endif
+#ifdef UNUSED
/****** getXXent_r */
static int FAST_FUNC getXXent_r(uintptr_t db_idx, 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) {
}
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)
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();
}