diff options
Diffstat (limited to 'move/img')
0 files changed, 0 insertions, 0 deletions
![]() |
index : drakx | |
Mageia Installer and base platform for many utilities | Thierry Vignaud [tv] |
summaryrefslogtreecommitdiffstats |
package devices; # $Id$
use diagnostics;
use strict;
use common;
use run_program;
use log;
use c;
sub size($) {
local *F;
sysopen F, $_[0], 0 or log::l("open $_[0]: $!"), return 0;
my $valid_offset = sub { sysseek(F, $_[0], 0) && sysread(F, my $a, 1) };
#- first try getting the size nicely
if (my $size = c::total_sectors(fileno F)) {
return $size * $common::SECTORSIZE;
}
#- sad it didn't work, well searching the size using the dichotomy algorithm!
my $low = 0;
my ($high, $mid);
#- first find n where 2^n < size <= 2^n+1
for ($high = 1; $high > 0 && &$valid_offset($high); $high *= 2) { $low = $high }
while ($low < $high - 1) {
$mid = int ($low + $high) / 2;
&$valid_offset($mid) ? $low : $high = $mid;
}
$low + 1;
}
sub del_loop {
my ($dev) = @_;
run_program::run("losetup", "-d", $dev);
}
sub find_free_loop {
foreach (0..7) {
my $dev = make("loop$_");
local *F;
sysopen F, $dev, 2 or next;
!ioctl(F, c::LOOP_GET_STATUS(), my $tmp) && $! == 6 or next; #- 6 == ENXIO
close F;
return $dev;
}
die "no free loop found";
}
sub set_loop {
my ($file, $encrypt_key, $encryption) = @_;
my $dev = find_free_loop();
if ($encrypt_key && $encryption) {
my $cmd = "losetup -p 0 -e $encryption $dev $file";
log::l("calling $cmd");
local *F;
open F, "|$cmd";
print F $encrypt_key;
close F or die "losetup failed";
} else {
run_program::run("losetup", $dev, $file) or return;
}
$dev;
}
sub entry {
my ($type, $major, $minor);
local ($_) = @_;
if (/^0x([\da-f]{3,4})$/i) {
$type = c::S_IFBLK();
($major, $minor) = unmakedev(hex $1);
} elsif (/^sd(.)(\d{0,2})/) {
$type = c::S_IFBLK();
$major = 8;
$minor = 16 * (ord($1) - ord('a')) + ($2 || 0);
} elsif (/^hd(.)(\d{0,2})/) {