/*
* Return a pointer to the portion of str that comes after the last
- * slash (or backslash, if `local' is TRUE).
+ * slash (or backslash or colon, if `local' is TRUE).
*/
static char *stripslashes(char *str, int local)
{
char *p;
+ if (local) {
+ p = strchr(str, ':');
+ if (p) str = p+1;
+ }
+
p = strrchr(str, '/');
if (p) str = p+1;
struct fxp_names *names;
struct fxp_name *ournames;
int nnames, namesize;
- char *dir;
int i;
printf("Listing directory %s\n", dirname);
dirh = fxp_opendir(dirname);
if (dirh == NULL) {
- printf("Unable to open %s: %s\n", dir, fxp_error());
+ printf("Unable to open %s: %s\n", dirname, fxp_error());
} else {
nnames = namesize = 0;
ournames = NULL;
if (names == NULL) {
if (fxp_error_type() == SSH_FX_EOF)
break;
- printf("Reading directory %s: %s\n", dir, fxp_error());
+ printf("Reading directory %s: %s\n", dirname, fxp_error());
break;
}
if (names->nnames == 0) {
int namepos, namelen;
char *dirpath;
char *wildcard;
+ int matched_something; /* wildcard match set was non-empty */
} *scp_sftp_dirstack_head;
static char *scp_sftp_remotepath, *scp_sftp_currentname;
static char *scp_sftp_wildcard;
head->names[head->namepos].filename))))
head->namepos++; /* skip . and .. */
if (head->namepos < head->namelen) {
+ head->matched_something = 1;
fname = dupcat(head->dirpath, "/",
head->names[head->namepos++].filename,
NULL);
*/
if (head->wildcard) {
act->action = SCP_SINK_RETRY;
+ if (!head->matched_something) {
+ tell_user(stderr, "pscp: wildcard '%s' matched "
+ "no files", head->wildcard);
+ errs++;
+ }
sfree(head->wildcard);
+
} else {
act->action = SCP_SINK_ENDDIR;
}
newitem->dirpath = dupstr(fname);
if (scp_sftp_wildcard) {
newitem->wildcard = scp_sftp_wildcard;
+ newitem->matched_something = 0;
scp_sftp_wildcard = NULL;
} else {
newitem->wildcard = NULL;
static void sink(char *targ, char *src)
{
char *destfname;
- char ch;
int targisdir = 0;
- int settime;
int exists;
DWORD attr;
HANDLE f;
* Prevent the remote side from maliciously writing to
* files outside the target area by sending a filename
* containing `../'. In fact, it shouldn't be sending
- * filenames with any slashes in at all; so we'll find
- * the last slash or backslash in the filename and use
- * only the part after that. (And warn!)
+ * filenames with any slashes or colons in at all; so
+ * we'll find the last slash, backslash or colon in the
+ * filename and use only the part after that. (And
+ * warn!)
*
* In addition, we also ensure here that if we're
* copying a single file and the target is a directory
striptarget = stripslashes(act.name, 1);
if (striptarget != act.name) {
tell_user(stderr, "warning: remote host sent a compound"
- " pathname - possibly malicious! (ignored)");
+ " pathname '%s'", act.name);
+ tell_user(stderr, " renaming local file to '%s'",
+ striptarget);
}
/*
}
(void) scp_finish_filerecv();
sfree(destfname);
- sfree(act.name);
+ sfree(act.buf);
}
}
*/
srcpath = dupstr(src);
last = stripslashes(srcpath, 1);
- if (last == srcpath) {
- last = strchr(srcpath, ':');
- if (last)
- last++;
- else
- last = srcpath;
- }
*last = '\0';
dir = FindFirstFile(src, &fdat);
continue;
}
do {
- char *last;
char *filename;
/*
* Ensure that . and .. are never matched by wildcards,