libpwdgrp: rewritten to use malloced implementation

This removed buffer size limitations.

function                                             old     new   delta
convert_to_struct                                      -     269    +269
getXXnam_r                                             -     204    +204
parse_common                                           -     185    +185
getXXnam                                               -     164    +164
tokenize                                               -     126    +126
bb_internal_getpwent_r                               102     167     +65
get_S                                                 30      88     +58
getgrouplist_internal                                195     240     +45
const_sp_db                                            -      20     +20
const_pw_db                                            -      20     +20
const_gr_db                                            -      20     +20
bb_internal_endpwent                                  27      36      +9
bb_internal_endgrent                                  27      36      +9
decode_one_format                                    726     734      +8
bb_internal_setpwent                                  17      24      +7
volume_id_probe_iso9660                              319     322      +3
scriptreplay_main                                    204     207      +3
mkfs_minix_main                                     2684    2687      +3
id_main                                              478     480      +2
hash_find                                            233     235      +2
pstree_main                                          321     322      +1
gr_off                                                 3       4      +1
expand_one_var                                      1579    1578      -1
pwf                                                    4       -      -4
grf                                                    4       -      -4
pack_gzip                                           1787    1780      -7
addattr32                                             67      56     -11
buffer_fill_and_print                                191     178     -13
dpkg_main                                           2944    2927     -17
bb_internal_setgrent                                  17       -     -17
bb_internal_getpwuid                                  38      19     -19
bb_internal_getgrgid                                  44      19     -25
bb_internal_getpwnam                                  38      11     -27
bb_internal_getgrnam                                  44      14     -30
bb_internal_fgetpwent_r                               51       -     -51
bb_internal_fgetgrent_r                               51       -     -51
bb_internal_getspnam_r                               121      42     -79
bb_internal_getpwnam_r                               121      39     -82
bb_internal_getgrent_r                               102       -    -102
bb__parsepwent                                       110       -    -110
bb_internal_getpwuid_r                               113       -    -113
bb_internal_getgrgid_r                               113       -    -113
bb__parsespent                                       120       -    -120
bb_internal_getgrnam_r                               121       -    -121
bb__pgsreader                                        213       -    -213
bb__parsegrent                                       226       -    -226
------------------------------------------------------------------------------
(add/remove: 8/13 grow/shrink: 14/11 up/down: 1224/-1556)    Total: -332 bytes
   text	   data	    bss	    dec	    hex	filename
 923471	    928	  17684	 942083	  e6003	busybox_old
 923167	    928	  17676	 941771	  e5ecb	busybox_unstripped

Signed-off-by: Tito Ragusa <farmatito@tiscali.it>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Tito Ragusa 2015-01-02 21:37:59 +01:00 committed by Denys Vlasenko
parent 78854520eb
commit 1da09cfacf
5 changed files with 394 additions and 1102 deletions

View File

