#!/usr/bin/perl #$Id: menu.pl,v 1.3 2006/05/03 13:27:47 tfiedler Exp $ use strict; use warnings; use IO::Socket::INET; use Crypt::CBC; my $cipher = Crypt::CBC->new( -key => 'S3cr#tabcDeSal35', -cipher => 'Blowfish'); $SIG{INT} = 'IGNORE'; sub do_menu { my( $menu ) = @_; while(1) { my( $menu ) = @_; # display the menu print "\n"; print $_+1, '. ', $menu->[$_]{'label'}, "\n" for 0 .. $#{$menu}; print '0. ', ( @_ > 1 ? 'Return' : 'Exit' ), "\n"; # get the user's input local @ARGV; print STDERR '> '; local $_ = <>; chomp; /\d/ && !/\D/ or next; $_ == 0 and last; # item 0 is special defined $menu->[$_-1] or warn("Invalid choice\n"), next; my $op = $menu->[$_-1]{'op'}; my $arg = $menu->[$_-1]{'arg'}; if ( $op eq 'submenu' ) { do_menu( $arg, @_ ); # maintain the stack! } elsif ( $op eq 'exec_cmd' ) { execute_command( $arg ); } else { warn "Unrecognized op '$op'\n"; } } } my @printers_menu = ( { label => 'Show all Printers', op => 'exec_cmd', arg => 'showprintersall', }, { label => 'Show user print jobs', op => 'exec_cmd', arg => 'showprintersuser', }, { label => 'Show single printer', op => 'exec_cmd', arg => 'showprinter', }, { label => 'Kill a print job', op => 'exec_cmd', arg => 'killprint', }, ); my @accounts_menu = ( { label => 'Unlock user account', op => 'exec_cmd', arg => 'unlockuser', }, { label => 'Change account password', op => 'exec_cmd', arg => 'changepass', }, ); my @main_menu = ( { label => 'List and Kill UDT* processes by user', op => 'exec_cmd', arg => 'ListKillProc', }, { label => 'List and Kill Print Jobs...', op => 'submenu', arg => \@printers_menu, }, { label => 'Manage user accounts...', op => 'submenu', arg => \@accounts_menu, }, { label => 'Run App', op => 'exec_cmd', arg => 'APP', }, ); sub execute_command { warn "Executing command @_\n"; my $command = $_[0]; my @stack = &build_stack($command); my $STACK = join'|', @stack; my $cryptostack = $cipher->encrypt($STACK); if ($STACK =~ /^\d/) { print "Houston we have a problem... STACK = $STACK\n"; return 1; } my $return = ( send_stack($cryptostack) == 0 ) ? "successful" : "unsuccessful" ; print "transmission of data was $return\n"; } sub build_stack { my $command = @_; my @needed = (); my $set = \&set_item; my ( $username, $password, $password2, $jobid, $printer ); push (@needed, @_); return @needed if grep ( /^(APP|showprintersall)/, @_ ); if ( grep /^(showprintersuser|unlockuser|ListKillProc|changepass)/, @_ ) { $username = $set->('username'); push (@needed, $username); } if ( grep /^changepass/, @_ ) { $password = $set->('password'); $password2 = $set->('password2'); return 0 if ( $password ne $password2 ); push (@needed, $password); } if ( grep /^showprinter/, @_ ) { $printer = $set->('printer'); push (@needed, $printer); } if ( grep /^killprint/, @_ ) { $jobid = $set->('jobid'); push (@needed, $jobid); } return @needed; } sub set_item { print "Enter @_: "; my $item = ; chomp($item); return $item; } sub send_stack { my $send = shift; my $host = shift || "localhost"; my $port = shift || 62750; my $sock = IO::Socket::INET ->new( PeerAddr => $host, PeerPort => $port, Proto => 'tcp' ); $sock->print($send); my $rtrn = 1; while (my $receive = <$sock>) { if ($receive =~ /^1970__/) { $rtrn = 0; last; } chomp($receive); print "$receive\n"; } return $rtrn; } sub AUTOLOAD { print "Sorry, I dont know how to do @_"; return 1; } do_menu( \@main_menu );