#!/usr/bin/perl use 5.14.0; use strict; use warnings; use Cwd qw(abs_path); use File::Basename qw(basename); use File::Copy qw(copy); use POSIX qw(ceil); sub usage { say "Usage: " . basename($0) . " [ infile ] [ outdir ]"; exit; } if (!$ARGV[0] || !$ARGV[1]) { usage(); } elsif (! -f $ARGV[0] || ! -d $ARGV[1]) { usage(); } my $limit = int((4294967295 / 1024 / 1024)); my $infile = abs_path($ARGV[0]); my $outfile; my $outdir = abs_path($ARGV[1]); chomp(my @free = split(' ', `df --block-size=1 "$outdir" | tail --lines 1`)); my $free = int(($free[3] / 1024 / 1024)); my $size = ceil(((stat($infile))[7] / 1024 / 1024)); say "$free megabytes free in $outdir"; say "$infile is $size megabytes"; if ($size > $free) { say "Not enough free space in '$outdir'"; exit; } if ($size > $limit) { my $parts = ceil(( $size / $limit )); my $last = $parts; my $skip = 0; foreach my $n (1 .. $parts) { $outfile = $outdir . '/' . basename($infile) . '.part' . $n; if (-f $outfile) { say "${outfile}: already exists!"; exit; } say "${outfile}: writing..."; if ($n == 1) { system('dd', 'if=' . "$infile", 'of=' . "$outfile", 'bs=1MB', 'count=' . $limit); $skip += $limit; } elsif ($n == $last) { system('dd', 'if=' . "$infile", 'of=' . "$outfile", 'bs=1MB', 'skip=' . "$skip"); } else { system('dd', 'if=' . "$infile", 'of=' . "$outfile", 'bs=1MB', 'skip=' . "$skip", 'count=' . $limit); $skip += $limit; } if ($? != 0 && $? != 2) { say "Something went wrong with 'dd': $!"; exit; } } } else { $outfile = $outdir . '/' . basename($infile); if (! -f $outfile) { say "${outfile}: writing..."; copy($infile, $outfile) or die "Can't copy '$infile': $!"; } else { say "${outfile}: already exists!"; exit; } } say "\nDone copying file!";