This seems to work:
sub _mkpath_local {
my ($sftp, $path, $perm, $parent) = @_;
my @parts = File::Spec->splitdir($path);
my @tail;
if ($debug and $debug & 32768) {
my $target = File::Spec->join(@parts);
_debug "_mkpath_local('$target')";
}
if ($parent) {
pop @parts while @parts and not length $parts[-1];
@parts or goto top_dir_reached;
pop @parts;
@parts or return 1;
}
while (1) {
my $target = File::Spec->join(@parts);
if (!defined $target or -e $target) {
if (!defined $target or -d $target) {
while (@tail) {
$target = defined($target) ? File::Spec->join($target, shift(@tail)) : shift(@tail);
$debug and $debug and 32768 and _debug "creating local directory $target";
unless (CORE::mkdir $target, $perm) {
unless (do { local $!; -d $target}) {
$sftp->_set_error(SFTP_ERR_LOCAL_MKDIR_FAILED,
"mkdir '$target' failed", $!);
return;
}
}
}
return 1;
}
else {
$sftp->_set_error(SFTP_ERR_LOCAL_BAD_OBJECT,
"Local file '$target' is not a directory");
return;
}
}
@parts or last;
unshift @tail, pop @parts;
}
top_dir_reached:
$sftp->_set_error(SFTP_ERR_LOCAL_MKDIR_FAILED,
"mkpath failed, top dir reached");
return;
}