eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
& eval 'exec perl -S $0 $argv:q'
if 0;
# THE PRECEEDING STUFF EXECS perl via $PATH
#
# $Id: //guest/sandy_currier/utils/p4users.pl#3 $
#
#
# Copyright (c) 2000, Sandy Currier (sandy@releng.com)
# Distributed under the GNU GENERAL PUBLIC LICENSE:
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 1, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
#
# Unbuffer STDERR and STDOUT
select(STDERR);
$| = 1; # Make STDERR be unbuffered.
select(STDOUT);
$| = 1; # STDOUT too
#
# set up some globals
$ThisCmd = "p4users"; # this command name
#
# local variables
$P4 = "p4";
$verbose = 0;
$err = "***";
#
# now parse any args
# the usage message (for -h or on error)
$help = "$ThisCmd
Function:
$ThisCmd will list the users catalogued in the various perforce
groups as well as those perforce groups. Will follow subgroups
links. Will also print <UNKNOWN> for those users listed in a
group but who have never logged into the server.
Switches/Options:
-h Prints this help message
-u Only print 'UNKNOWN' users (see above)
";
#
# parse command line
{
my($i) = 0;
while($i <= $#ARGV) {
# scan for a help switch
if ($ARGV[$i] =~ /^-h/i) {
&DieHelp("", $help);
}
# scan for switches
elsif ($ARGV[$i] =~ /^-n/i) {
$printonly = 1;
$i++;
}
elsif ($ARGV[$i] =~ /^-u/i) {
$unknown = 1;
$i++;
}
# scan for variable definitions (-variable value)
elsif ($ARGV[$i] =~ /^-\w+/ and defined($ARGV[$i+1]) and $ARGV[$i+1] !~ /^-[^-]/) {
# NOTE: nt has a difficult time with '=' on a command line...
# process any variable value switches
my($var) = $ARGV[$i];
$var =~ s/^-//;
my($value) = $ARGV[$i+1];
if (defined $$var) {
$$var = $value;
}
else {
&DieHelp("Unknown parameter '$var'\n", $help);
}
$i=$i+2;
}
# catch unsupported switches
elsif ($ARGV[$i] =~ /^-/) {
&DieHelp("Unsupported switch \"$ARGV[$i]\"\n", $help);
}
else {
&DieHelp("Unsupported argument \"$ARGV[$i]\"\n", $help);
}
}
}
#
# first, list the groups
@Groups = &ExecuteP4Cmd("$P4 groups", $verbose);
chomp(@Groups);
#
# get the group info, collecting user and subgroups
foreach my $group (@Groups) {
&GetGroupInfo($group, \%GroupInfo);
}
#
# now, create a hash for each user found, and add up all the group info
foreach my $group (@Groups) {
# for each top level group, only visit the subgroups once
# use a local instead of a my for proper scoping
local @Visited;
&GetUsers($group, $group);
}
#
# now get the real p4 user output
@Users = &ExecuteP4Cmd("$P4 users", $verbose);
chomp(@Users);
# make an array of just the user names for easy grep'ing
foreach (@Users) {
/^(\S+)\s+</;
push @Usernames, $1;
}
#
# now print stuff
foreach my $user (sort(keys(%Users))) {
my $tmp = join(', ', sort(@{$Users{$user}}));
my $foo = grep(/^$user$/, @Usernames);
if ($foo) {
printf STDOUT "%-20s%s\n", $user, $tmp unless ($unknown);
}
else {
printf STDOUT "%-20s%s <UNKNOWN>\n", $user, $tmp;
}
}
#
# the end
exit(0);
#
# subroutines
#
# for the specified group, set the hash with the values
sub GetGroupInfo {
my($group, $groupinfo) = @_;
my($sub_p, $users_p);
my(@output) = &ExecuteP4Cmd("$P4 group -o $group", $verbose);
chomp(@output);
foreach my $line (@output) {
if ($line =~ /^MaxResults:\s+(\S+)/) {
$$groupinfo{$group}{'MaxResults'} = $1;
}
elsif ($line =~ /^Subgroups:/) {
$sub_p++;
}
elsif ($sub_p and $line =~ /^\s+(\S+)/) {
push @{$$groupinfo{$group}{'Subgroups'}}, $1;
}
elsif ($sub_p and $line eq "") {
$sub_p = 0;
}
elsif ($line =~ /^Users:/) {
$users_p++;
}
elsif ($users_p and $line =~ /^\s+(\S+)/) {
push @{$$groupinfo{$group}{'Users'}}, $1;
}
}
}
sub GetUsers {
my($group, $subgroup) = @_;
# loop over explicit users and add info
foreach my $user (@{$GroupInfo{$subgroup}{'Users'}}) {
if (!grep(/^$group$/, @{$Users{$user}})) {
push @{$Users{$user}}, $group;
}
}
# loop over subgroups if they have not been visited yet
foreach my $subg (@{$GroupInfo{$subgroup}{'Subgroups'}}) {
if (!grep(/^$subg$/, @Visited)) {
# this subgroup has not been visited yet - must visit it
&GetUsers($group, $subg);
# add this subgroup to the visited list
push @Visited, $subg;
}
else {
# this subgroup has already been visited - just return
}
}
}
sub DieHelp {
my($str, $help) = @_;
print STDERR "$err $str\nUsage: $help";
exit(1);
}
#
# Note: this will actually execute any command...
# returns the action of the revision of the specified file#revision
sub ExecuteP4Cmd {
my($script, $verbose, $print_output, $no_error_check, $stream_p) = @_;
my(@output);
if ($stream_p) {
print $stream_p "$vb\n$vb running: $script\n$vb\n" if ($verbose);
}
else {
print STDOUT "$vb\n$vb running: $script\n$vb\n" if ($verbose);
}
if (!$Platform{'nt'} and $Platform{'os'} eq "win32") {
@output = `$script` unless ($printonly);
}
else {
@output = `$script 2>&1` unless ($printonly);
}
if ($stream_p) {
print $stream_p "@output" if ($print_output);
} else {
print STDOUT "@output" if ($print_output);
}
if (!$no_error_check and $?) {
# now what - just keep going
print STDERR "$err $ThisCmd - something happened with '$script'\n$?";
}
return(@output);
}