Bugzilla – Attachment 3619 Details for
Bug 3488
scp fails to locate remote paths containing a non-empty square bracket pair
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
handle glob no-match conditions like olde scp
bz3488.diff (text/plain), 3.87 KB, created by
Damien Miller
on 2022-10-24 15:21:33 AEDT
(
hide
)
Description:
handle glob no-match conditions like olde scp
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2022-10-24 15:21:33 AEDT
Size:
3.87 KB
patch
obsolete
>diff --git a/scp.c b/scp.c >index 582e232..58ac050 100644 >--- a/scp.c >+++ b/scp.c >@@ -1474,7 +1474,8 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) > } > > debug3_f("copying remote %s to local %s", abs_src, dst); >- if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) { >+ if ((r = remote_glob(conn, abs_src, GLOB_NOCHECK|GLOB_MARK, >+ NULL, &g)) != 0) { > if (r == GLOB_NOSPACE) > error("%s: too many glob matches", src); > else >@@ -1483,6 +1484,20 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) > goto out; > } > >+ /* Did we actually get any matches back from the glob? */ >+ if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) { >+ /* >+ * If nothing matched but a path returned, then it's probably >+ * a GLOB_NOCHECK result. Check whether the unglobbed path >+ * exists so we can give a nice error message early. >+ */ >+ if (do_stat(conn, g.gl_pathv[0], 1) == NULL) { >+ error("%s: %s", src, strerror(ENOENT)); >+ err = -1; >+ goto out; >+ } >+ } >+ > if ((r = stat(dst, &st)) != 0) > debug2_f("stat local \"%s\": %s", dst, strerror(errno)); > dst_is_dir = r == 0 && S_ISDIR(st.st_mode); >@@ -1883,7 +1898,8 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to, > } > > debug3_f("copying remote %s to remote %s", abs_src, target); >- if ((r = remote_glob(from, abs_src, GLOB_MARK, NULL, &g)) != 0) { >+ if ((r = remote_glob(from, abs_src, GLOB_NOCHECK|GLOB_MARK, >+ NULL, &g)) != 0) { > if (r == GLOB_NOSPACE) > error("%s: too many glob matches", src); > else >@@ -1892,6 +1908,20 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to, > goto out; > } > >+ /* Did we actually get any matches back from the glob? */ >+ if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) { >+ /* >+ * If nothing matched but a path returned, then it's probably >+ * a GLOB_NOCHECK result. Check whether the unglobbed path >+ * exists so we can give a nice error message early. >+ */ >+ if (do_stat(from, g.gl_pathv[0], 1) == NULL) { >+ error("%s: %s", src, strerror(ENOENT)); >+ err = -1; >+ goto out; >+ } >+ } >+ > for (i = 0; g.gl_pathv[i] && !interrupted; i++) { > tmp = xstrdup(g.gl_pathv[i]); > if ((filename = basename(tmp)) == NULL) { >diff --git a/sftp-glob.c b/sftp-glob.c >index ee1d123..ea171d2 100644 >--- a/sftp-glob.c >+++ b/sftp-glob.c >@@ -110,6 +110,11 @@ int > remote_glob(struct sftp_conn *conn, const char *pattern, int flags, > int (*errfunc)(const char *, int), glob_t *pglob) > { >+ int r; >+ size_t l; >+ char *s; >+ struct stat sb; >+ > pglob->gl_opendir = fudge_opendir; > pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; > pglob->gl_closedir = (void (*)(void *))fudge_closedir; >@@ -119,5 +124,30 @@ remote_glob(struct sftp_conn *conn, const char *pattern, int flags, > memset(&cur, 0, sizeof(cur)); > cur.conn = conn; > >- return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); >+ if ((r = glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)) != 0) >+ return r; >+ /* >+ * When both GLOB_NOCHECK and GLOB_MARK are active, a single gl_pathv >+ * entry has been returned and that entry has not already been marked, >+ * then check whether it needs a '/' appended as a directory mark. >+ * >+ * This ensures that a NOCHECK result is annotated as a directory. >+ * The glob(3) spec doesn't promise to mark NOCHECK entries, but doing >+ * it simplifies our callers (sftp/scp) considerably. >+ * >+ * XXX doesn't try to handle gl_offs. >+ */ >+ if ((flags & (GLOB_NOCHECK|GLOB_MARK)) == (GLOB_NOCHECK|GLOB_MARK) && >+ pglob->gl_matchc == 0 && pglob->gl_offs == 0 && >+ pglob->gl_pathc == 1 && (s = pglob->gl_pathv[0]) != NULL && >+ (l = strlen(s)) > 0 && s[l-1] != '/') { >+ if (fudge_stat(s, &sb) == 0 && S_ISDIR(sb.st_mode)) { >+ /* NOCHECK on a directory; annotate */ >+ if ((s = realloc(s, l + 2)) != NULL) { >+ memcpy(s + l, "/", 2); >+ pglob->gl_pathv[0] = s; >+ } >+ } >+ } >+ return 0; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
dtucker
:
ok+
Actions:
View
|
Diff
Attachments on
bug 3488
: 3619