#!/usr/local/bin/perl -w use strict; use Log::Log4perl qw(:easy); use DB_File; use Tk; my %sudo_programs = map { $_ => 1 } qw(synaptic); my @misc_paths = qw(/usr/sbin); my($home) = glob "~"; my $spotty_dir = "$home/.spotty"; #Log::Log4perl->easy_init(); if(! -d $spotty_dir) { mkdir $spotty_dir, 0755 or LOGDIE "Cannot mkdir $spotty_dir ($!)"; } # Init database my %DB_FILE; tie %DB_FILE, "DB_File", "$spotty_dir/db_file.dat" or LOGDIE "$!"; # Application window my $top = MainWindow->new(); $top->geometry("-0+0"); my($input, $first_match, $label_text); my $label = $top->Label( -textvariable => \$label_text, -width => 20 ); my $entry = $top->Entry( -textvariable => \$input, -validatecommand => \&validate, -validate => "key", ); $entry->pack( -side => "left" ); $label->pack( -side => "left" ); $entry->bind("", \&bail); $entry->bind("", sub { launch($input) }); $entry->bind("", \&complete); $entry->focus(); MainLoop; ########################################### sub bail { ########################################### $top->destroy(); } ########################################### sub validate { ########################################### my($got) = @_; $label_text = join "\n", matches($got); return 1; } ########################################### sub matches { ########################################### my($got) = @_; my @all = sort keys %DB_FILE; my @matches = grep { /^$got/ } @all; if(@matches) { $first_match = $matches[0]; } else { $first_match = undef; } return @matches; } ########################################### sub complete { ########################################### $input = $first_match; launch($input); } ########################################### sub launch { ########################################### my($program) = @_; my $path = path_search( $program ); LOGDIE "$program not found ", "in path ($ENV{PATH})" unless defined $path; $DB_FILE{ $program }++ if defined $path; DEBUG "Launching $path"; untie %DB_FILE; if(exists $sudo_programs{ $program } ) { exec "xterm", "-e", "sudo", "$path"; } else { exec $path; } LOGDIE "exec $path failed: $!"; } ########################################### sub path_search { ########################################### my($program) = @_; DEBUG "PATH is $ENV{PATH}"; for my $path ( split(/:/, $ENV{PATH}), @misc_paths ) { if(-x "$path/$program") { DEBUG "$program found in $path"; return "$path/$program"; } } ERROR "$program not found"; return undef; }