Wanna see this logo while booting your 2.6 kernel? Click here!

21.06.2005 08:44

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.