@ -30,17 +30,9 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
* so that function calls are directed to bb_internal_XXX replacements * so that function calls are directed to bb_internal_XXX replacements
*/ */
#undef endgrent #undef endgrent
#define setgrent bb_internal_setgrent
#define endgrent bb_internal_endgrent #define endgrent bb_internal_endgrent
#define getgrent bb_internal_getgrent
#define fgetgrent bb_internal_fgetgrent
#define putgrent bb_internal_putgrent
#define getgrgid bb_internal_getgrgid #define getgrgid bb_internal_getgrgid
#define getgrnam bb_internal_getgrnam #define getgrnam bb_internal_getgrnam
#define getgrent_r bb_internal_getgrent_r
#define getgrgid_r bb_internal_getgrgid_r
#define getgrnam_r bb_internal_getgrnam_r
#define fgetgrent_r bb_internal_fgetgrent_r
#define getgrouplist bb_internal_getgrouplist #define getgrouplist bb_internal_getgrouplist
#define initgroups bb_internal_initgroups #define initgroups bb_internal_initgroups
@ -48,60 +40,16 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
/* All function names below should be remapped by #defines above /* All function names below should be remapped by #defines above
* in order to not collide with libc names. */ * in order to not collide with libc names. */
/* Rewind the group-file stream. */
extern void setgrent(void);
/* Close the group-file stream. */ /* Close the group-file stream. */
extern void endgrent(void); extern void endgrent(void);
#ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS
/* Read an entry from the group-file stream, opening it if necessary. */
extern struct group *getgrent(void);
/* Read a group entry from STREAM. */
extern struct group *fgetgrent(FILE *__stream);
/* Write the given entry onto the given stream. */
extern int putgrent(const struct group *__restrict __p,
FILE *__restrict __f);
#endif
/* Search for an entry with a matching group ID. */ /* Search for an entry with a matching group ID. */
extern struct group *getgrgid(gid_t __gid); extern struct group *getgrgid(gid_t __gid);
/* Search for an entry with a matching group name. */ /* Search for an entry with a matching group name. */
extern struct group *getgrnam(const char *__name); extern struct group *getgrnam(const char *__name);
/* Reentrant versions of some of the functions above. /* Reentrant versions of some of the functions above. */
PLEASE NOTE: the `getgrent_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. */
extern int getgrent_r(struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Search for an entry with a matching group ID. */
extern int getgrgid_r(gid_t __gid, struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Search for an entry with a matching group name. */
extern int getgrnam_r(const char *__restrict __name,
struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Read a group entry from STREAM. This function is not standardized
an probably never will. */
extern int fgetgrent_r(FILE *__restrict __stream,
struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Store at most *NGROUPS members of the group set for USER into /* Store at most *NGROUPS members of the group set for USER into
*GROUPS. Also include GROUP. The actual number of groups found is *GROUPS. Also include GROUP. The actual number of groups found is

View File

@ -34,20 +34,14 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
#define setpwent bb_internal_setpwent #define setpwent bb_internal_setpwent
#define endpwent bb_internal_endpwent #define endpwent bb_internal_endpwent
#define getpwent bb_internal_getpwent #define getpwent bb_internal_getpwent
#define fgetpwent bb_internal_fgetpwent
#define putpwent bb_internal_putpwent
#define getpwuid bb_internal_getpwuid #define getpwuid bb_internal_getpwuid
#define getpwnam bb_internal_getpwnam #define getpwnam bb_internal_getpwnam
#define getpwent_r bb_internal_getpwent_r #define getpwent_r bb_internal_getpwent_r
#define getpwuid_r bb_internal_getpwuid_r
#define getpwnam_r bb_internal_getpwnam_r #define getpwnam_r bb_internal_getpwnam_r
#define fgetpwent_r bb_internal_fgetpwent_r
/* All function names below should be remapped by #defines above /* All function names below should be remapped by #defines above
* in order to not collide with libc names. */ * in order to not collide with libc names. */
/* Rewind the password-file stream. */ /* Rewind the password-file stream. */
extern void setpwent(void); extern void setpwent(void);
@ -57,13 +51,6 @@ extern void endpwent(void);
#ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS
/* Read an entry from the password-file stream, opening it if necessary. */ /* Read an entry from the password-file stream, opening it if necessary. */
extern struct passwd *getpwent(void); extern struct passwd *getpwent(void);
/* Read an entry from STREAM. */
extern struct passwd *fgetpwent(FILE *__stream);
/* Write the given entry onto the given stream. */
extern int putpwent(const struct passwd *__restrict __p,
FILE *__restrict __f);
#endif #endif
/* Search for an entry with a matching user ID. */ /* Search for an entry with a matching user ID. */
@ -84,23 +71,11 @@ extern int getpwent_r(struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen, char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result); struct passwd **__restrict __result);
extern int getpwuid_r(uid_t __uid,
struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result);
extern int getpwnam_r(const char *__restrict __name, extern int getpwnam_r(const char *__restrict __name,
struct passwd *__restrict __resultbuf, struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen, char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result); struct passwd **__restrict __result);
/* Read an entry from STREAM. This function is not standardized and
probably never will. */
extern int fgetpwent_r(FILE *__restrict __stream,
struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result);
POP_SAVED_FUNCTION_VISIBILITY POP_SAVED_FUNCTION_VISIBILITY
#endif #endif

View File

@ -110,51 +110,3 @@ unsigned long FAST_FUNC get_ug_id(const char *s,
return xname2id(s); return xname2id(s);
return r; return r;
} }
/* Experimental "mallocing" API.
* The goal is nice: "we want to support a case when "guests" group is very large"
* but the code is butt-ugly.
*/
#if 0
static char *find_latest(char last, char *cp)
{
if (!cp)
return last;
cp += strlen(cp) + 1;
if (last < cp)
last = cp;
return last;
}
struct group* FAST_FUNC xmalloc_getgrnam(const char *name)
{
struct {
struct group gr;
// May still be not enough!
char buf[64*1024 - sizeof(struct group) - 16];
} *s;
struct group *grp;
int r;
char *last;
char **gr_mem;
s = xmalloc(sizeof(*s));
r = getgrnam_r(name, &s->gr, s->buf, sizeof(s->buf), &grp);
if (!grp) {
free(s);
return grp;
}
last = find_latest(s->buf, grp->gr_name);
last = find_latest(last, grp->gr_passwd);
gr_mem = grp->gr_mem;
while (*gr_mem)
last = find_latest(last, *gr_mem++);
gr_mem++; /* points past NULL */
if (last < (char*)gr_mem)
last = (char*)gr_mem;
//FIXME: what if we get not only truncated, but also moved here?
// grp->gr_name pointer and friends are invalid now!!!
s = xrealloc(s, last - (char*)s);
return grp;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/* vi: set sw=4 ts=4: */
/* Copyright (C) 2003 Manuel Novoa III
*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
/* Nov 6, 2003 Initial version.
*
* NOTE: This implementation is quite strict about requiring all
* field seperators. It also does not allow leading whitespace
* except when processing the numeric fields. glibc is more
* lenient. See the various glibc difference comments below.
*
* TODO:
* Move to dynamic allocation of (currently statically allocated)
* buffers; especially for the group-related functions since
* large group member lists will cause error returns.
*/
#ifndef GETXXKEY_R_FUNC
#error GETXXKEY_R_FUNC is not defined!
#endif
int GETXXKEY_R_FUNC(GETXXKEY_R_KEYTYPE key,
GETXXKEY_R_ENTTYPE *__restrict resultbuf,
char *__restrict buffer, size_t buflen,
GETXXKEY_R_ENTTYPE **__restrict result)
{
FILE *stream;
int rv;
*result = NULL;
stream = fopen_for_read(GETXXKEY_R_PATHNAME);
if (!stream)
return errno;
while (1) {
rv = bb__pgsreader(GETXXKEY_R_PARSER, resultbuf, buffer, buflen, stream);
if (!rv) {
if (GETXXKEY_R_TEST(resultbuf)) { /* found key? */
*result = resultbuf;
break;
}
} else {
if (rv == ENOENT) { /* EOF encountered */
rv = 0;
}
break;
}
}
fclose(stream);
return rv;
}
#undef GETXXKEY_R_FUNC
#undef GETXXKEY_R_PARSER
#undef GETXXKEY_R_ENTTYPE
#undef GETXXKEY_R_TEST
#undef GETXXKEY_R_KEYTYPE
#undef GETXXKEY_R_PATHNAME