summaryrefslogtreecommitdiffstats
path: root/perl-install/share/themes/marble3d-bg1.png
Commit message (Expand)AuthorAgeFilesLines
* re-adding with -kbPascal Rigaux2001-07-031-0/+0
* removing for re-adding with -kbPascal Rigaux2001-07-031-0/+0
* no_commentPascal Rigaux1999-11-051-0/+0
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
package resize_fat::fat; # $Id$

use diagnostics;
use strict;

use resize_fat::any;
use resize_fat::io;
use resize_fat::c_rewritten;

1;

sub read($) {
    my ($fs) = @_;

    resize_fat::c_rewritten::read_fat(fileno $fs->{fd}, $fs->{fat_offset}, $fs->{fat_size}, $fs->{media});

    @{$fs->{clusters}{count}}{qw(free bad used)} =
      resize_fat::c_rewritten::scan_fat($fs->{nb_clusters}, $fs->{fs_type_size});
}

sub write($) {
    my ($fs) = @_;

    sysseek $fs->{fd}, $fs->{fat_offset}, 0 or die "write_fat: seek failed";
    foreach (1..$fs->{nb_fats}) {
	resize_fat::c_rewritten::write_fat(fileno $fs->{fd}, $fs->{fat_size});
    }
}



#- 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 { resize_fat::c_rewritten::set_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...");
    };

    #- this must call allocate_fat_remap that zeroes the buffer allocated.
    resize_fat::c_rewritten::allocate_fat_remap($fs->{nb_clusters} + 2);

    $fs->{last_free_cluster} = 2;
    for ($cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
	if ($cluster < $cut_point) {
	    if (resize_fat::c_rewritten::flag($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 (resize_fat::c_rewritten::flag($cluster)) {
	     my $old_next = &next($fs, $cluster);
	     my $new      = resize_fat::c_rewritten::fat_remap($cluster);
	     my $new_next = resize_fat::c_rewritten::fat_remap($old_next);

	     set_available($fs, $cluster);

	     is_eof($old_next) ?
		 set_eof($fs, $new) :
		 set_next ($fs, $new, $new_next);
	 }
    }
}


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;
}

*next = \&resize_fat::c_rewritten::next;
*set_next = \&resize_fat::c_rewritten::set_next;



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);
}