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)

