[PATCHv2,02/12] extrahd.cgi: Refactor code to use new introduced perl functions.
Commit Message
This also gets rid of allmost all unsafe system calls.
Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
---
html/cgi-bin/extrahd.cgi | 336 ++++++++++++++++++++++++---------------
1 file changed, 208 insertions(+), 128 deletions(-)
Comments
Reviewed-by: Bernhard Bitsch <bbitsch@ipfire.org>
Am 01.08.2023 um 17:48 schrieb Stefan Schantl:
> This also gets rid of allmost all unsafe system calls.
>
> Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
> ---
> 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 5aadf15e8..bafdb9fc9 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";
>
> my %extrahdsettings = ();
> -my $message = "";
> my $errormessage = "";
> -my $size = "";
> -my $ok = "true";
> -my @tmp = ();
> -my @tmpline = ();
> -my $tmpentry = "";
> -my @devices = ();
> -my @deviceline = ();
> -my $deviceentry = "";
> -my @scans = ();
> -my @scanline = ();
> -my $scanentry = "";
> -my @partitions = ();
> -my @partitionline = ();
> -my $partitionentry = "";
> +
> +# SYSFS directory which contains all block device data.
> +my $sysfs_block_dir = "/sys/class/block";
> +
> +# Array which contains the valid mount directories.
> +# Only mounting to subdirectories inside them is allowed.
> +my @valid_mount_dirs = (
> + "/data",
> + "/media",
> + "/mnt",
> +);
> +
> +# Array which contains the supported file systems.
> +my @supported_filesystems = (
> + "auto",
> + "ext3",
> + "ext4",
> + "xfs",
> + "vfat",
> + "ntfs-3g"
> +);
> +
> +# Grab all available block devices.
> +my @devices = &get_block_devices();
> +
> +# Grab all known UUID's.
> +my %uuids = &get_uuids();
> +
> +# Grab all mountpoints.
> +my %mountpoints = &get_mountpoints();
> +
> +# Omit the file system types of the mounted devices.
> +my %filesystems = &get_mountedfs();
> +
> +# Gather all used swap devices.
> +my @swaps = &get_swaps();
> +
> +# The config file which contains the configured devices.
> my $devicefile = "/var/ipfire/extrahd/devices";
> -my $scanfile = "/var/ipfire/extrahd/scan";
> -my $partitionsfile = "/var/ipfire/extrahd/partitions";
>
> #workaround to suppress a warning when a variable is used only once
> my @dummy = ( ${Header::colourgreen}, ${Header::colourred} );
> undef (@dummy);
>
> -&General::system("/usr/local/bin/extrahdctrl", "scanhd", "ide");
> -&General::system("/usr/local/bin/extrahdctrl", "scanhd", "partitions");
> -
> &Header::showhttpheaders();
>
> ### Values that have to be initialized
> @@ -65,7 +83,6 @@ $extrahdsettings{'DEVICE'} = '';
> $extrahdsettings{'ACTION'} = '';
> $extrahdsettings{'UUID'} = '';
>
> -&General::readhash("${General::swroot}/extrahd/settings", \%extrahdsettings);
> &Header::getcgihash(\%extrahdsettings);
>
> &Header::openpage('ExtraHD', 1, '');
> @@ -74,52 +91,88 @@ $extrahdsettings{'UUID'} = '';
> ############################################################################################################################
> ############################################################################################################################
>
> -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 = <FILE>;
> + my @devices = <FILE>;
> close FILE;
> - foreach $deviceentry (sort @devices)
> - {
> - @deviceline = split( /\;/, $deviceentry );
> - if ( "$extrahdsettings{'PATH'}" eq "$deviceline[2]" ) {
> - $ok = "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) = split( /\;/, $entry );
> +
> + # Check if the path is allready used.
> + if ( "$extrahdsettings{'PATH'}" eq "$path" ) {
> $errormessage = "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'DEVICE'} $Lang::tr{'extrahd to'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd because there is already a device mounted'}.";
> }
> - if ( "$extrahdsettings{'PATH'}" eq "/" ) {
> - $ok = "false";
> - $errormessage = "$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 = "$extrahdsettings{'DEVICE'} is allready mounted.";
> }
> }
>
> - if ( "$ok" eq "true" ) {
> + # Check if a valid mount path has been choosen.
> + unless(&is_valid_dir("$extrahdsettings{'PATH'}")) {
> + $errormessage = "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'DEVICE'} $Lang::tr{'extrahd to root'}.";
> + }
> +
> + # Check if the given path allready is mounted somewhere.
> + if(&is_mounted("$extrahdsettings{'PATH'}")) {
> + $errormessage = "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'DEVICE'} $Lang::tr{'extrahd to'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd because 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 <<END
> -UUID=$extrahdsettings{'UUID'};$extrahdsettings{'FS'};$extrahdsettings{'PATH'};
> -END
> -;
> - &General::system("/usr/local/bin/extrahdctrl", "mount", "$extrahdsettings{'PATH'}");
> +
> + # Write the config line.
> + print FILE "UUID=$extrahdsettings{'UUID'};$extrahdsettings{'FS'};$extrahdsettings{'PATH'};\n";
> +
> + # Close file handle.
> + close(FILE);
> +
> + # Call helper binary to mount the device.
> + &General::system("/usr/local/bin/extrahdctrl", "mount", "$extrahdsettings{'PATH'}");
> }
> -}
> -elsif ($extrahdsettings{'ACTION'} eq $Lang::tr{'delete'})
> -{
> - if ( ! &General::system("/usr/local/bin/extrahdctrl", "umount", "$extrahdsettings{'PATH'}")) {
> - open( FILE, "< $devicefile" ) or die "Unable to read $devicefile";
> - @tmp = <FILE>;
> - close FILE;
> - open( FILE, "> $devicefile" ) or die "Unable to write $devicefile";
> - foreach $deviceentry (sort @tmp)
> - {
> - @tmpline = 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 = <FILE>;
> +
> + # 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) = 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 = "$Lang::tr{'extrahd cant umount'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd maybe the device is in use'}?";
> }
> +
> + # Close file handle.
> + close(FILE);
> }
>
> if ($errormessage) {
> @@ -132,34 +185,38 @@ if ($errormessage) {
> ############################################################################################################################
> ############################################################################################################################
>
> - open( FILE, "< $devicefile" ) or die "Unable to read $devicefile";
> - @devices = <FILE>;
> - close FILE;
> print <<END
> <table border='0' width='600' cellspacing="0">
> END
> ;
> - foreach $deviceentry (sort @devices)
> - {
> - @deviceline = split( /\;/, $deviceentry );
> - my $color="$Header::colourred";
> + # Re-read mountpoints.
> + %mountpoints = &get_mountpoints();
>
> - # Use safe system_output to get mountpoint details.
> - my @mountpoint = &General::system_output("/bin/mountpoint", "$deviceline[2]");
> + # Read-in the device config file.
> + open( FILE, "< $devicefile" ) or die "Unable to read $devicefile";
> + my @configfile = <FILE>;
> + close FILE;
> +
> + # Loop through the file content.
> + foreach my $entry (sort @configfile) {
> + my ($uuid, $fs, $path) = split( /\;/, $entry );
> + my $color="$Header::colourred";
>
> - if ( ! grep(/not/, @mountpoint)) {
> + # Check if the device is currently mounted.
> + if (&is_mounted($path)) {
> $color=$Header::colourgreen;
> }
> +
> print <<END
> <tr><td colspan="4"> </td></tr>
> - <tr><td align='left'><font color=$color><b>$deviceline[0]</b></font></td>
> - <td align='left'>$deviceline[1]</td>
> - <td align='left'>$deviceline[2]</td>
> + <tr><td align='left'><font color=$color><b>$uuid</b></font></td>
> + <td align='left'>$fs</td>
> + <td align='left'>$path</td>
> <td align='center'>
> <form method='post' action='$ENV{'SCRIPT_NAME'}'>
> - <input type='hidden' name='DEVICE' value='$deviceline[0]' />
> - <input type='hidden' name='FS' value='$deviceline[1]' />
> - <input type='hidden' name='PATH' value='$deviceline[2]' />
> + <input type='hidden' name='DEVICE' value='$uuid' />
> + <input type='hidden' name='FS' value='$fs' />
> + <input type='hidden' name='PATH' value='$path' />
> <input type='hidden' name='ACTION' value='$Lang::tr{'delete'}' />
> <input type='image' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' src='/images/delete.gif' />
> </form></td></tr>
> @@ -170,78 +227,101 @@ END
> </table>
> END
> ;
> +
> &Header::openbox('100%', 'center', $Lang::tr{'extrahd detected drives'});
> print <<END
> <table border='0' width='600' cellspacing="0">
> END
> ;
> - open( FILE, "< $scanfile" ) or die "Unable to read $scanfile";
> - @scans = <FILE>;
> - close FILE;
> - open( FILE, "< $partitionsfile" ) or die "Unable to read $partitionsfile";
> - @partitions = <FILE>;
> - close FILE;
> - foreach $scanentry (sort @scans)
> - {
> - @scanline = split( /\;/, $scanentry );
> - # remove wrong entries like usb controller name
> - if ($scanline[1] ne "\n")
> - {
> - print <<END
> - <tr><td colspan="5"> </td></tr>
> - <tr><td align='left' colspan="2"><b>/dev/$scanline[0]</b></td>
> - <td align='center' colspan="2">$scanline[1]</td>
> + foreach my $device (sort @devices) {
> + # Grab the device details.
> + my $vendor = &get_device_vendor($device);
> + my $model = &get_device_model($device);
> + my $bsize = &get_device_size($device);
> +
> + # Convert size into human-readable format.
> + my $size = &General::formatBytes($bsize);
> +
> + print <<END
> + <tr><td colspan="5"> </td></tr>
> + <tr><td align='left' colspan="2"><b>/dev/$device</b></td>
> + <td align='center' colspan="2">$vendor $model</td>
> +
> + <td align='center'>$Lang::tr{'size'} $size</td>
> + <td> </td></tr>
> + <tr><td colspan="5"> </td></tr>
> END
> ;
>
> - }
> - foreach $partitionentry (sort @partitions)
> - {
> - @partitionline = split( /\;/, $partitionentry );
> - if ( "$partitionline[0]" eq "$scanline[0]" ) {
> - $size = int($partitionline[1] / 1024);
> - print <<END
> - <td align='center'>$Lang::tr{'size'} $size MB</td>
> - <td> </td></tr>
> - <tr><td colspan="5"> </td></tr>
> + # Grab the known partitions of the current block device.
> + my @partitions = &get_device_partitions($device);
> +
> + foreach my $partition (@partitions) {
> + my $disabled;
> +
> + # Omit the partition size.
> + my $bsize = &get_device_size($partition);
> +
> + # Convert into human-readable format.
> + my $size = &General::formatBytes($bsize);
> +
> + # Get the mountpoint.
> + my $mountpoint = $mountpoints{$partition};
> +
> + if ($mountpoint eq "/" or $mountpoint =~ "^/boot") {
> + $disabled = "disabled";
> + } elsif(&is_mounted($mountpoint)) {
> + $disabled = "disabled";
> + }
> +
> + # Omit the used filesystem.
> + my $fs = $filesystems{$partition};
> +
> + # Check if the device is used as swap.
> + if (&is_swap($partition)) {
> + $disabled = "disabled";
> + $mountpoint = "swap";
> + }
> +
> + print <<END
> +
> + <form method='post' action='$ENV{'SCRIPT_NAME'}'>
> + <tr><td align="left" colspan=5><strong>UUID=$uuids{$partition}</strong></td></tr>
> + <tr>
> + <td align="list">/dev/$partition</td>
> + <td align="center">$Lang::tr{'size'} $size</td>
> + <td align="center"><select name="FS" $disabled>
> END
> ;
> - }
> - }
> + # Loop through the array of supported filesystems.
> + foreach my $filesystem (@supported_filesystems) {
> + my $selected;
>
> - foreach $partitionentry (sort @partitions)
> - {
> - @partitionline = split( /\;/, $partitionentry );
> - if (( "$partitionline[0]" =~ /^$scanline[0]/ ) && !( "$partitionline[2]" eq "" )) {
> - $size = int($partitionline[1] / 1024);
> - print <<END
> - <form method='post' action='$ENV{'SCRIPT_NAME'}'>
> - <tr><td align="left" colspan=5><strong>UUID=$partitionline[2]</strong></td></tr>
> - <tr>
> - <td align="list">/dev/$partitionline[0]</td>
> - <td align="center">$Lang::tr{'size'} $size MB</td>
> - <td align="center"><select name="FS">
> - <option value="auto">auto</option>
> - <option value="ext3">ext3</option>
> - <option value="ext4">ext4</option>
> - <option value="reiserfs">reiserfs</option>
> - <option value="vfat">fat</option>
> - <option value="ntfs-3g">ntfs (experimental)</option>
> - </select></td>
> - <td align="center"><input type='text' name='PATH' value=/mnt/harddisk /></td>
> + # Mark the used filesystem as selected.
> + if ($filesystem eq $fs) {
> + $selected = "selected";
> + }
> +
> + print "<option value='$filesystem' $selected>$filesystem</option>\n";
> + }
> +
> + print <<END
> + </select></td>
> + <td align="center"><input type='text' name='PATH' value=$mountpoint $disabled></td>
> <td align="center">
> - <input type='hidden' name='DEVICE' value='$partitionline[0]' />
> - <input type='hidden' name='UUID' value='$partitionline[2]' />
> + <input type='hidden' name='DEVICE' value='/dev/$partition' />
> + <input type='hidden' name='UUID' value='$uuids{$partition}' />
> <input type='hidden' name='ACTION' value='$Lang::tr{'add'}' />
> - <input type='image' alt='$Lang::tr{'add'}' title='$Lang::tr{'add'}' src='/images/add.gif' />
> - </form></td></tr>
> END
> -;
> +; unless($disabled) {
> + print"<input type='image' alt='$Lang::tr{'add'}' title='$Lang::tr{'add'}' src='/images/add.gif' />\n";
> + }
>
> + print <<END
> + </form></td></tr>
> END
> -;
> - }
> - }
> +; }
> +
> }
>
> print <<END
@@ -29,33 +29,51 @@ require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
my %extrahdsettings = ();
-my $message = "";
my $errormessage = "";
-my $size = "";
-my $ok = "true";
-my @tmp = ();
-my @tmpline = ();
-my $tmpentry = "";
-my @devices = ();
-my @deviceline = ();
-my $deviceentry = "";
-my @scans = ();
-my @scanline = ();
-my $scanentry = "";
-my @partitions = ();
-my @partitionline = ();
-my $partitionentry = "";
+
+# SYSFS directory which contains all block device data.
+my $sysfs_block_dir = "/sys/class/block";
+
+# Array which contains the valid mount directories.
+# Only mounting to subdirectories inside them is allowed.
+my @valid_mount_dirs = (
+ "/data",
+ "/media",
+ "/mnt",
+);
+
+# Array which contains the supported file systems.
+my @supported_filesystems = (
+ "auto",
+ "ext3",
+ "ext4",
+ "xfs",
+ "vfat",
+ "ntfs-3g"
+);
+
+# Grab all available block devices.
+my @devices = &get_block_devices();
+
+# Grab all known UUID's.
+my %uuids = &get_uuids();
+
+# Grab all mountpoints.
+my %mountpoints = &get_mountpoints();
+
+# Omit the file system types of the mounted devices.
+my %filesystems = &get_mountedfs();
+
+# Gather all used swap devices.
+my @swaps = &get_swaps();
+
+# The config file which contains the configured devices.
my $devicefile = "/var/ipfire/extrahd/devices";
-my $scanfile = "/var/ipfire/extrahd/scan";
-my $partitionsfile = "/var/ipfire/extrahd/partitions";
#workaround to suppress a warning when a variable is used only once
my @dummy = ( ${Header::colourgreen}, ${Header::colourred} );
undef (@dummy);
-&General::system("/usr/local/bin/extrahdctrl", "scanhd", "ide");
-&General::system("/usr/local/bin/extrahdctrl", "scanhd", "partitions");
-
&Header::showhttpheaders();
### Values that have to be initialized
@@ -65,7 +83,6 @@ $extrahdsettings{'DEVICE'} = '';
$extrahdsettings{'ACTION'} = '';
$extrahdsettings{'UUID'} = '';
-&General::readhash("${General::swroot}/extrahd/settings", \%extrahdsettings);
&Header::getcgihash(\%extrahdsettings);
&Header::openpage('ExtraHD', 1, '');
@@ -74,52 +91,88 @@ $extrahdsettings{'UUID'} = '';
############################################################################################################################
############################################################################################################################
-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 = <FILE>;
+ my @devices = <FILE>;
close FILE;
- foreach $deviceentry (sort @devices)
- {
- @deviceline = split( /\;/, $deviceentry );
- if ( "$extrahdsettings{'PATH'}" eq "$deviceline[2]" ) {
- $ok = "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) = split( /\;/, $entry );
+
+ # Check if the path is allready used.
+ if ( "$extrahdsettings{'PATH'}" eq "$path" ) {
$errormessage = "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'DEVICE'} $Lang::tr{'extrahd to'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd because there is already a device mounted'}.";
}
- if ( "$extrahdsettings{'PATH'}" eq "/" ) {
- $ok = "false";
- $errormessage = "$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 = "$extrahdsettings{'DEVICE'} is allready mounted.";
}
}
- if ( "$ok" eq "true" ) {
+ # Check if a valid mount path has been choosen.
+ unless(&is_valid_dir("$extrahdsettings{'PATH'}")) {
+ $errormessage = "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'DEVICE'} $Lang::tr{'extrahd to root'}.";
+ }
+
+ # Check if the given path allready is mounted somewhere.
+ if(&is_mounted("$extrahdsettings{'PATH'}")) {
+ $errormessage = "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'DEVICE'} $Lang::tr{'extrahd to'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd because 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 <<END
-UUID=$extrahdsettings{'UUID'};$extrahdsettings{'FS'};$extrahdsettings{'PATH'};
-END
-;
- &General::system("/usr/local/bin/extrahdctrl", "mount", "$extrahdsettings{'PATH'}");
+
+ # Write the config line.
+ print FILE "UUID=$extrahdsettings{'UUID'};$extrahdsettings{'FS'};$extrahdsettings{'PATH'};\n";
+
+ # Close file handle.
+ close(FILE);
+
+ # Call helper binary to mount the device.
+ &General::system("/usr/local/bin/extrahdctrl", "mount", "$extrahdsettings{'PATH'}");
}
-}
-elsif ($extrahdsettings{'ACTION'} eq $Lang::tr{'delete'})
-{
- if ( ! &General::system("/usr/local/bin/extrahdctrl", "umount", "$extrahdsettings{'PATH'}")) {
- open( FILE, "< $devicefile" ) or die "Unable to read $devicefile";
- @tmp = <FILE>;
- close FILE;
- open( FILE, "> $devicefile" ) or die "Unable to write $devicefile";
- foreach $deviceentry (sort @tmp)
- {
- @tmpline = 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 = <FILE>;
+
+ # 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) = 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 = "$Lang::tr{'extrahd cant umount'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd maybe the device is in use'}?";
}
+
+ # Close file handle.
+ close(FILE);
}
if ($errormessage) {
@@ -132,34 +185,38 @@ if ($errormessage) {
############################################################################################################################
############################################################################################################################
- open( FILE, "< $devicefile" ) or die "Unable to read $devicefile";
- @devices = <FILE>;
- close FILE;
print <<END
<table border='0' width='600' cellspacing="0">
END
;
- foreach $deviceentry (sort @devices)
- {
- @deviceline = split( /\;/, $deviceentry );
- my $color="$Header::colourred";
+ # Re-read mountpoints.
+ %mountpoints = &get_mountpoints();
- # Use safe system_output to get mountpoint details.
- my @mountpoint = &General::system_output("/bin/mountpoint", "$deviceline[2]");
+ # Read-in the device config file.
+ open( FILE, "< $devicefile" ) or die "Unable to read $devicefile";
+ my @configfile = <FILE>;
+ close FILE;
+
+ # Loop through the file content.
+ foreach my $entry (sort @configfile) {
+ my ($uuid, $fs, $path) = split( /\;/, $entry );
+ my $color="$Header::colourred";
- if ( ! grep(/not/, @mountpoint)) {
+ # Check if the device is currently mounted.
+ if (&is_mounted($path)) {
$color=$Header::colourgreen;
}
+
print <<END
<tr><td colspan="4"> </td></tr>
- <tr><td align='left'><font color=$color><b>$deviceline[0]</b></font></td>
- <td align='left'>$deviceline[1]</td>
- <td align='left'>$deviceline[2]</td>
+ <tr><td align='left'><font color=$color><b>$uuid</b></font></td>
+ <td align='left'>$fs</td>
+ <td align='left'>$path</td>
<td align='center'>
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
- <input type='hidden' name='DEVICE' value='$deviceline[0]' />
- <input type='hidden' name='FS' value='$deviceline[1]' />
- <input type='hidden' name='PATH' value='$deviceline[2]' />
+ <input type='hidden' name='DEVICE' value='$uuid' />
+ <input type='hidden' name='FS' value='$fs' />
+ <input type='hidden' name='PATH' value='$path' />
<input type='hidden' name='ACTION' value='$Lang::tr{'delete'}' />
<input type='image' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' src='/images/delete.gif' />
</form></td></tr>
@@ -170,78 +227,101 @@ END
</table>
END
;
+
&Header::openbox('100%', 'center', $Lang::tr{'extrahd detected drives'});
print <<END
<table border='0' width='600' cellspacing="0">
END
;
- open( FILE, "< $scanfile" ) or die "Unable to read $scanfile";
- @scans = <FILE>;
- close FILE;
- open( FILE, "< $partitionsfile" ) or die "Unable to read $partitionsfile";
- @partitions = <FILE>;
- close FILE;
- foreach $scanentry (sort @scans)
- {
- @scanline = split( /\;/, $scanentry );
- # remove wrong entries like usb controller name
- if ($scanline[1] ne "\n")
- {
- print <<END
- <tr><td colspan="5"> </td></tr>
- <tr><td align='left' colspan="2"><b>/dev/$scanline[0]</b></td>
- <td align='center' colspan="2">$scanline[1]</td>
+ foreach my $device (sort @devices) {
+ # Grab the device details.
+ my $vendor = &get_device_vendor($device);
+ my $model = &get_device_model($device);
+ my $bsize = &get_device_size($device);
+
+ # Convert size into human-readable format.
+ my $size = &General::formatBytes($bsize);
+
+ print <<END
+ <tr><td colspan="5"> </td></tr>
+ <tr><td align='left' colspan="2"><b>/dev/$device</b></td>
+ <td align='center' colspan="2">$vendor $model</td>
+
+ <td align='center'>$Lang::tr{'size'} $size</td>
+ <td> </td></tr>
+ <tr><td colspan="5"> </td></tr>
END
;
- }
- foreach $partitionentry (sort @partitions)
- {
- @partitionline = split( /\;/, $partitionentry );
- if ( "$partitionline[0]" eq "$scanline[0]" ) {
- $size = int($partitionline[1] / 1024);
- print <<END
- <td align='center'>$Lang::tr{'size'} $size MB</td>
- <td> </td></tr>
- <tr><td colspan="5"> </td></tr>
+ # Grab the known partitions of the current block device.
+ my @partitions = &get_device_partitions($device);
+
+ foreach my $partition (@partitions) {
+ my $disabled;
+
+ # Omit the partition size.
+ my $bsize = &get_device_size($partition);
+
+ # Convert into human-readable format.
+ my $size = &General::formatBytes($bsize);
+
+ # Get the mountpoint.
+ my $mountpoint = $mountpoints{$partition};
+
+ if ($mountpoint eq "/" or $mountpoint =~ "^/boot") {
+ $disabled = "disabled";
+ } elsif(&is_mounted($mountpoint)) {
+ $disabled = "disabled";
+ }
+
+ # Omit the used filesystem.
+ my $fs = $filesystems{$partition};
+
+ # Check if the device is used as swap.
+ if (&is_swap($partition)) {
+ $disabled = "disabled";
+ $mountpoint = "swap";
+ }
+
+ print <<END
+
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <tr><td align="left" colspan=5><strong>UUID=$uuids{$partition}</strong></td></tr>
+ <tr>
+ <td align="list">/dev/$partition</td>
+ <td align="center">$Lang::tr{'size'} $size</td>
+ <td align="center"><select name="FS" $disabled>
END
;
- }
- }
+ # Loop through the array of supported filesystems.
+ foreach my $filesystem (@supported_filesystems) {
+ my $selected;
- foreach $partitionentry (sort @partitions)
- {
- @partitionline = split( /\;/, $partitionentry );
- if (( "$partitionline[0]" =~ /^$scanline[0]/ ) && !( "$partitionline[2]" eq "" )) {
- $size = int($partitionline[1] / 1024);
- print <<END
- <form method='post' action='$ENV{'SCRIPT_NAME'}'>
- <tr><td align="left" colspan=5><strong>UUID=$partitionline[2]</strong></td></tr>
- <tr>
- <td align="list">/dev/$partitionline[0]</td>
- <td align="center">$Lang::tr{'size'} $size MB</td>
- <td align="center"><select name="FS">
- <option value="auto">auto</option>
- <option value="ext3">ext3</option>
- <option value="ext4">ext4</option>
- <option value="reiserfs">reiserfs</option>
- <option value="vfat">fat</option>
- <option value="ntfs-3g">ntfs (experimental)</option>
- </select></td>
- <td align="center"><input type='text' name='PATH' value=/mnt/harddisk /></td>
+ # Mark the used filesystem as selected.
+ if ($filesystem eq $fs) {
+ $selected = "selected";
+ }
+
+ print "<option value='$filesystem' $selected>$filesystem</option>\n";
+ }
+
+ print <<END
+ </select></td>
+ <td align="center"><input type='text' name='PATH' value=$mountpoint $disabled></td>
<td align="center">
- <input type='hidden' name='DEVICE' value='$partitionline[0]' />
- <input type='hidden' name='UUID' value='$partitionline[2]' />
+ <input type='hidden' name='DEVICE' value='/dev/$partition' />
+ <input type='hidden' name='UUID' value='$uuids{$partition}' />
<input type='hidden' name='ACTION' value='$Lang::tr{'add'}' />
- <input type='image' alt='$Lang::tr{'add'}' title='$Lang::tr{'add'}' src='/images/add.gif' />
- </form></td></tr>
END
-;
+; unless($disabled) {
+ print"<input type='image' alt='$Lang::tr{'add'}' title='$Lang::tr{'add'}' src='/images/add.gif' />\n";
+ }
+ print <<END
+ </form></td></tr>
END
-;
- }
- }
+; }
+
}
print <<END