#!/usr/bin/perl
#############################################################################
#  nodeattr,v 1.5 2003/01/22 04:19:42 garlick Exp
#############################################################################
#  Copyright (C) 2001-2002 The Regents of the University of California.
#  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
#  Written by Jim Garlick <garlick@llnl.gov>.
#  UCRL-CODE-2003-004.
#  
#  This file is part of Genders, a cluster configuration database and
#  rdist preprocessor.
#  For details, see <http://www.llnl.gov/linux/genders/>.
#  
#  Genders 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 2 of the License, or (at your option)
#  any later version.
#  
#  Genders 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 Genders; if not, write to the Free Software Foundation, Inc.,
#  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
#############################################################################
#
# Perl doesn't like these to be set insecurely when running in setuid mode.
# Pdsh calls nodeattr in setuid mode.  
$ENV{PATH} = "";
$ENV{ENV} = ""; 
$ENV{BASH_ENV} = ""; 

use Getopt::Std;

require "/usr/lib/genders/gendlib.pl";
require "/usr/lib/genders/hostlist.pl";

##
## MAIN
##

my ($mycluster, $arg_attr, $arg_node, $rname);

#
# handle arguments
#
getopts('srClvcnf:') or usage();
($#ARGV > 0) && ($arg_node = shift(@ARGV));
($#ARGV > -1) && ($arg_attr = shift(@ARGV));
if ($#ARGV > -1) { 
	usage();
}

if ($opt_f) {					# -f path_genders
	#
	# Explicitly initialize package with non-default genders file.
	# If this is not called, package self-initializes with the default
	# on first call.
	#
	if (!Genders::init($opt_f)) {
		print STDERR ("$opt_f: $!\n");
		exit(1);
	}	
} 

#
# perform function specified by command line arguments
#
if (($opt_c || $opt_n || $opt_s) && $arg_attr) {# -s|-c|-n attr   - list nodes with attr
	@nodes = Genders::getnode($arg_attr);
	if ($opt_r) {
		@nodes = Genders::to_altnames(@nodes);
	}
	if ($opt_s) {
		@nodes = Hostlist::compress(@nodes);
		$opt_c = 1;
	}
	if (@nodes) {
		printf("%s\n", join($opt_c ? "," : "\n", @nodes));
	}
} elsif ($opt_l) {			# -l           - list attrs in genders
	printf("%s\n", join("\n", Genders::getallattr()));

} elsif ($opt_C) {			# -C           - list "this" cluster
	($mycluster) = Genders::get_clusters();
	printf("%s\n", $mycluster ? $mycluster : "unknown");
} elsif ($arg_attr) {			# [-v] [node] attr - test node for attr
	nodeattr($opt_v, $arg_attr, $arg_node);

} else {
	usage();
}

##
## SUBROUTINES
##

use strict;

# Test whether or not node has attribute.  If -v specified, 
# also print the attribute on stdout (including any attr=value) 
#	$opt_v (IN)	1 if -v specified, else 0
#	$arg_attr (IN)	attribute name
#	$arg_node (IN)  [optional] node name (this host if null)
#	$rv (RETURN)	1=no, 0=yes
sub nodeattr 
{
	my $opt_v = shift(@_);
	my $arg_attr = shift(@_);
	my $arg_node = shift(@_);

	my ($val, $hasit);

	if ($arg_node) {
		$hasit = Genders::hasattr($arg_attr, $arg_node);
		$opt_v && ($val = Genders::getattrval($arg_attr, $arg_node));
	} else {
		$hasit = Genders::hasattr($arg_attr);
		$opt_v && ($val = Genders::getattrval($arg_attr));
	}

	if ($opt_v && $hasit) {
		printf("%s\n", $val)
	}
	exit($hasit ? 0 : 1);
}

# list my cluster or "unknown" on stdout
sub print_mycluster
{
	my ($mycluster);

	($mycluster) = (Genders::get_clusters());
	
	printf("%s\n", $mycluster ? $mycluster : "unknown");
}

# print usage instructions and exit
sub usage
{
        print "Usage: nodeattr [-f genders] {-c | -n | -s] [-r] attr\n";
        print "or     nodeattr [-f genders] [-v] [node] attr\n";
        print "or     nodeattr [-f genders] -l\n";
        print "or     nodeattr -C\n";
        exit(1);
}
