version 1.148, 2021/08/07 00:09:57 |
version 1.149, 2021/08/07 00:10:49 |
|
|
return handle; |
return handle; |
} |
} |
|
|
|
/* XXX returing &static is error-prone. Refactor to fill *Attrib argument */ |
static Attrib * |
static Attrib * |
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet) |
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet) |
{ |
{ |
|
|
SFTP_DIRENT **dir_entries; |
SFTP_DIRENT **dir_entries; |
char *filename, *new_from_path = NULL, *new_to_path = NULL; |
char *filename, *new_from_path = NULL, *new_to_path = NULL; |
mode_t mode = 0777; |
mode_t mode = 0777; |
|
Attrib curdir; |
|
|
if (depth >= MAX_DIR_DEPTH) { |
if (depth >= MAX_DIR_DEPTH) { |
error("Maximum directory depth exceeded: %d levels", depth); |
error("Maximum directory depth exceeded: %d levels", depth); |
|
|
if (print_flag) |
if (print_flag) |
mprintf("Retrieving %s\n", from_path); |
mprintf("Retrieving %s\n", from_path); |
|
|
dirattrib->flags &= ~SSH2_FILEXFER_ATTR_SIZE; |
curdir = *dirattrib; /* dirattrib will be clobbered */ |
dirattrib->flags &= ~SSH2_FILEXFER_ATTR_UIDGID; |
curdir.flags &= ~SSH2_FILEXFER_ATTR_SIZE; |
if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { |
curdir.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; |
mode = dirattrib->perm & 01777; |
if ((curdir.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) == 0) { |
dirattrib->perm = mode | (S_IWUSR|S_IXUSR); /* temp */ |
debug("Origin did not send permissions for " |
} else { |
|
debug("Server did not send permissions for " |
|
"directory \"%s\"", to_path); |
"directory \"%s\"", to_path); |
|
curdir.perm = S_IWUSR|S_IXUSR; |
|
curdir.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; |
} |
} |
if (do_mkdir(to, to_path, dirattrib, print_flag) != 0) |
/* We need to be able to write to the directory while we transfer it */ |
return -1; |
mode = curdir.perm & 01777; |
|
curdir.perm = mode | (S_IWUSR|S_IXUSR); |
|
|
|
/* |
|
* sftp lacks a portable status value to match errno EEXIST, |
|
* so if we get a failure back then we must check whether |
|
* the path already existed and is a directory. Ensure we can |
|
* write to the directory we create for the duration of the transfer. |
|
*/ |
|
if (do_mkdir(to, to_path, &curdir, 0) != 0) { |
|
if ((dirattrib = do_stat(to, to_path, 0)) == NULL) |
|
return -1; |
|
if (!S_ISDIR(dirattrib->perm)) { |
|
error("\"%s\" exists but is not a directory", to_path); |
|
return -1; |
|
} |
|
} |
|
curdir.perm = mode; |
|
|
if (do_readdir(from, from_path, &dir_entries) == -1) { |
if (do_readdir(from, from_path, &dir_entries) == -1) { |
error("%s: Failed to get directory contents", from_path); |
error("%s: Failed to get directory contents", from_path); |
return -1; |
return -1; |
|
|
free(new_to_path); |
free(new_to_path); |
free(new_from_path); |
free(new_from_path); |
|
|
dirattrib->perm = mode; /* original mode */ |
do_setstat(to, to_path, &curdir); |
do_setstat(to, to_path, dirattrib); |
|
|
|
free_sftp_dirents(dir_entries); |
free_sftp_dirents(dir_entries); |
|
|