unlink($tmp_to) or warn "unlink: $tmp_to: $!"; # Try, possibly in vain, to clean up
die "rename: $tmp_to -> $from: $saved_bang";
}
- print STDERR "\b \b";
+ print STDERR "\b";
}
my $link_dir = shift @ARGV;
return ($prefix, $suffix);
}
+sub mkdir_p {
+ my ($dir) = @_;
+ return if -d $dir;
+ $dir =~ s:/+$::os;
+ my $parent;
+ ($parent = $dir) =~ s:[^/]+$::os;
+ if ($parent ne $dir) {
+ mkdir_p($parent);
+ print STDERR 'm';
+ mkdir($dir) or die "mkdir: $dir: $!";
+ }
+ die "mkdir: $dir: $!" unless -d $dir;
+}
+
sub prepare_parents {
my ($link_dir, $file) = @_;
my ($prefix, $suffix) = slash_prefix($file);
my $parent = "$link_dir/$prefix";
- print STDERR 'm';
- mkpath($parent, { verbose => 0 });
- print STDERR "\b";
- die "mkpath: $parent: $!" unless -d $parent;
+ mkdir_p($parent);
return "$parent/$suffix";
}
print STDERR "\b";
# Which file are we keeping?
- my $keep_file;
+ my $keep_ino;
# If digest link exists, link it to file
if ($digest_st) {
# Old, replace input with old file
print STDERR '-';
link_files($digest_link, $file);
- $keep_file = $digest_link;
+ $keep_ino = $digest_st->ino;
} else {
# New, add input to digest
print STDERR '+';
link_files($file, $digest_link);
- $keep_file = $file;
+ $keep_ino = $st->ino;
}
# A link to the inode indicates we are done, so do it last
+ my $keep_link = prepare_parents("$link_dir/inode", $keep_ino);
print STDERR '_';
- link_files($keep_file, $inode_link);
+ link_files($keep_link, $inode_link);
}
};
warn "$file: $@" if $@;
}
+# Garbage collection
+print STDERR "\nGarbage collection in '$link_dir'...";
+chdir($link_dir) || die "chdir: $link_dir: $!";
+print STDERR "\nRemoving files with link count < 3...";
+system("find digest inode -type f -links -3 -print0 | xargs -0 rm -f") and die "system: exit status $?";
+print STDERR "\nRemoving empty directories...";
+system("find digest inode -type d -empty -print0 | xargs -0r rmdir -p --ignore-fail-on-non-empty") and die "system: exit status $?";
+print STDERR "\nDone.\n";
+
exit(0);
__END__