3 $ENV{PATH} = '/usr/xpg4/bin:/bin:/usr/bin:/usr/ucb';
5 # We have to find a command that prints all (effective
6 # and real) group names (not ids). The known commands are:
10 # Beware 1: some systems do just 'id -G' even when 'id -Gn' is used.
11 # Beware 2: id -Gn or id -a format might be id(name) or name(id).
12 # Beware 3: the groups= might be anywhere in the id output.
14 # That is, we might meet the following:
16 # foo bar zot # accept
18 # groups=foo(1),bar(2),zot(3) # parse
19 # groups=1(foo),2(bar),3(zot) # parse
21 # and the groups= might be after, before, or between uid=... and gid=...
24 last GROUPS if ($groups = `groups 2>/dev/null`) ne '';
25 if ($groups = `id -Gn 2>/dev/null` ne '') {
26 last GROUPS unless $groups =~ /^(\d+)(\s+\d)*$/;
28 if ($groups = `id -a 2>/dev/null` ne '') {
37 # Remember that group names can contain whitespace, '-', et cetera.
38 # That is: do not \w, do not \S.
39 if ($groups =~ /groups=((.+?\(.+?\))(,.+?\(.+?\))*)( [ug]id=|$)/) {
41 my @g0 = $gr =~ /(.+?)\((.+?)\),?/g;
42 my @g1 = @g0[ map { $_ * 2 } 0..$#g0/2 ];
43 my @g2 = @g0[ map { $_ * 2 + 1 } 0..$#g0/2 ];
48 $groups = join(" ", @g1);
49 } elsif (grep /\D/, @g2) {
50 $groups = join(" ", @g2);
52 # Let's fail. We want to parse the output. Really.
59 ($pwgnam) = getgrgid($pwgid);
60 @basegroup{$pwgid,$pwgnam} = (1,1);
64 for (split(' ', $()) {
66 ($group) = getgrgid($_);
75 if ($^O eq "uwin") { # Or anybody else who can have spaces in group names.
76 $gr1 = join(' ', grep(!$did{$_}++, sort split(' ', join(' ', @gr))));
78 $gr1 = join(' ', sort @gr);
81 $gr2 = join(' ', grep(!$basegroup{$_}++, sort split(' ',$groups)));
87 print "#gr1 is <$gr1>\n";
88 print "#gr2 is <$gr2>\n";
92 # multiple 0's indicate GROUPSTYPE is currently long but should be short
94 if ($pwgid == 0 || $seen{0} < 2) {
98 print "not ok 2 (groupstype should be type short, not long)\n";