busybox id -G patch
Today I enhanced the busybox "id" command with the -G option which
is used to print out all groups a user belongs to (instead of -g which just
prints the users gid).
The following diff allows busybox's id command to handle -G and -Gn (which
would display the names instead of the gids). The output is the same as
with GNU id.
diff -Nur busybox/coreutils/id.c busybox.new/coreutils/id.c
--- busybox/coreutils/id.c 2005-06-20 08:20:09.000000000 +0200
+++ busybox.new/coreutils/id.c 2005-06-21 08:22:29.226988717 +0200
@@ -23,6 +23,7 @@
/* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
/* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to
* be more similar to GNU id.
+ * -G and -Gn implemented by Alexander Griesser [busybox@tuxx-home.at] 2005
*/
#include "busybox.h"
@@ -30,6 +31,7 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
+#include <grp.h>
#ifdef CONFIG_SELINUX
#include <selinux/selinux.h> /* for is_selinux_enabled() */
@@ -39,6 +41,7 @@
#define NAME_NOT_NUMBER 2
#define JUST_USER 4
#define JUST_GROUP 8
+#define JUST_GROUP_LIST 16
static short printf_full(unsigned int id, const char *arg, const char prefix)
{
@@ -53,6 +56,16 @@
return status;
}
+static void print_group(gid_t gid, int use_name)
+{
+ struct group *grp = NULL;
+ grp = getgrgid(gid);
+ if(use_name)
+ bb_printf("%s", grp->gr_name);
+ else
+ bb_printf("%u", grp->gr_gid);
+}
+
extern int id_main(int argc, char **argv)
{
struct passwd *p;
@@ -61,8 +74,8 @@
unsigned long flags;
short status;
- bb_opt_complementaly = "u~g:g~u";
- flags = bb_getopt_ulflags(argc, argv, "rnug");
+ bb_opt_complementaly = "u~g:g~u:g~G:G~g:u~G:G~u";
+ flags = bb_getopt_ulflags(argc, argv, "rnugG");
if ((flags & BB_GETOPT_ERROR)
/* Don't allow -n -r -nr */
@@ -78,7 +91,7 @@
uid = getuid();
gid = getgid();
}
-
+
if(argv[optind]) {
p=getpwnam(argv[optind]);
/* my_getpwnam is needed because it exits on failure */
@@ -99,6 +112,28 @@
bb_fflush_stdout_and_exit(EXIT_SUCCESS);
}
+ /* Support -G and -Gn */
+ if(flags & JUST_GROUP_LIST) {
+ gid_t *groups;
+ long ngroups_max;
+ int i, ngroups;
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ groups = (gid_t*) malloc(ngroups_max * sizeof(gid_t) + 1);
+ ngroups = getgroups(ngroups_max, groups);
+ /* first print the (e)gid */
+ print_group(gid, flags & NAME_NOT_NUMBER);
+ /* now cycle through all other gids, except for egid */
+ for(i = 0; i < ngroups; i++) {
+ if(groups[i] != gid) {
+ bb_printf(" ");
+ print_group(groups[i], flags & NAME_NOT_NUMBER);
+ }
+ }
+ bb_printf("\n");
+ /* exit */
+ bb_fflush_stdout_and_exit(EXIT_SUCCESS);
+ }
+
/* Print full info like GNU id */
/* my_getpwuid doesn't exit on failure here */
status=printf_full(uid, my_getpwuid(NULL, uid, 0), 'u');
diff -Nur busybox/include/usage.h busybox.new/include/usage.h
--- busybox/include/usage.h 2005-06-20 08:20:13.000000000 +0200
+++ busybox.new/include/usage.h 2005-06-21 07:55:51.482737569 +0200
@@ -1111,7 +1111,8 @@
"\t-g\tprints only the group ID\n" \
"\t-u\tprints only the user ID\n" \
"\t-n\tprint a name instead of a number\n" \
- "\t-r\tprints the real user ID instead of the effective ID"
+ "\t-r\tprints the real user ID instead of the effective ID\n" \
+ "\t-G\tprint all group IDs\n"
#define id_example_usage \
"$ id\n" \
"uid=1000(andersen) gid=1000(andersen)\n"
diff -Nur busybox/testsuite/id/id-G-works busybox.new/testsuite/id/id-G-works
--- busybox/testsuite/id/id-G-works 1970-01-01 01:00:00.000000000 +0100
+++ busybox.new/testsuite/id/id-G-works 2005-06-21 08:26:49.403257154 +0200
@@ -0,0 +1 @@
+test x$(id -G) = x$(busybox id -G)
diff -Nur busybox/testsuite/id/id-Gn-works busybox.new/testsuite/id/id-Gn-works
--- busybox/testsuite/id/id-Gn-works 1970-01-01 01:00:00.000000000 +0100
+++ busybox.new/testsuite/id/id-Gn-works 2005-06-21 08:26:58.917657846 +0200
@@ -0,0 +1 @@
+test x$(id -Gn) = x$(busybox id -Gn)
This patch may also be downloaded
here.
Posted by Alexander Griesser
| Categories:
Busybox
| Comments:
--> New comment