#! /usr/bin/perl # Copyright (C) 2007 Nick Urbanik # 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 # of the License, 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. use warnings; use strict; use Getopt::Long; use Fcntl qw{:DEFAULT :seek}; use Time::HiRes qw{sleep}; my $numparts = 100; my $debug; sub usage { ( my $prog = $0 ) =~ s{.*/}{}; print < \$numparts, 'debug' => \$debug, ) or usage; FILE: foreach my $file ( @ARGV ) { my $length = -s $file or die "File '$file' is of zero length\n"; print "length = $length\n" if $debug; my @positions = ( $length ); ++$numparts; for ( my $i = 1; $i < $numparts; ++$i ) { $positions[ $i ] = $positions[ $i - 1 ] - int rand ( 2 * $positions[ $i - 1 ] / ( $numparts - $i ) ); $positions[ $i ] = 0 if $positions[ $i ] < 0; } $positions[ -1 ] = 0; @positions = reverse @positions; print join( "\n", @positions ), "\n" if $debug; open my $fh, '<', $file or die "Cannot open file '$file': $!"; sysopen $fh, $file, O_RDONLY or die "Cannot sysopen file '$file': $!"; my $lastpos = shift @positions; POS: foreach my $pos ( @positions ) { sysseek $fh, $lastpos, SEEK_SET or die "Cannot seek to position '$pos' in '$file': $!"; my $to_read = $pos - $lastpos; next POS unless $to_read; my $buffer; my $bytes_read = sysread $fh, $buffer, $to_read; die "Error reading $to_read bytes from $file at position $lastpos: $!\n" unless defined $bytes_read; die "Read $bytes_read bytes instead of $to_read from $file at position $lastpos\n" unless $bytes_read == $to_read; my $written = syswrite STDOUT, $buffer; $written == $to_read or die "Could write only $written bytes instead of $to_read bytes\n"; $lastpos = $pos; sleep rand 1; } close $fh or die "Cannot close file '$file': $!"; }