diff options
Diffstat (limited to 'perl-install')
-rw-r--r-- | perl-install/install2.pm | 2 | ||||
-rw-r--r-- | perl-install/install_steps.pm | 4 | ||||
-rw-r--r-- | perl-install/partition_table.pm | 7 | ||||
-rw-r--r-- | perl-install/partition_table_raw.pm | 11 | ||||
-rw-r--r-- | perl-install/resize_fat/Makefile | 12 | ||||
-rw-r--r-- | perl-install/resize_fat/README | 8 | ||||
-rw-r--r-- | perl-install/resize_fat/any.pm | 82 | ||||
-rw-r--r-- | perl-install/resize_fat/boot_sector.pm | 107 | ||||
-rw-r--r-- | perl-install/resize_fat/dir_entry.pm | 72 | ||||
-rw-r--r-- | perl-install/resize_fat/directory.pm | 78 | ||||
-rw-r--r-- | perl-install/resize_fat/fat.pm | 167 | ||||
-rw-r--r-- | perl-install/resize_fat/info_sector.pm | 36 | ||||
-rw-r--r-- | perl-install/resize_fat/io.pm | 74 | ||||
-rw-r--r-- | perl-install/resize_fat/main.pm | 166 |
14 files changed, 7 insertions, 819 deletions
diff --git a/perl-install/install2.pm b/perl-install/install2.pm index 2ac1d1430..470799d39 100644 --- a/perl-install/install2.pm +++ b/perl-install/install2.pm @@ -269,7 +269,7 @@ sub partitionDisks { return if ($o->{isUpgrade}); $::o->{steps}{formatPartitions}{done} = 0; - fs::umount_all($o->{fstab}, $o->{prefix}) if $o->{fstab} && !$::testing; + eval { fs::umount_all($o->{fstab}, $o->{prefix}) } if $o->{fstab} && !$::testing; my $ok = is_empty_array_ref($o->{hds}) ? install_any::getHds($o) : 1; my $auto = $ok && !$o->{partitioning}{readonly} && diff --git a/perl-install/install_steps.pm b/perl-install/install_steps.pm index 464e564ef..353a0e1a1 100644 --- a/perl-install/install_steps.pm +++ b/perl-install/install_steps.pm @@ -121,7 +121,7 @@ sub ask_mntpoint_s { $m{$m} = 1; #- in case the type does not correspond, force it to ext2 - $_->{type} = 0x83 if $m =~ m|^/| && !isDos($_) && !isWin($_) + $_->{type} = 0x83 if $m =~ m|^/| && !isFat($_); } } @@ -143,7 +143,7 @@ sub choosePartitionsToFormat($$) { my $t = fsedit::typeOfPart($_->{device}); $_->{toFormatUnsure} = #- if detected dos/win, it's not precise enough to just compare the types (too many of them) - isDos({ type => $t }) || isWin({type => $t}) ? !isDos($_) && !isWin($_) : $t != $_->{type}; + isFat({ type => $t }) ? !isFat($_) : $t != $_->{type}; } } } diff --git a/perl-install/partition_table.pm b/perl-install/partition_table.pm index 9cb2aee6f..88bf8ef83 100644 --- a/perl-install/partition_table.pm +++ b/perl-install/partition_table.pm @@ -6,7 +6,7 @@ use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK @important_types @fields2save); @ISA = qw(Exporter); %EXPORT_TAGS = ( - types => [ qw(type2name type2fs name2type fs2type isExtended isExt2 isSwap isDos isWin isPrimary isNfs) ], + types => [ qw(type2name type2fs name2type fs2type isExtended isExt2 isSwap isDos isWin isFat isPrimary isNfs) ], ); @EXPORT_OK = map { @$_ } values %EXPORT_TAGS; @@ -95,6 +95,7 @@ sub isSwap($) { $type2fs{$_[0]{type}} eq 'swap' } sub isExt2($) { $type2fs{$_[0]{type}} eq 'ext2' } sub isDos($) { $ {{ 1=>1, 4=>1, 6=>1 }}{$_[0]{type}} } sub isWin($) { $ {{ 0xb=>1, 0xc=>1, 0xe=>1 }}{$_[0]{type}} } +sub isFat($) { isDos($_[0]) || isWin($_[0]) } sub isNfs($) { $_[0]{type} eq 'nfs' } #- small hack sub isPrimary($$) { @@ -165,11 +166,11 @@ sub assign_device_numbers($) { # #- first verify there's at least one primary dos partition, otherwise it #- means it is a secondary disk and all will be false :( - my ($c, @others) = grep { isDos($_) || isWin($_) } @{$hd->{primary}{normal}}; + my ($c, @others) = grep { isFat($_) } @{$hd->{primary}{normal}}; $c or return; $i = ord 'D'; - foreach (grep { isDos($_) || isWin($_) } map { $_->{normal} } @{$hd->{extended}}) { + foreach (grep { isFat($_) } map { $_->{normal} } @{$hd->{extended}}) { $_->{device_windobe} = chr($i++); } $c->{device_windobe} = 'C'; diff --git a/perl-install/partition_table_raw.pm b/perl-install/partition_table_raw.pm index 7cb61a371..6a098af5a 100644 --- a/perl-install/partition_table_raw.pm +++ b/perl-install/partition_table_raw.pm @@ -114,15 +114,4 @@ sub zero_MBR($) { delete $hd->{extended}; } - -sub isFatFormatted($) { - my $dev = devices::make($_[0]); - local *F; sysopen F, $dev, 0 or return; - sysseek F, $common::SECTORSIZE - length($magic), 0; - - #- check magic number - my $tmp; - sysread(F, $tmp, length $magic) && $tmp eq $magic; -} - 1; diff --git a/perl-install/resize_fat/Makefile b/perl-install/resize_fat/Makefile deleted file mode 100644 index 34c257a4e..000000000 --- a/perl-install/resize_fat/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -PRODUCT = libresize -TARSOURCE = $(PRODUCT).tar.bz2 - -.PHONY: clean tar - -clean: - rm -f *~ TAGS $(TARSOURCE) - -tar: clean - cp -f ../common.pm . - cd .. ; tar cfy $(TARSOURCE) $(PRODUCT) ; mv $(TARSOURCE) $(PRODUCT) - rm -f common.pm diff --git a/perl-install/resize_fat/README b/perl-install/resize_fat/README deleted file mode 100644 index 1c4798c82..000000000 --- a/perl-install/resize_fat/README +++ /dev/null @@ -1,8 +0,0 @@ -TODO: - -resize_fat::fat::update($fs) should be called before doing undoable things -(before the sync in construct_dir_tree) - -BUGS: -no known bugs :) -if you found one, please mail pixel@linux-mandrake.com !! diff --git a/perl-install/resize_fat/any.pm b/perl-install/resize_fat/any.pm deleted file mode 100644 index 6acd0b52c..000000000 --- a/perl-install/resize_fat/any.pm +++ /dev/null @@ -1,82 +0,0 @@ -package resize_fat::any; - -use diagnostics; -use strict; -use vars qw($FREE $FILE $DIRECTORY); - -use common qw(:common :constant); -use resize_fat::fat; -use resize_fat::directory; -use resize_fat::dir_entry; - - -$FREE = 0; -$FILE = 1; -$DIRECTORY = 2; - - -1; - - -#- returns the number of clusters for a given filesystem type -sub min_cluster_count($) { - my ($fs) = @_; - (1 << $ {{ FAT16 => 12, FAT32 => 12 }}{$fs->{fs_type}}) - 12; -} -sub max_cluster_count($) { - my ($fs) = @_; - 2 ** $fs->{fs_type_size} - 11; -} - - - -#- calculates the minimum size of a partition, in physical sectors -sub min_size($) { - my ($fs) = @_; - my $count = $fs->{clusters}{count}; - - #- directories are both in `used' and `dirs', so are counted twice - #- It's done on purpose since we're moving all directories. So at the worse - #- moment, 2 directories are there, but that way nothing wrong can happen :) - my $min_cluster_count = max(2 + $count->{used} + $count->{bad} + $count->{dirs}, min_cluster_count($fs)); - - $min_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) + - divide($fs->{cluster_offset}, $SECTORSIZE); -} -#- calculates the maximum size of a partition, in physical sectors -sub max_size($) { - my ($fs) = @_; - - my $max_cluster_count = min($fs->{nb_fat_entries} - 2, max_cluster_count($fs)); - - $max_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) + - divide($fs->{cluster_offset}, $SECTORSIZE); -} - -#- fills in $fs->{fat_flag_map}. -#- Each FAT entry is flagged as either FREE, FILE or DIRECTORY. -sub flag_clusters { - my ($fs) = @_; - my ($cluster, $entry, $type); - - my $f = sub { - ($entry) = @_; - $cluster = resize_fat::dir_entry::get_cluster($entry); - - if (resize_fat::dir_entry::is_file($entry)) { - $type = $FILE; - } elsif (resize_fat::dir_entry::is_directory($entry)) { - $type = $DIRECTORY; - } else { return } - - for (; !resize_fat::fat::is_eof($cluster); $cluster = resize_fat::fat::next($fs, $cluster)) { - $cluster == 0 and die "Bad FAT: unterminated chain for $entry->{name}\n"; - $fs->{fat_flag_map}[$cluster] and die "Bad FAT: cluster $cluster is cross-linked for $entry->{name}\n"; - $fs->{fat_flag_map}[$cluster] = $type; - $fs->{clusters}{count}{dirs}++ if $type == $DIRECTORY; - } - }; - $fs->{fat_flag_map} = [ ($FREE) x ($fs->{nb_clusters} + 2) ]; - $fs->{clusters}{count}{dirs} = 0; - resize_fat::directory::traverse_all($fs, $f); -} diff --git a/perl-install/resize_fat/boot_sector.pm b/perl-install/resize_fat/boot_sector.pm deleted file mode 100644 index 48e2a8d4e..000000000 --- a/perl-install/resize_fat/boot_sector.pm +++ /dev/null @@ -1,107 +0,0 @@ -package resize_fat::boot_sector; - -use diagnostics; -use strict; - -use common qw(:common :system :constant); -use resize_fat::io; -use resize_fat::any; -use resize_fat::directory; - - -my $format = "a3 a8 S C S C S S C S S S I I I S S I S S a458 S"; -my @fields = ( - 'boot_jump', #- boot strap short or near jump - 'system_id', #- Name - can be used to special case partition manager volumes - 'sector_size', #- bytes per logical sector - 'cluster_size_in_sectors', #- sectors/cluster - 'nb_reserved', #- reserved sectors - 'nb_fats', #- number of FATs - 'nb_root_dir_entries', #- number of root directory entries - 'small_nb_sectors', #- number of sectors: big_nb_sectors supersedes - 'media', #- media code - 'fat16_fat_length', #- sectors/FAT for FAT12/16 - 'sectors_per_track', - 'nb_heads', - 'nb_hidden', #- (unused) - 'big_nb_sectors', #- number of sectors (if small_nb_sectors == 0) - -#- FAT32-only entries - 'fat32_fat_length', #- size of FAT in sectors - 'fat32_flags', #- bit8: fat mirroring, - #- low4: active fat - 'fat32_version', #- minor * 256 + major - 'fat32_root_dir_cluster', - 'info_offset_in_sectors', - 'fat32_backup_sector', - -#- Common again... - 'boot_code', #- Boot code (or message) - 'boot_sign', #- 0xAA55 -); - -1; - - -#- trimfs_init_boot_sector() - reads in the boot sector - gets important info out -#- of boot sector, and puts in main structure - performs sanity checks - returns 1 -#- on success, 0 on failureparameters: filesystem an empty structure to fill. -sub read($) { - my ($fs) = @_; - - my $boot = eval { resize_fat::io::read($fs, 0, $SECTORSIZE) }; $@ and die "reading boot sector failed on device $fs->{fs_name}"; - @{$fs}{@fields} = unpack $format, $boot; - - $fs->{nb_sectors} = $fs->{small_nb_sectors} || $fs->{big_nb_sectors}; - $fs->{cluster_size} = $fs->{cluster_size_in_sectors} * $fs->{sector_size}; - - $fs->{boot_sign} == 0xAA55 or die "Invalid signature for a MS-based filesystem."; - $fs->{nb_fats} == 2 or die "Weird number of FATs: $fs->{nb_fats}, not 2.", - $fs->{nb_sectors} < 32 and die "Too few sectors for viable file system\n"; - - if ($fs->{fat16_fat_length}) { - #- asserting FAT16, will be verified later on - $fs->{fs_type} = 'FAT16'; - $fs->{fs_type_size} = 16; - $fs->{fat_length} = $fs->{fat16_fat_length}; - $resize_fat::bad_cluster_value = 0xfff7; #- 2**16 - 1 - } else { - $resize_fat::isFAT32 = 1; - $fs->{fs_type} = 'FAT32'; - $fs->{fs_type_size} = 32; - $fs->{fat_length} = $fs->{fat32_fat_length}; - - $fs->{nb_root_dir_entries} = 0; - $fs->{info_offset} = $fs->{info_offset_in_sectors} * $fs->{sector_size}; - $resize_fat::bad_cluster_value = 0xffffff7; - } - - $fs->{fat_offset} = $fs->{nb_reserved} * $fs->{sector_size}; - $fs->{fat_size} = $fs->{fat_length} * $fs->{sector_size}; - $fs->{root_dir_offset} = $fs->{fat_offset} + $fs->{fat_size} * $fs->{nb_fats}; - $fs->{root_dir_size} = $fs->{nb_root_dir_entries} * resize_fat::directory::entry_size(); - $fs->{cluster_offset} = $fs->{root_dir_offset} + $fs->{root_dir_size} - 2 * $fs->{cluster_size}; - - $fs->{nb_fat_entries} = divide($fs->{fat_size}, $fs->{fs_type_size} / 8); - - #- - 2 because clusters 0 & 1 doesn't exist - $fs->{nb_clusters} = divide($fs->{nb_sectors} * $fs->{sector_size} - $fs->{cluster_offset}, $fs->{cluster_size}) - 2; - - $fs->{dir_entries_per_cluster} = divide($fs->{cluster_size}, psizeof($format)); - -#- $fs->{nb_clusters} >= resize_fat::any::min_cluster_count($fs) or die "error: not enough sectors for a $fs->{fs_type}\n"; - $fs->{nb_clusters} < resize_fat::any::max_cluster_count($fs) or die "error: too many sectors for a $fs->{fs_type}\n"; -} - -sub write($) { - my ($fs) = @_; - my $boot = pack($format, @{$fs}{@fields}); - - eval { resize_fat::io::write($fs, 0, $SECTORSIZE, $boot) }; $@ and die "writing the boot sector failed on device $fs->{fs_name}"; - - if ($resize_fat::isFAT32) { - #- write backup - eval { resize_fat::io::write($fs, $fs->{fat32_backup_sector} * $SECTORSIZE, $SECTORSIZE, $boot) }; - $@ and die "writing the backup boot sector (#$fs->{fat32_backup_sector}) failed on device $fs->{fs_name}"; - } -} diff --git a/perl-install/resize_fat/dir_entry.pm b/perl-install/resize_fat/dir_entry.pm deleted file mode 100644 index cfee23dae..000000000 --- a/perl-install/resize_fat/dir_entry.pm +++ /dev/null @@ -1,72 +0,0 @@ -package resize_fat::dir_entry; - -use diagnostics; -use strict; - - -my $DELETED_FLAG = 0xe5; -my $VOLUME_LABEL_ATTR = 0x08; -my $VFAT_ATTR = 0x0f; -my $DIRECTORY_ATTR = 0x10; - -1; - -sub get_cluster($) { - my ($entry) = @_; - $entry->{first_cluster} + ($resize_fat::isFAT32 ? $entry->{first_cluster_high} * 65536 : 0); -} -sub set_cluster($$) { - my ($entry, $val) = @_; - $entry->{first_cluster} = $val & (1 << 16) - 1; - $entry->{first_cluster_high} = $val >> 16 if $resize_fat::isFAT32; -} - -sub is_directory_raw($) { - my ($entry) = @_; - !is_special_entry($entry) && $entry->{attributes} & $DIRECTORY_ATTR; -} - -sub is_directory($) { - my ($entry) = @_; - is_directory_raw($entry) && $entry->{name} !~ /^\.\.? /; -} - -sub is_volume($) { - my ($entry) = @_; - !is_special_entry($entry) && $entry->{attributes} & $VOLUME_LABEL_ATTR; -} - -sub is_file($) { - my ($entry) = @_; - !is_special_entry($entry) && !is_directory($entry) && !is_volume($entry) && $entry->{length}; -} - - -sub is_special_entry($) { - my ($entry) = @_; - my ($c) = unpack "C", $entry->{name}; - - #- skip empty slots, deleted files, and 0xF6?? (taken from kernel) - $c == 0 || $c == $DELETED_FLAG || $c == 0xF6 and return 1; - - $entry->{attributes} == $VFAT_ATTR and return 1; - 0; -} - - -#- return true if entry has been modified -sub remap { - my ($fat_remap, $entry) = @_; - - is_special_entry($entry) and return; - - my $cluster = get_cluster($entry); - my $new_cluster = $fat_remap->[$cluster]; - - #-print "remapping cluster ", get_first_cluster($fs, $entry), " to $new_cluster"; - - $new_cluster == $cluster and return; #- no need to modify - - set_cluster($entry, $new_cluster); - 1; -} diff --git a/perl-install/resize_fat/directory.pm b/perl-install/resize_fat/directory.pm deleted file mode 100644 index 46e810021..000000000 --- a/perl-install/resize_fat/directory.pm +++ /dev/null @@ -1,78 +0,0 @@ -package resize_fat::directory; - -use diagnostics; -use strict; - -use common qw(:system); -use resize_fat::dir_entry; -use resize_fat::io; - - -my $format = "a8 a3 C C C S7 I"; -my @fields = ( - 'name', - 'extension', - 'attributes', - 'is_upper_case_name', - 'creation_time_low', #- milliseconds - 'creation_time_high', - 'creation_date', - 'access_date', - 'first_cluster_high', #- for FAT32 - 'time', - 'date', - 'first_cluster', - 'length', -); - -1; - -sub entry_size { psizeof($format) } - -#- call `f' for each entry of the directory -#- if f return true, then modification in the entry are taken back -sub traverse($$$) { - my ($fs, $directory, $f) = @_; - - for (my $i = 0;; $i++) { - my $raw = \substr($directory, $i * psizeof($format), psizeof($format)); - - #- empty entry means end of directory - $$raw =~ /^\0*$/ and return $directory; - - my $entry; @{$entry}{@fields} = unpack $format, $$raw; - - &$f($entry) - and $$raw = pack $format, @{$entry}{@fields}; - } - $directory; -} - -sub traverse_all($$) { - my ($fs, $f) = @_; - - my $traverse_all; $traverse_all = sub { - my ($entry) = @_; - - &$f($entry); - - resize_fat::dir_entry::is_directory($entry) - and traverse($fs, resize_fat::io::read_file($fs, resize_fat::dir_entry::get_cluster($entry)), $traverse_all); - - undef; #- no need to write back (cf traverse) - }; - - my $directory = $resize_fat::isFAT32 ? - resize_fat::io::read_file($fs, $fs->{fat32_root_dir_cluster}) : - resize_fat::io::read($fs, $fs->{root_dir_offset}, $fs->{root_dir_size}); - traverse($fs, $directory, $traverse_all); -} - - -#- function used by construct_dir_tree to translate the `cluster' fields in each -#- directory entry -sub remap { - my ($fs, $directory) = @_; - - traverse($fs->{fat_remap}, $directory, sub { resize_fat::dir_entry::remap($fs->{fat_remap}, $_[0]) }); -} diff --git a/perl-install/resize_fat/fat.pm b/perl-install/resize_fat/fat.pm deleted file mode 100644 index e6039077a..000000000 --- a/perl-install/resize_fat/fat.pm +++ /dev/null @@ -1,167 +0,0 @@ -package resize_fat::fat; - -use diagnostics; -use strict; - -use resize_fat::any; -use resize_fat::io; - -1; - -sub read($) { - my ($fs) = @_; - - @{$fs->{fats}} = map { - my $fat = eval { resize_fat::io::read($fs, $fs->{fat_offset} + $_ * $fs->{fat_size}, $fs->{fat_size}) }; - $@ and die "reading fat #$_ failed"; - vec($fat, 0, 8) == $fs->{media} or die "FAT $_ has invalid signature"; - $fat; - } (0 .. $fs->{nb_fats} - 1); - - $fs->{fat} = $fs->{fats}[0]; - - my ($free, $bad, $used) = (0, 0, 0); - - for (my $i = 2; $i < $fs->{nb_clusters} + 2; $i++) { - my $cluster = &next($fs, $i); - if ($cluster == 0) { $free++; } - elsif ($cluster == $resize_fat::bad_cluster_value) { $bad++; } - else { $used++; } - } - @{$fs->{clusters}{count}}{qw(free bad used)} = ($free, $bad, $used); -} - -sub write($) { - my ($fs) = @_; - - sysseek $fs->{fd}, $fs->{fat_offset}, 0 or die "write_fat: seek failed"; - foreach (1..$fs->{nb_fats}) { - syswrite $fs->{fd}, $fs->{fat} or die "write_fat: write failed"; - } -} - - - -#- allocates where all the clusters will be moved to. Clusters before cut_point -#- remain in the same position, however cluster that are part of a directory are -#- moved regardless (this is a mechanism to prevent data loss) (cut_point is the -#- first cluster that won't occur in the new fs) -sub allocate_remap { - my ($fs, $cut_point) = @_; - my ($cluster, $new_cluster); - my $remap = sub { $fs->{fat_remap}[$cluster] = $new_cluster; }; - my $get_new = sub { - $new_cluster = get_free($fs); - 0 < $new_cluster && $new_cluster < $cut_point or die "no free clusters"; - set_eof($fs, $new_cluster); #- mark as used - #-log::ld("resize_fat: [$cluster,", &next($fs, $cluster), "...]->$new_cluster..."); - }; - - $fs->{fat_remap}[0] = 0; - $fs->{last_free_cluster} = 2; - for ($cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) { - if ($cluster < $cut_point) { - if ($fs->{fat_flag_map}[$cluster] == $resize_fat::any::DIRECTORY) { - &$get_new(); - } else { - $new_cluster = $cluster; - } - &$remap(); - } elsif (!is_empty(&next($fs, $cluster))) { - &$get_new(); - &$remap(); - } - } -} - - -#- updates the fat for the resized filesystem -sub update { - my ($fs) = @_; - - for (my $cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) { - if ($fs->{fat_flag_map}[$cluster]) { - my $old_next = &next($fs, $cluster); - my $new = $fs->{fat_remap}[$cluster]; - my $new_next = $fs->{fat_remap}[$old_next]; - - set_available($fs, $cluster); - - is_eof($old_next) ? - set_eof($fs, $new) : - set_next($fs, $new, $new_next); - } - } -} - - -#- - compares the two FATs (one's a backup that should match) - skips first entry -#- - its just a signature (already checked above) NOTE: checks for cross-linking -#- are done in count.c -sub check($) { - my ($fs) = @_; - foreach (@{$fs->{fats}}) { - $_ eq $fs->{fats}[0] or die "FAT tables do not match"; - } -} - -sub endianness16($) { (($_[0] & 0xff) << 8) + ($_[0] >> 8); } -sub endianness($$) { - my ($val, $nb_bits) = @_; - my $r = 0; - for (; $nb_bits > 0; $nb_bits -= 8) { - $r <<= 8; - $r += $val & 0xff; - $val >>= 8; - } - $nb_bits < 0 and die "error: endianness only handle numbers divisible by 8"; - $r; -} - -sub next($$) { - my ($fs, $cluster) = @_; - $cluster > $fs->{nb_clusters} + 2 and die "fat::next: cluster $cluster outside filesystem"; - endianness(vec($fs->{fat}, $cluster, $fs->{fs_type_size}), $fs->{fs_type_size}); - -} -sub set_next($$$) { - my ($fs, $cluster, $new_v) = @_; - $cluster > $fs->{nb_clusters} + 2 and die "fat::set_next: cluster $cluster outside filesystem"; - vec($fs->{fat}, $cluster, $fs->{fs_type_size}) = endianness($new_v, $fs->{fs_type_size}); -} - - -sub get_free($) { - my ($fs) = @_; - foreach (my $i = 0; $i < $fs->{nb_clusters}; $i++) { - my $cluster = ($i + $fs->{last_free_cluster} - 2) % $fs->{nb_clusters} + 2; - is_available(&next($fs, $cluster)) and return $fs->{last_free_cluster} = $cluster; - } - die "no free clusters"; -} - -#- returns true if <cluster> represents an EOF marker -sub is_eof($) { - my ($cluster) = @_; - $cluster >= $resize_fat::bad_cluster_value; -} -sub set_eof($$) { - my ($fs, $cluster) = @_; - set_next($fs, $cluster, $resize_fat::bad_cluster_value + 1); -} - -#- returns true if <cluster> is empty. Note that this includes bad clusters. -sub is_empty($) { - my ($cluster) = @_; - $cluster == 0 || $cluster == $resize_fat::bad_cluster_value; -} - -#- returns true if <cluster> is available. -sub is_available($) { - my ($cluster) = @_; - $cluster == 0; -} -sub set_available($$) { - my ($fs, $cluster) = @_; - set_next($fs, $cluster, 0); -} diff --git a/perl-install/resize_fat/info_sector.pm b/perl-install/resize_fat/info_sector.pm deleted file mode 100644 index 3a6f7cfed..000000000 --- a/perl-install/resize_fat/info_sector.pm +++ /dev/null @@ -1,36 +0,0 @@ -package resize_fat::info_sector; - -use diagnostics; -use strict; - -use common qw(:system); -use resize_fat::io; - -my $format = "a484 I I I a16"; -my @fields = ( - 'unused', - 'signature', #- should be 0x61417272 - 'free_clusters', #- -1 for unknown - 'next_cluster', #- most recently allocated cluster - 'unused2', -); - -1; - - -sub read($) { - my ($fs) = @_; - my $info = resize_fat::io::read($fs, $fs->{info_offset}, psizeof($format)); - @{$fs->{info_sector}}{@fields} = unpack $format, $info; - $fs->{info_sector}{signature} == 0x61417272 or die "Invalid information sector signature\n"; -} - -sub write($) { - my ($fs) = @_; - $fs->{info_sector}{free_clusters} = $fs->{clusters}->{count}->{free}; - $fs->{info_sector}{next_cluster} = 2; - - my $info = pack $format, @{$fs->{info_sector}}{@fields}; - - resize_fat::io::write($fs, $fs->{info_offset}, psizeof($format), $info); -} diff --git a/perl-install/resize_fat/io.pm b/perl-install/resize_fat/io.pm deleted file mode 100644 index 48309db91..000000000 --- a/perl-install/resize_fat/io.pm +++ /dev/null @@ -1,74 +0,0 @@ -package resize_fat::io; - -use diagnostics; -use strict; - -use resize_fat::fat; - -1; - - -sub read($$$) { - my ($fs, $pos, $size) = @_; - my $buf; - sysseek $fs->{fd}, $pos, 0 or die "seeking to byte #$pos failed on device $fs->{fs_name}"; - sysread $fs->{fd}, $buf, $size or die "reading at byte #$pos failed on device $fs->{fs_name}"; - $buf; -} -sub write($$$$) { - my ($fs, $pos, $size, $buf) = @_; - sysseek $fs->{fd}, $pos, 0 or die "seeking to byte #$pos failed on device $fs->{fs_name}"; - syswrite $fs->{fd}, $buf or die "writing at byte #$pos failed on device $fs->{fs_name}"; -} - -sub read_cluster($$) { - my ($fs, $cluster) = @_; - my $buf; - - eval { - $buf = &read($fs, - $fs->{cluster_offset} + $cluster * $fs->{cluster_size}, - $fs->{cluster_size}); - }; @$ and die "reading cluster #$cluster failed on device $fs->{fs_name}"; - $buf; -} -sub write_cluster($$$) { - my ($fs, $cluster, $buf) = @_; - - eval { - &write($fs, - $fs->{cluster_offset} + $cluster * $fs->{cluster_size}, - $fs->{cluster_size}, - $buf); - }; @$ and die "writing cluster #$cluster failed on device $fs->{fs_name}"; -} - -sub read_file($$) { - my ($fs, $cluster) = @_; - my $buf = ''; - - for (; !resize_fat::fat::is_eof($cluster); $cluster = resize_fat::fat::next($fs, $cluster)) { - $cluster == 0 and die "Bad FAT: unterminated chain\n"; - $buf .= read_cluster($fs, $cluster); - } - $buf; -} - -sub check_mounted($) { - my ($f) = @_; - - local *F; - open F, "/proc/mounts" or die "error opening /proc/mounts\n"; - foreach (<F>) { - /^$f\s/ and die "device is mounted"; - } -} - -sub open($) { - my ($fs) = @_; - - check_mounted($fs->{device}); - - sysopen F, $fs->{fs_name}, 2 or sysopen F, $fs->{fs_name}, 0 or die "error opening device $fs->{fs_name} for writing\n"; - $fs->{fd} = \*F; -} diff --git a/perl-install/resize_fat/main.pm b/perl-install/resize_fat/main.pm deleted file mode 100644 index 1e5ac62be..000000000 --- a/perl-install/resize_fat/main.pm +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -# DiskDrake -# Copyright (C) 1999 MandrakeSoft (pixel@linux-mandrake.com) -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# This is mainly a perl rewrite of the work of Andrew Clausen (libresize) - -package resize_fat::main; - -use diagnostics; -use strict; - -use log; -use common qw(:common :system :constant); -use resize_fat::boot_sector; -use resize_fat::info_sector; -use resize_fat::directory; -use resize_fat::io; -use resize_fat::fat; -use resize_fat::any; - - -1; - -#- - reads in the boot sector/partition info., and tries to make some sense of it -sub new($$$) { - my ($type, $device, $fs_name) = @_; - my $fs = { device => $device, fs_name => $fs_name } ; - - resize_fat::io::open($fs); - resize_fat::boot_sector::read($fs); - $resize_fat::isFAT32 and eval { resize_fat::info_sector::read($fs) }; - resize_fat::fat::read($fs); - resize_fat::fat::check($fs); - resize_fat::any::flag_clusters($fs); - - bless $fs, $type; -} - -#- copy all clusters >= <start_cluster> to a new place on the partition, less -#- than <start_cluster>. Only copies files, not directories. -#- (use of buffer needed because the seeks slow like hell the hard drive) -sub copy_clusters { - my ($fs, $cluster) = @_; - my @buffer; - my $flush = sub { - while (@buffer) { - my $cluster = shift @buffer; - resize_fat::io::write_cluster($fs, $cluster, shift @buffer); - } - }; - for (; $cluster < $fs->{nb_clusters} + 2; $cluster++) { - $fs->{fat_flag_map}[$cluster] == $resize_fat::any::FILE or next; - push @buffer, $fs->{fat_remap}[$cluster], resize_fat::io::read_cluster($fs, $cluster); - @buffer > 50 and &$flush(); - } - &$flush(); -} - -#- Constructs the new directory tree to match the new file locations. -sub construct_dir_tree { - my ($fs) = @_; - - if ($resize_fat::isFAT32) { - #- fat32's root must remain in the first 64k clusters - #- so don't set it as DIRECTORY, it will be specially handled - $fs->{fat_flag_map}[$fs->{fat32_root_dir_cluster}] = $resize_fat::any::FREE; - } - - for (my $cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) { - $fs->{fat_flag_map}[$cluster] == $resize_fat::any::DIRECTORY or next; - - resize_fat::io::write_cluster($fs, - $fs->{fat_remap}[$cluster], - resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster))); - } - - sync(); - - #- until now, only free clusters have been written. it's a null operation if we stop here. - #- it means no corruption :) - # - #- now we must be as fast as possible! - - #- remapping non movable root directory - if ($resize_fat::isFAT32) { - my $cluster = $fs->{fat32_root_dir_cluster}; - - resize_fat::io::write_cluster($fs, - $fs->{fat_remap}[$cluster], - resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster))); - } else { - resize_fat::io::write($fs, $fs->{root_dir_offset}, $fs->{root_dir_size}, - resize_fat::directory::remap($fs, resize_fat::io::read($fs, $fs->{root_dir_offset}, $fs->{root_dir_size}))); - } -} - -sub min_size($) { &resize_fat::any::min_size } -sub max_size($) { &resize_fat::any::max_size } - -#- resize -#- - size is in sectors -#- - checks boundaries before starting -#- - copies all data beyond new_cluster_count behind the frontier -sub resize { - my ($fs, $size) = @_; - - my ($min, $max) = (min_size($fs), max_size($fs)); - - - $size += $min if $size =~ /^\+/; - - $size >= $min or die "Minimum filesystem size is $min sectors"; - $size <= $max or die "Maximum filesystem size is $max sectors"; - - log::l("resize_fat: Partition size fill be ", $size * $SECTORSIZE >> 20, "Mb (well exactly ${size} sectors)"); - - my $new_data_size = $size * $SECTORSIZE - $fs->{cluster_offset}; - my $new_nb_clusters = divide($new_data_size, $fs->{cluster_size}); - - log::l("resize_fat: Allocating new clusters"); - resize_fat::fat::allocate_remap($fs, $new_nb_clusters); - - log::l("resize_fat: Copying files"); - copy_clusters($fs, $new_nb_clusters); - - log::l("resize_fat: Copying directories"); - construct_dir_tree($fs); - - log::l("Writing new FAT..."); - resize_fat::fat::update($fs); - resize_fat::fat::write($fs); - - $fs->{nb_sectors} = $size; - $fs->{nb_clusters} = $new_nb_clusters; - $fs->{clusters}{count}->{free} = - $fs->{nb_clusters} - $fs->{clusters}{count}->{used} - $fs->{clusters}->{count}->{bad} - 2; - - $fs->{system_id} = 'was here!'; - $fs->{small_nb_sectors} = 0; - $fs->{big_nb_sectors} = $size; - - log::l("resize_fat: Writing new boot sector..."); - - resize_fat::boot_sector::write($fs); - - $resize_fat::isFAT32 and eval { resize_fat::info_sector::write($fs) }; #- doesn't matter if this fails - its pretty useless! - - sync(); - log::l("resize_fat: done"); -} - |