]>
Commit | Line | Data |
---|---|---|
aa2870e6 | 1 | #!/usr/bin/perl |
70df8302 MT |
2 | ############################################################################### |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
20730a6f | 5 | # Copyright (C) 2011 IPFire Team <info@ipfire.org> # |
70df8302 MT |
6 | # # |
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. # | |
11 | # # | |
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. # | |
16 | # # | |
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/>. # | |
19 | # # | |
20 | ############################################################################### | |
aa2870e6 MT |
21 | |
22 | use strict; | |
23 | # enable only the following on debugging purpose | |
cb5e9c6c CS |
24 | #use warnings; |
25 | #use CGI::Carp 'fatalsToBrowser'; | |
aa2870e6 MT |
26 | |
27 | require '/var/ipfire/general-functions.pl'; | |
28 | require "${General::swroot}/lang.pl"; | |
29 | require "${General::swroot}/header.pl"; | |
30 | ||
31 | my %extrahdsettings = (); | |
aa2870e6 | 32 | my $errormessage = ""; |
56ce3e19 | 33 | |
d0a6f9bd SS |
34 | # Hash to store the configured drives. |
35 | my %configured_drives; | |
36 | ||
56ce3e19 SS |
37 | # SYSFS directory which contains all block device data. |
38 | my $sysfs_block_dir = "/sys/class/block"; | |
39 | ||
40 | # Array which contains the valid mount directories. | |
41 | # Only mounting to subdirectories inside them is allowed. | |
42 | my @valid_mount_dirs = ( | |
43 | "/data", | |
44 | "/media", | |
45 | "/mnt", | |
46 | ); | |
47 | ||
56ce3e19 SS |
48 | # Grab all available block devices. |
49 | my @devices = &get_block_devices(); | |
50 | ||
51 | # Grab all known UUID's. | |
52 | my %uuids = &get_uuids(); | |
53 | ||
54 | # Grab all mountpoints. | |
55 | my %mountpoints = &get_mountpoints(); | |
56 | ||
57 | # Omit the file system types of the mounted devices. | |
58 | my %filesystems = &get_mountedfs(); | |
59 | ||
60 | # Gather all used swap devices. | |
61 | my @swaps = &get_swaps(); | |
62 | ||
63 | # The config file which contains the configured devices. | |
aa2870e6 | 64 | my $devicefile = "/var/ipfire/extrahd/devices"; |
d5f061e9 MF |
65 | |
66 | #workaround to suppress a warning when a variable is used only once | |
67 | my @dummy = ( ${Header::colourgreen}, ${Header::colourred} ); | |
68 | undef (@dummy); | |
69 | ||
aa2870e6 MT |
70 | &Header::showhttpheaders(); |
71 | ||
72 | ### Values that have to be initialized | |
73 | $extrahdsettings{'PATH'} = ''; | |
74 | $extrahdsettings{'FS'} = ''; | |
75 | $extrahdsettings{'DEVICE'} = ''; | |
76 | $extrahdsettings{'ACTION'} = ''; | |
784d72a2 | 77 | $extrahdsettings{'UUID'} = ''; |
aa2870e6 | 78 | |
aa2870e6 MT |
79 | &Header::getcgihash(\%extrahdsettings); |
80 | ||
81 | &Header::openpage('ExtraHD', 1, ''); | |
82 | &Header::openbigbox('100%', 'left', '', $errormessage); | |
83 | ||
84 | ############################################################################################################################ | |
85 | ############################################################################################################################ | |
86 | ||
56ce3e19 SS |
87 | # |
88 | ## Add a new device. | |
89 | # | |
90 | if ($extrahdsettings{'ACTION'} eq $Lang::tr{'add'}) { | |
72dfa1b0 SS |
91 | # Check if a mount path has been given. |
92 | if (not $extrahdsettings{'PATH'}) { | |
93 | $errormessage = "$Lang::tr{'extrahd no mount point given'}."; | |
94 | ||
7907c1e0 | 95 | # Check if a valid mount path has been choosen. |
72dfa1b0 SS |
96 | } elsif(not &is_valid_dir("$extrahdsettings{'PATH'}")) { |
97 | $errormessage = "$Lang::tr{'extrahd you cant mount'} $extrahdsettings{'DEVICE'} $Lang::tr{'extrahd to'} $extrahdsettings{'PATH'} $Lang::tr{'extrahd because it is outside the allowed mount path'}."; | |
56ce3e19 SS |
98 | |
99 | # Check if the given path allready is mounted somewhere. | |
72dfa1b0 SS |
100 | } elsif(&is_mounted("$extrahdsettings{'PATH'}")) { |
101 | $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'}."; | |
56ce3e19 SS |
102 | } |
103 | ||
7907c1e0 SS |
104 | # Check against may previously configured drives. |
105 | unless ($errormessage) { | |
106 | # Open device file for reading. | |
107 | open( FILE, "< $devicefile" ) or die "Unable to read $devicefile"; | |
108 | my @devices = <FILE>; | |
109 | close FILE; | |
110 | ||
111 | # Loop through the entries line-by-line. | |
112 | foreach my $entry (sort @devices) { | |
113 | # Split the line into pieces and assign nice variables. | |
114 | my ($uuid, $fs, $path) = split( /\;/, $entry ); | |
115 | ||
116 | # Check if the path is allready used. | |
117 | if ( "$extrahdsettings{'PATH'}" eq "$path" ) { | |
72dfa1b0 | 118 | $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'}."; |
7907c1e0 SS |
119 | } |
120 | ||
121 | # Check if the uuid is allready used. | |
122 | if ("$extrahdsettings{'DEVICE'} eq $uuid") { | |
123 | $errormessage = "$extrahdsettings{'DEVICE'} is allready mounted."; | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
128 | # Go further if there was no error message. | |
56ce3e19 SS |
129 | unless($errormessage) { |
130 | # Re-open the device file for writing. | |
aa2870e6 | 131 | open(FILE, ">> $devicefile" ) or die "Unable to write $devicefile"; |
56ce3e19 SS |
132 | |
133 | # Write the config line. | |
134 | print FILE "UUID=$extrahdsettings{'UUID'};$extrahdsettings{'FS'};$extrahdsettings{'PATH'};\n"; | |
135 | ||
136 | # Close file handle. | |
137 | close(FILE); | |
138 | ||
139 | # Call helper binary to mount the device. | |
140 | &General::system("/usr/local/bin/extrahdctrl", "mount", "$extrahdsettings{'PATH'}"); | |
aa2870e6 | 141 | } |
56ce3e19 SS |
142 | |
143 | # | |
144 | # Remove an existing one. | |
145 | # | |
146 | } elsif ($extrahdsettings{'ACTION'} eq $Lang::tr{'delete'}) { | |
147 | # Call helper binary to unmount the device. | |
94aeac8a SS |
148 | unless(&General::system("/usr/local/bin/extrahdctrl", "umount", "$extrahdsettings{'PATH'}")) { |
149 | # Open the device file for reading. | |
150 | open(FILE, "< $devicefile" ) or die "Unable to read $devicefile"; | |
56ce3e19 | 151 | |
94aeac8a SS |
152 | # Read the file content into a temporary array. |
153 | my @tmp = <FILE>; | |
56ce3e19 | 154 | |
94aeac8a SS |
155 | # Close file handle. |
156 | close(FILE); | |
56ce3e19 | 157 | |
94aeac8a SS |
158 | # Re-open device file for writing. |
159 | open(FILE, "> $devicefile" ) or die "Unable to write $devicefile"; | |
56ce3e19 | 160 | |
94aeac8a SS |
161 | # Loop through the previous read file content. |
162 | foreach my $line (sort @tmp) { | |
163 | # Split line content and assign nice variables. | |
164 | my ($uuid, $fs, $path) = split( /\;/, $line ); | |
56ce3e19 | 165 | |
94aeac8a SS |
166 | # Write the line in case it does not contain our element to delete. |
167 | if ($path ne $extrahdsettings{'PATH'}) { | |
168 | print FILE "$line"; | |
169 | } | |
aa2870e6 | 170 | } |
56ce3e19 | 171 | |
94aeac8a SS |
172 | # Close file handle. |
173 | close(FILE); | |
174 | } else { | |
175 | $errormessage = "$Lang::tr{'extrahd cant umount'} $extrahdsettings{'PATH'}$Lang::tr{'extrahd maybe the device is in use'}?"; | |
176 | } | |
aa2870e6 MT |
177 | } |
178 | ||
179 | if ($errormessage) { | |
180 | &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); | |
181 | print "<class name='base'>$errormessage\n"; | |
182 | print " </class>\n"; | |
183 | &Header::closebox(); | |
184 | } | |
185 | ||
186 | ############################################################################################################################ | |
187 | ############################################################################################################################ | |
188 | ||
d0a6f9bd SS |
189 | &Header::openbox('100%', 'center', $Lang::tr{'extrahd detected drives'}); |
190 | ||
56ce3e19 SS |
191 | # Re-read mountpoints. |
192 | %mountpoints = &get_mountpoints(); | |
3a69c4fb | 193 | |
56ce3e19 SS |
194 | # Read-in the device config file. |
195 | open( FILE, "< $devicefile" ) or die "Unable to read $devicefile"; | |
56ce3e19 SS |
196 | |
197 | # Loop through the file content. | |
d0a6f9bd SS |
198 | while (<FILE>) { |
199 | # Cut the line into pieces. | |
200 | my ($uuid, $fs, $path) = split( /\;/, $_ ); | |
56ce3e19 | 201 | |
d0a6f9bd SS |
202 | # Add the found entry to the hash of configured drives. |
203 | $configured_drives{$uuid} = $path; | |
aa2870e6 | 204 | } |
56ce3e19 | 205 | |
d0a6f9bd SS |
206 | # Close the file handle. |
207 | close(FILE); | |
208 | ||
aa2870e6 MT |
209 | print <<END |
210 | <table border='0' width='600' cellspacing="0"> | |
211 | END | |
212 | ; | |
56ce3e19 SS |
213 | foreach my $device (sort @devices) { |
214 | # Grab the device details. | |
215 | my $vendor = &get_device_vendor($device); | |
216 | my $model = &get_device_model($device); | |
217 | my $bsize = &get_device_size($device); | |
218 | ||
219 | # Convert size into human-readable format. | |
220 | my $size = &General::formatBytes($bsize); | |
221 | ||
222 | print <<END | |
223 | <tr><td colspan="5"> </td></tr> | |
224 | <tr><td align='left' colspan="2"><b>/dev/$device</b></td> | |
225 | <td align='center' colspan="2">$vendor $model</td> | |
226 | ||
227 | <td align='center'>$Lang::tr{'size'} $size</td> | |
228 | <td> </td></tr> | |
229 | <tr><td colspan="5"> </td></tr> | |
aa2870e6 MT |
230 | END |
231 | ; | |
20730a6f | 232 | |
56ce3e19 SS |
233 | # Grab the known partitions of the current block device. |
234 | my @partitions = &get_device_partitions($device); | |
235 | ||
236 | foreach my $partition (@partitions) { | |
237 | my $disabled; | |
238 | ||
239 | # Omit the partition size. | |
240 | my $bsize = &get_device_size($partition); | |
241 | ||
242 | # Convert into human-readable format. | |
243 | my $size = &General::formatBytes($bsize); | |
244 | ||
480c5253 SS |
245 | # Try to omit the used filesystem. |
246 | my $fs = $filesystems{$partition}; | |
247 | ||
56ce3e19 SS |
248 | # Get the mountpoint. |
249 | my $mountpoint = $mountpoints{$partition}; | |
250 | ||
d0a6f9bd SS |
251 | # If no mountpoint could be determined try to grab from |
252 | # configured drives. | |
253 | unless($mountpoint) { | |
254 | my $uuid = $uuids{$partition}; | |
255 | ||
256 | # Build uuid string. | |
257 | $uuid = "UUID=" . $uuid; | |
258 | ||
259 | # Try to obtain a possible moutpoint from configured drives. | |
260 | $mountpoint = $configured_drives{$uuid} if ($configured_drives{$uuid}); | |
261 | } | |
262 | ||
263 | # Check if the mountpoint is used as root or boot device. | |
56ce3e19 SS |
264 | if ($mountpoint eq "/" or $mountpoint =~ "^/boot") { |
265 | $disabled = "disabled"; | |
d0a6f9bd SS |
266 | |
267 | # Check if it is mounted. | |
56ce3e19 SS |
268 | } elsif(&is_mounted($mountpoint)) { |
269 | $disabled = "disabled"; | |
56ce3e19 SS |
270 | |
271 | # Check if the device is used as swap. | |
d0a6f9bd | 272 | } elsif (&is_swap($partition)) { |
56ce3e19 SS |
273 | $disabled = "disabled"; |
274 | $mountpoint = "swap"; | |
480c5253 | 275 | $fs = "swap"; |
56ce3e19 SS |
276 | } |
277 | ||
278 | print <<END | |
279 | ||
280 | <form method='post' action='$ENV{'SCRIPT_NAME'}'> | |
281 | <tr><td align="left" colspan=5><strong>UUID=$uuids{$partition}</strong></td></tr> | |
282 | <tr> | |
283 | <td align="list">/dev/$partition</td> | |
284 | <td align="center">$Lang::tr{'size'} $size</td> | |
480c5253 | 285 | <td align="center">$fs</td> |
fd815c36 | 286 | <td align="center"><input type='text' name='PATH' value='$mountpoint' $disabled></td> |
aa2870e6 | 287 | <td align="center"> |
56ce3e19 SS |
288 | <input type='hidden' name='DEVICE' value='/dev/$partition' /> |
289 | <input type='hidden' name='UUID' value='$uuids{$partition}' /> | |
20730a6f | 290 | END |
fd815c36 SS |
291 | ; |
292 | # Check if the mountpoint refers to a known configured drive. | |
293 | if(&is_configured($mountpoint)) { | |
294 | print "<input type='hidden' name='ACTION' value='$Lang::tr{'delete'}'>\n"; | |
295 | print "<input type='hidden' name='PATH' value='$mountpoint'>\n"; | |
296 | ||
297 | # Check if the device is mounted properly. | |
298 | if(&is_mounted($mountpoint)) { | |
72dfa1b0 | 299 | print "<img src='/images/updbooster/updxl-led-green.gif' alt='$Lang::tr{'extrahd mounted'}' title='$Lang::tr{'extrahd mounted'}'> \n"; |
fd815c36 | 300 | } else { |
72dfa1b0 | 301 | print "<img src='/images/updbooster/updxl-led-red.gif' alt='$Lang::tr{'extrahd not mounted'}' title='$Lang::tr{'extrahd not mounted'}'> \n"; |
fd815c36 SS |
302 | } |
303 | ||
304 | print "<input type='image' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' src='/images/delete.gif'>\n"; | |
305 | } else { | |
306 | unless($disabled) { | |
307 | print "<input type='hidden' name='ACTION' value='$Lang::tr{'add'}'>\n"; | |
65dc35dc | 308 | print "<input type='hidden' name='FS' value='auto'>\n"; |
72dfa1b0 | 309 | print "<img src='/images/updbooster/updxl-led-gray.gif' alt='$Lang::tr{'extrahd not configured'}' title='$Lang::tr{'extrahd not configured'}'> \n"; |
fd815c36 SS |
310 | print "<input type='image' alt='$Lang::tr{'add'}' title='$Lang::tr{'add'}' src='/images/add.gif'>\n"; |
311 | } | |
56ce3e19 | 312 | } |
aa2870e6 | 313 | |
56ce3e19 SS |
314 | print <<END |
315 | </form></td></tr> | |
aa2870e6 | 316 | END |
56ce3e19 SS |
317 | ; } |
318 | ||
aa2870e6 MT |
319 | } |
320 | ||
321 | print <<END | |
20730a6f JPT |
322 | <tr><td align="center" colspan="5"> </td></tr> |
323 | <tr><td align="center" colspan="5"> </td></tr> | |
324 | <tr><td align="center" colspan="5">$Lang::tr{'extrahd install or load driver'}</td></tr> | |
aa2870e6 MT |
325 | </table> |
326 | END | |
327 | ; | |
328 | &Header::closebox(); | |
329 | ||
330 | &Header::closebigbox(); | |
331 | &Header::closepage(); | |
a2c88aad SS |
332 | |
333 | # | |
334 | ## Function which return an array with all available block devices. | |
335 | # | |
336 | sub get_block_devices () { | |
337 | my @devices; | |
338 | ||
339 | # Open directory from kernel sysfs. | |
340 | opendir(DEVICES, "/sys/block"); | |
341 | ||
342 | # Loop through the directory. | |
343 | while(readdir(DEVICES)) { | |
344 | # Skip . and .. | |
345 | next if($_ =~ /^\.$/); | |
346 | next if($_ =~ /^\..$/); | |
347 | ||
348 | # Skip any loopback and ram devices. | |
349 | next if($_ =~ "^loop"); | |
350 | next if($_ =~ "^ram"); | |
351 | ||
352 | # Add the device to the array of found devices. | |
353 | push(@devices, $_); | |
354 | } | |
355 | ||
356 | # Close directory handle. | |
357 | closedir(DEVICES); | |
358 | ||
359 | # Return the devices array. | |
360 | return @devices; | |
361 | } | |
362 | ||
363 | # | |
364 | ## Function which return all partitions of a given block device. | |
365 | # | |
366 | sub get_device_partitions ($) { | |
367 | my ($device) = @_; | |
368 | ||
369 | # Array to store the known partitions for the given | |
370 | # device. | |
371 | my @partitions; | |
372 | ||
373 | # Assign device directory. | |
374 | my $device_dir = "$sysfs_block_dir/$device"; | |
375 | ||
376 | # Abort and return nothing if the device dir does not exist. | |
377 | return unless(-d "$device_dir"); | |
378 | ||
379 | opendir(DEVICE, "$sysfs_block_dir/$device"); | |
380 | while(readdir(DEVICE)) { | |
381 | next unless($_ =~ "^$device"); | |
382 | ||
383 | push(@partitions, $_); | |
384 | } | |
385 | ||
386 | closedir(DEVICE); | |
387 | ||
388 | @partitions = sort(@partitions); | |
389 | ||
390 | return @partitions; | |
391 | } | |
392 | ||
393 | # | |
394 | ## Returns the vendor of a given block device. | |
395 | # | |
396 | sub get_device_vendor ($) { | |
397 | my ($device) = @_; | |
398 | ||
399 | # Assign device directory. | |
400 | my $device_dir = "$sysfs_block_dir/$device"; | |
401 | ||
402 | # Abort and return nothing if the device dir does not exist | |
403 | # or no vendor file exists. | |
404 | return unless(-d "$device_dir"); | |
405 | return unless(-f "$device_dir/device/vendor"); | |
406 | ||
407 | # Open and read-in the device vendor. | |
408 | open(VENDOR, "$device_dir/device/vendor"); | |
409 | my $vendor = <VENDOR>; | |
410 | close(VENDOR); | |
411 | ||
412 | # Abort and return nothing if no vendor could be read. | |
413 | return unless($vendor); | |
414 | ||
415 | # Remove any newlines from the vendor string. | |
416 | chomp($vendor); | |
417 | ||
418 | # Return the omited vendor. | |
419 | return $vendor; | |
420 | } | |
421 | ||
422 | # | |
423 | ## Returns the model name (string) of a given block device. | |
424 | # | |
425 | sub get_device_model ($) { | |
426 | my ($device) = @_; | |
427 | ||
428 | # Assign device directory. | |
429 | my $device_dir = "$sysfs_block_dir/$device"; | |
430 | ||
431 | # Abort and return nothing if the device dir does not exist | |
432 | # or no model file exists. | |
433 | return unless(-d "$device_dir"); | |
434 | return unless(-f "$device_dir/device/model"); | |
435 | ||
436 | # Open and read-in the device model. | |
437 | open(MODEL, "$device_dir/device/model"); | |
438 | my $model = <MODEL>; | |
439 | close(MODEL); | |
440 | ||
441 | # Abort and return nothing if no model could be read. | |
442 | return unless($model); | |
443 | ||
444 | # Remove any newlines from the model string. | |
445 | chomp($model); | |
446 | ||
447 | # Return the model string. | |
448 | return $model; | |
449 | } | |
450 | ||
451 | # | |
452 | ## Returns the size of a given device in bytes. | |
453 | # | |
454 | sub get_device_size ($) { | |
455 | my ($device) = @_; | |
456 | ||
457 | # Assign device directory. | |
458 | my $device_dir = "$sysfs_block_dir/$device"; | |
459 | ||
460 | # Abort and return nothing if the device dir does not exist | |
461 | # or no size file exists. | |
462 | return unless(-d "$device_dir"); | |
463 | return unless(-f "$device_dir/size"); | |
464 | ||
465 | # Open and read-in the device size. | |
466 | open(SIZE, "$device_dir/size"); | |
467 | my $size = <SIZE>; | |
468 | close(SIZE); | |
469 | ||
470 | # Abort and return nothing if the size could not be read. | |
471 | return unless($size); | |
472 | ||
473 | # Remove any newlines for the size string. | |
474 | chomp($size); | |
475 | ||
476 | # The omited size only contains the amount of blocks from the | |
477 | # given device. To convert this into bytes we have to multiply this | |
478 | # value with 512 bytes for each block. This is a static value used by | |
479 | # the linux kernel. | |
480 | $size = $size * 512; | |
481 | ||
482 | # Return the size in bytes. | |
483 | return $size; | |
484 | } | |
485 | ||
486 | # | |
487 | ## Function which returns all currently mounted devices as a hash. | |
488 | ## example: "sda1" -> "/boot" | |
489 | # | |
490 | sub get_mountpoints () { | |
491 | my %mounts; | |
492 | ||
493 | # Open and read-in the current mounts from the | |
494 | # kernel file system. | |
495 | open(MOUNT, "/proc/mounts"); | |
496 | ||
497 | # Loop through the known mounts. | |
498 | while(<MOUNT>) { | |
499 | # Skip mounts which does not belong to a device. | |
500 | next unless ($_ =~ "^/dev"); | |
501 | ||
502 | # Cut the line into pieces and assign nice variables. | |
503 | my ($dev, $mpoint, $fs, $options, $a, $b) = split(/ /, $_); | |
504 | ||
505 | # Split the device name. | |
506 | my @tmp = split("/", $dev); | |
507 | ||
508 | # Assign the plain device name to a new variable. | |
509 | # It is the last element of the array. | |
510 | my $device = $tmp[-1]; | |
511 | ||
512 | # Add the mountpoint to the hash of mountpoints. | |
513 | $mounts{"$device"} = $mpoint; | |
514 | } | |
515 | ||
516 | # Close file handle. | |
517 | close(MOUNT); | |
518 | ||
519 | # Return the hash of known mountpoints. | |
520 | return %mounts; | |
521 | } | |
522 | ||
523 | sub get_swaps () { | |
524 | my @swaps; | |
525 | ||
526 | # Open and read the swaps file. | |
527 | open(SWAP, "/proc/swaps"); | |
528 | ||
529 | # Loop though the file content. | |
530 | while(<SWAP>) { | |
531 | # Skip lines which does not belong to a device. | |
532 | next unless ($_ =~ "^/dev"); | |
533 | ||
534 | # Split the line and assign nice variables. | |
535 | my ($dev, $type, $size, $used, $prio) = split(/ /, $_); | |
536 | ||
537 | # Cut the device line into pieces. | |
538 | my @tmp = split("/", $dev); | |
539 | ||
540 | my $device = @tmp[-1]; | |
541 | ||
542 | # Add the found swap to the array of swaps. | |
543 | push(@swaps, $device); | |
544 | } | |
545 | ||
546 | # Close file handle. | |
547 | close(SWAP); | |
548 | ||
549 | # Sort the array. | |
550 | @swaps = sort(@swaps); | |
551 | ||
552 | # Return the array. | |
553 | return @swaps; | |
554 | } | |
555 | ||
556 | # | |
557 | ## Function with returns the mounted devices and the used filesystems as a hash. | |
558 | ## Example: "sda1" -> "ext4" | |
559 | # | |
560 | sub get_mountedfs () { | |
561 | my %mountedfs; | |
562 | ||
563 | # Open and read the current mounts from the kernel | |
564 | # file system. | |
565 | open(MOUNT, "/proc/mounts"); | |
566 | ||
567 | # Loop through the known mounts. | |
568 | while(<MOUNT>) { | |
569 | # Skip mounts which does not belong to a device. | |
570 | next unless ($_ =~ "^/dev"); | |
571 | ||
572 | # Split line and assign nice variables. | |
573 | my ($dev, $mpoint, $fs, $options, $a, $b) = split(/ /, $_); | |
574 | ||
575 | # Cut the device line into pieces. | |
576 | my @tmp = split("/", $dev); | |
577 | ||
578 | # Assign the plain device name to a variable | |
579 | # It is the last element of the temporary array. | |
580 | my $device = $tmp[-1]; | |
581 | ||
582 | # Convert the filesystem into lower case format. | |
583 | $fs = lc($fs); | |
584 | ||
585 | # Add the mounted file system. | |
586 | $mountedfs{$device} = $fs; | |
587 | } | |
588 | ||
589 | # Close file handle. | |
590 | close(MOUNT); | |
591 | ||
592 | # Return the hash with the mounted filesystems. | |
593 | return %mountedfs; | |
594 | } | |
595 | ||
596 | # | |
597 | ## Function which returns all known UUID's as a hash. | |
598 | ## Example: "sda1" -> "1234-5678-abcd" | |
599 | # | |
600 | sub get_uuids () { | |
601 | my %uuids; | |
602 | ||
603 | # Directory where the uuid mappings can be found. | |
604 | my $uuid_dir = "/dev/disk/by-uuid"; | |
605 | ||
606 | # Open uuid directory and read-in the current known uuids. | |
607 | opendir(UUIDS, "$uuid_dir"); | |
608 | ||
609 | # Loop through the uuids. | |
610 | foreach my $uuid (readdir(UUIDS)) { | |
611 | # Skip . and .. | |
612 | next if($uuid eq "." or $uuid eq ".."); | |
613 | ||
614 | # Skip everything which is not a symbolic link. | |
615 | next unless(-l "$uuid_dir/$uuid"); | |
616 | ||
617 | # Resolve the target of the symbolic link. | |
618 | my $target = readlink("$uuid_dir/$uuid"); | |
619 | ||
620 | # Split the link target into pieces. | |
621 | my @tmp = split("/", $target); | |
622 | ||
623 | # Assign the last element of the array to the dev variable. | |
624 | my $dev = "$tmp[-1]"; | |
625 | ||
626 | # Add the device and uuid to the hash of uuids. | |
627 | $uuids{$dev} = $uuid; | |
628 | } | |
629 | ||
630 | # Close directory handle. | |
631 | closedir(UUIDS); | |
632 | ||
633 | # Return the hash of uuids. | |
634 | return %uuids; | |
635 | } | |
636 | ||
637 | # | |
638 | ## Returns the device name of a given uuid. | |
639 | # | |
640 | sub device_by_uuid ($) { | |
641 | my ($uuid) = @_; | |
642 | ||
643 | # Reverse the main uuids hash. | |
644 | my %uuids = reverse %uuids; | |
645 | ||
646 | # Lookup and return the device name. | |
647 | return $uuids{$uuid}; | |
648 | } | |
649 | ||
650 | # | |
651 | ## Returns "True" in case a given path is a known mountpoint. | |
652 | # | |
653 | sub is_mounted ($) { | |
654 | my ($mpoint) = @_; | |
655 | ||
656 | my %mountpoints = reverse %mountpoints; | |
657 | ||
658 | # Return "True" if the requested mountpoint is known and | |
659 | # therefore mounted. | |
660 | return 1 if($mountpoints{$mpoint}); | |
661 | } | |
662 | ||
663 | # | |
664 | ## Returns "True" if a given mountpoint is a subdirectory of one | |
665 | ## of the directories specified by the valid_mount_dirs array abouve. | |
666 | # | |
667 | sub is_valid_dir ($) { | |
668 | my ($mpoint) = @_; | |
669 | ||
19a3b883 SS |
670 | # Do not allow "/mnt" or "/media" as mount points. |
671 | return if($mpoint eq "/mnt"); | |
672 | return if($mpoint eq "/media"); | |
673 | ||
a2c88aad SS |
674 | # Split the given mountpoint into pieces and store them |
675 | # in a temporay array. | |
676 | my @tmp = split("/", $mpoint); | |
677 | ||
678 | # Exit and return nothing if the temporary array is empty. | |
679 | return unless(@tmp); | |
680 | ||
681 | # Build the root path based on the given mount point. | |
682 | my $root_path = "/" . @tmp[1]; | |
683 | ||
684 | # Check if the root path is valid. | |
685 | return 1 if(grep /$root_path/, @valid_mount_dirs); | |
686 | } | |
687 | ||
688 | # | |
689 | # Returns "True" if a device is used as swap. | |
690 | # | |
691 | sub is_swap ($) { | |
692 | my ($device) = @_; | |
693 | ||
694 | return 1 if(grep /$device/, @swaps); | |
695 | } | |
0aa77c2f SS |
696 | |
697 | # | |
698 | ## Returns "True" if a drive is a configured one. | |
699 | # | |
700 | sub is_configured ($) { | |
701 | my ($path) = @_; | |
702 | ||
703 | # Loop through the hash of configured drives. | |
704 | foreach my $uuid (keys %configured_drives) { | |
705 | return 1 if($configured_drives{$uuid} eq "$path"); | |
706 | } | |
707 | } |