#!/usr/bin/perl # == fill == rune bjerke # version 1.0 - 2000-06-08 - initial version # version 1.1 - 2001-06-24 - removed unix 'du' dependency #$pwd = `pwd`; #chop $pwd; $syntax = "\nsyntax: fill [switches] size\n\n"; $syntax .= "fill, a pretty-stupid-algorithm-but-works-to-some-extent-anyhow tool\n"; $syntax .= "version 1.1 - \n\n"; $syntax .= "switches:\n"; $syntax .= " -l or --softlinks Create directories with softlinks to the directories (unix only, uses 'ln -s')\n"; $syntax .= " -s or --simulation Just simulate\n"; $syntax .= "\n'size' can be # of kilobytes or # of megabytes (append \"mb\" after #,\n ie 100mb) or \"CD\" for 650mb.\n\n"; if ($#ARGV < 0) { print $syntax; exit; } $simulation = 0; $softlinks = 0; $seqno = 0; while ($ARGV[0] =~ /^\-/) { $s = shift @ARGV; if (($s eq "--simulation") || ($s eq "-s")) { $simulation = 1; } elsif (($s eq "--softlinks") || ($s eq "-l")) { $softlinks = 1; } else { print "ERROR: Unknown switch: $s\n\n".$syntax; exit; } } $maxsz = -1; if ($ARGV[0] eq "CD" || $ARGV[0] eq "cd") { $maxsz = 650 * 1024 * 1024; } elsif ($ARGV[0] =~ /^(\d+)[Mm][Bb]?$/) { $maxsz = $1 * 1024 * 1024; } elsif ($ARGV[0] =~ /^(\d+)[Kk][Bb]?$/) { $maxsz = $1 * 1024; } else { $maxsz = int($ARGV[0]); } if ($maxsz <= 0) { print "ERROR: Size parameter not specified, or 0!\n\n" . $syntax; exit; } print "maxsz = $maxsz\n"; print "softlinks = " . (($softlinks == 1) ? "[ ON ]" : "[ off ]") . "\n"; print "simulation = " . (($simulation == 1) ? "[ ON ]" : "[ off ]") . "\n"; #$DU = "/usr/bin/du"; #$cmd = "$DU -s *|sort -n"; @xdirs = (); print "getting directory sizes: \n"; opendir(DIR, "."); my @files = grep { /^[^.]/ && /^.+$/ } readdir(DIR); closedir(DIR); foreach $f (@files) { if (-d $f) { my %d = ( 'dir'=>$f, 'sz'=>0 ); $d{'sz'} = du($f); push @xdirs, \%d; print " $f: ".$d{'sz'}."\n"; } } print "\n"; print "sorting directory sizes: "; @dirs = sort {$$a{sz} cmp $$b{sz}} @xdirs; print "done\n"; #foreach $d (@dirs) { # print $$d{'dir'}." :: ".$$d{'sz'}."\n"; #} #exit; #open(PIPE, "$cmd |") || die("pipe failed ($cmd)!"); #while ($l = ) { # chop $l; # ($sz, $dir) = split /[ \t]+/, $l, 2; # if ( -d "$dir" && ! -e "$dir/.cdr" ) { # if (!($dir =~ /^__fill_part_/)) { # print "."; # push @dirs, $dir; # push @sizes, $sz; # } # } #} #close(PIPE); #print "\n"; $more = 1; while ($more == 1) { $seqno++; print "\n\n".$seqno.")"; printf("\n\n%10s files\n---------- -----\n", "size"); my @fill = (); my @indexes = (); $leftsz = $maxsz; $totsz = 0; for ($i=$#dirs; $i>=0; $i--) { $dir = $dirs[$i]->{'dir'}; $sz = $dirs[$i]->{'sz'}; if ($leftsz > $sz) { push @indexes, $i; push @fill, $dir; $leftsz -= $sz; $totsz += $sz; printf("%10d %s\n", $sz, $dir); } } printf("---------- -----\n%10d (sum)\n", $totsz); printf("%10d (slack)\n", $leftsz); for ($i=0; $#indexes>=$i; $i++) { splice @dirs, $indexes[$i], 1; } if ($#dirs == -1) { last; } print "more? [yn] "; $i = ; if ($i =~ /y/) { $more = 1; } else { $more = 0; } #$date = `date`; if (($simulation == 0) && ($softlinks == 1)) { print "Making softlinks: "; $dir2 = "__fill_part_".$seqno; mkdir $dir2, 0755; print "o"; foreach $dir (@fill) { $ln = "ln -s '../" . $dir . "' '".$dir2."/" . $dir . "'"; `$ln`; print "."; } print "\n"; } #if (($more == 1) && ($simulation == 0)) { # foreach $dir (@fill) { # open(TAG, ">$dir/.cdr"); # print TAG $date; # close(TAG); # } #} } exit; sub du { my $dir = shift; my $verbose = shift; my $sz = 0; my @dirs; if ($verbose == 1) { print "$dir: "; } # get dirlisting opendir(DIR, "$dir"); my @files = grep { /^[^.]/ && /^.+$/ } readdir(DIR); closedir(DIR); # scan through dirlist foreach my $file (@files) { $fullname = "$dir/$file"; if (-d $fullname) { push @dirs, $file; } else { $sz += (stat($fullname))[7]; } } if ($verbose == 1) { print "$sz\n"; } # process all subdirectories foreach my $file (@dirs) { my $x = du("$dir\\$file", $verbose); if ($x == -1) { return -1; } else { $sz += $x; }; } return $sz; }