From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefan Schantl To: development@lists.ipfire.org Subject: [PATCH 2/8] extrahd.cgi: Refactor code to use new introduced perl functions. Date: Fri, 23 Jun 2023 06:01:18 +0200 Message-ID: <20230623040124.3826-2-stefan.schantl@ipfire.org> In-Reply-To: <20230623040124.3826-1-stefan.schantl@ipfire.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3818257272030462405==" List-Id: --===============3818257272030462405== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable This also gets rid of allmost all unsafe system calls. Signed-off-by: Stefan Schantl --- html/cgi-bin/extrahd.cgi | 336 ++++++++++++++++++++++++--------------- 1 file changed, 208 insertions(+), 128 deletions(-) diff --git a/html/cgi-bin/extrahd.cgi b/html/cgi-bin/extrahd.cgi index 44065a8a1..117890f08 100644 --- a/html/cgi-bin/extrahd.cgi +++ b/html/cgi-bin/extrahd.cgi @@ -29,33 +29,51 @@ require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; =20 my %extrahdsettings =3D (); -my $message =3D ""; my $errormessage =3D ""; -my $size =3D ""; -my $ok =3D "true"; -my @tmp =3D (); -my @tmpline =3D (); -my $tmpentry =3D ""; -my @devices =3D (); -my @deviceline =3D (); -my $deviceentry =3D ""; -my @scans =3D (); -my @scanline =3D (); -my $scanentry =3D ""; -my @partitions =3D (); -my @partitionline =3D (); -my $partitionentry =3D ""; + +# SYSFS directory which contains all block device data. +my $sysfs_block_dir =3D "/sys/class/block"; + +# Array which contains the valid mount directories. +# Only mounting to subdirectories inside them is allowed. +my @valid_mount_dirs =3D ( + "/data", + "/media", + "/mnt", +); + +# Array which contains the supported file systems. +my @supported_filesystems =3D ( + "auto", + "ext3", + "ext4", + "xfs", + "vfat", + "ntfs-3g" +); + +# Grab all available block devices. +my @devices =3D &get_block_devices(); + +# Grab all known UUID's. +my %uuids =3D &get_uuids(); + +# Grab all mountpoints. +my %mountpoints =3D &get_mountpoints(); + +# Omit the file system types of the mounted devices. +my %filesystems =3D &get_mountedfs(); + +# Gather all used swap devices. +my @swaps =3D &get_swaps(); + +# The config file which contains the configured devices. my $devicefile =3D "/var/ipfire/extrahd/devices"; -my $scanfile =3D "/var/ipfire/extrahd/scan"; -my $partitionsfile =3D "/var/ipfire/extrahd/partitions"; =20 #workaround to suppress a warning when a variable is used only once my @dummy =3D ( ${Header::colourgreen}, ${Header::colourred} ); undef (@dummy); =20 -&General::system("/usr/local/bin/extrahdctrl", "scanhd", "ide"); -&General::system("/usr/local/bin/extrahdctrl", "scanhd", "partitions"); - &Header::showhttpheaders(); =20 ### Values that have to be initialized @@ -65,7 +83,6 @@ $extrahdsettings{'DEVICE'} =3D ''; $extrahdsettings{'ACTION'} =3D ''; $extrahdsettings{'UUID'} =3D ''; =20 -&General::readhash("${General::swroot}/extrahd/settings", \%extrahdsettings); &Header::getcgihash(\%extrahdsettings); =20 &Header::openpage('ExtraHD', 1, ''); @@ -74,52 +91,88 @@ $extrahdsettings{'UUID'} =3D ''; ############################################################################= ################################################ ############################################################################= ################################################ =20 -if ($extrahdsettings{'ACTION'} eq $Lang::tr{'add'}) -{ +# +## Add a new device. +# +if ($extrahdsettings{'ACTION'} eq $Lang::tr{'add'}) { + # Open device file for reading. open( FILE, "< $devicefile" ) or die "Unable to read $devicefile"; - @devices =3D ; + my @devices =3D ; close FILE; - foreach $deviceentry (sort @devices) - { - @deviceline =3D split( /\;/, $deviceentry ); - if ( "$extrahdsettings{'PATH'}" eq "$deviceline[2]" ) { - $ok =3D "false"; + + # Loop through the entries line-by-line. + foreach my $entry (sort @devices) { + # Split the line into pieces and assign nice variables. + my ($uuid, $fs, $path) =3D split( /\;/, $entry ); + + # Check if the path is allready used. + if ( "$extrahdsettings{'PATH'}" eq "$path" ) { $errormessage =3D "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'= DEVICE'} $Lang::tr{'extrahd to'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd b= ecause there is already a device mounted'}."; } - if ( "$extrahdsettings{'PATH'}" eq "/" ) { - $ok =3D "false"; - $errormessage =3D "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'= DEVICE'} $Lang::tr{'extrahd to root'}."; + + # Check if the uuid is allready used. + if ("$extrahdsettings{'DEVICE'} eq $uuid") { + $errormessage =3D "$extrahdsettings{'DEVICE'} is allready mounted."; } } =20 - if ( "$ok" eq "true" ) { + # Check if a valid mount path has been choosen.=20 + unless(&is_valid_dir("$extrahdsettings{'PATH'}")) { + $errormessage =3D "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'D= EVICE'} $Lang::tr{'extrahd to root'}."; + } + + # Check if the given path allready is mounted somewhere. + if(&is_mounted("$extrahdsettings{'PATH'}")) { + $errormessage =3D "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'D= EVICE'} $Lang::tr{'extrahd to'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd be= cause there is already a device mounted'}."; + } + + # Check if there was an error message. + unless($errormessage) { + # Re-open the device file for writing. open(FILE, ">> $devicefile" ) or die "Unable to write $devicefile"; - print FILE <; - close FILE; - open( FILE, "> $devicefile" ) or die "Unable to write $devicefile"; - foreach $deviceentry (sort @tmp) - { - @tmpline =3D split( /\;/, $deviceentry ); - if ( $tmpline[2] ne $extrahdsettings{'PATH'} ) - { - print FILE $deviceentry; - } + +# +# Remove an existing one. +# +} elsif ($extrahdsettings{'ACTION'} eq $Lang::tr{'delete'}) { + # Call helper binary to unmount the device. + &General::system("/usr/local/bin/extrahdctrl", "umount", "$extrahdsettings{= 'PATH'}"); + + # Open the device file for reading. + open(FILE, "< $devicefile" ) or die "Unable to read $devicefile"; + + # Read the file content into a temporary array. + my @tmp =3D ; + + # Close file handle. + close(FILE); + + # Re-open device file for writing. + open(FILE, "> $devicefile" ) or die "Unable to write $devicefile"; + + # Loop through the previous read file content. + foreach my $line (sort @tmp) { + # Split line content and assign nice variables. + my ($uuid, $fs, $path) =3D split( /\;/, $line ); + + # Write the line in case it does not contain our element to delete. + if ($path ne $extrahdsettings{'PATH'}) { + print FILE "$line"; } - close FILE; - } else { - $errormessage =3D "$Lang::tr{'extrahd cant umount'} $extrahdsettings{'PATH= '}$Lang::tr{'extrahd maybe the device is in use'}?"; } + + # Close file handle. + close(FILE); } =20 if ($errormessage) { @@ -132,34 +185,38 @@ if ($errormessage) { ############################################################################= ################################################ ############################################################################= ################################################ =20 - open( FILE, "< $devicefile" ) or die "Unable to read $devicefile"; - @devices =3D ; - close FILE; print < END ; - foreach $deviceentry (sort @devices) - { - @deviceline =3D split( /\;/, $deviceentry ); - my $color=3D"$Header::colourred"; + # Re-read mountpoints. + %mountpoints =3D &get_mountpoints(); =20 - # Use safe system_output to get mountpoint details. - my @mountpoint =3D &General::system_output("/bin/mountpoint", "$deviceline= [2]"); + # Read-in the device config file. + open( FILE, "< $devicefile" ) or die "Unable to read $devicefile"; + my @configfile =3D ; + close FILE; + + # Loop through the file content. + foreach my $entry (sort @configfile) { + my ($uuid, $fs, $path) =3D split( /\;/, $entry ); + my $color=3D"$Header::colourred"; =20 - if ( ! grep(/not/, @mountpoint)) { + # Check if the device is currently mounted. + if (&is_mounted($path)) { $color=3D$Header::colourgreen; } + print <  - $deviceline[0]<= /td> - $deviceline[1] - $deviceline[2] + $uuid + $fs + $path
- - - + + +
@@ -170,78 +227,101 @@ END END ; + &Header::openbox('100%', 'center', $Lang::tr{'extrahd detected drives'}); print < END ; - open( FILE, "< $scanfile" ) or die "Unable to read $scanfile"; - @scans =3D ; - close FILE; - open( FILE, "< $partitionsfile" ) or die "Unable to read $partitionsfile"; - @partitions =3D ; - close FILE; - foreach $scanentry (sort @scans) - { - @scanline =3D split( /\;/, $scanentry ); - # remove wrong entries like usb controller name - if ($scanline[1] ne "\n") - { - print <  - /dev/$scanline[0] - $scanline[1] + foreach my $device (sort @devices) { + # Grab the device details. + my $vendor =3D &get_device_vendor($device); + my $model =3D &get_device_model($device); + my $bsize =3D &get_device_size($device); + + # Convert size into human-readable format. + my $size =3D &General::formatBytes($bsize); + + print <  + /dev/$device + $vendor $model + + $Lang::tr{'size'} $size +   +   END ; =20 - } - foreach $partitionentry (sort @partitions) - { - @partitionline =3D split( /\;/, $partitionentry ); - if ( "$partitionline[0]" eq "$scanline[0]" ) { - $size =3D int($partitionline[1] / 1024); - print <$Lang::tr{'size'} $size MB -   -   + # Grab the known partitions of the current block device. + my @partitions =3D &get_device_partitions($device); + + foreach my $partition (@partitions) { + my $disabled; + + # Omit the partition size. + my $bsize =3D &get_device_size($partition); + + # Convert into human-readable format. + my $size =3D &General::formatBytes($bsize); + + # Get the mountpoint. + my $mountpoint =3D $mountpoints{$partition}; + + if ($mountpoint eq "/" or $mountpoint =3D~ "^/boot") { + $disabled =3D "disabled"; + } elsif(&is_mounted($mountpoint)) { + $disabled =3D "disabled"; + } + + # Omit the used filesystem. + my $fs =3D $filesystems{$partition}; + + # Check if the device is used as swap. + if (&is_swap($partition)) { + $disabled =3D "disabled"; + $mountpoint =3D "swap"; + } + + print < + UUID=3D$uuids{$partition} + + /dev/$partition + $Lang::tr{'size'} $size + - - - - - - - - + # Mark the used filesystem as selected. + if ($filesystem eq $fs) { + $selected =3D "selected"; + } + + print "\n"; + } + + print < + - - + + - - END -; +; unless($disabled) { + print"\n"; + } =20 + print < END -; - } - } +; } + } =20 print <