#!/usr/bin/env perl #****************************************************************************** # ConMen: a wrapper to aid in ConMan broadcast sessions. #****************************************************************************** # $Id: conmen 500 2005-02-10 02:19:46Z dun $ #****************************************************************************** # Copyright (C) 2001-2002 The Regents of the University of California. # Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). # Written by Chris Dunlap . # UCRL-CODE-2002-009. # # This file is part of ConMan, a remote console management program. # For details, see . # # ConMan 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. # # ConMan 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 ConMan; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. #****************************************************************************** # ConMen spawns an xterm for each of the selected consoles # and uses the current tty as the broadcast window. # All of the spawned xterm clients are terminated when the # broadcast window session is closed. #****************************************************************************** use Getopt::Std; $SIG{TERM} = exit_handler; $ENV{PATH} = "/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/X/bin"; $ENV{DISPLAY} or die("ERROR: DISPLAY not set.\n"); !system("which conman 1>/dev/null 2>&1") or die("ERROR: conman not found in PATH.\n"); !system("which xterm 1>/dev/null 2>&1") or die("ERROR: xterm not found in PATH.\n"); $help = `conman -h`; ($def_dst) = ($help =~ /-d .* \[([^\]]*)\]/); ($def_esc) = ($help =~ /-e .* \[([^\]]*)\]/); print_usage() if (!@ARGV || !getopts('d:e:fg:hjLmqrV') || $opt_h); @patterns = @ARGV; exec("conman", "-L") or die("ERROR: Cannot exec conman: $!\n") if ($opt_L); exec("conman", "-V") or die("ERROR: Cannot exec conman: $!\n") if ($opt_V); ($opt_f + $opt_j + $opt_m <= 1) or die("ERROR: Only one mode [fjm] can be specified.\n"); if ($opt_f) { $mode = "-f"; } elsif ($opt_j) { $mode = "-j"; } elsif ($opt_m) { $mode = "-m"; } else { $mode = "-m"; } @conman = ("conman", "-Q"); push(@conman, ("-d", $opt_d)) if ($opt_d); push(@conman, ("-e", $opt_e)) if ($opt_e); push(@conman, ("-r")) if ($opt_r); @xterm = ("xterm"); push(@xterm, ("-geometry", $opt_g)) if ($opt_g); query_consoles(); spawn_consoles(); exit_handler(); kill(-9, $$); exit(0); sub exit_handler { kill('TERM', @pids); select(undef, undef, undef, 0.5); kill('KILL', @pids); exit(0); } sub print_usage { ($prog) = ($0 =~ m|(?:.*/)?([^/]*)|); print("Usage: $prog [OPTIONS] [CONSOLES]\n"); print("\n"); print(" -d HOST Specify server destination. [$def_dst]\n"); print(" -e CHAR Specify escape character. [$def_esc]\n"); print(" -f Force connections (console-stealing).\n"); print(" -g SIZE Specify xterm's geometry (eg, 80x24).\n"); print(" -h Display this help.\n"); print(" -j Join connections (console-sharing).\n"); print(" -L Display license information.\n"); print(" -m Monitor connections (read-only).\n"); print(" -q Query server about specified console(s).\n"); print(" -r Match console names via regex instead of globbing.\n"); print(" -V Display version information.\n"); print("\n"); exit(0); } sub query_consoles { die("ERROR: Cannot fork query: $!\n") unless defined($pid = open(QUERY, "-|")); if ($pid == 0) { exec(@conman, "-q", @patterns) or die("ERROR: Cannot exec query: $!\n"); } else { chomp(@consoles = ); close(QUERY); } if ($opt_q) { foreach (@consoles) { print("$_\n"); } exit(0); } if (@consoles == 0) { exit(1); } elsif (@consoles == 1) { exec(@conman, $mode, $consoles[0]) or die("ERROR: Cannot exec conman for console $consoles[0]: $!\n"); } } sub spawn_consoles { foreach $console (@consoles) { $name = "ConMan: $console"; if (!defined($pid = fork)) { die("ERROR: Cannot fork xterm for console $console: $!\n"); } elsif ($pid == 0) { local $SIG{TERM} = 'DEFAULT'; exec(@xterm, "-T", $name, "-e", @conman, $mode, $console) or die("ERROR: Cannot exec xterm for console $console: $!\n"); } else { push(@pids, $pid); } select(undef, undef, undef, 0.2); } select(undef, undef, undef, 1.0); if (!defined($pid = fork)) { die("ERROR: Cannot fork xterm for console broadcast: $!\n"); } elsif ($pid == 0) { exec(@conman, "-b", "-j", @patterns) or die("ERROR: Cannot exec xterm for console broadcast: $!\n"); } else { waitpid($pid, 0); } }