|
Lines 88-93
int showprogress = 1;
Link Here
|
| 88 |
/* When this option is set, we always recursively download/upload directories */ |
88 |
/* When this option is set, we always recursively download/upload directories */ |
| 89 |
int global_rflag = 0; |
89 |
int global_rflag = 0; |
| 90 |
|
90 |
|
|
|
91 |
/* When this option is set, we resume download if possible */ |
| 92 |
int global_aflag = 0; |
| 93 |
|
| 91 |
/* When this option is set, the file transfers will always preserve times */ |
94 |
/* When this option is set, the file transfers will always preserve times */ |
| 92 |
int global_pflag = 0; |
95 |
int global_pflag = 0; |
| 93 |
|
96 |
|
|
Lines 151-156
extern char *__progname;
Link Here
|
| 151 |
#define I_SYMLINK 21 |
154 |
#define I_SYMLINK 21 |
| 152 |
#define I_VERSION 22 |
155 |
#define I_VERSION 22 |
| 153 |
#define I_PROGRESS 23 |
156 |
#define I_PROGRESS 23 |
|
|
157 |
#define I_REGET 26 |
| 154 |
|
158 |
|
| 155 |
struct CMD { |
159 |
struct CMD { |
| 156 |
const char *c; |
160 |
const char *c; |
|
Lines 190-195
static const struct CMD cmds[] = {
Link Here
|
| 190 |
{ "put", I_PUT, LOCAL }, |
194 |
{ "put", I_PUT, LOCAL }, |
| 191 |
{ "pwd", I_PWD, REMOTE }, |
195 |
{ "pwd", I_PWD, REMOTE }, |
| 192 |
{ "quit", I_QUIT, NOARGS }, |
196 |
{ "quit", I_QUIT, NOARGS }, |
|
|
197 |
{ "reget", I_REGET, REMOTE }, |
| 193 |
{ "rename", I_RENAME, REMOTE }, |
198 |
{ "rename", I_RENAME, REMOTE }, |
| 194 |
{ "rm", I_RM, REMOTE }, |
199 |
{ "rm", I_RM, REMOTE }, |
| 195 |
{ "rmdir", I_RMDIR, REMOTE }, |
200 |
{ "rmdir", I_RMDIR, REMOTE }, |
|
Lines 239-244
help(void)
Link Here
|
| 239 |
" filesystem containing 'path'\n" |
244 |
" filesystem containing 'path'\n" |
| 240 |
"exit Quit sftp\n" |
245 |
"exit Quit sftp\n" |
| 241 |
"get [-Ppr] remote [local] Download file\n" |
246 |
"get [-Ppr] remote [local] Download file\n" |
|
|
247 |
"reget remote [local] Resume download file\n" |
| 242 |
"help Display this help text\n" |
248 |
"help Display this help text\n" |
| 243 |
"lcd path Change local directory to 'path'\n" |
249 |
"lcd path Change local directory to 'path'\n" |
| 244 |
"lls [ls-options [path]] Display local directory listing\n" |
250 |
"lls [ls-options [path]] Display local directory listing\n" |
|
Lines 350-357
make_absolute(char *p, char *pwd)
Link Here
|
| 350 |
} |
356 |
} |
| 351 |
|
357 |
|
| 352 |
static int |
358 |
static int |
| 353 |
parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag, |
359 |
parse_getput_flags(const char *cmd, char **argv, int argc, |
| 354 |
int *rflag) |
360 |
int *aflag, int *pflag, int *rflag) |
| 355 |
{ |
361 |
{ |
| 356 |
extern int opterr, optind, optopt, optreset; |
362 |
extern int opterr, optind, optopt, optreset; |
| 357 |
int ch; |
363 |
int ch; |
|
Lines 359-367
parse_getput_flags(const char *cmd, char
Link Here
|
| 359 |
optind = optreset = 1; |
365 |
optind = optreset = 1; |
| 360 |
opterr = 0; |
366 |
opterr = 0; |
| 361 |
|
367 |
|
| 362 |
*rflag = *pflag = 0; |
368 |
*aflag = *rflag = *pflag = 0; |
| 363 |
while ((ch = getopt(argc, argv, "PpRr")) != -1) { |
369 |
while ((ch = getopt(argc, argv, "aPpRr")) != -1) { |
| 364 |
switch (ch) { |
370 |
switch (ch) { |
|
|
371 |
case 'a': |
| 372 |
*aflag = 1; |
| 373 |
break; |
| 365 |
case 'p': |
374 |
case 'p': |
| 366 |
case 'P': |
375 |
case 'P': |
| 367 |
*pflag = 1; |
376 |
*pflag = 1; |
|
Lines 519-525
pathname_is_dir(char *pathname)
Link Here
|
| 519 |
|
528 |
|
| 520 |
static int |
529 |
static int |
| 521 |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
530 |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
| 522 |
int pflag, int rflag) |
531 |
int pflag, int rflag, int resume) |
| 523 |
{ |
532 |
{ |
| 524 |
char *abs_src = NULL; |
533 |
char *abs_src = NULL; |
| 525 |
char *abs_dst = NULL; |
534 |
char *abs_dst = NULL; |
|
Lines 571-585
process_get(struct sftp_conn *conn, char
Link Here
|
| 571 |
} |
580 |
} |
| 572 |
free(tmp); |
581 |
free(tmp); |
| 573 |
|
582 |
|
| 574 |
if (!quiet) |
583 |
resume |= global_aflag; |
|
|
584 |
if (!quiet && resume) |
| 585 |
printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst); |
| 586 |
else if (!quiet && !resume) |
| 575 |
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
587 |
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
| 576 |
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
588 |
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
| 577 |
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
589 |
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
| 578 |
pflag || global_pflag, 1) == -1) |
590 |
pflag || global_pflag, 1, resume) == -1) |
| 579 |
err = -1; |
591 |
err = -1; |
| 580 |
} else { |
592 |
} else { |
| 581 |
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, |
593 |
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, |
| 582 |
pflag || global_pflag) == -1) |
594 |
pflag || global_pflag, resume) == -1) |
| 583 |
err = -1; |
595 |
err = -1; |
| 584 |
} |
596 |
} |
| 585 |
free(abs_dst); |
597 |
free(abs_dst); |
|
Lines 1118-1125
makeargv(const char *arg, int *argcp, in
Link Here
|
| 1118 |
} |
1130 |
} |
| 1119 |
|
1131 |
|
| 1120 |
static int |
1132 |
static int |
| 1121 |
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, |
1133 |
parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, |
| 1122 |
int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2) |
1134 |
int *pflag, int *rflag, int *sflag, unsigned long *n_arg, |
|
|
1135 |
char **path1, char **path2) |
| 1123 |
{ |
1136 |
{ |
| 1124 |
const char *cmd, *cp = *cpp; |
1137 |
const char *cmd, *cp = *cpp; |
| 1125 |
char *cp2, **argv; |
1138 |
char *cp2, **argv; |
|
Lines 1163-1176
parse_args(const char **cpp, int *pflag,
Link Here
|
| 1163 |
} |
1176 |
} |
| 1164 |
|
1177 |
|
| 1165 |
/* Get arguments and parse flags */ |
1178 |
/* Get arguments and parse flags */ |
| 1166 |
*lflag = *pflag = *rflag = *hflag = *n_arg = 0; |
1179 |
*aflag = *lflag = *pflag = *rflag = *hflag = *n_arg = 0; |
| 1167 |
*path1 = *path2 = NULL; |
1180 |
*path1 = *path2 = NULL; |
| 1168 |
optidx = 1; |
1181 |
optidx = 1; |
| 1169 |
switch (cmdnum) { |
1182 |
switch (cmdnum) { |
| 1170 |
case I_GET: |
1183 |
case I_GET: |
|
|
1184 |
case I_REGET: |
| 1171 |
case I_PUT: |
1185 |
case I_PUT: |
| 1172 |
if ((optidx = parse_getput_flags(cmd, argv, argc, |
1186 |
if ((optidx = parse_getput_flags(cmd, argv, argc, |
| 1173 |
pflag, rflag)) == -1) |
1187 |
aflag, pflag, rflag)) == -1) |
| 1174 |
return -1; |
1188 |
return -1; |
| 1175 |
/* Get first pathname (mandatory) */ |
1189 |
/* Get first pathname (mandatory) */ |
| 1176 |
if (argc - optidx < 1) { |
1190 |
if (argc - optidx < 1) { |
|
Lines 1185-1190
parse_args(const char **cpp, int *pflag,
Link Here
|
| 1185 |
/* Destination is not globbed */ |
1199 |
/* Destination is not globbed */ |
| 1186 |
undo_glob_escape(*path2); |
1200 |
undo_glob_escape(*path2); |
| 1187 |
} |
1201 |
} |
|
|
1202 |
if (*aflag && cmdnum == I_PUT) { |
| 1203 |
/* XXX implement resume for uploads */ |
| 1204 |
error("Resume is not supported for uploads"); |
| 1205 |
return -1; |
| 1206 |
} |
| 1188 |
break; |
1207 |
break; |
| 1189 |
case I_LINK: |
1208 |
case I_LINK: |
| 1190 |
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) |
1209 |
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) |
|
Lines 1293-1299
parse_dispatch_command(struct sftp_conn
Link Here
|
| 1293 |
int err_abort) |
1312 |
int err_abort) |
| 1294 |
{ |
1313 |
{ |
| 1295 |
char *path1, *path2, *tmp; |
1314 |
char *path1, *path2, *tmp; |
| 1296 |
int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0; |
1315 |
int aflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0; |
|
|
1316 |
int rflag = 0, sflag = 0; |
| 1297 |
int cmdnum, i; |
1317 |
int cmdnum, i; |
| 1298 |
unsigned long n_arg = 0; |
1318 |
unsigned long n_arg = 0; |
| 1299 |
Attrib a, *aa; |
1319 |
Attrib a, *aa; |
|
Lines 1302-1310
parse_dispatch_command(struct sftp_conn
Link Here
|
| 1302 |
glob_t g; |
1322 |
glob_t g; |
| 1303 |
|
1323 |
|
| 1304 |
path1 = path2 = NULL; |
1324 |
path1 = path2 = NULL; |
| 1305 |
cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, |
1325 |
cmdnum = parse_args(&cmd, &aflag, &hflag, &iflag, &lflag, &pflag, |
| 1306 |
&sflag, &n_arg, &path1, &path2); |
1326 |
&rflag, &sflag, &n_arg, &path1, &path2); |
| 1307 |
|
|
|
| 1308 |
if (iflag != 0) |
1327 |
if (iflag != 0) |
| 1309 |
err_abort = 0; |
1328 |
err_abort = 0; |
| 1310 |
|
1329 |
|
|
Lines 1319-1326
parse_dispatch_command(struct sftp_conn
Link Here
|
| 1319 |
/* Unrecognized command */ |
1338 |
/* Unrecognized command */ |
| 1320 |
err = -1; |
1339 |
err = -1; |
| 1321 |
break; |
1340 |
break; |
|
|
1341 |
case I_REGET: |
| 1342 |
aflag = 1; |
| 1343 |
/* FALLTHROUGH */ |
| 1322 |
case I_GET: |
1344 |
case I_GET: |
| 1323 |
err = process_get(conn, path1, path2, *pwd, pflag, rflag); |
1345 |
err = process_get(conn, path1, path2, *pwd, pflag, |
|
|
1346 |
rflag, aflag); |
| 1324 |
break; |
1347 |
break; |
| 1325 |
case I_PUT: |
1348 |
case I_PUT: |
| 1326 |
err = process_put(conn, path1, path2, *pwd, pflag, rflag); |
1349 |
err = process_put(conn, path1, path2, *pwd, pflag, rflag); |
|
Lines 1948-1959
interactive_loop(struct sftp_conn *conn,
Link Here
|
| 1948 |
} |
1971 |
} |
| 1949 |
} else { |
1972 |
} else { |
| 1950 |
/* XXX this is wrong wrt quoting */ |
1973 |
/* XXX this is wrong wrt quoting */ |
| 1951 |
if (file2 == NULL) |
1974 |
snprintf(cmd, sizeof cmd, "get%s %s%s%s", |
| 1952 |
snprintf(cmd, sizeof cmd, "get %s", dir); |
1975 |
global_aflag ? " -a" : "", dir, |
| 1953 |
else |
1976 |
file2 == NULL ? "" : " ", |
| 1954 |
snprintf(cmd, sizeof cmd, "get %s %s", dir, |
1977 |
file2 == NULL ? "" : file2); |
| 1955 |
file2); |
|
|
| 1956 |
|
| 1957 |
err = parse_dispatch_command(conn, cmd, |
1978 |
err = parse_dispatch_command(conn, cmd, |
| 1958 |
&remote_path, 1); |
1979 |
&remote_path, 1); |
| 1959 |
free(dir); |
1980 |
free(dir); |
|
Lines 2142-2148
main(int argc, char **argv)
Link Here
|
| 2142 |
infile = stdin; |
2163 |
infile = stdin; |
| 2143 |
|
2164 |
|
| 2144 |
while ((ch = getopt(argc, argv, |
2165 |
while ((ch = getopt(argc, argv, |
| 2145 |
"1246hpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { |
2166 |
"1246ahpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { |
| 2146 |
switch (ch) { |
2167 |
switch (ch) { |
| 2147 |
/* Passed through to ssh(1) */ |
2168 |
/* Passed through to ssh(1) */ |
| 2148 |
case '4': |
2169 |
case '4': |
|
Lines 2181-2186
main(int argc, char **argv)
Link Here
|
| 2181 |
break; |
2202 |
break; |
| 2182 |
case '2': |
2203 |
case '2': |
| 2183 |
sshver = 2; |
2204 |
sshver = 2; |
|
|
2205 |
break; |
| 2206 |
case 'a': |
| 2207 |
global_aflag = 1; |
| 2184 |
break; |
2208 |
break; |
| 2185 |
case 'B': |
2209 |
case 'B': |
| 2186 |
copy_buffer_len = strtol(optarg, &cp, 10); |
2210 |
copy_buffer_len = strtol(optarg, &cp, 10); |