/*
- * scp.c - Scp (Secure Copy) client for PuTTY.
- * Joris van Rantwijk, Simon Tatham
+ * scp.c - Scp (Secure Copy) client for PuTTY.
+ * Joris van Rantwijk, Simon Tatham
*
- * This is mainly based on ssh-1.2.26/scp.c by Timo Rinne & Tatu Ylonen.
- * They, in turn, used stuff from BSD rcp.
- *
- * Adaptations to enable connecting a GUI by L. Gunnarsson - Sept 2000
+ * This is mainly based on ssh-1.2.26/scp.c by Timo Rinne & Tatu Ylonen.
+ * They, in turn, used stuff from BSD rcp.
+ *
+ * (SGT, 2001-09-10: Joris van Rantwijk assures me that although
+ * this file as originally submitted was inspired by, and
+ * _structurally_ based on, ssh-1.2.26's scp.c, there wasn't any
+ * actual code duplicated, so the above comment shouldn't give rise
+ * to licensing issues.)
*/
#include <windows.h>
#include <limits.h>
#include <time.h>
#include <assert.h>
-/* GUI Adaptation - Sept 2000 */
-#include <winuser.h>
-#include <winbase.h>
#define PUTTY_DO_GLOBALS
#include "putty.h"
{
}
-void ldisc_send(char *buf, int len)
+void ldisc_send(char *buf, int len, int interactive)
{
/*
* This is only here because of the calls to ldisc_send(NULL,
return 0;
}
- inbuf_head = 0;
-
/*
* If this is before the real session begins, just return.
*/
if (portnumber)
cfg.port = portnumber;
+ /*
+ * Disable scary things which shouldn't be enabled for simple
+ * things like SCP and SFTP: agent forwarding, port forwarding,
+ * X forwarding.
+ */
+ cfg.x11_forward = 0;
+ cfg.agentfwd = 0;
+ cfg.portfwd[0] = cfg.portfwd[1] = '\0';
+
/*
* Attempt to start the SFTP subsystem as a first choice,
* falling back to the provided scp command if that fails.
sprintf(etastr, "%02ld:%02ld:%02ld",
eta / 3600, (eta % 3600) / 60, eta % 60);
- pct = (int) (100.0 * (float) done / size);
+ pct = (int) (100 * (done * 1.0 / size));
len = printf("\r%-25.25s | %10ld kB | %5.1f kB/s | ETA: %8s | %3d%%",
name, done / 1024, ratebs / 1024.0, etastr, pct);
/*
* 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,