#!/usr/bin/perl -wTU #---------------------------------------------------------------------- # heading : Miscellaneous # description : USB Disks # navigation : 5000 5200 #---------------------------------------------------------------------- # JP Pialasse January 2007 #---------------------------------------------------------------------- #package usbdisks; use diagnostics; use strict; use CGI ':all'; use CGI::Carp qw(fatalsToBrowser); use esmith::db; use esmith::templates; use esmith::FormMagick; my $fm = esmith::FormMagick->new(); $fm->parse_xml(); #use Sys::Filesystem (); #use FileHandle; # use Shell qw (ls cat); #use File::Temp 0.12 qw(tempdir); #use File::Basename; use esmith::cgi; use esmith::config; use esmith::util; use esmith::DB; use esmith::DB::db; sub showInitial ($$); sub modifyConfig ($$); sub GeneralMenu ($); sub aide($); sub USBModifyConfig; sub validUSBModifyConfig; sub USBAddDisk; sub validUSBAddDisk; sub USBModifyDisk; sub validUSBModifyDisk; sub USBMountDisk; sub USBUnMountDisk; sub USBMounttoDisk; sub USBUnMounttoDisk; sub disable_entry; sub enable_entry; sub disable_mediaentry; sub enable_mediaentry; sub delete_entry; sub UUIDgenerate; BEGIN { # Clear PATH and related environment variables so that calls to # external programs do not cause results to be tainted. See # "perlsec" manual page for details. $ENV {'PATH'} = '/bin:/usr/bin:/sbin/'; $ENV {'SHELL'} = '/bin/bash'; delete $ENV {'ENV'}; } esmith::util::setRealToEffective (); $CGI::POST_MAX=1024 * 100; # max 100K posts $CGI::DISABLE_UPLOADS = 1; # no uploads my %conf; tie %conf, 'esmith::config'; #db_set(\%conf, "usbdisks", "service|frequence|3"); my %usbdisks; if (-e "/home/e-smith/db/confusbdisks" ) { tie %usbdisks, 'esmith::config', '/home/e-smith/db/confusbdisks'; } else { `echo "">/home/e-smith/db/confusbdisks`; tie %usbdisks, 'esmith::config', '/home/e-smith/db/confusbdisks'; } my $usbd_frequence = db_get_prop(\%conf, "usbdisks","frequence") || "2"; my $usbd_status = db_get_prop(\%conf, "usbdisks","status") || "disabled"; my $usbd_status_mediaG = db_get_prop(\%conf, "usbdisks","status_mediaG") || "disabled"; my $usbd_status_mediaU = db_get_prop(\%conf, "usbdisks","status_mediaU") || "disabled"; #------------------------------------------------------------ # traduction #------------------------------------------------------------ my $sec = 5; my $tr_menu_config = $fm->localise('tr_menu_config'); my $tr_menu_accueil = $fm->localise('tr_menu_accueil'); my $tr_disks_online = $fm->localise('tr_disks_online'); my $tr_known_mounts = $fm->localise('tr_known_mounts'); my $tr_description = $fm->localise('tr_description'); my $tr_aide = $fm->localise('tr_aide'); my $tr_no = $fm->localise('tr_no'); my $tr_yes = $fm->localise('tr_yes'); my $tr_dev = $fm->localise('tr_dev'); my $tr_uuid = $fm->localise('tr_uuid'); my $tr_mount = $fm->localise('tr_mount'); my $tr_fstab = $fm->localise('tr_fstab'); my $tr_label = $fm->localise('tr_label'); my $tr_fs_type = $fm->localise('tr_fs_type'); my $tr_device_type = $fm->localise('tr_device_type'); my $tr_action = $fm->localise('tr_action'); my $tr_mount_to = $fm->localise('tr_mount_to'); my $tr_mounted_to = $fm->localise('tr_mounted_to'); my $tr_connected = $fm->localise('tr_connected'); my $tr_status = $fm->localise('tr_status'); my $tr_success = $fm->localise('tr_success'); my $tr_failure = $fm->localise('tr_failure'); my $tr_unknown = $fm->localise('tr_unknown'); my $tr_add = $fm->localise('tr_add'); my $tr_modify = $fm->localise('tr_modify'); my $tr_remove = $fm->localise('tr_remove'); my $tr_refresh = $fm->localise('tr_refresh'); my $tr_removed = $fm->localise('tr_removed'); my $tr_added = $fm->localise('tr_added'); my $tr_save_label = $fm->localise('tr_save_label'); my $tr_save_button = $fm->localise('tr_save_button'); my $tr_rapport = $fm->localise('tr_rapport'); my $tr_with = $fm->localise('tr_with'); my $tr_disabled = $fm->localise('tr_disabled'); my $tr_enabled = $fm->localise('tr_enabled'); my $tr_pageaide = $fm->localise('tr_pageaide'); my $tr_titre_ajout = $fm->localise('tr_title_ajout'); my $tr_titre_modifier= $fm->localise('tr_titre_modifier'); my $tr_titre_accueil = $fm->localise('tr_titre_accueil'); my $tr_titre_config = $fm->localise('tr_titre_config'); my $tr_frequence = $fm->localise('tr_frequence'); my $tr_incorect = $fm->localise('tr_incorect'); my $tr_forbidden_directory = $fm->localise('tr_forbidden_directory'); my $tr_directory_does_not_exist= $fm->localise('tr_directory_does_not_exist'); my $tr_uuidgenerate= $fm->localise('tr_uuidgenerate'); #ajout verion 0.2-0.1 my $tr_options_mount_to = $fm->localise('tr_options_mount_to'); my $tr_status_media = $fm->localise('tr_status_media'); my $tr_status_mediaG = $fm->localise('tr_status_mediaG'); my $tr_status_mediaU = $fm->localise('tr_status_mediaU'); my $tr_status_mountmedia = $fm->localise('tr_status_mountmedia'); my $tr_status_mountto = $fm->localise('tr_status_mountto'); #------------------------------------------------------------ # examine state parameter and display the appropriate form #------------------------------------------------------------ my $q = new CGI; if (! grep (/^state$/, $q->param)) { showInitial ($q,''); } elsif ($q->param ('state') eq "USBModifyConfig") { USBModifyConfig ($q); } elsif ($q->param ('state') eq "validUSBModifyConfig") { validUSBModifyConfig ($q); } elsif ($q->param ('state') eq "USBAddDisk") { USBAddDisk ($q); } elsif ($q->param ('state') eq "validUSBAddDisk") { validUSBAddDisk ($q); } elsif ($q->param ('state') eq "USBModifyDisk") { USBModifyDisk ($q); } elsif ($q->param ('state') eq "validUSBModifyDisk") { validUSBModifyDisk ($q); } elsif ($q->param ('state') eq "USBMountDisk") { USBMountDisk ($q); } elsif ($q->param ('state') eq "USBUnMountDisk") { USBUnMountDisk ($q); } elsif ($q->param ('state') eq "USBMounttoDisk") { USBMounttoDisk ($q); } elsif ($q->param ('state') eq "USBUnMounttoDisk") { USBUnMounttoDisk ($q); } elsif ($q->param ('state') eq "disable_entry") { disable_entry ($q); } elsif ($q->param ('state') eq "enable_entry") { enable_entry ($q); } elsif ($q->param ('state') eq "disable_mediaentry") { disable_mediaentry ($q); } elsif ($q->param ('state') eq "enable_mediaentry") { enable_mediaentry ($q); } elsif ($q->param ('state') eq "delete_entry") { delete_entry ($q); } elsif ($q->param ('state') eq "UUIDgenerate") { UUIDgenerate ($q); } elsif ($q->param ('state') eq "aide") { aide ($q); } else { esmith::cgi::genStateError ($q, \%conf); } exit (0); #------------------------------------------------------------ # subroutine to display initial form #------------------------------------------------------------ sub showInitial ($$) { my ($q, $msg) = @_; #------------------------------------------------------------ # db init #------------------------------------------------------------ if (not defined db_get(\%conf, "usbdisks")) { my %default_db=( 'status' => 'disabled', 'Debug' => 'no', ); db_set(\%conf, "usbdisks","service",\%default_db); } #------------------------------------------------------------ # If there's a message, we just finished an operation so show the # status report. If no message, this is a new list of domains. #------------------------------------------------------------ if ($msg eq '') { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'USB Disks '); } else { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Operation status report'); print $q->p ($msg); print $q->hr; } print $q->hr; GeneralMenu ($q); print $tr_description; print $q->hr; my %disques= subdevices(); print "

