#!/usr/bin/perl

# MAD 2.0
# Menu de Acceso a Dispositivos
# By Alfonso E.M. alfonso@el-magnifico.org
# Muestra una lista de dispositivos (de /etc/fstab) con su estado (de /etc/mtab)
# de forma clara para un usuario comn, permitiendo montar o desmontar las
# unidades o explorar su contenido



# Requiere el modulo UI::Dialog

use UI::Dialog::Backend::XDialog;



$|=1;
%hd=("a"=>"Maestro","b"=>"Esclavo","c"=>"Maestro secundario","d"=>"Esclavo secundario");

while (1) {

open (FSTAB,"/etc/fstab") or die "ERROR: No puedo leer el archivo /etc/fstab\n";
%device=();
%hdevice=();
%status=();
%mountp=();
while (<FSTAB>) {
	@items=split(/[\s\t]+/);
	if ($#items > 1 && $items[0]=~/^\/dev\//) {
		$name=$items[0];
		$mountpoint=$items[1];
		$device{$name}=$mountpoint;
		$mountp{$mountpoint}=$name;
		$status{$name}="off";
	}
}
close FSTAB;


open (MOUNTTAB,"/etc/mtab") or die "ERROR: No puedo leer el archivo /etc/mtab\n";
while (<MOUNTTAB>) {
	@items=split(/[\s\t]+/);
	if ($#items > 1 && $items[0]=~/^\/dev\//) {
		$name=$items[0];
		$mountpoint=$items[1];
		$status{$name}="on";
		$name=$mountp{$mountpoint};
		$status{$name}="on";
	}
}
close MOUNTTAB;

$numdevices=keys(%device);

if (open (SCSI,"/proc/scsi/scsi")) {
	while (<SCSI>) {
		if (/Host.*Id:\s*(\d+)\s*Lun/i) { $id=$1;}
		elsif (/Vendor:\s*(.*?)\s*Model:\s*(.*)\s*Rev:/i) { $vendor=$1; $model=$2; }
		elsif (/Type:\s*([A-Z\-]+)\s*/i) { 
			$type=$1; 
			if (defined $id) {
			   $scsi{$id}="$type $vendor $model";
			}
		}
	}
}

@device_menu=();
foreach (sort (keys %device)) {
#	print $device{$_}."-".$status{$_}."\n";
	$hdevice{$_}=&humanize($_,$device{$_},$status{$_});
	if ($hdevice{$_}) { push (@device_menu, $_, $hdevice{$_} ) };
}

$dialog = new UI::Dialog::Backend::XDialog ( 
	backtitle => 'Lista de Unidades y Accesorios',
	title => 'M.A.D. Menu de Acceso a Dispositivos',
	height => 20, width=>65,
	oklabel => 'Continuar',
	listheight => $numdevices );

my $selected_dev = $dialog->menu( text => 'Elija uno:',
                            list => \@device_menu );

if (!$selected_dev) { exit(0) };

@action_menu=();
if ($status{$selected_dev} eq "on") { 
	push @action_menu, "explore", "Mostrar el contenido";
	push @action_menu, "off", "Desactivar el dispositivo";
	if ($selected_dev=~/\/[cd|dvd]/) {
		push @action_menu, "off&eject", "Desactivar y expulsar el dispositivo";
	}
}
elsif ($status{$selected_dev} eq "off") {	 
	push @action_menu, "on", "Activar el dispositivo";
	push @action_menu, "on&explore", "Activar y mostrar el contenido";
}

my $selected_action = $dialog->menu( text => "Qu desea hacer con su $hdevice{$selected_dev}",
                            itemhelp => 0 ,
			    oklabel => 'Ejecutar',
                            list => \@action_menu );
		
if ($selected_action) { 

	if ($selected_action=~/^on/) { &mount($selected_dev); }
	elsif ( $selected_action=~/^off/) { &umount($selected_dev); }

	if ( $selected_action=~/explore$/) {  &browse($selected_dev); }
	if ( $selected_action=~/eject$/) {  &eject($selected_dev); }
}


}

sub browse() {
        local($dev)=@_;
        open(BROWSE,"/usr/bin/nautilus $device{$dev} |");
        if ($?) { $dialog->msgbox( text => "Error: No es posible ver el contenido de unidad. "); }
	close BROWSE;
}

sub eject() {
        local($dev)=@_;
        open(EJECT,"/usr/bin/eject $device{$dev} |");
        if ($?) { $dialog->msgbox( text => "Error: No es posible expulsar el disco. "); }
	close EJECT;
}

sub mount() {
	local($dev)=@_;
	open(MNT,"/bin/mount $dev 2>&1 |");
	@log=<MNT>;
	close MNT;
	if ($?) { $dialog->msgbox( text => "Error: No es posible activar la unidad  (@log). " ); }
}

sub umount() {
	local($dev)=@_;
	open(MNT,"/bin/umount $dev 2>&1 |");
	@log=<MNT>;
	close MNT;
	if ($?) { $dialog->msgbox( text => "Error: No es posible desactivar la unidad (@log)" ); }
}


# humanize
# Convert device and path to an easier to understand format for no-geeks :-)
sub humanize() {
	local($dev,$mpoint,$st)=@_;

	my $hst="";

	if ($st eq "on") { $hst="(Activa)"}

	if ($mpoint=~/none/) {
	   return ("");
	}
	if ($mpoint=~/swap/) {
	   return ("");
	}

	if ($dev=~/^\/dev\/fd([0-9]+)/) {
	   return ("Lectora de Disquetes $1 $hst");
	}
	if ($dev=~/^\/dev\/hd([a-z])([0-9]+)/) {
	   return ("Particin $2 del disco $hd{$1} $hst");
	}
	if ($mpoint=~/^\/cd\w+([0-9]*)/) {
	   $model=&get_unit_data($dev);
	   if ($model) { 
		return ("$model $hst") 
	   } 
		else { 
			return ("Lector de CD-Rom $1 $hst");
	   }
	}
	if ($mpoint=~/\/usb([0-9]*)/) {
	   return ("Conector para USB $1 $hst");
	}
	if ($mpoint=~/\/zip([0-9]*)/) {
	   return ("Unidad de discos ZIP $1 $hst");
	}
	return $mpoint;
}		

sub get_unit_data() {
	my ($dev)=@_;
	$realname=readlink($dev);
	if ($realname=~/scd(\d+)/) { 
		$id=sprintf("%02d", $1);
		return $scsi{$id} 
	}
	if ($realname=~/(hd\w)/) { 
	   open(IDE,"/proc/ide/$1/model") or return ("");
	   $model=<IDE>;
	   chop($model);
	   close IDE;
	   return $model;
	}
}