|
Lines 69-74
int showprogress = 1;
Link Here
|
| 69 |
/* When this option is set, we always recursively download/upload directories */ |
69 |
/* When this option is set, we always recursively download/upload directories */ |
| 70 |
int global_rflag = 0; |
70 |
int global_rflag = 0; |
| 71 |
|
71 |
|
|
|
72 |
/* When this option is set, we resume download if possible */ |
| 73 |
int global_aflag = 0; |
| 74 |
|
| 72 |
/* When this option is set, the file transfers will always preserve times */ |
75 |
/* When this option is set, the file transfers will always preserve times */ |
| 73 |
int global_pflag = 0; |
76 |
int global_pflag = 0; |
| 74 |
|
77 |
|
|
Lines 130-135
int remote_glob(struct sftp_conn *, const char *, int,
Link Here
|
| 130 |
#define I_SYMLINK 21 |
133 |
#define I_SYMLINK 21 |
| 131 |
#define I_VERSION 22 |
134 |
#define I_VERSION 22 |
| 132 |
#define I_PROGRESS 23 |
135 |
#define I_PROGRESS 23 |
|
|
136 |
#define I_REGET 26 |
| 133 |
|
137 |
|
| 134 |
struct CMD { |
138 |
struct CMD { |
| 135 |
const char *c; |
139 |
const char *c; |
|
Lines 169-174
static const struct CMD cmds[] = {
Link Here
|
| 169 |
{ "put", I_PUT, LOCAL }, |
173 |
{ "put", I_PUT, LOCAL }, |
| 170 |
{ "pwd", I_PWD, REMOTE }, |
174 |
{ "pwd", I_PWD, REMOTE }, |
| 171 |
{ "quit", I_QUIT, NOARGS }, |
175 |
{ "quit", I_QUIT, NOARGS }, |
|
|
176 |
{ "reget", I_REGET, REMOTE }, |
| 172 |
{ "rename", I_RENAME, REMOTE }, |
177 |
{ "rename", I_RENAME, REMOTE }, |
| 173 |
{ "rm", I_RM, REMOTE }, |
178 |
{ "rm", I_RM, REMOTE }, |
| 174 |
{ "rmdir", I_RMDIR, REMOTE }, |
179 |
{ "rmdir", I_RMDIR, REMOTE }, |
|
Lines 218-223
help(void)
Link Here
|
| 218 |
" filesystem containing 'path'\n" |
223 |
" filesystem containing 'path'\n" |
| 219 |
"exit Quit sftp\n" |
224 |
"exit Quit sftp\n" |
| 220 |
"get [-Ppr] remote [local] Download file\n" |
225 |
"get [-Ppr] remote [local] Download file\n" |
|
|
226 |
"reget remote [local] Resume download file\n" |
| 221 |
"help Display this help text\n" |
227 |
"help Display this help text\n" |
| 222 |
"lcd path Change local directory to 'path'\n" |
228 |
"lcd path Change local directory to 'path'\n" |
| 223 |
"lls [ls-options [path]] Display local directory listing\n" |
229 |
"lls [ls-options [path]] Display local directory listing\n" |
|
Lines 329-336
make_absolute(char *p, char *pwd)
Link Here
|
| 329 |
} |
335 |
} |
| 330 |
|
336 |
|
| 331 |
static int |
337 |
static int |
| 332 |
parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag, |
338 |
parse_getput_flags(const char *cmd, char **argv, int argc, |
| 333 |
int *rflag) |
339 |
int *aflag, int *pflag, int *rflag) |
| 334 |
{ |
340 |
{ |
| 335 |
extern int opterr, optind, optopt, optreset; |
341 |
extern int opterr, optind, optopt, optreset; |
| 336 |
int ch; |
342 |
int ch; |
|
Lines 338-346
parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag,
Link Here
|
| 338 |
optind = optreset = 1; |
344 |
optind = optreset = 1; |
| 339 |
opterr = 0; |
345 |
opterr = 0; |
| 340 |
|
346 |
|
| 341 |
*rflag = *pflag = 0; |
347 |
*aflag = *rflag = *pflag = 0; |
| 342 |
while ((ch = getopt(argc, argv, "PpRr")) != -1) { |
348 |
while ((ch = getopt(argc, argv, "aPpRr")) != -1) { |
| 343 |
switch (ch) { |
349 |
switch (ch) { |
|
|
350 |
case 'a': |
| 351 |
*aflag = 1; |
| 352 |
break; |
| 344 |
case 'p': |
353 |
case 'p': |
| 345 |
case 'P': |
354 |
case 'P': |
| 346 |
*pflag = 1; |
355 |
*pflag = 1; |
|
Lines 498-504
pathname_is_dir(char *pathname)
Link Here
|
| 498 |
|
507 |
|
| 499 |
static int |
508 |
static int |
| 500 |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
509 |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
| 501 |
int pflag, int rflag) |
510 |
int pflag, int rflag, int resume) |
| 502 |
{ |
511 |
{ |
| 503 |
char *abs_src = NULL; |
512 |
char *abs_src = NULL; |
| 504 |
char *abs_dst = NULL; |
513 |
char *abs_dst = NULL; |
|
Lines 550-564
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
Link Here
|
| 550 |
} |
559 |
} |
| 551 |
free(tmp); |
560 |
free(tmp); |
| 552 |
|
561 |
|
| 553 |
if (!quiet) |
562 |
resume |= global_aflag; |
|
|
563 |
if (!quiet && resume) |
| 564 |
printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst); |
| 565 |
else if (!quiet && !resume) |
| 554 |
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
566 |
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
| 555 |
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
567 |
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
| 556 |
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
568 |
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
| 557 |
pflag || global_pflag, 1) == -1) |
569 |
pflag || global_pflag, 1, resume) == -1) |
| 558 |
err = -1; |
570 |
err = -1; |
| 559 |
} else { |
571 |
} else { |
| 560 |
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, |
572 |
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, |
| 561 |
pflag || global_pflag) == -1) |
573 |
pflag || global_pflag, resume) == -1) |
| 562 |
err = -1; |
574 |
err = -1; |
| 563 |
} |
575 |
} |
| 564 |
free(abs_dst); |
576 |
free(abs_dst); |
|
Lines 1097-1104
makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
Link Here
|
| 1097 |
} |
1109 |
} |
| 1098 |
|
1110 |
|
| 1099 |
static int |
1111 |
static int |
| 1100 |
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, |
1112 |
parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, |
| 1101 |
int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2) |
1113 |
int *pflag, int *rflag, int *sflag, unsigned long *n_arg, |
|
|
1114 |
char **path1, char **path2) |
| 1102 |
{ |
1115 |
{ |
| 1103 |
const char *cmd, *cp = *cpp; |
1116 |
const char *cmd, *cp = *cpp; |
| 1104 |
char *cp2, **argv; |
1117 |
char *cp2, **argv; |
|
Lines 1142-1155
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
Link Here
|
| 1142 |
} |
1155 |
} |
| 1143 |
|
1156 |
|
| 1144 |
/* Get arguments and parse flags */ |
1157 |
/* Get arguments and parse flags */ |
| 1145 |
*lflag = *pflag = *rflag = *hflag = *n_arg = 0; |
1158 |
*aflag = *lflag = *pflag = *rflag = *hflag = *n_arg = 0; |
| 1146 |
*path1 = *path2 = NULL; |
1159 |
*path1 = *path2 = NULL; |
| 1147 |
optidx = 1; |
1160 |
optidx = 1; |
| 1148 |
switch (cmdnum) { |
1161 |
switch (cmdnum) { |
| 1149 |
case I_GET: |
1162 |
case I_GET: |
|
|
1163 |
case I_REGET: |
| 1150 |
case I_PUT: |
1164 |
case I_PUT: |
| 1151 |
if ((optidx = parse_getput_flags(cmd, argv, argc, |
1165 |
if ((optidx = parse_getput_flags(cmd, argv, argc, |
| 1152 |
pflag, rflag)) == -1) |
1166 |
aflag, pflag, rflag)) == -1) |
| 1153 |
return -1; |
1167 |
return -1; |
| 1154 |
/* Get first pathname (mandatory) */ |
1168 |
/* Get first pathname (mandatory) */ |
| 1155 |
if (argc - optidx < 1) { |
1169 |
if (argc - optidx < 1) { |
|
Lines 1164-1169
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
Link Here
|
| 1164 |
/* Destination is not globbed */ |
1178 |
/* Destination is not globbed */ |
| 1165 |
undo_glob_escape(*path2); |
1179 |
undo_glob_escape(*path2); |
| 1166 |
} |
1180 |
} |
|
|
1181 |
if (*aflag && cmdnum == I_PUT) { |
| 1182 |
/* XXX implement resume for uploads */ |
| 1183 |
error("Resume is not supported for uploads"); |
| 1184 |
return -1; |
| 1185 |
} |
| 1167 |
break; |
1186 |
break; |
| 1168 |
case I_LINK: |
1187 |
case I_LINK: |
| 1169 |
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) |
1188 |
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) |
|
Lines 1272-1278
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
Link Here
|
| 1272 |
int err_abort) |
1291 |
int err_abort) |
| 1273 |
{ |
1292 |
{ |
| 1274 |
char *path1, *path2, *tmp; |
1293 |
char *path1, *path2, *tmp; |
| 1275 |
int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0; |
1294 |
int aflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0; |
|
|
1295 |
int rflag = 0, sflag = 0; |
| 1276 |
int cmdnum, i; |
1296 |
int cmdnum, i; |
| 1277 |
unsigned long n_arg = 0; |
1297 |
unsigned long n_arg = 0; |
| 1278 |
Attrib a, *aa; |
1298 |
Attrib a, *aa; |
|
Lines 1281-1289
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
Link Here
|
| 1281 |
glob_t g; |
1301 |
glob_t g; |
| 1282 |
|
1302 |
|
| 1283 |
path1 = path2 = NULL; |
1303 |
path1 = path2 = NULL; |
| 1284 |
cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, |
1304 |
cmdnum = parse_args(&cmd, &aflag, &hflag, &iflag, &lflag, &pflag, |
| 1285 |
&sflag, &n_arg, &path1, &path2); |
1305 |
&rflag, &sflag, &n_arg, &path1, &path2); |
| 1286 |
|
|
|
| 1287 |
if (iflag != 0) |
1306 |
if (iflag != 0) |
| 1288 |
err_abort = 0; |
1307 |
err_abort = 0; |
| 1289 |
|
1308 |
|
|
Lines 1298-1305
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
Link Here
|
| 1298 |
/* Unrecognized command */ |
1317 |
/* Unrecognized command */ |
| 1299 |
err = -1; |
1318 |
err = -1; |
| 1300 |
break; |
1319 |
break; |
|
|
1320 |
case I_REGET: |
| 1321 |
aflag = 1; |
| 1322 |
/* FALLTHROUGH */ |
| 1301 |
case I_GET: |
1323 |
case I_GET: |
| 1302 |
err = process_get(conn, path1, path2, *pwd, pflag, rflag); |
1324 |
err = process_get(conn, path1, path2, *pwd, pflag, |
|
|
1325 |
rflag, aflag); |
| 1303 |
break; |
1326 |
break; |
| 1304 |
case I_PUT: |
1327 |
case I_PUT: |
| 1305 |
err = process_put(conn, path1, path2, *pwd, pflag, rflag); |
1328 |
err = process_put(conn, path1, path2, *pwd, pflag, rflag); |
|
Lines 1924-1935
interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
Link Here
|
| 1924 |
} |
1947 |
} |
| 1925 |
} else { |
1948 |
} else { |
| 1926 |
/* XXX this is wrong wrt quoting */ |
1949 |
/* XXX this is wrong wrt quoting */ |
| 1927 |
if (file2 == NULL) |
1950 |
snprintf(cmd, sizeof cmd, "get%s %s%s%s", |
| 1928 |
snprintf(cmd, sizeof cmd, "get %s", dir); |
1951 |
global_aflag ? " -a" : "", dir, |
| 1929 |
else |
1952 |
file2 == NULL ? "" : " ", |
| 1930 |
snprintf(cmd, sizeof cmd, "get %s %s", dir, |
1953 |
file2 == NULL ? "" : file2); |
| 1931 |
file2); |
|
|
| 1932 |
|
| 1933 |
err = parse_dispatch_command(conn, cmd, |
1954 |
err = parse_dispatch_command(conn, cmd, |
| 1934 |
&remote_path, 1); |
1955 |
&remote_path, 1); |
| 1935 |
free(dir); |
1956 |
free(dir); |
|
Lines 2101-2107
main(int argc, char **argv)
Link Here
|
| 2101 |
infile = stdin; |
2122 |
infile = stdin; |
| 2102 |
|
2123 |
|
| 2103 |
while ((ch = getopt(argc, argv, |
2124 |
while ((ch = getopt(argc, argv, |
| 2104 |
"1246hpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { |
2125 |
"1246ahpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { |
| 2105 |
switch (ch) { |
2126 |
switch (ch) { |
| 2106 |
/* Passed through to ssh(1) */ |
2127 |
/* Passed through to ssh(1) */ |
| 2107 |
case '4': |
2128 |
case '4': |
|
Lines 2141-2146
main(int argc, char **argv)
Link Here
|
| 2141 |
case '2': |
2162 |
case '2': |
| 2142 |
sshver = 2; |
2163 |
sshver = 2; |
| 2143 |
break; |
2164 |
break; |
|
|
2165 |
case 'a': |
| 2166 |
global_aflag = 1; |
| 2167 |
break; |
| 2144 |
case 'B': |
2168 |
case 'B': |
| 2145 |
copy_buffer_len = strtol(optarg, &cp, 10); |
2169 |
copy_buffer_len = strtol(optarg, &cp, 10); |
| 2146 |
if (copy_buffer_len == 0 || *cp != '\0') |
2170 |
if (copy_buffer_len == 0 || *cp != '\0') |