diff options
Diffstat (limited to 'sftp.c')
-rw-r--r-- | sftp.c | 77 |
1 files changed, 42 insertions, 35 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp.c,v 1.172 2016/02/15 09:47:49 dtucker Exp $ */ | 1 | /* $OpenBSD: sftp.c,v 1.175 2016/07/22 03:47:36 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -49,6 +49,7 @@ typedef void EditLine; | |||
49 | #endif | 49 | #endif |
50 | #include <limits.h> | 50 | #include <limits.h> |
51 | #include <signal.h> | 51 | #include <signal.h> |
52 | #include <stdarg.h> | ||
52 | #include <stdlib.h> | 53 | #include <stdlib.h> |
53 | #include <stdio.h> | 54 | #include <stdio.h> |
54 | #include <string.h> | 55 | #include <string.h> |
@@ -63,6 +64,7 @@ typedef void EditLine; | |||
63 | #include "log.h" | 64 | #include "log.h" |
64 | #include "pathnames.h" | 65 | #include "pathnames.h" |
65 | #include "misc.h" | 66 | #include "misc.h" |
67 | #include "utf8.h" | ||
66 | 68 | ||
67 | #include "sftp.h" | 69 | #include "sftp.h" |
68 | #include "ssherr.h" | 70 | #include "ssherr.h" |
@@ -335,7 +337,7 @@ local_do_ls(const char *args) | |||
335 | 337 | ||
336 | /* Strip one path (usually the pwd) from the start of another */ | 338 | /* Strip one path (usually the pwd) from the start of another */ |
337 | static char * | 339 | static char * |
338 | path_strip(char *path, char *strip) | 340 | path_strip(const char *path, const char *strip) |
339 | { | 341 | { |
340 | size_t len; | 342 | size_t len; |
341 | 343 | ||
@@ -353,7 +355,7 @@ path_strip(char *path, char *strip) | |||
353 | } | 355 | } |
354 | 356 | ||
355 | static char * | 357 | static char * |
356 | make_absolute(char *p, char *pwd) | 358 | make_absolute(char *p, const char *pwd) |
357 | { | 359 | { |
358 | char *abs_str; | 360 | char *abs_str; |
359 | 361 | ||
@@ -551,7 +553,7 @@ parse_no_flags(const char *cmd, char **argv, int argc) | |||
551 | } | 553 | } |
552 | 554 | ||
553 | static int | 555 | static int |
554 | is_dir(char *path) | 556 | is_dir(const char *path) |
555 | { | 557 | { |
556 | struct stat sb; | 558 | struct stat sb; |
557 | 559 | ||
@@ -563,7 +565,7 @@ is_dir(char *path) | |||
563 | } | 565 | } |
564 | 566 | ||
565 | static int | 567 | static int |
566 | remote_is_dir(struct sftp_conn *conn, char *path) | 568 | remote_is_dir(struct sftp_conn *conn, const char *path) |
567 | { | 569 | { |
568 | Attrib *a; | 570 | Attrib *a; |
569 | 571 | ||
@@ -577,7 +579,7 @@ remote_is_dir(struct sftp_conn *conn, char *path) | |||
577 | 579 | ||
578 | /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ | 580 | /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ |
579 | static int | 581 | static int |
580 | pathname_is_dir(char *pathname) | 582 | pathname_is_dir(const char *pathname) |
581 | { | 583 | { |
582 | size_t l = strlen(pathname); | 584 | size_t l = strlen(pathname); |
583 | 585 | ||
@@ -585,8 +587,8 @@ pathname_is_dir(char *pathname) | |||
585 | } | 587 | } |
586 | 588 | ||
587 | static int | 589 | static int |
588 | process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, | 590 | process_get(struct sftp_conn *conn, const char *src, const char *dst, |
589 | int pflag, int rflag, int resume, int fflag) | 591 | const char *pwd, int pflag, int rflag, int resume, int fflag) |
590 | { | 592 | { |
591 | char *abs_src = NULL; | 593 | char *abs_src = NULL; |
592 | char *abs_dst = NULL; | 594 | char *abs_dst = NULL; |
@@ -644,9 +646,11 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, | |||
644 | 646 | ||
645 | resume |= global_aflag; | 647 | resume |= global_aflag; |
646 | if (!quiet && resume) | 648 | if (!quiet && resume) |
647 | printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst); | 649 | mprintf("Resuming %s to %s\n", |
650 | g.gl_pathv[i], abs_dst); | ||
648 | else if (!quiet && !resume) | 651 | else if (!quiet && !resume) |
649 | printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); | 652 | mprintf("Fetching %s to %s\n", |
653 | g.gl_pathv[i], abs_dst); | ||
650 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { | 654 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
651 | if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, | 655 | if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
652 | pflag || global_pflag, 1, resume, | 656 | pflag || global_pflag, 1, resume, |
@@ -669,8 +673,8 @@ out: | |||
669 | } | 673 | } |
670 | 674 | ||
671 | static int | 675 | static int |
672 | process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, | 676 | process_put(struct sftp_conn *conn, const char *src, const char *dst, |
673 | int pflag, int rflag, int resume, int fflag) | 677 | const char *pwd, int pflag, int rflag, int resume, int fflag) |
674 | { | 678 | { |
675 | char *tmp_dst = NULL; | 679 | char *tmp_dst = NULL; |
676 | char *abs_dst = NULL; | 680 | char *abs_dst = NULL; |
@@ -735,10 +739,11 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, | |||
735 | 739 | ||
736 | resume |= global_aflag; | 740 | resume |= global_aflag; |
737 | if (!quiet && resume) | 741 | if (!quiet && resume) |
738 | printf("Resuming upload of %s to %s\n", g.gl_pathv[i], | 742 | mprintf("Resuming upload of %s to %s\n", |
739 | abs_dst); | 743 | g.gl_pathv[i], abs_dst); |
740 | else if (!quiet && !resume) | 744 | else if (!quiet && !resume) |
741 | printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); | 745 | mprintf("Uploading %s to %s\n", |
746 | g.gl_pathv[i], abs_dst); | ||
742 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { | 747 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
743 | if (upload_dir(conn, g.gl_pathv[i], abs_dst, | 748 | if (upload_dir(conn, g.gl_pathv[i], abs_dst, |
744 | pflag || global_pflag, 1, resume, | 749 | pflag || global_pflag, 1, resume, |
@@ -779,7 +784,8 @@ sdirent_comp(const void *aa, const void *bb) | |||
779 | 784 | ||
780 | /* sftp ls.1 replacement for directories */ | 785 | /* sftp ls.1 replacement for directories */ |
781 | static int | 786 | static int |
782 | do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) | 787 | do_ls_dir(struct sftp_conn *conn, const char *path, |
788 | const char *strip_path, int lflag) | ||
783 | { | 789 | { |
784 | int n; | 790 | int n; |
785 | u_int c = 1, colspace = 0, columns = 1; | 791 | u_int c = 1, colspace = 0, columns = 1; |
@@ -839,12 +845,12 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) | |||
839 | attrib_to_stat(&d[n]->a, &sb); | 845 | attrib_to_stat(&d[n]->a, &sb); |
840 | lname = ls_file(fname, &sb, 1, | 846 | lname = ls_file(fname, &sb, 1, |
841 | (lflag & LS_SI_UNITS)); | 847 | (lflag & LS_SI_UNITS)); |
842 | printf("%s\n", lname); | 848 | mprintf("%s\n", lname); |
843 | free(lname); | 849 | free(lname); |
844 | } else | 850 | } else |
845 | printf("%s\n", d[n]->longname); | 851 | mprintf("%s\n", d[n]->longname); |
846 | } else { | 852 | } else { |
847 | printf("%-*s", colspace, fname); | 853 | mprintf("%-*s", colspace, fname); |
848 | if (c >= columns) { | 854 | if (c >= columns) { |
849 | printf("\n"); | 855 | printf("\n"); |
850 | c = 1; | 856 | c = 1; |
@@ -864,8 +870,8 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) | |||
864 | 870 | ||
865 | /* sftp ls.1 replacement which handles path globs */ | 871 | /* sftp ls.1 replacement which handles path globs */ |
866 | static int | 872 | static int |
867 | do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | 873 | do_globbed_ls(struct sftp_conn *conn, const char *path, |
868 | int lflag) | 874 | const char *strip_path, int lflag) |
869 | { | 875 | { |
870 | char *fname, *lname; | 876 | char *fname, *lname; |
871 | glob_t g; | 877 | glob_t g; |
@@ -925,10 +931,10 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
925 | } | 931 | } |
926 | lname = ls_file(fname, g.gl_statv[i], 1, | 932 | lname = ls_file(fname, g.gl_statv[i], 1, |
927 | (lflag & LS_SI_UNITS)); | 933 | (lflag & LS_SI_UNITS)); |
928 | printf("%s\n", lname); | 934 | mprintf("%s\n", lname); |
929 | free(lname); | 935 | free(lname); |
930 | } else { | 936 | } else { |
931 | printf("%-*s", colspace, fname); | 937 | mprintf("%-*s", colspace, fname); |
932 | if (c >= columns) { | 938 | if (c >= columns) { |
933 | printf("\n"); | 939 | printf("\n"); |
934 | c = 1; | 940 | c = 1; |
@@ -949,7 +955,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
949 | } | 955 | } |
950 | 956 | ||
951 | static int | 957 | static int |
952 | do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) | 958 | do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) |
953 | { | 959 | { |
954 | struct sftp_statvfs st; | 960 | struct sftp_statvfs st; |
955 | char s_used[FMT_SCALED_STRSIZE]; | 961 | char s_used[FMT_SCALED_STRSIZE]; |
@@ -1205,7 +1211,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, | |||
1205 | 1211 | ||
1206 | static int | 1212 | static int |
1207 | parse_args(const char **cpp, int *ignore_errors, int *aflag, | 1213 | parse_args(const char **cpp, int *ignore_errors, int *aflag, |
1208 | int *fflag, int *hflag, int *iflag, int *lflag, int *pflag, | 1214 | int *fflag, int *hflag, int *iflag, int *lflag, int *pflag, |
1209 | int *rflag, int *sflag, | 1215 | int *rflag, int *sflag, |
1210 | unsigned long *n_arg, char **path1, char **path2) | 1216 | unsigned long *n_arg, char **path1, char **path2) |
1211 | { | 1217 | { |
@@ -1397,7 +1403,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1397 | int err_abort) | 1403 | int err_abort) |
1398 | { | 1404 | { |
1399 | char *path1, *path2, *tmp; | 1405 | char *path1, *path2, *tmp; |
1400 | int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, | 1406 | int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, |
1401 | iflag = 0; | 1407 | iflag = 0; |
1402 | int lflag = 0, pflag = 0, rflag = 0, sflag = 0; | 1408 | int lflag = 0, pflag = 0, rflag = 0, sflag = 0; |
1403 | int cmdnum, i; | 1409 | int cmdnum, i; |
@@ -1456,7 +1462,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1456 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); | 1462 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); |
1457 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { | 1463 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
1458 | if (!quiet) | 1464 | if (!quiet) |
1459 | printf("Removing %s\n", g.gl_pathv[i]); | 1465 | mprintf("Removing %s\n", g.gl_pathv[i]); |
1460 | err = do_rm(conn, g.gl_pathv[i]); | 1466 | err = do_rm(conn, g.gl_pathv[i]); |
1461 | if (err != 0 && err_abort) | 1467 | if (err != 0 && err_abort) |
1462 | break; | 1468 | break; |
@@ -1556,7 +1562,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1556 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); | 1562 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); |
1557 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { | 1563 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
1558 | if (!quiet) | 1564 | if (!quiet) |
1559 | printf("Changing mode on %s\n", g.gl_pathv[i]); | 1565 | mprintf("Changing mode on %s\n", |
1566 | g.gl_pathv[i]); | ||
1560 | err = do_setstat(conn, g.gl_pathv[i], &a); | 1567 | err = do_setstat(conn, g.gl_pathv[i], &a); |
1561 | if (err != 0 && err_abort) | 1568 | if (err != 0 && err_abort) |
1562 | break; | 1569 | break; |
@@ -1586,12 +1593,12 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1586 | aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; | 1593 | aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; |
1587 | if (cmdnum == I_CHOWN) { | 1594 | if (cmdnum == I_CHOWN) { |
1588 | if (!quiet) | 1595 | if (!quiet) |
1589 | printf("Changing owner on %s\n", | 1596 | mprintf("Changing owner on %s\n", |
1590 | g.gl_pathv[i]); | 1597 | g.gl_pathv[i]); |
1591 | aa->uid = n_arg; | 1598 | aa->uid = n_arg; |
1592 | } else { | 1599 | } else { |
1593 | if (!quiet) | 1600 | if (!quiet) |
1594 | printf("Changing group on %s\n", | 1601 | mprintf("Changing group on %s\n", |
1595 | g.gl_pathv[i]); | 1602 | g.gl_pathv[i]); |
1596 | aa->gid = n_arg; | 1603 | aa->gid = n_arg; |
1597 | } | 1604 | } |
@@ -1601,7 +1608,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1601 | } | 1608 | } |
1602 | break; | 1609 | break; |
1603 | case I_PWD: | 1610 | case I_PWD: |
1604 | printf("Remote working directory: %s\n", *pwd); | 1611 | mprintf("Remote working directory: %s\n", *pwd); |
1605 | break; | 1612 | break; |
1606 | case I_LPWD: | 1613 | case I_LPWD: |
1607 | if (!getcwd(path_buf, sizeof(path_buf))) { | 1614 | if (!getcwd(path_buf, sizeof(path_buf))) { |
@@ -1609,7 +1616,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1609 | err = -1; | 1616 | err = -1; |
1610 | break; | 1617 | break; |
1611 | } | 1618 | } |
1612 | printf("Local working directory: %s\n", path_buf); | 1619 | mprintf("Local working directory: %s\n", path_buf); |
1613 | break; | 1620 | break; |
1614 | case I_QUIT: | 1621 | case I_QUIT: |
1615 | /* Processed below */ | 1622 | /* Processed below */ |
@@ -1678,7 +1685,7 @@ complete_display(char **list, u_int len) | |||
1678 | for (y = 0; list[y]; y++) { | 1685 | for (y = 0; list[y]; y++) { |
1679 | llen = strlen(list[y]); | 1686 | llen = strlen(list[y]); |
1680 | tmp = llen > len ? list[y] + len : ""; | 1687 | tmp = llen > len ? list[y] + len : ""; |
1681 | printf("%-*s", colspace, tmp); | 1688 | mprintf("%-*s", colspace, tmp); |
1682 | if (m >= columns) { | 1689 | if (m >= columns) { |
1683 | printf("\n"); | 1690 | printf("\n"); |
1684 | m = 1; | 1691 | m = 1; |
@@ -2062,7 +2069,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) | |||
2062 | 2069 | ||
2063 | if (remote_is_dir(conn, dir) && file2 == NULL) { | 2070 | if (remote_is_dir(conn, dir) && file2 == NULL) { |
2064 | if (!quiet) | 2071 | if (!quiet) |
2065 | printf("Changing to: %s\n", dir); | 2072 | mprintf("Changing to: %s\n", dir); |
2066 | snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); | 2073 | snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); |
2067 | if (parse_dispatch_command(conn, cmd, | 2074 | if (parse_dispatch_command(conn, cmd, |
2068 | &remote_path, 1) != 0) { | 2075 | &remote_path, 1) != 0) { |
@@ -2106,7 +2113,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) | |||
2106 | break; | 2113 | break; |
2107 | } | 2114 | } |
2108 | if (!interactive) { /* Echo command */ | 2115 | if (!interactive) { /* Echo command */ |
2109 | printf("sftp> %s", cmd); | 2116 | mprintf("sftp> %s", cmd); |
2110 | if (strlen(cmd) > 0 && | 2117 | if (strlen(cmd) > 0 && |
2111 | cmd[strlen(cmd) - 1] != '\n') | 2118 | cmd[strlen(cmd) - 1] != '\n') |
2112 | printf("\n"); | 2119 | printf("\n"); |