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;