".$tr_disks_online."

"; print "\n"; print "\n"; my $clef; my $disque; for $clef ( sort keys %disques ) { print "\n"; print ""; print ""; print ""; print ""; print ""; print ""; print ""; if ( ( "$disques{$clef}{DEVTYPE}" eq "USB" ) ||("$disques{$clef}{DEVTYPE}" eq "FireWire" ) ) { my %disque = %{$disques{$clef}}; my $options= OptionMenu(\%disque) || ""; print ""; } else { print ""; } print "\n"; } print "
$tr_dev$tr_mount$tr_fstab$tr_uuid$tr_label$tr_fs_type$tr_device_type$tr_action
$disques{$clef}{dev} "; if ($disques{$clef}{mounted} eq "no") {print $tr_no;} else {print $disques{$clef}{mounted}; } print ""; if ($disques{$clef}{fstab} eq "yes") {print $tr_yes;} elsif ($disques{$clef}{fstab} eq "no") {print $tr_no;} else {print $disques{$clef}{fstab};} print "$disques{$clef}{UUID}$disques{$clef}{LABEL}$disques{$clef}{FSTYPE}$disques{$clef}{DEVTYPE}$options 
\n"; print $q->hr; my $OUT= knowndevices(); print $OUT; esmith::cgi::genFooter ($q); } ## # # sub fstab # ## sub showfstab ($) { my @sensorOutput = `cat /etc/fstab`; my ($q) = @_; # esmith::cgi ($q, \%conf, 'Sensor Information'); print $q->hr; print $q->p ($q->pre ("@sensorOutput")); # esmith::cgi::genFooter ($q); } ## # # sub liste des devices # return hashe with data to create the html table ## sub subdevices ($) { #my %mounted=`mount`; my $mounted=`mount`; my @fstab= `cat /etc/fstab`; my @blkid= `/sbin/blkid -c /dev/null `; my @swap= `cat /proc/swaps|grep '/' |cut -f1`; my @lvscan = `/sbin/lvscan`; my %disques; my $i = 0; #my %hashes = (clef =>"valeur", clef2 => "valeur2", [%tablo], %table); #verif usb #for SME8: udevinfo -a -p /sys/block/sda #for SME9: udevadm info -a -p /sys/block/sda for (@blkid) { # chemin dev #$disques{$i}{dev}= $_ =~ /^(\/dev\/[a-z\-]{2,3}[0-9]{1}):/ ? $1 : "$tr_unknown"; $disques{$i}{dev}= $_ =~ /^(\/dev\/[a-z0-9\-_\/]{2,}):/ ? $1 : "$tr_unknown"; my $oridevice = $disques{$i}{dev}; # for lvm /dev/mapper/main-root; change to /dev/main/root $disques{$i}{dev}= $disques{$i}{dev} =~ /^\/dev\/mapper\/([a-z0-9_]{2,})-([a-z0-9_]{2,})$/ ? "/dev/$1/$2" : $disques{$i}{dev}; my $device = $disques{$i}{dev}; my $good = ""; $good = `/bin/readlink -f $device` if $device ne $oridevice; # nom disque sda (not partition but hard drive) $disques{$i}{name}= $_ =~ /^\/dev\/([a-z\-]{2,})[0-9]*:/ ? $1 : "$tr_unknown"; #$disques{$i}{name}= $_ =~ /^\/dev\/([a-z0-9\-_\/]{2,}):/ ? $1 : "$tr_unknown"; # UUID $disques{$i}{UUID}= $_ =~ /UUID="([0-9a-zA-Z\-]*)"/ ? $1 : "$tr_unknown"; # label for partition $disques{$i}{LABEL}= $_ =~ /LABEL="([a-zA-Z0-9_\-]*)"/ ? $1 : "$tr_unknown"; # mouted or not $disques{$i}{mounted}= $mounted =~ /$device on ([\/\-a-zA-Z0-9_]+) / ? $1 : "no" ; $disques{$i}{mounted}= $mounted =~ /$oridevice on ([\/\-a-zA-Z0-9_]+) / ? $1 : "no" if $oridevice ne $device; # the one under does not work with regex , do not know why : map (/$good/ , @swap) ,maybe the / in the device path $disques{$i}{mounted}= grep($good , @swap) ? 'swap' : "no" if $device =~ /swap/; # is it in fstab $disques{$i}{fstab}= map ( /$device/, @fstab)? "yes" : "no"; my $UUID= $disques{$i}{UUID}; my $label= $disques{$i}{LABEL}; if ( ($disques{$i}{fstab} eq "no") && (! $UUID eq "") ) {$disques{$i}{fstab}= map ( /$UUID/, @fstab)? "yes" : "no";} if ( ($disques{$i}{fstab} eq "no") && (! $label eq "") ) {$disques{$i}{fstab}= map ( /$label/, @fstab)? "yes" : "no";} # file system type ext2 ext3 swap vfat ... if ( $_ =~ / SEC_TYPE="([a-zA-Z0-9_\-]*)"/ ) {$disques{$i}{FSTYPE}= $_ =~ / SEC_TYPE="([a-zA-Z0-9_\-]*)"/ ? $1 : "$tr_unknown";} else {$disques{$i}{FSTYPE}= $_ =~ / TYPE="([a-zA-Z0-9_\-]*)"/ ? $1 : "$tr_unknown";} # device type : usb ide sata/scsi $disques{$i}{DEVTYPE}= "$tr_unknown"; my $name = $disques{$i}{name}; # for SME8: my $udevinfo = `/usr/bin/udevinfo -a -p /sys/block/$name` ; # for SME9: my $udevinfo = `/sbin/udevadm info -a -p /sys/block/$name` ; # small change in udevinfo between rhel 4 and 5 $disques{$i}{DEVTYPE}= ""; #LVM $disques{$i}{DEVTYPE}= map ( /$device/, @lvscan)? "LVM" : ""; #RAID my $infobis=`cat /proc/mdstat |grep -o md[0-9]*`; $disques{$i}{DEVTYPE}= "RAID" if ($infobis =~ /$name/); # real device if ( $disques{$i}{DEVTYPE} eq "" ) { my $udevinfo = `/sbin/udevadm info -p /sys/block/$name -q env |grep "ID_BUS="|sed -e 's/^ID_//g'` ; if ($udevinfo =~ /BUS=ide/) { $disques{$i}{DEVTYPE}= "IDE"; } elsif ($udevinfo =~ /BUS=usb/) { $disques{$i}{DEVTYPE}= "USB"; } elsif ($udevinfo =~ /\/fw-host[0-9]+\//) { $disques{$i}{DEVTYPE}= "FireWire"; } elsif ($udevinfo =~ /BUS=scsi/) { $disques{$i}{DEVTYPE}= "SCSI_SATA"; } elsif ($udevinfo =~ /couldn\'t get the class device/) { $disques{$i}{DEVTYPE}= "$tr_unknown"; } else { my $infobis=`cat /proc/mdstat |grep -o md[0-9]*`; if ($infobis =~ /$name/) { $disques{$i}{DEVTYPE}= "RAID"; } else { $disques{$i}{DEVTYPE}= $udevinfo; } } } $i++; } return %disques; } ## # # sub liste des devices # return hashe with data to create the html table ## sub OptionMenu ($) { my(%disque) = %{$_[0]}; my $option; #if ($disque{UUID} eq $tr_unknown ) # { # $option .= " $tr_uuidgenerate "; # } # else # { if ( !db_get_type(\%usbdisks, $disque{UUID}) ) { $option .= " $tr_add "; } if ($disque{fstab} eq "yes") { if ($disque{mounted} eq "no") {$option .=" Mount " } else {$option .=" Umount " } } # } return $option ; } ## # # sub liste des devices # return hashe with data to create the html table ## sub GeneralMenu ($) { my ($q) = @_; print $q->table ({border => 1, cellspacing => 1, cellpadding => 4}); print $q->Tr ( esmith::cgi::genSmallCell ($q, "$tr_menu_accueil"), esmith::cgi::genSmallCell ($q, "$tr_menu_config"), esmith::cgi::genSmallCell ($q, "[$tr_aide]") ); print '
'; return ; } ## # # sub liste des devices # return hashe with data to create the html table ## sub USBModifyConfig ($$) { my ($q, $msg) = @_; esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'USBDisks : '.$tr_titre_config.'

'); GeneralMenu ($q); print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); print $q->table ({border => 1, cellspacing => 1, cellpadding => 4}); print $q->Tr (esmith::cgi::genSmallCell ($q, "$tr_frequence :"), esmith::cgi::genSmallCell ($q, "")); print $q->Tr (esmith::cgi::genSmallCell ($q, "$tr_status :"), esmith::cgi::genSmallCell ($q, "