Hi,
this patch:
1) ports id to bb_getgrouplist_malloc removig lots of ifdefs for better code
readability
2) fixes some cases where we returned incorrect exit codes in case of failed
gid to name
translation while printing group lists.
Denys, I know that the patch is rather big, but I was not able to make it
smaller, sorry for that.
The changes to the print_* functions where needed for fixing
the exit code error and to support euid/egid handling of patch 3.
Hints and critics are welcome.
Please apply if you like it.
Ciao,
Tito
--- coreutils/id_orig.c 2008-09-18 09:01:25.000000000 +0200
+++ coreutils/id.c 2008-09-21 14:16:59.000000000 +0200
@@ -25,26 +25,47 @@
#define JUST_CONTEXT 32
#endif
-static int printf_full(unsigned id, const char *arg, const char *prefix)
+static int print_single(gid_t gid, const char *name, unsigned flags, const char *prefix)
{
- const char *fmt = "%s%u";
- int status = EXIT_FAILURE;
+ short status = EXIT_SUCCESS;
- if (arg) {
- fmt = "%s%u(%s)";
- status = EXIT_SUCCESS;
+ if (prefix) {
+ printf("%s", prefix);
+ }
+ if (!flags || !(flags & NAME_NOT_NUMBER) || !name) {
+ printf("%u", gid);
+ }
+ if (!flags || flags & NAME_NOT_NUMBER) {
+ if (name) {
+ printf((!flags) ? "(%s)" : "%s", name);
+ } else {
+ status = EXIT_FAILURE;
+ }
}
- printf(fmt, prefix, id, arg);
return status;
}
-#if (defined(__GLIBC__) && !defined(__UCLIBC__))
-#define HAVE_getgrouplist 1
-#elif ENABLE_USE_BB_PWD_GRP
-#define HAVE_getgrouplist 1
-#else
-#define HAVE_getgrouplist 0
-#endif
+static int print_group_list(llist_t *grp_list, unsigned flags, const char *prefix)
+{
+ short status = EXIT_SUCCESS;
+ gid_t *gid;
+
+ while (grp_list) {
+ gid = llist_pop(&grp_list);
+ status |= print_single(*gid, bb_getgrgid(NULL, 0, *gid), flags, prefix);
+ prefix = NULL;
+ if (ENABLE_FEATURE_CLEAN_UP) {
+ free(gid);
+ }
+ if (grp_list) {
+ bb_putchar((flags) ? ' ' : ',');
+ }
+ }
+ if (ENABLE_FEATURE_CLEAN_UP) {
+ free(grp_list);
+ }
+ return status;
+}
int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int id_main(int argc UNUSED_PARAM, char **argv)
@@ -53,12 +74,9 @@
struct passwd *p;
uid_t uid;
gid_t gid;
-#if HAVE_getgrouplist
- gid_t *groups;
- int n;
-#endif
+ llist_t *group_list;
unsigned flags;
- short status;
+ short status = EXIT_SUCCESS;
#if ENABLE_SELINUX
security_context_t scontext;
#endif
@@ -77,57 +95,27 @@
}
if (username) {
-#if HAVE_getgrouplist
- int m;
-#endif
p = getpwnam(username);
/* xuname2uid is needed because it exits on failure */
uid = xuname2uid(username);
gid = p->pw_gid; /* in this case PRINT_REAL is the same */
-
-#if HAVE_getgrouplist
- n = 16;
- groups = NULL;
- do {
- m = n;
- groups = xrealloc(groups, sizeof(groups[0]) * m);
- getgrouplist(username, gid, groups, &n); /* GNUism? */
- } while (n > m);
-#endif
- } else {
-#if HAVE_getgrouplist
- n = getgroups(0, NULL);
- groups = xmalloc(sizeof(groups[0]) * n);
- getgroups(n, groups);
-#endif
}
+ group_list = bb_getgrouplist_malloc(uid, gid, NULL);
if (flags & JUST_ALL_GROUPS) {
-#if HAVE_getgrouplist
- while (n--) {
- if (flags & NAME_NOT_NUMBER)
- printf("%s", bb_getgrgid(NULL, 0, *groups++));
- else
- printf("%u", (unsigned) *groups++);
- bb_putchar((n > 0) ? ' ' : '\n');
- }
-#endif
+ status = print_group_list(group_list, flags, NULL);
+ bb_putchar('\n');
/* exit */
- fflush_stdout_and_exit(EXIT_SUCCESS);
+ fflush_stdout_and_exit(status);
}
if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) {
/* JUST_GROUP and JUST_USER are mutually exclusive */
- if (flags & NAME_NOT_NUMBER) {
- /* bb_getXXXid(-1) exits on failure, puts cannot segfault */
- puts((flags & JUST_USER) ? bb_getpwuid(NULL, -1, uid) : bb_getgrgid(NULL, -1, gid));
+ if (flags & JUST_USER) {
+ /* Ignore return value, bb_getXXXid(-1) exits on failure */
+ print_single(uid, bb_getpwuid(NULL, -1, uid), flags, NULL);
} else {
- if (flags & JUST_USER) {
- printf("%u\n", (unsigned)uid);
- }
- if (flags & JUST_GROUP) {
- printf("%u\n", (unsigned)gid);
- }
+ print_single(gid, bb_getgrgid(NULL, -1, gid), flags, NULL);
}
#if ENABLE_SELINUX
@@ -143,25 +131,16 @@
puts(scontext);
}
#endif
+ bb_putchar('\n');
/* exit */
fflush_stdout_and_exit(EXIT_SUCCESS);
}
/* Print full info like GNU id */
/* bb_getpwuid(0) doesn't exit on failure (returns NULL) */
- status = printf_full(uid, bb_getpwuid(NULL, 0, uid), "uid=");
- status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), " gid=");
-#if HAVE_getgrouplist
- {
- const char *msg = " groups=";
- while (n--) {
- status |= printf_full(*groups, bb_getgrgid(NULL, 0, *groups), msg);
- msg = ",";
- groups++;
- }
- }
- /* we leak groups vector... */
-#endif
+ status = print_single(uid, bb_getpwuid(NULL, 0, uid), flags, "uid=");
+ status |= print_single(gid, bb_getgrgid(NULL, 0, gid), flags, " gid=");
+ status |= print_group_list(group_list, flags, " groups=");
#if ENABLE_SELINUX
if (is_selinux_enabled()) {
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox