]>
git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - html/cgi-bin/extrahd.cgi
2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2011 IPFire Team <info@ipfire.org> #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
23 # enable only the following on debugging purpose
25 #use CGI::Carp 'fatalsToBrowser';
27 require '/var/ipfire/general-functions.pl' ;
28 require "${General::swroot}/lang.pl" ;
29 require "${General::swroot}/header.pl" ;
31 my %extrahdsettings = ();
33 my $errormessage = "" ;
46 my @partitionline = ();
47 my $partitionentry = "" ;
48 my $devicefile = "/var/ipfire/extrahd/devices" ;
49 my $scanfile = "/var/ipfire/extrahd/scan" ;
50 my $partitionsfile = "/var/ipfire/extrahd/partitions" ;
52 #workaround to suppress a warning when a variable is used only once
53 my @dummy = ( ${ Header
:: colourgreen
}, ${ Header
:: colourred
} );
56 & General
:: system ( "/usr/local/bin/extrahdctrl" , "scanhd" , "ide" );
57 & General
:: system ( "/usr/local/bin/extrahdctrl" , "scanhd" , "partitions" );
59 & Header
:: showhttpheaders
();
61 ### Values that have to be initialized
62 $extrahdsettings { 'PATH' } = '' ;
63 $extrahdsettings { 'FS' } = '' ;
64 $extrahdsettings { 'DEVICE' } = '' ;
65 $extrahdsettings { 'ACTION' } = '' ;
66 $extrahdsettings { 'UUID' } = '' ;
68 & General
:: readhash
( "${General::swroot}/extrahd/settings" , \
%extrahdsettings );
69 & Header
:: getcgihash
( \
%extrahdsettings );
71 & Header
:: openpage
( 'ExtraHD' , 1 , '' );
72 & Header
:: openbigbox
( '100%' , 'left' , '' , $errormessage );
74 ############################################################################################################################
75 ############################################################################################################################
77 if ( $extrahdsettings { 'ACTION' } eq $Lang :: tr
{ 'add' })
79 open ( FILE
, "< $devicefile " ) or die "Unable to read $devicefile " ;
82 foreach $deviceentry ( sort @devices )
84 @deviceline = split ( /\;/ , $deviceentry );
85 if ( " $extrahdsettings {'PATH'}" eq " $deviceline [2]" ) {
87 $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'}." ;
89 if ( " $extrahdsettings {'PATH'}" eq "/" ) {
91 $errormessage = " $Lang ::tr{'extrahd you cant mount'} $extrahdsettings {'DEVICE'} $Lang ::tr{'extrahd to root'}." ;
95 if ( " $ok " eq "true" ) {
96 open ( FILE
, ">> $devicefile " ) or die "Unable to write $devicefile " ;
98 UUID= $extrahdsettings {'UUID'}; $extrahdsettings {'FS'}; $extrahdsettings {'PATH'};
101 & General
:: system ( "/usr/local/bin/extrahdctrl" , "mount" , " $extrahdsettings {'PATH'}" );
104 elsif ( $extrahdsettings { 'ACTION' } eq $Lang :: tr
{ 'delete' })
106 if ( ! & General
:: system ( "/usr/local/bin/extrahdctrl" , "umount" , " $extrahdsettings {'PATH'}" )) {
107 open ( FILE
, "< $devicefile " ) or die "Unable to read $devicefile " ;
110 open ( FILE
, "> $devicefile " ) or die "Unable to write $devicefile " ;
111 foreach $deviceentry ( sort @tmp )
113 @tmpline = split ( /\;/ , $deviceentry );
114 if ( $tmpline [ 2 ] ne $extrahdsettings { 'PATH' } )
116 print FILE
$deviceentry ;
121 $errormessage = " $Lang ::tr{'extrahd cant umount'} $extrahdsettings {'PATH'} $Lang ::tr{'extrahd maybe the device is in use'}?" ;
126 & Header
:: openbox
( '100%' , 'left' , $Lang :: tr
{ 'error messages' });
127 print "<class name='base'> $errormessage \n " ;
128 print " </class> \n " ;
132 ############################################################################################################################
133 ############################################################################################################################
135 open ( FILE
, "< $devicefile " ) or die "Unable to read $devicefile " ;
139 <table border='0' width='600' cellspacing="0">
142 foreach $deviceentry ( sort @devices )
144 @deviceline = split ( /\;/ , $deviceentry );
145 my $color = " $Header ::colourred" ;
147 # Use safe system_output to get mountpoint details.
148 my @mountpoint = & General
:: system_output
( "/bin/mountpoint" , " $deviceline [2]" );
150 if ( ! grep ( /not/ , @mountpoint )) {
151 $color = $Header :: colourgreen
;
154 <tr><td colspan="4"> </td></tr>
155 <tr><td align='left'><font color= $color ><b> $deviceline [0]</b></font></td>
156 <td align='left'> $deviceline [1]</td>
157 <td align='left'> $deviceline [2]</td>
159 <form method='post' action=' $ENV {'SCRIPT_NAME'}'>
160 <input type='hidden' name='DEVICE' value=' $deviceline [0]' />
161 <input type='hidden' name='FS' value=' $deviceline [1]' />
162 <input type='hidden' name='PATH' value=' $deviceline [2]' />
163 <input type='hidden' name='ACTION' value=' $Lang ::tr{'delete'}' />
164 <input type='image' alt=' $Lang ::tr{'delete'}' title=' $Lang ::tr{'delete'}' src='/images/delete.gif' />
173 & Header
:: openbox
( '100%' , 'center' , $Lang :: tr
{ 'extrahd detected drives' });
175 <table border='0' width='600' cellspacing="0">
178 open ( FILE
, "< $scanfile " ) or die "Unable to read $scanfile " ;
181 open ( FILE
, "< $partitionsfile " ) or die "Unable to read $partitionsfile " ;
182 @partitions = < FILE
>;
184 foreach $scanentry ( sort @scans )
186 @scanline = split ( /\;/ , $scanentry );
187 # remove wrong entries like usb controller name
188 if ( $scanline [ 1 ] ne " \n " )
191 <tr><td colspan="5"> </td></tr>
192 <tr><td align='left' colspan="2"><b>/dev/ $scanline [0]</b></td>
193 <td align='center' colspan="2"> $scanline [1]</td>
198 foreach $partitionentry ( sort @partitions )
200 @partitionline = split ( /\;/ , $partitionentry );
201 if ( " $partitionline [0]" eq " $scanline [0]" ) {
202 $size = int ( $partitionline [ 1 ] / 1024 );
204 <td align='center'> $Lang ::tr{'size'} $size MB</td>
206 <tr><td colspan="5"> </td></tr>
212 foreach $partitionentry ( sort @partitions )
214 @partitionline = split ( /\;/ , $partitionentry );
215 if (( " $partitionline [0]" =~ /^$scanline[0]/ ) && !( " $partitionline [2]" eq "" )) {
216 $size = int ( $partitionline [ 1 ] / 1024 );
218 <form method='post' action=' $ENV {'SCRIPT_NAME'}'>
219 <tr><td align="left" colspan=5><strong>UUID= $partitionline [2]</strong></td></tr>
221 <td align="list">/dev/ $partitionline [0]</td>
222 <td align="center"> $Lang ::tr{'size'} $size MB</td>
223 <td align="center"><select name="FS">
224 <option value="auto">auto</option>
225 <option value="ext3">ext3</option>
226 <option value="ext4">ext4</option>
227 <option value="reiserfs">reiserfs</option>
228 <option value="vfat">fat</option>
229 <option value="ntfs-3g">ntfs (experimental)</option>
231 <td align="center"><input type='text' name='PATH' value=/mnt/harddisk /></td>
233 <input type='hidden' name='DEVICE' value=' $partitionline [0]' />
234 <input type='hidden' name='UUID' value=' $partitionline [2]' />
235 <input type='hidden' name='ACTION' value=' $Lang ::tr{'add'}' />
236 <input type='image' alt=' $Lang ::tr{'add'}' title=' $Lang ::tr{'add'}' src='/images/add.gif' />
248 <tr><td align="center" colspan="5"> </td></tr>
249 <tr><td align="center" colspan="5"> </td></tr>
250 <tr><td align="center" colspan="5"> $Lang ::tr{'extrahd install or load driver'}</td></tr>
256 & Header
:: closebigbox
();
257 & Header
:: closepage
();
260 ## Function which return an array with all available block devices.
262 sub get_block_devices
() {
265 # Open directory from kernel sysfs.
266 opendir ( DEVICES
, "/sys/block" );
268 # Loop through the directory.
269 while ( readdir ( DEVICES
)) {
271 next if ( $_ =~ /^\.$/ );
272 next if ( $_ =~ /^\..$/ );
274 # Skip any loopback and ram devices.
275 next if ( $_ =~ "^loop" );
276 next if ( $_ =~ "^ram" );
278 # Add the device to the array of found devices.
282 # Close directory handle.
285 # Return the devices array.
290 ## Function which return all partitions of a given block device.
292 sub get_device_partitions
($) {
295 # Array to store the known partitions for the given
299 # Assign device directory.
300 my $device_dir = " $sysfs_block_dir / $device " ;
302 # Abort and return nothing if the device dir does not exist.
303 return unless (- d
" $device_dir " );
305 opendir ( DEVICE
, " $sysfs_block_dir / $device " );
306 while ( readdir ( DEVICE
)) {
307 next unless ( $_ =~ "^ $device " );
309 push ( @partitions , $_ );
314 @partitions = sort ( @partitions );
320 ## Returns the vendor of a given block device.
322 sub get_device_vendor
($) {
325 # Assign device directory.
326 my $device_dir = " $sysfs_block_dir / $device " ;
328 # Abort and return nothing if the device dir does not exist
329 # or no vendor file exists.
330 return unless (- d
" $device_dir " );
331 return unless (- f
" $device_dir /device/vendor" );
333 # Open and read-in the device vendor.
334 open ( VENDOR
, " $device_dir /device/vendor" );
335 my $vendor = < VENDOR
>;
338 # Abort and return nothing if no vendor could be read.
339 return unless ( $vendor );
341 # Remove any newlines from the vendor string.
344 # Return the omited vendor.
349 ## Returns the model name (string) of a given block device.
351 sub get_device_model
($) {
354 # Assign device directory.
355 my $device_dir = " $sysfs_block_dir / $device " ;
357 # Abort and return nothing if the device dir does not exist
358 # or no model file exists.
359 return unless (- d
" $device_dir " );
360 return unless (- f
" $device_dir /device/model" );
362 # Open and read-in the device model.
363 open ( MODEL
, " $device_dir /device/model" );
367 # Abort and return nothing if no model could be read.
368 return unless ( $model );
370 # Remove any newlines from the model string.
373 # Return the model string.
378 ## Returns the size of a given device in bytes.
380 sub get_device_size
($) {
383 # Assign device directory.
384 my $device_dir = " $sysfs_block_dir / $device " ;
386 # Abort and return nothing if the device dir does not exist
387 # or no size file exists.
388 return unless (- d
" $device_dir " );
389 return unless (- f
" $device_dir /size" );
391 # Open and read-in the device size.
392 open ( SIZE
, " $device_dir /size" );
396 # Abort and return nothing if the size could not be read.
397 return unless ( $size );
399 # Remove any newlines for the size string.
402 # The omited size only contains the amount of blocks from the
403 # given device. To convert this into bytes we have to multiply this
404 # value with 512 bytes for each block. This is a static value used by
408 # Return the size in bytes.
413 ## Function which returns all currently mounted devices as a hash.
414 ## example: "sda1" -> "/boot"
416 sub get_mountpoints
() {
419 # Open and read-in the current mounts from the
420 # kernel file system.
421 open ( MOUNT
, "/proc/mounts" );
423 # Loop through the known mounts.
425 # Skip mounts which does not belong to a device.
426 next unless ( $_ =~ "^/dev" );
428 # Cut the line into pieces and assign nice variables.
429 my ( $dev , $mpoint , $fs , $options , $a , $b ) = split ( / / , $_ );
431 # Split the device name.
432 my @tmp = split ( "/" , $dev );
434 # Assign the plain device name to a new variable.
435 # It is the last element of the array.
436 my $device = $tmp [- 1 ];
438 # Add the mountpoint to the hash of mountpoints.
439 $mounts { " $device " } = $mpoint ;
445 # Return the hash of known mountpoints.
452 # Open and read the swaps file.
453 open ( SWAP
, "/proc/swaps" );
455 # Loop though the file content.
457 # Skip lines which does not belong to a device.
458 next unless ( $_ =~ "^/dev" );
460 # Split the line and assign nice variables.
461 my ( $dev , $type , $size , $used , $prio ) = split ( / / , $_ );
463 # Cut the device line into pieces.
464 my @tmp = split ( "/" , $dev );
466 my $device = @tmp [- 1 ];
468 # Add the found swap to the array of swaps.
469 push ( @swaps , $device );
476 @swaps = sort ( @swaps );
483 ## Function with returns the mounted devices and the used filesystems as a hash.
484 ## Example: "sda1" -> "ext4"
486 sub get_mountedfs
() {
489 # Open and read the current mounts from the kernel
491 open ( MOUNT
, "/proc/mounts" );
493 # Loop through the known mounts.
495 # Skip mounts which does not belong to a device.
496 next unless ( $_ =~ "^/dev" );
498 # Split line and assign nice variables.
499 my ( $dev , $mpoint , $fs , $options , $a , $b ) = split ( / / , $_ );
501 # Cut the device line into pieces.
502 my @tmp = split ( "/" , $dev );
504 # Assign the plain device name to a variable
505 # It is the last element of the temporary array.
506 my $device = $tmp [- 1 ];
508 # Convert the filesystem into lower case format.
511 # Add the mounted file system.
512 $mountedfs { $device } = $fs ;
518 # Return the hash with the mounted filesystems.
523 ## Function which returns all known UUID's as a hash.
524 ## Example: "sda1" -> "1234-5678-abcd"
529 # Directory where the uuid mappings can be found.
530 my $uuid_dir = "/dev/disk/by-uuid" ;
532 # Open uuid directory and read-in the current known uuids.
533 opendir ( UUIDS
, " $uuid_dir " );
535 # Loop through the uuids.
536 foreach my $uuid ( readdir ( UUIDS
)) {
538 next if ( $uuid eq "." or $uuid eq ".." );
540 # Skip everything which is not a symbolic link.
541 next unless (- l
" $uuid_dir / $uuid " );
543 # Resolve the target of the symbolic link.
544 my $target = readlink ( " $uuid_dir / $uuid " );
546 # Split the link target into pieces.
547 my @tmp = split ( "/" , $target );
549 # Assign the last element of the array to the dev variable.
550 my $dev = " $tmp [-1]" ;
552 # Add the device and uuid to the hash of uuids.
553 $uuids { $dev } = $uuid ;
556 # Close directory handle.
559 # Return the hash of uuids.
564 ## Returns the device name of a given uuid.
566 sub device_by_uuid
($) {
569 # Reverse the main uuids hash.
570 my %uuids = reverse %uuids ;
572 # Lookup and return the device name.
573 return $uuids { $uuid };
577 ## Returns "True" in case a given path is a known mountpoint.
582 my %mountpoints = reverse %mountpoints ;
584 # Return "True" if the requested mountpoint is known and
586 return 1 if ( $mountpoints { $mpoint });
590 ## Returns "True" if a given mountpoint is a subdirectory of one
591 ## of the directories specified by the valid_mount_dirs array abouve.
593 sub is_valid_dir
($) {
596 # Split the given mountpoint into pieces and store them
597 # in a temporay array.
598 my @tmp = split ( "/" , $mpoint );
600 # Exit and return nothing if the temporary array is empty.
603 # Build the root path based on the given mount point.
604 my $root_path = "/" . @tmp [ 1 ];
606 # Check if the root path is valid.
607 return 1 if ( grep /$root_path/ , @valid_mount_dirs );
611 # Returns "True" if a device is used as swap.
616 return 1 if ( grep /$device/ , @swaps );