On Sun, 17 Dec 2017 18:11:46 +0200, Artturi Alm wrote:

> something doesn't feel right here, as manpage suggests path to be
> optional? and that first try with ~/ does report success after failing?
> didn't know any use-case for /~/ before trying this :)

Yes, the path is supposed to be optional.  A missing path should
be treated as ".".  The following diff fixes the crash and the exit
value on error.  I'll cook up a better diff with warnings later;
scp's error handling is pretty poor.

 - todd

Index: usr.bin/ssh/scp.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/scp.c,v
retrieving revision 1.193
diff -u -p -u -r1.193 scp.c
--- usr.bin/ssh/scp.c   21 Oct 2017 23:06:24 -0000      1.193
+++ usr.bin/ssh/scp.c   17 Dec 2017 21:16:25 -0000
@@ -583,6 +583,18 @@ do_times(int fd, int verb, const struct 
        return (response());
 }
 
+static int
+parse_scp_uri(const char *uri, char **userp, char **hostp, int *portp,
+     char **pathp)
+{
+       int r;
+
+       r = parse_uri("scp", uri, userp, hostp, portp, pathp);
+       if (r == 0 && *pathp == NULL)
+               *pathp = xstrdup(".");
+       return r;
+}
+
 void
 toremote(int argc, char **argv)
 {
@@ -597,25 +609,33 @@ toremote(int argc, char **argv)
        alist.list = NULL;
 
        /* Parse target */
-       r = parse_uri("scp", argv[argc - 1], &tuser, &thost, &tport, &targ);
-       if (r == -1)
+       r = parse_scp_uri(argv[argc - 1], &tuser, &thost, &tport, &targ);
+       if (r == -1) {
+               ++errs;
                goto out;       /* invalid URI */
+       }
        if (r != 0) {
                if (parse_user_host_path(argv[argc - 1], &tuser, &thost,
-                   &targ) == -1)
+                   &targ) == -1) {
+                       ++errs;
                        goto out;
+               }
        }
-       if (tuser != NULL && !okname(tuser))
+       if (tuser != NULL && !okname(tuser)) {
+               ++errs;
                goto out;
+       }
 
        /* Parse source files */
        for (i = 0; i < argc - 1; i++) {
                free(suser);
                free(host);
                free(src);
-               r = parse_uri("scp", argv[i], &suser, &host, &sport, &src);
-               if (r == -1)
+               r = parse_scp_uri(argv[i], &suser, &host, &sport, &src);
+               if (r == -1) {
+                       ++errs;
                        continue;       /* invalid URI */
+               }
                if (r != 0)
                        parse_user_host_path(argv[i], &suser, &host, &src);
                if (suser != NULL && !okname(suser)) {
@@ -707,7 +727,7 @@ tolocal(int argc, char **argv)
                free(suser);
                free(host);
                free(src);
-               r = parse_uri("scp", argv[i], &suser, &host, &sport, &src);
+               r = parse_scp_uri(argv[i], &suser, &host, &sport, &src);
                if (r == -1) {
                        ++errs;
                        continue;

Reply via email to