|
Lines 282-288
Link Here
|
| 282 |
} |
282 |
} |
| 283 |
|
283 |
|
| 284 |
static int |
284 |
static int |
| 285 |
parse_getput_flags(const char **cpp, int *pflag) |
285 |
parse_getput_flags(const char **cpp, int *pflag, int *recursive_flag) |
| 286 |
{ |
286 |
{ |
| 287 |
const char *cp = *cpp; |
287 |
const char *cp = *cpp; |
| 288 |
|
288 |
|
|
Lines 293-298
Link Here
|
| 293 |
case 'P': |
293 |
case 'P': |
| 294 |
*pflag = 1; |
294 |
*pflag = 1; |
| 295 |
break; |
295 |
break; |
|
|
296 |
case 'r': |
| 297 |
case 'R': |
| 298 |
*recursive_flag = 1; |
| 299 |
break; |
| 296 |
default: |
300 |
default: |
| 297 |
error("Invalid flag -%c", cp[1]); |
301 |
error("Invalid flag -%c", cp[1]); |
| 298 |
return(-1); |
302 |
return(-1); |
|
Lines 420-425
Link Here
|
| 420 |
} |
424 |
} |
| 421 |
|
425 |
|
| 422 |
static int |
426 |
static int |
|
|
427 |
is_symlink(char *path) |
| 428 |
{ |
| 429 |
struct stat sb; |
| 430 |
|
| 431 |
if (stat(path, &sb) == -1) |
| 432 |
fatal("stat %s: %s", path, strerror(errno)); |
| 433 |
|
| 434 |
return(S_ISLNK(sb.st_mode)); |
| 435 |
} |
| 436 |
|
| 437 |
static int |
| 438 |
remote_file_exists(struct sftp_conn *conn, char *path) |
| 439 |
{ |
| 440 |
Attrib *a; |
| 441 |
|
| 442 |
/* XXX: report errors? */ |
| 443 |
if ((a = do_stat(conn, path, 1)) == NULL) |
| 444 |
return(0); |
| 445 |
if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) |
| 446 |
return(0); |
| 447 |
return(1); |
| 448 |
} |
| 449 |
|
| 450 |
static int |
| 423 |
remote_is_dir(struct sftp_conn *conn, char *path) |
451 |
remote_is_dir(struct sftp_conn *conn, char *path) |
| 424 |
{ |
452 |
{ |
| 425 |
Attrib *a; |
453 |
Attrib *a; |
|
Lines 433-439
Link Here
|
| 433 |
} |
461 |
} |
| 434 |
|
462 |
|
| 435 |
static int |
463 |
static int |
| 436 |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) |
464 |
remote_is_reg(struct sftp_conn *conn, char *path) |
|
|
465 |
{ |
| 466 |
Attrib *a; |
| 467 |
|
| 468 |
/* XXX: report errors? */ |
| 469 |
if ((a = do_stat(conn, path, 1)) == NULL) |
| 470 |
return(0); |
| 471 |
if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) |
| 472 |
return(0); |
| 473 |
return(a->perm & S_IFREG); |
| 474 |
} |
| 475 |
|
| 476 |
static int |
| 477 |
remote_is_symlink(struct sftp_conn *conn, char *path) |
| 478 |
{ |
| 479 |
Attrib *a; |
| 480 |
|
| 481 |
/* XXX: report errors? */ |
| 482 |
if ((a = do_stat(conn, path, 1)) == NULL) |
| 483 |
return(0); |
| 484 |
if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) |
| 485 |
return(0); |
| 486 |
return(a->perm & S_IFLNK); |
| 487 |
} |
| 488 |
|
| 489 |
char * |
| 490 |
str_replace(char *string, char *target, char *replacement) |
| 491 |
{ |
| 492 |
char *strloc_p; |
| 493 |
char *new_buffer; |
| 494 |
int len; |
| 495 |
|
| 496 |
new_buffer = NULL; |
| 497 |
new_buffer = xrealloc(new_buffer, 1); |
| 498 |
new_buffer[0] = NULL; |
| 499 |
|
| 500 |
/* Search for the target string */ |
| 501 |
|
| 502 |
if ( NULL != (strloc_p = strstr(string, target)) ) { |
| 503 |
/* Test for wherein the string we found the target. */ |
| 504 |
|
| 505 |
if (strloc_p != string) { |
| 506 |
/* In the middle of the string */ |
| 507 |
len = 0; |
| 508 |
len += strlen(new_buffer); |
| 509 |
len += strloc_p - string; |
| 510 |
len += 1; /* for NULL byte */ |
| 511 |
new_buffer = xrealloc(new_buffer, len); |
| 512 |
new_buffer = strncpy(new_buffer, string, len); |
| 513 |
} |
| 514 |
|
| 515 |
/* Put the replacement in place. */ |
| 516 |
|
| 517 |
len = 0; |
| 518 |
len += strlen(new_buffer); |
| 519 |
len += ( replacement == NULL ) ? 0 : strlen(replacement); |
| 520 |
len += 1; /* for NULL byte added by strcat */ |
| 521 |
new_buffer = xrealloc(new_buffer, len); |
| 522 |
new_buffer = strcat(new_buffer, replacement); |
| 523 |
|
| 524 |
/* Advance the pointer past the target string. */ |
| 525 |
|
| 526 |
len = 0; |
| 527 |
len += ( target == NULL ) ? 0 : strlen(target); |
| 528 |
strloc_p += len; |
| 529 |
|
| 530 |
/* Add the rest of the old string to the new string. */ |
| 531 |
|
| 532 |
len = 0; |
| 533 |
len += strlen(new_buffer); |
| 534 |
len += ( strloc_p == NULL ) ? 0 : strlen(strloc_p); |
| 535 |
len += 1; /* for NULL byte added by strcat */ |
| 536 |
new_buffer = xrealloc(new_buffer, len); |
| 537 |
new_buffer = strcat(new_buffer, strloc_p); |
| 538 |
} |
| 539 |
|
| 540 |
return(new_buffer); |
| 541 |
} |
| 542 |
|
| 543 |
static int |
| 544 |
do_recursive_upload(struct sftp_conn *conn, char *local_path, |
| 545 |
char *remote_path, int pflag, char *pwd) |
| 546 |
{ |
| 547 |
int this_rc = 1; /* our return value */ |
| 548 |
int rc, len; /* internal return values, stores length values */ |
| 549 |
|
| 550 |
Attrib a; |
| 551 |
|
| 552 |
char link[MAXPATHLEN]; /* stores contents of symbolic links */ |
| 553 |
char *remote_tmp; |
| 554 |
char *tmp_path; |
| 555 |
char **local_paths; /* for fts_open string array */ |
| 556 |
|
| 557 |
FTS *local_tree; /* for fts_open/fts_read */ |
| 558 |
FTSENT *local_fsent; /* for fts_read */ |
| 559 |
|
| 560 |
/* Create the string array needed for fts_open. */ |
| 561 |
|
| 562 |
local_paths = calloc(2, sizeof(char *)); |
| 563 |
local_paths[0] = local_path; |
| 564 |
local_paths[1] = NULL; |
| 565 |
|
| 566 |
if ( NULL == (local_tree = fts_open(local_paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) ) { |
| 567 |
fatal("do_recursive_upload: fts_open() returned null: %s", strerror(errno)); |
| 568 |
} |
| 569 |
|
| 570 |
xfree(local_paths); |
| 571 |
local_paths = NULL; |
| 572 |
|
| 573 |
/* Loop over all the fs entries in the tree. */ |
| 574 |
|
| 575 |
while ( NULL != (local_fsent = fts_read(local_tree)) ) { |
| 576 |
switch (local_fsent->fts_info) { |
| 577 |
case FTS_ERR: |
| 578 |
case FTS_DNR: |
| 579 |
case FTS_NS: |
| 580 |
/* Fatal error generated from fts_read. */ |
| 581 |
fatal("fts_read error: %s: %s", local_fsent->fts_path, strerror(local_fsent->fts_errno)); |
| 582 |
case FTS_DOT: |
| 583 |
/* We should *not* see dot directories since we're not using FTS_SEEDOT. */ |
| 584 |
fatal("do_recursive_upload: fts_read returned dot directory but FTS_SEEDOT wasn't used! See fts(3) for more information."); |
| 585 |
case FTS_D: |
| 586 |
debug3("FTS_D: Will make the directory %s\n", local_fsent->fts_path); |
| 587 |
|
| 588 |
/* Create the directory on the remote machine. */ |
| 589 |
attrib_clear(&a); |
| 590 |
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; |
| 591 |
a.perm = 0777; |
| 592 |
|
| 593 |
if ( NULL != remote_path ) { |
| 594 |
remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path); |
| 595 |
} else { |
| 596 |
remote_tmp = xstrdup(local_fsent->fts_path); |
| 597 |
remote_tmp = make_absolute(remote_tmp, pwd); |
| 598 |
} |
| 599 |
|
| 600 |
/* If the directory we plan to use is already in place, move on. */ |
| 601 |
|
| 602 |
if ( remote_is_dir(conn, remote_tmp) ) { |
| 603 |
printf("%s already exists as directory\n", remote_tmp); |
| 604 |
xfree(remote_tmp); |
| 605 |
remote_tmp = NULL; |
| 606 |
break; |
| 607 |
} else if ( remote_file_exists(conn, remote_tmp) ) { |
| 608 |
printf("%s already exists as non-directory... removing\n", remote_tmp); |
| 609 |
|
| 610 |
if ( -1 == do_rm(conn, remote_tmp) ) |
| 611 |
{ |
| 612 |
error("Couldn't remove \"%s\"", remote_tmp); |
| 613 |
this_rc = -1; |
| 614 |
xfree(remote_tmp); |
| 615 |
remote_tmp = NULL; |
| 616 |
goto END; |
| 617 |
} |
| 618 |
} |
| 619 |
|
| 620 |
if ( -1 == do_mkdir(conn, remote_tmp, &a) ) { |
| 621 |
error("Couldn't create remote directory \"%s\"", remote_tmp); |
| 622 |
this_rc = -1; |
| 623 |
xfree(remote_tmp); |
| 624 |
remote_tmp = NULL; |
| 625 |
goto END; |
| 626 |
} else |
| 627 |
printf("Created directory %s\n", remote_tmp); |
| 628 |
|
| 629 |
xfree(remote_tmp); |
| 630 |
remote_tmp = NULL; |
| 631 |
|
| 632 |
break; |
| 633 |
case FTS_F: |
| 634 |
debug3("FTS_F: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path); |
| 635 |
|
| 636 |
/* Upload the file. */ |
| 637 |
|
| 638 |
if ( NULL != remote_path ) { |
| 639 |
remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path); |
| 640 |
} else { |
| 641 |
remote_tmp = xstrdup(local_fsent->fts_path); |
| 642 |
remote_tmp = make_absolute(remote_tmp, pwd); |
| 643 |
} |
| 644 |
|
| 645 |
/* If the file we plan to upload is already in place, remove it. */ |
| 646 |
|
| 647 |
if ( remote_is_dir(conn, remote_tmp) ) { |
| 648 |
printf("%s already exists as directory\n", remote_tmp); |
| 649 |
xfree(remote_tmp); |
| 650 |
remote_tmp = NULL; |
| 651 |
break; |
| 652 |
} else if ( remote_file_exists(conn, remote_tmp) ) { |
| 653 |
printf("%s already exists as non-directory... removing\n", remote_tmp); |
| 654 |
|
| 655 |
if ( -1 == do_rm(conn, remote_tmp) ) |
| 656 |
{ |
| 657 |
error("Couldn't remove \"%s\"", remote_tmp); |
| 658 |
this_rc = -1; |
| 659 |
xfree(remote_tmp); |
| 660 |
remote_tmp = NULL; |
| 661 |
goto END; |
| 662 |
} |
| 663 |
} |
| 664 |
|
| 665 |
if ( -1 == do_upload(conn, local_fsent->fts_accpath, remote_tmp, pflag) ) { |
| 666 |
error("Couldn't upload \"%s\"", remote_tmp); |
| 667 |
this_rc = -1; |
| 668 |
xfree(remote_tmp); |
| 669 |
remote_tmp = NULL; |
| 670 |
goto END; |
| 671 |
} |
| 672 |
|
| 673 |
xfree(remote_tmp); |
| 674 |
remote_tmp = NULL; |
| 675 |
|
| 676 |
break; |
| 677 |
case FTS_SL: |
| 678 |
case FTS_SLNONE: |
| 679 |
debug3("FTS_SL: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path); |
| 680 |
|
| 681 |
/* Read the fts_statp information and create a link on the remote machine. */ |
| 682 |
|
| 683 |
if ( -1 == (len = readlink(local_fsent->fts_accpath, link, sizeof(link) - 1)) ) { |
| 684 |
error("Couldn't readlink \"%s\"", local_fsent->fts_accpath); |
| 685 |
this_rc = -1; |
| 686 |
goto END; |
| 687 |
} |
| 688 |
|
| 689 |
link[len] = '\0'; |
| 690 |
|
| 691 |
if ( NULL != remote_path ) { |
| 692 |
remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path); |
| 693 |
} else { |
| 694 |
remote_tmp = xstrdup(local_fsent->fts_path); |
| 695 |
remote_tmp = make_absolute(remote_tmp, pwd); |
| 696 |
} |
| 697 |
|
| 698 |
/* If the symlink we plan to make is already in place, remove it. */ |
| 699 |
|
| 700 |
if ( remote_is_dir(conn, remote_tmp) ) { |
| 701 |
printf("%s already exists as directory\n", remote_tmp); |
| 702 |
xfree(remote_tmp); |
| 703 |
remote_tmp = NULL; |
| 704 |
|
| 705 |
if ( -1 == fts_set(local_tree, local_fsent, FTS_SKIP) ) { |
| 706 |
fatal("fts_set error: %s: %s", local_fsent->fts_path, strerror(errno)); |
| 707 |
} |
| 708 |
|
| 709 |
break; |
| 710 |
} else if ( remote_file_exists(conn, remote_tmp) ) { |
| 711 |
printf("%s already exists as non-directory... removing\n", remote_tmp); |
| 712 |
|
| 713 |
if ( -1 == do_rm(conn, remote_tmp) ) |
| 714 |
{ |
| 715 |
error("Couldn't remove \"%s\"", remote_tmp); |
| 716 |
this_rc = -1; |
| 717 |
xfree(remote_tmp); |
| 718 |
remote_tmp = NULL; |
| 719 |
goto END; |
| 720 |
} |
| 721 |
} |
| 722 |
|
| 723 |
if ( -1 == do_symlink(conn, link, remote_tmp) ) { |
| 724 |
error("Couldn't symlink \"%s\"", remote_tmp); |
| 725 |
this_rc = -1; |
| 726 |
xfree(remote_tmp); |
| 727 |
remote_tmp = NULL; |
| 728 |
goto END; |
| 729 |
} else |
| 730 |
printf("Created symlink %s -> %s\n", remote_tmp, link); |
| 731 |
|
| 732 |
xfree(remote_tmp); |
| 733 |
remote_tmp = NULL; |
| 734 |
|
| 735 |
break; |
| 736 |
case FTS_DEFAULT: |
| 737 |
debug3("FTS_DEFAULT: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path); |
| 738 |
error("skipping non-regular file %s", local_fsent->fts_accpath); |
| 739 |
break; |
| 740 |
case FTS_DC: /* Directory visited in a cycle, already exists on remote machine from FTS_D, non-error */ |
| 741 |
case FTS_DP: /* Directory visited in post-order, non-error */ |
| 742 |
/* Do-nothing cases. */ |
| 743 |
break; |
| 744 |
default: |
| 745 |
/* Unknown/unaccounted for FTS_* case. Cause a fatal error. */ |
| 746 |
error("skipping non-regular file %s", local_fsent->fts_accpath); |
| 747 |
debug3("do_recursive_upload: fts_read returned unknown case! See fts(3) for more information."); |
| 748 |
debug3("type: %d, ", local_fsent->fts_info); |
| 749 |
debug3("local path: %s, ", local_fsent->fts_accpath); |
| 750 |
debug3("remote path: %s\n", local_fsent->fts_path); |
| 751 |
break; |
| 752 |
} |
| 753 |
|
| 754 |
} |
| 755 |
|
| 756 |
/* Break out of the while loop. */ |
| 757 |
END: |
| 758 |
|
| 759 |
/* Finished processing, close the tree. */ |
| 760 |
if ( -1 == (rc = fts_close(local_tree)) ) { |
| 761 |
fatal("do_recursive_upload: fts_close() returned error: %s", strerror(errno)); |
| 762 |
} |
| 763 |
|
| 764 |
return this_rc; |
| 765 |
} |
| 766 |
|
| 767 |
static int |
| 768 |
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag, |
| 769 |
int recursive_flag) |
| 437 |
{ |
770 |
{ |
| 438 |
char *abs_src = NULL; |
771 |
char *abs_src = NULL; |
| 439 |
char *abs_dst = NULL; |
772 |
char *abs_dst = NULL; |
|
Lines 499-506
Link Here
|
| 499 |
return(err); |
832 |
return(err); |
| 500 |
} |
833 |
} |
| 501 |
|
834 |
|
|
|
835 |
/* |
| 836 |
* The inputs into the upload is file-glob fg. fg matches a set of |
| 837 |
* local files {f1..fn}. For src-fsent in {f1..fn}: |
| 838 |
* |
| 839 |
* if (src-fsent is a file) { |
| 840 |
* * Recursive upload is irrelevant. Use standard upload rules for |
| 841 |
* this file. |
| 842 |
* } else if (src-fsent is a directory) { |
| 843 |
* if (dst exists) { |
| 844 |
* if (dst is a directory) { |
| 845 |
* Put (local) src-fsent as (remote) dst/src-fsent |
| 846 |
* } else * dst is not directory * { |
| 847 |
* Error out, no way to add into dst/src-fsent (dst is a file!) |
| 848 |
* } |
| 849 |
* } else * dst doesn't exist * { |
| 850 |
* create a directory dst |
| 851 |
* let all paths src-fsent/{f1..fn} become dst/{f1..fn} |
| 852 |
* } |
| 853 |
* } else * src-fsent is an un-uploadable filetype * { |
| 854 |
* } |
| 855 |
*/ |
| 856 |
|
| 502 |
static int |
857 |
static int |
| 503 |
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) |
858 |
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag, |
|
|
859 |
int recursive_flag) |
| 504 |
{ |
860 |
{ |
| 505 |
char *tmp_dst = NULL; |
861 |
char *tmp_dst = NULL; |
| 506 |
char *abs_dst = NULL; |
862 |
char *abs_dst = NULL; |
|
Lines 531-567
Link Here
|
| 531 |
} |
887 |
} |
| 532 |
|
888 |
|
| 533 |
for (i = 0; g.gl_pathv[i]; i++) { |
889 |
for (i = 0; g.gl_pathv[i]; i++) { |
| 534 |
if (!is_reg(g.gl_pathv[i])) { |
890 |
if (recursive_flag) { |
| 535 |
error("skipping non-regular file %s", |
891 |
if ( !is_reg(g.gl_pathv[i]) && !is_dir(g.gl_pathv[i]) && !is_symlink(g.gl_pathv[i])) { |
| 536 |
g.gl_pathv[i]); |
892 |
error("skipping %s", g.gl_pathv[i]); |
| 537 |
continue; |
893 |
continue; |
| 538 |
} |
894 |
} |
| 539 |
if (infer_path(g.gl_pathv[i], &tmp)) { |
|
|
| 540 |
err = -1; |
| 541 |
goto out; |
| 542 |
} |
| 543 |
|
895 |
|
| 544 |
if (g.gl_matchc == 1 && tmp_dst) { |
896 |
if (tmp_dst) { |
| 545 |
/* If directory specified, append filename */ |
897 |
if (remote_is_dir(conn, tmp_dst)) { |
| 546 |
if (remote_is_dir(conn, tmp_dst)) { |
898 |
/* If directory specified, append filename */ |
| 547 |
if (infer_path(g.gl_pathv[0], &tmp)) { |
899 |
if (infer_path(g.gl_pathv[i], &tmp)) { |
|
|
900 |
err = 1; |
| 901 |
goto out; |
| 902 |
} |
| 903 |
abs_dst = path_append(tmp_dst, tmp); |
| 904 |
xfree(tmp); |
| 905 |
tmp = NULL; |
| 906 |
} else { |
| 907 |
/* |
| 908 |
* Possible cases: |
| 909 |
* 1. Upload the file/dir to remote, overwriting remote file: dup specified name |
| 910 |
* 2. Remote tmp_dst doesn't exist: dup specified name |
| 911 |
* |
| 912 |
* Impossible cases: |
| 913 |
* 1. tmp_dst specified, more than one match, and !remote_is_dir() checked for earlier. |
| 914 |
*/ |
| 915 |
abs_dst = xstrdup(tmp_dst); |
| 916 |
abs_dst = make_absolute(tmp_dst, pwd); |
| 917 |
} |
| 918 |
} else { |
| 919 |
if (infer_path(g.gl_pathv[i], &tmp)) { |
| 548 |
err = 1; |
920 |
err = 1; |
| 549 |
goto out; |
921 |
goto out; |
| 550 |
} |
922 |
} |
|
|
923 |
abs_dst = make_absolute(tmp, pwd); |
| 924 |
xfree(tmp); |
| 925 |
tmp = NULL; |
| 926 |
} |
| 927 |
|
| 928 |
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); |
| 929 |
if (do_recursive_upload(conn, g.gl_pathv[i], abs_dst, pflag, pwd) == -1) |
| 930 |
err = -1; |
| 931 |
} else { |
| 932 |
if (!is_reg(g.gl_pathv[i])) { |
| 933 |
error("skipping non-regular file %s", |
| 934 |
g.gl_pathv[i]); |
| 935 |
continue; |
| 936 |
} |
| 937 |
if (infer_path(g.gl_pathv[i], &tmp)) { |
| 938 |
err = -1; |
| 939 |
goto out; |
| 940 |
} |
| 941 |
|
| 942 |
if (g.gl_matchc == 1 && tmp_dst) { |
| 943 |
/* If directory specified, append filename */ |
| 944 |
if (remote_is_dir(conn, tmp_dst)) { |
| 945 |
if (infer_path(g.gl_pathv[0], &tmp)) { |
| 946 |
err = 1; |
| 947 |
goto out; |
| 948 |
} |
| 949 |
abs_dst = path_append(tmp_dst, tmp); |
| 950 |
xfree(tmp); |
| 951 |
tmp = NULL; |
| 952 |
} else |
| 953 |
abs_dst = xstrdup(tmp_dst); |
| 954 |
|
| 955 |
} else if (tmp_dst) { |
| 551 |
abs_dst = path_append(tmp_dst, tmp); |
956 |
abs_dst = path_append(tmp_dst, tmp); |
| 552 |
xfree(tmp); |
957 |
xfree(tmp); |
|
|
958 |
tmp = NULL; |
| 553 |
} else |
959 |
} else |
| 554 |
abs_dst = xstrdup(tmp_dst); |
960 |
abs_dst = make_absolute(tmp, pwd); |
| 555 |
|
961 |
|
| 556 |
} else if (tmp_dst) { |
962 |
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); |
| 557 |
abs_dst = path_append(tmp_dst, tmp); |
963 |
if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1) |
| 558 |
xfree(tmp); |
964 |
err = -1; |
| 559 |
} else |
965 |
} |
| 560 |
abs_dst = make_absolute(tmp, pwd); |
|
|
| 561 |
|
966 |
|
| 562 |
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); |
967 |
xfree(abs_dst); |
| 563 |
if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1) |
968 |
abs_dst = NULL; |
| 564 |
err = -1; |
|
|
| 565 |
} |
969 |
} |
| 566 |
|
970 |
|
| 567 |
out: |
971 |
out: |
|
Lines 746-752
Link Here
|
| 746 |
} |
1150 |
} |
| 747 |
|
1151 |
|
| 748 |
static int |
1152 |
static int |
| 749 |
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, |
1153 |
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *recursive_flag, |
| 750 |
unsigned long *n_arg, char **path1, char **path2) |
1154 |
unsigned long *n_arg, char **path1, char **path2) |
| 751 |
{ |
1155 |
{ |
| 752 |
const char *cmd, *cp = *cpp; |
1156 |
const char *cmd, *cp = *cpp; |
|
Lines 794-805
Link Here
|
| 794 |
} |
1198 |
} |
| 795 |
|
1199 |
|
| 796 |
/* Get arguments and parse flags */ |
1200 |
/* Get arguments and parse flags */ |
| 797 |
*lflag = *pflag = *n_arg = 0; |
1201 |
*lflag = *pflag = *recursive_flag = *n_arg = 0; |
| 798 |
*path1 = *path2 = NULL; |
1202 |
*path1 = *path2 = NULL; |
| 799 |
switch (cmdnum) { |
1203 |
switch (cmdnum) { |
| 800 |
case I_GET: |
1204 |
case I_GET: |
| 801 |
case I_PUT: |
1205 |
case I_PUT: |
| 802 |
if (parse_getput_flags(&cp, pflag)) |
1206 |
if (parse_getput_flags(&cp, pflag, recursive_flag)) |
| 803 |
return(-1); |
1207 |
return(-1); |
| 804 |
/* Get first pathname (mandatory) */ |
1208 |
/* Get first pathname (mandatory) */ |
| 805 |
if (get_pathname(&cp, path1)) |
1209 |
if (get_pathname(&cp, path1)) |
|
Lines 905-911
Link Here
|
| 905 |
int err_abort) |
1309 |
int err_abort) |
| 906 |
{ |
1310 |
{ |
| 907 |
char *path1, *path2, *tmp; |
1311 |
char *path1, *path2, *tmp; |
| 908 |
int pflag, lflag, iflag, cmdnum, i; |
1312 |
int pflag, lflag, iflag, recursive_flag, cmdnum, i; |
| 909 |
unsigned long n_arg; |
1313 |
unsigned long n_arg; |
| 910 |
Attrib a, *aa; |
1314 |
Attrib a, *aa; |
| 911 |
char path_buf[MAXPATHLEN]; |
1315 |
char path_buf[MAXPATHLEN]; |
|
Lines 913-919
Link Here
|
| 913 |
glob_t g; |
1317 |
glob_t g; |
| 914 |
|
1318 |
|
| 915 |
path1 = path2 = NULL; |
1319 |
path1 = path2 = NULL; |
| 916 |
cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, |
1320 |
cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &recursive_flag, &n_arg, |
| 917 |
&path1, &path2); |
1321 |
&path1, &path2); |
| 918 |
|
1322 |
|
| 919 |
if (iflag != 0) |
1323 |
if (iflag != 0) |
|
Lines 931-940
Link Here
|
| 931 |
err = -1; |
1335 |
err = -1; |
| 932 |
break; |
1336 |
break; |
| 933 |
case I_GET: |
1337 |
case I_GET: |
| 934 |
err = process_get(conn, path1, path2, *pwd, pflag); |
1338 |
err = process_get(conn, path1, path2, *pwd, pflag, recursive_flag); |
| 935 |
break; |
1339 |
break; |
| 936 |
case I_PUT: |
1340 |
case I_PUT: |
| 937 |
err = process_put(conn, path1, path2, *pwd, pflag); |
1341 |
err = process_put(conn, path1, path2, *pwd, pflag, recursive_flag); |
| 938 |
break; |
1342 |
break; |
| 939 |
case I_RENAME: |
1343 |
case I_RENAME: |
| 940 |
path1 = make_absolute(path1, *pwd); |
1344 |
path1 = make_absolute(path1, *pwd); |