version 1.147, 2013/07/12 00:20:00 |
version 1.148, 2013/07/25 00:56:52 |
|
|
/* When this option is set, we always recursively download/upload directories */ |
/* When this option is set, we always recursively download/upload directories */ |
int global_rflag = 0; |
int global_rflag = 0; |
|
|
|
/* When this option is set, we resume download if possible */ |
|
int global_aflag = 0; |
|
|
/* When this option is set, the file transfers will always preserve times */ |
/* When this option is set, the file transfers will always preserve times */ |
int global_pflag = 0; |
int global_pflag = 0; |
|
|
|
|
#define I_SYMLINK 21 |
#define I_SYMLINK 21 |
#define I_VERSION 22 |
#define I_VERSION 22 |
#define I_PROGRESS 23 |
#define I_PROGRESS 23 |
|
#define I_REGET 26 |
|
|
struct CMD { |
struct CMD { |
const char *c; |
const char *c; |
|
|
{ "put", I_PUT, LOCAL }, |
{ "put", I_PUT, LOCAL }, |
{ "pwd", I_PWD, REMOTE }, |
{ "pwd", I_PWD, REMOTE }, |
{ "quit", I_QUIT, NOARGS }, |
{ "quit", I_QUIT, NOARGS }, |
|
{ "reget", I_REGET, REMOTE }, |
{ "rename", I_RENAME, REMOTE }, |
{ "rename", I_RENAME, REMOTE }, |
{ "rm", I_RM, REMOTE }, |
{ "rm", I_RM, REMOTE }, |
{ "rmdir", I_RMDIR, REMOTE }, |
{ "rmdir", I_RMDIR, REMOTE }, |
|
|
" filesystem containing 'path'\n" |
" filesystem containing 'path'\n" |
"exit Quit sftp\n" |
"exit Quit sftp\n" |
"get [-Ppr] remote [local] Download file\n" |
"get [-Ppr] remote [local] Download file\n" |
|
"reget remote [local] Resume download file\n" |
"help Display this help text\n" |
"help Display this help text\n" |
"lcd path Change local directory to 'path'\n" |
"lcd path Change local directory to 'path'\n" |
"lls [ls-options [path]] Display local directory listing\n" |
"lls [ls-options [path]] Display local directory listing\n" |
|
|
} |
} |
|
|
static int |
static int |
parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag, |
parse_getput_flags(const char *cmd, char **argv, int argc, |
int *rflag) |
int *aflag, int *pflag, int *rflag) |
{ |
{ |
extern int opterr, optind, optopt, optreset; |
extern int opterr, optind, optopt, optreset; |
int ch; |
int ch; |
|
|
optind = optreset = 1; |
optind = optreset = 1; |
opterr = 0; |
opterr = 0; |
|
|
*rflag = *pflag = 0; |
*aflag = *rflag = *pflag = 0; |
while ((ch = getopt(argc, argv, "PpRr")) != -1) { |
while ((ch = getopt(argc, argv, "aPpRr")) != -1) { |
switch (ch) { |
switch (ch) { |
|
case 'a': |
|
*aflag = 1; |
|
break; |
case 'p': |
case 'p': |
case 'P': |
case 'P': |
*pflag = 1; |
*pflag = 1; |
|
|
|
|
static int |
static int |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
int pflag, int rflag) |
int pflag, int rflag, int resume) |
{ |
{ |
char *abs_src = NULL; |
char *abs_src = NULL; |
char *abs_dst = NULL; |
char *abs_dst = NULL; |
|
|
} |
} |
free(tmp); |
free(tmp); |
|
|
if (!quiet) |
resume |= global_aflag; |
|
if (!quiet && resume) |
|
printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst); |
|
else if (!quiet && !resume) |
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
pflag || global_pflag, 1) == -1) |
pflag || global_pflag, 1, resume) == -1) |
err = -1; |
err = -1; |
} else { |
} else { |
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, |
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, |
pflag || global_pflag) == -1) |
pflag || global_pflag, resume) == -1) |
err = -1; |
err = -1; |
} |
} |
free(abs_dst); |
free(abs_dst); |
|
|
} |
} |
|
|
static int |
static int |
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, |
parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, |
int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2) |
int *pflag, int *rflag, int *sflag, unsigned long *n_arg, |
|
char **path1, char **path2) |
{ |
{ |
const char *cmd, *cp = *cpp; |
const char *cmd, *cp = *cpp; |
char *cp2, **argv; |
char *cp2, **argv; |
|
|
} |
} |
|
|
/* Get arguments and parse flags */ |
/* Get arguments and parse flags */ |
*lflag = *pflag = *rflag = *hflag = *n_arg = 0; |
*aflag = *lflag = *pflag = *rflag = *hflag = *n_arg = 0; |
*path1 = *path2 = NULL; |
*path1 = *path2 = NULL; |
optidx = 1; |
optidx = 1; |
switch (cmdnum) { |
switch (cmdnum) { |
case I_GET: |
case I_GET: |
|
case I_REGET: |
case I_PUT: |
case I_PUT: |
if ((optidx = parse_getput_flags(cmd, argv, argc, |
if ((optidx = parse_getput_flags(cmd, argv, argc, |
pflag, rflag)) == -1) |
aflag, pflag, rflag)) == -1) |
return -1; |
return -1; |
/* Get first pathname (mandatory) */ |
/* Get first pathname (mandatory) */ |
if (argc - optidx < 1) { |
if (argc - optidx < 1) { |
|
|
/* Destination is not globbed */ |
/* Destination is not globbed */ |
undo_glob_escape(*path2); |
undo_glob_escape(*path2); |
} |
} |
|
if (*aflag && cmdnum == I_PUT) { |
|
/* XXX implement resume for uploads */ |
|
error("Resume is not supported for uploads"); |
|
return -1; |
|
} |
break; |
break; |
case I_LINK: |
case I_LINK: |
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) |
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) |
|
|
int err_abort) |
int err_abort) |
{ |
{ |
char *path1, *path2, *tmp; |
char *path1, *path2, *tmp; |
int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0; |
int aflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0; |
|
int rflag = 0, sflag = 0; |
int cmdnum, i; |
int cmdnum, i; |
unsigned long n_arg = 0; |
unsigned long n_arg = 0; |
Attrib a, *aa; |
Attrib a, *aa; |
|
|
glob_t g; |
glob_t g; |
|
|
path1 = path2 = NULL; |
path1 = path2 = NULL; |
cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, |
cmdnum = parse_args(&cmd, &aflag, &hflag, &iflag, &lflag, &pflag, |
&sflag, &n_arg, &path1, &path2); |
&rflag, &sflag, &n_arg, &path1, &path2); |
|
|
if (iflag != 0) |
if (iflag != 0) |
err_abort = 0; |
err_abort = 0; |
|
|
|
|
/* Unrecognized command */ |
/* Unrecognized command */ |
err = -1; |
err = -1; |
break; |
break; |
|
case I_REGET: |
|
aflag = 1; |
|
/* FALLTHROUGH */ |
case I_GET: |
case I_GET: |
err = process_get(conn, path1, path2, *pwd, pflag, rflag); |
err = process_get(conn, path1, path2, *pwd, pflag, |
|
rflag, aflag); |
break; |
break; |
case I_PUT: |
case I_PUT: |
err = process_put(conn, path1, path2, *pwd, pflag, rflag); |
err = process_put(conn, path1, path2, *pwd, pflag, rflag); |
|
|
} |
} |
} else { |
} else { |
/* XXX this is wrong wrt quoting */ |
/* XXX this is wrong wrt quoting */ |
if (file2 == NULL) |
snprintf(cmd, sizeof cmd, "get%s %s%s%s", |
snprintf(cmd, sizeof cmd, "get %s", dir); |
global_aflag ? " -a" : "", dir, |
else |
file2 == NULL ? "" : " ", |
snprintf(cmd, sizeof cmd, "get %s %s", dir, |
file2 == NULL ? "" : file2); |
file2); |
|
|
|
err = parse_dispatch_command(conn, cmd, |
err = parse_dispatch_command(conn, cmd, |
&remote_path, 1); |
&remote_path, 1); |
free(dir); |
free(dir); |
|
|
infile = stdin; |
infile = stdin; |
|
|
while ((ch = getopt(argc, argv, |
while ((ch = getopt(argc, argv, |
"1246hpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { |
"1246ahpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { |
switch (ch) { |
switch (ch) { |
/* Passed through to ssh(1) */ |
/* Passed through to ssh(1) */ |
case '4': |
case '4': |
|
|
break; |
break; |
case '2': |
case '2': |
sshver = 2; |
sshver = 2; |
|
break; |
|
case 'a': |
|
global_aflag = 1; |
break; |
break; |
case 'B': |
case 'B': |
copy_buffer_len = strtol(optarg, &cp, 10); |
copy_buffer_len = strtol(optarg, &cp, 10); |