version 1.104, 2013/09/19 00:49:12 |
version 1.105, 2013/10/11 02:45:36 |
|
|
|
|
|
|
static int |
static int |
do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, |
do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, |
SFTP_DIRENT ***dir) |
SFTP_DIRENT ***dir) |
{ |
{ |
Buffer msg; |
Buffer msg; |
|
|
longname = buffer_get_string(&msg, NULL); |
longname = buffer_get_string(&msg, NULL); |
a = decode_attrib(&msg); |
a = decode_attrib(&msg); |
|
|
if (printflag) |
if (print_flag) |
printf("%s\n", longname); |
printf("%s\n", longname); |
|
|
/* |
/* |
|
|
} |
} |
|
|
int |
int |
do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) |
do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) |
{ |
{ |
u_int status, id; |
u_int status, id; |
|
|
|
|
strlen(path), a); |
strlen(path), a); |
|
|
status = get_status(conn, id); |
status = get_status(conn, id); |
if (status != SSH2_FX_OK && printflag) |
if (status != SSH2_FX_OK && print_flag) |
error("Couldn't create directory: %s", fx2txt(status)); |
error("Couldn't create directory: %s", fx2txt(status)); |
|
|
return(status); |
return(status); |
|
|
|
|
int |
int |
do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
Attrib *a, int pflag, int resume) |
Attrib *a, int preserve_flag, int resume_flag) |
{ |
{ |
Attrib junk; |
Attrib junk; |
Buffer msg; |
Buffer msg; |
|
|
return(-1); |
return(-1); |
} |
} |
|
|
local_fd = open(local_path, O_WRONLY | O_CREAT | (resume ? : O_TRUNC), |
local_fd = open(local_path, |
mode | S_IWUSR); |
O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR); |
if (local_fd == -1) { |
if (local_fd == -1) { |
error("Couldn't open local file \"%s\" for writing: %s", |
error("Couldn't open local file \"%s\" for writing: %s", |
local_path, strerror(errno)); |
local_path, strerror(errno)); |
goto fail; |
goto fail; |
} |
} |
offset = highwater = 0; |
offset = highwater = 0; |
if (resume) { |
if (resume_flag) { |
if (fstat(local_fd, &st) == -1) { |
if (fstat(local_fd, &st) == -1) { |
error("Unable to stat local file \"%s\": %s", |
error("Unable to stat local file \"%s\": %s", |
local_path, strerror(errno)); |
local_path, strerror(errno)); |
|
|
fatal("Transfer complete, but requests still in queue"); |
fatal("Transfer complete, but requests still in queue"); |
/* Truncate at highest contiguous point to avoid holes on interrupt */ |
/* Truncate at highest contiguous point to avoid holes on interrupt */ |
if (read_error || write_error || interrupted) { |
if (read_error || write_error || interrupted) { |
if (reordered && resume) { |
if (reordered && resume_flag) { |
error("Unable to resume download of \"%s\": " |
error("Unable to resume download of \"%s\": " |
"server reordered requests", local_path); |
"server reordered requests", local_path); |
} |
} |
|
|
if (interrupted || status != SSH2_FX_OK) |
if (interrupted || status != SSH2_FX_OK) |
status = -1; |
status = -1; |
/* Override umask and utimes if asked */ |
/* Override umask and utimes if asked */ |
if (pflag && fchmod(local_fd, mode) == -1) |
if (preserve_flag && fchmod(local_fd, mode) == -1) |
error("Couldn't set mode on \"%s\": %s", local_path, |
error("Couldn't set mode on \"%s\": %s", local_path, |
strerror(errno)); |
strerror(errno)); |
if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { |
if (preserve_flag && |
|
(a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { |
struct timeval tv[2]; |
struct timeval tv[2]; |
tv[0].tv_sec = a->atime; |
tv[0].tv_sec = a->atime; |
tv[1].tv_sec = a->mtime; |
tv[1].tv_sec = a->mtime; |
|
|
} |
} |
|
|
static int |
static int |
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, |
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
Attrib *dirattrib, int pflag, int printflag, int depth, int resume) |
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag) |
{ |
{ |
int i, ret = 0; |
int i, ret = 0; |
SFTP_DIRENT **dir_entries; |
SFTP_DIRENT **dir_entries; |
|
|
error("\"%s\" is not a directory", src); |
error("\"%s\" is not a directory", src); |
return -1; |
return -1; |
} |
} |
if (printflag) |
if (print_flag) |
printf("Retrieving %s\n", src); |
printf("Retrieving %s\n", src); |
|
|
if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) |
if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) |
|
|
strcmp(filename, "..") == 0) |
strcmp(filename, "..") == 0) |
continue; |
continue; |
if (download_dir_internal(conn, new_src, new_dst, |
if (download_dir_internal(conn, new_src, new_dst, |
&(dir_entries[i]->a), pflag, printflag, |
depth + 1, &(dir_entries[i]->a), preserve_flag, |
depth + 1, resume) == -1) |
print_flag, resume_flag) == -1) |
ret = -1; |
ret = -1; |
} else if (S_ISREG(dir_entries[i]->a.perm) ) { |
} else if (S_ISREG(dir_entries[i]->a.perm) ) { |
if (do_download(conn, new_src, new_dst, |
if (do_download(conn, new_src, new_dst, |
&(dir_entries[i]->a), pflag, resume) == -1) { |
&(dir_entries[i]->a), preserve_flag, resume_flag) == -1) { |
error("Download of file %s to %s failed", |
error("Download of file %s to %s failed", |
new_src, new_dst); |
new_src, new_dst); |
ret = -1; |
ret = -1; |
|
|
free(new_src); |
free(new_src); |
} |
} |
|
|
if (pflag) { |
if (preserve_flag) { |
if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { |
if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { |
struct timeval tv[2]; |
struct timeval tv[2]; |
tv[0].tv_sec = dirattrib->atime; |
tv[0].tv_sec = dirattrib->atime; |
|
|
|
|
int |
int |
download_dir(struct sftp_conn *conn, char *src, char *dst, |
download_dir(struct sftp_conn *conn, char *src, char *dst, |
Attrib *dirattrib, int pflag, int printflag, int resume) |
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag) |
{ |
{ |
char *src_canon; |
char *src_canon; |
int ret; |
int ret; |
|
|
return -1; |
return -1; |
} |
} |
|
|
ret = download_dir_internal(conn, src_canon, dst, |
ret = download_dir_internal(conn, src_canon, dst, 0, |
dirattrib, pflag, printflag, 0, resume); |
dirattrib, preserve_flag, print_flag, resume_flag); |
free(src_canon); |
free(src_canon); |
return ret; |
return ret; |
} |
} |
|
|
int |
int |
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
int pflag) |
int preserve_flag) |
{ |
{ |
int local_fd; |
int local_fd; |
int status = SSH2_FX_OK; |
int status = SSH2_FX_OK; |
|
|
a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; |
a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; |
a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; |
a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; |
a.perm &= 0777; |
a.perm &= 0777; |
if (!pflag) |
if (!preserve_flag) |
a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; |
a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; |
|
|
buffer_init(&msg); |
buffer_init(&msg); |
|
|
} |
} |
|
|
/* Override umask and utimes if asked */ |
/* Override umask and utimes if asked */ |
if (pflag) |
if (preserve_flag) |
do_fsetstat(conn, handle, handle_len, &a); |
do_fsetstat(conn, handle, handle_len, &a); |
|
|
if (do_close(conn, handle, handle_len) != SSH2_FX_OK) |
if (do_close(conn, handle, handle_len) != SSH2_FX_OK) |
|
|
} |
} |
|
|
static int |
static int |
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, |
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
int pflag, int printflag, int depth) |
int preserve_flag, int print_flag) |
{ |
{ |
int ret = 0, status; |
int ret = 0, status; |
DIR *dirp; |
DIR *dirp; |
|
|
error("\"%s\" is not a directory", src); |
error("\"%s\" is not a directory", src); |
return -1; |
return -1; |
} |
} |
if (printflag) |
if (print_flag) |
printf("Entering %s\n", src); |
printf("Entering %s\n", src); |
|
|
attrib_clear(&a); |
attrib_clear(&a); |
|
|
a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; |
a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; |
a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; |
a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; |
a.perm &= 01777; |
a.perm &= 01777; |
if (!pflag) |
if (!preserve_flag) |
a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; |
a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; |
|
|
status = do_mkdir(conn, dst, &a, 0); |
status = do_mkdir(conn, dst, &a, 0); |
|
|
continue; |
continue; |
|
|
if (upload_dir_internal(conn, new_src, new_dst, |
if (upload_dir_internal(conn, new_src, new_dst, |
pflag, printflag, depth + 1) == -1) |
depth + 1, preserve_flag, print_flag) == -1) |
ret = -1; |
ret = -1; |
} else if (S_ISREG(sb.st_mode)) { |
} else if (S_ISREG(sb.st_mode)) { |
if (do_upload(conn, new_src, new_dst, pflag) == -1) { |
if (do_upload(conn, new_src, new_dst, |
|
preserve_flag) == -1) { |
error("Uploading of file %s to %s failed!", |
error("Uploading of file %s to %s failed!", |
new_src, new_dst); |
new_src, new_dst); |
ret = -1; |
ret = -1; |
|
|
} |
} |
|
|
int |
int |
upload_dir(struct sftp_conn *conn, char *src, char *dst, int pflag, |
upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, |
int printflag) |
int print_flag) |
{ |
{ |
char *dst_canon; |
char *dst_canon; |
int ret; |
int ret; |
|
|
return -1; |
return -1; |
} |
} |
|
|
ret = upload_dir_internal(conn, src, dst_canon, pflag, printflag, 0); |
ret = upload_dir_internal(conn, src, dst_canon, preserve_flag, |
|
print_flag, 0); |
free(dst_canon); |
free(dst_canon); |
return ret; |
return ret; |
} |
} |