summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c77
1 files changed, 42 insertions, 35 deletions
diff --git a/sftp.c b/sftp.c
index 2077219fa..08e13a733 100644
--- a/sftp.c
+++ b/sftp.c
@@ -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 */
337static char * 339static char *
338path_strip(char *path, char *strip) 340path_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
355static char * 357static char *
356make_absolute(char *p, char *pwd) 358make_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
553static int 555static int
554is_dir(char *path) 556is_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
565static int 567static int
566remote_is_dir(struct sftp_conn *conn, char *path) 568remote_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 */
579static int 581static int
580pathname_is_dir(char *pathname) 582pathname_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
587static int 589static int
588process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, 590process_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
671static int 675static int
672process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, 676process_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 */
781static int 786static int
782do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) 787do_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 */
866static int 872static int
867do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, 873do_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
951static int 957static int
952do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) 958do_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
1206static int 1212static int
1207parse_args(const char **cpp, int *ignore_errors, int *aflag, 1213parse_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");