]>
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"; | |
72dfa1b0 | 308 | print "<img src='/images/updbooster/updxl-led-gray.gif' alt='$Lang::tr{'extrahd not configured'}' title='$Lang::tr{'extrahd not configured'}'> \n"; |
fd815c36 SS |
309 | print "<input type='image' alt='$Lang::tr{'add'}' title='$Lang::tr{'add'}' src='/images/add.gif'>\n"; |
310 | } | |
56ce3e19 | 311 | } |
aa2870e6 | 312 | |
56ce3e19 SS |
313 | print <<END |
314 | </form></td></tr> | |
aa2870e6 | 315 | END |
56ce3e19 SS |
316 | ; } |
317 | ||
aa2870e6 MT |
318 | } |
319 | ||
320 | print <<END | |
20730a6f JPT |
321 | <tr><td align="center" colspan="5"> </td></tr> |
322 | <tr><td align="center" colspan="5"> </td></tr> | |
323 | <tr><td align="center" colspan="5">$Lang::tr{'extrahd install or load driver'}</td></tr> | |
aa2870e6 MT |
324 | </table> |
325 | END | |
326 | ; | |
327 | &Header::closebox(); | |
328 | ||
329 | &Header::closebigbox(); | |
330 | &Header::closepage(); | |
a2c88aad SS |
331 | |
332 | # | |
333 | ## Function which return an array with all available block devices. | |
334 | # | |
335 | sub get_block_devices () { | |
336 | my @devices; | |
337 | ||
338 | # Open directory from kernel sysfs. | |
339 | opendir(DEVICES, "/sys/block"); | |
340 | ||
341 | # Loop through the directory. | |
342 | while(readdir(DEVICES)) { | |
343 | # Skip . and .. | |
344 | next if($_ =~ /^\.$/); | |
345 | next if($_ =~ /^\..$/); | |
346 | ||
347 | # Skip any loopback and ram devices. | |
348 | next if($_ =~ "^loop"); | |
349 | next if($_ =~ "^ram"); | |
350 | ||
351 | # Add the device to the array of found devices. | |
352 | push(@devices, $_); | |
353 | } | |
354 | ||
355 | # Close directory handle. | |
356 | closedir(DEVICES); | |
357 | ||
358 | # Return the devices array. | |
359 | return @devices; | |
360 | } | |
361 | ||
362 | # | |
363 | ## Function which return all partitions of a given block device. | |
364 | # | |
365 | sub get_device_partitions ($) { | |
366 | my ($device) = @_; | |
367 | ||
368 | # Array to store the known partitions for the given | |
369 | # device. | |
370 | my @partitions; | |
371 | ||
372 | # Assign device directory. | |
373 | my $device_dir = "$sysfs_block_dir/$device"; | |
374 | ||
375 | # Abort and return nothing if the device dir does not exist. | |
376 | return unless(-d "$device_dir"); | |
377 | ||
378 | opendir(DEVICE, "$sysfs_block_dir/$device"); | |
379 | while(readdir(DEVICE)) { | |
380 | next unless($_ =~ "^$device"); | |
381 | ||
382 | push(@partitions, $_); | |
383 | } | |
384 | ||
385 | closedir(DEVICE); | |
386 | ||
387 | @partitions = sort(@partitions); | |
388 | ||
389 | return @partitions; | |
390 | } | |
391 | ||
392 | # | |
393 | ## Returns the vendor of a given block device. | |
394 | # | |
395 | sub get_device_vendor ($) { | |
396 | my ($device) = @_; | |
397 | ||
398 | # Assign device directory. | |
399 | my $device_dir = "$sysfs_block_dir/$device"; | |
400 | ||
401 | # Abort and return nothing if the device dir does not exist | |
402 | # or no vendor file exists. | |
403 | return unless(-d "$device_dir"); | |
404 | return unless(-f "$device_dir/device/vendor"); | |
405 | ||
406 | # Open and read-in the device vendor. | |
407 | open(VENDOR, "$device_dir/device/vendor"); | |
408 | my $vendor = <VENDOR>; | |
409 | close(VENDOR); | |
410 | ||
411 | # Abort and return nothing if no vendor could be read. | |
412 | return unless($vendor); | |
413 | ||
414 | # Remove any newlines from the vendor string. | |
415 | chomp($vendor); | |
416 | ||
417 | # Return the omited vendor. | |
418 | return $vendor; | |
419 | } | |
420 | ||
421 | # | |
422 | ## Returns the model name (string) of a given block device. | |
423 | # | |
424 | sub get_device_model ($) { | |
425 | my ($device) = @_; | |
426 | ||
427 | # Assign device directory. | |
428 | my $device_dir = "$sysfs_block_dir/$device"; | |
429 | ||
430 | # Abort and return nothing if the device dir does not exist | |
431 | # or no model file exists. | |
432 | return unless(-d "$device_dir"); | |
433 | return unless(-f "$device_dir/device/model"); | |
434 | ||
435 | # Open and read-in the device model. | |
436 | open(MODEL, "$device_dir/device/model"); | |
437 | my $model = <MODEL>; | |
438 | close(MODEL); | |
439 | ||
440 | # Abort and return nothing if no model could be read. | |
441 | return unless($model); | |
442 | ||
443 | # Remove any newlines from the model string. | |
444 | chomp($model); | |
445 | ||
446 | # Return the model string. | |
447 | return $model; | |
448 | } | |
449 | ||
450 | # | |
451 | ## Returns the size of a given device in bytes. | |
452 | # | |
453 | sub get_device_size ($) { | |
454 | my ($device) = @_; | |
455 | ||
456 | # Assign device directory. | |
457 | my $device_dir = "$sysfs_block_dir/$device"; | |
458 | ||
459 | # Abort and return nothing if the device dir does not exist | |
460 | # or no size file exists. | |
461 | return unless(-d "$device_dir"); | |
462 | return unless(-f "$device_dir/size"); | |
463 | ||
464 | # Open and read-in the device size. | |
465 | open(SIZE, "$device_dir/size"); | |
466 | my $size = <SIZE>; | |
467 | close(SIZE); | |
468 | ||
469 | # Abort and return nothing if the size could not be read. | |
470 | return unless($size); | |
471 | ||
472 | # Remove any newlines for the size string. | |
473 | chomp($size); | |
474 | ||
475 | # The omited size only contains the amount of blocks from the | |
476 | # given device. To convert this into bytes we have to multiply this | |
477 | # value with 512 bytes for each block. This is a static value used by | |
478 | # the linux kernel. | |
479 | $size = $size * 512; | |
480 | ||
481 | # Return the size in bytes. | |
482 | return $size; | |
483 | } | |
484 | ||
485 | # | |
486 | ## Function which returns all currently mounted devices as a hash. | |
487 | ## example: "sda1" -> "/boot" | |
488 | # | |
489 | sub get_mountpoints () { | |
490 | my %mounts; | |
491 | ||
492 | # Open and read-in the current mounts from the | |
493 | # kernel file system. | |
494 | open(MOUNT, "/proc/mounts"); | |
495 | ||
496 | # Loop through the known mounts. | |
497 | while(<MOUNT>) { | |
498 | # Skip mounts which does not belong to a device. | |
499 | next unless ($_ =~ "^/dev"); | |
500 | ||
501 | # Cut the line into pieces and assign nice variables. | |
502 | my ($dev, $mpoint, $fs, $options, $a, $b) = split(/ /, $_); | |
503 | ||
504 | # Split the device name. | |
505 | my @tmp = split("/", $dev); | |
506 | ||
507 | # Assign the plain device name to a new variable. | |
508 | # It is the last element of the array. | |
509 | my $device = $tmp[-1]; | |
510 | ||
511 | # Add the mountpoint to the hash of mountpoints. | |
512 | $mounts{"$device"} = $mpoint; | |
513 | } | |
514 | ||
515 | # Close file handle. | |
516 | close(MOUNT); | |
517 | ||
518 | # Return the hash of known mountpoints. | |
519 | return %mounts; | |
520 | } | |
521 | ||
522 | sub get_swaps () { | |
523 | my @swaps; | |
524 | ||
525 | # Open and read the swaps file. | |
526 | open(SWAP, "/proc/swaps"); | |
527 | ||
528 | # Loop though the file content. | |
529 | while(<SWAP>) { | |
530 | # Skip lines which does not belong to a device. | |
531 | next unless ($_ =~ "^/dev"); | |
532 | ||
533 | # Split the line and assign nice variables. | |
534 | my ($dev, $type, $size, $used, $prio) = split(/ /, $_); | |
535 | ||
536 | # Cut the device line into pieces. | |
537 | my @tmp = split("/", $dev); | |
538 | ||
539 | my $device = @tmp[-1]; | |
540 | ||
541 | # Add the found swap to the array of swaps. | |
542 | push(@swaps, $device); | |
543 | } | |
544 | ||
545 | # Close file handle. | |
546 | close(SWAP); | |
547 | ||
548 | # Sort the array. | |
549 | @swaps = sort(@swaps); | |
550 | ||
551 | # Return the array. | |
552 | return @swaps; | |
553 | } | |
554 | ||
555 | # | |
556 | ## Function with returns the mounted devices and the used filesystems as a hash. | |
557 | ## Example: "sda1" -> "ext4" | |
558 | # | |
559 | sub get_mountedfs () { | |
560 | my %mountedfs; | |
561 | ||
562 | # Open and read the current mounts from the kernel | |
563 | # file system. | |
564 | open(MOUNT, "/proc/mounts"); | |
565 | ||
566 | # Loop through the known mounts. | |
567 | while(<MOUNT>) { | |
568 | # Skip mounts which does not belong to a device. | |
569 | next unless ($_ =~ "^/dev"); | |
570 | ||
571 | # Split line and assign nice variables. | |
572 | my ($dev, $mpoint, $fs, $options, $a, $b) = split(/ /, $_); | |
573 | ||
574 | # Cut the device line into pieces. | |
575 | my @tmp = split("/", $dev); | |
576 | ||
577 | # Assign the plain device name to a variable | |
578 | # It is the last element of the temporary array. | |
579 | my $device = $tmp[-1]; | |
580 | ||
581 | # Convert the filesystem into lower case format. | |
582 | $fs = lc($fs); | |
583 | ||
584 | # Add the mounted file system. | |
585 | $mountedfs{$device} = $fs; | |
586 | } | |
587 | ||
588 | # Close file handle. | |
589 | close(MOUNT); | |
590 | ||
591 | # Return the hash with the mounted filesystems. | |
592 | return %mountedfs; | |
593 | } | |
594 | ||
595 | # | |
596 | ## Function which returns all known UUID's as a hash. | |
597 | ## Example: "sda1" -> "1234-5678-abcd" | |
598 | # | |
599 | sub get_uuids () { | |
600 | my %uuids; | |
601 | ||
602 | # Directory where the uuid mappings can be found. | |
603 | my $uuid_dir = "/dev/disk/by-uuid"; | |
604 | ||
605 | # Open uuid directory and read-in the current known uuids. | |
606 | opendir(UUIDS, "$uuid_dir"); | |
607 | ||
608 | # Loop through the uuids. | |
609 | foreach my $uuid (readdir(UUIDS)) { | |
610 | # Skip . and .. | |
611 | next if($uuid eq "." or $uuid eq ".."); | |
612 | ||
613 | # Skip everything which is not a symbolic link. | |
614 | next unless(-l "$uuid_dir/$uuid"); | |
615 | ||
616 | # Resolve the target of the symbolic link. | |
617 | my $target = readlink("$uuid_dir/$uuid"); | |
618 | ||
619 | # Split the link target into pieces. | |
620 | my @tmp = split("/", $target); | |
621 | ||
622 | # Assign the last element of the array to the dev variable. | |
623 | my $dev = "$tmp[-1]"; | |
624 | ||
625 | # Add the device and uuid to the hash of uuids. | |
626 | $uuids{$dev} = $uuid; | |
627 | } | |
628 | ||
629 | # Close directory handle. | |
630 | closedir(UUIDS); | |
631 | ||
632 | # Return the hash of uuids. | |
633 | return %uuids; | |
634 | } | |
635 | ||
636 | # | |
637 | ## Returns the device name of a given uuid. | |
638 | # | |
639 | sub device_by_uuid ($) { | |
640 | my ($uuid) = @_; | |
641 | ||
642 | # Reverse the main uuids hash. | |
643 | my %uuids = reverse %uuids; | |
644 | ||
645 | # Lookup and return the device name. | |
646 | return $uuids{$uuid}; | |
647 | } | |
648 | ||
649 | # | |
650 | ## Returns "True" in case a given path is a known mountpoint. | |
651 | # | |
652 | sub is_mounted ($) { | |
653 | my ($mpoint) = @_; | |
654 | ||
655 | my %mountpoints = reverse %mountpoints; | |
656 | ||
657 | # Return "True" if the requested mountpoint is known and | |
658 | # therefore mounted. | |
659 | return 1 if($mountpoints{$mpoint}); | |
660 | } | |
661 | ||
662 | # | |
663 | ## Returns "True" if a given mountpoint is a subdirectory of one | |
664 | ## of the directories specified by the valid_mount_dirs array abouve. | |
665 | # | |
666 | sub is_valid_dir ($) { | |
667 | my ($mpoint) = @_; | |
668 | ||
669 | # Split the given mountpoint into pieces and store them | |
670 | # in a temporay array. | |
671 | my @tmp = split("/", $mpoint); | |
672 | ||
673 | # Exit and return nothing if the temporary array is empty. | |
674 | return unless(@tmp); | |
675 | ||
676 | # Build the root path based on the given mount point. | |
677 | my $root_path = "/" . @tmp[1]; | |
678 | ||
679 | # Check if the root path is valid. | |
680 | return 1 if(grep /$root_path/, @valid_mount_dirs); | |
681 | } | |
682 | ||
683 | # | |
684 | # Returns "True" if a device is used as swap. | |
685 | # | |
686 | sub is_swap ($) { | |
687 | my ($device) = @_; | |
688 | ||
689 | return 1 if(grep /$device/, @swaps); | |
690 | } | |
0aa77c2f SS |
691 | |
692 | # | |
693 | ## Returns "True" if a drive is a configured one. | |
694 | # | |
695 | sub is_configured ($) { | |
696 | my ($path) = @_; | |
697 | ||
698 | # Loop through the hash of configured drives. | |
699 | foreach my $uuid (keys %configured_drives) { | |
700 | return 1 if($configured_drives{$uuid} eq "$path"); | |
701 | } | |
702 | } |