static int scp_unsafe_mode = 0;
static int errs = 0;
static int gui_mode = 0;
+static int try_scp = 1;
+static int try_sftp = 1;
+static int main_cmd_is_sftp = 0;
+static int fallback_cmd_is_sftp = 0;
static int using_sftp = 0;
static Backend *back;
if (ssh_sftp_loop_iteration() < 0)
return; /* doom */
}
- using_sftp = !ssh_fallback_cmd(backhandle);
+
+ /* Work out which backend we ended up using. */
+ if (!ssh_fallback_cmd(backhandle))
+ using_sftp = main_cmd_is_sftp;
+ else
+ using_sftp = fallback_cmd_is_sftp;
+
if (verbose) {
if (using_sftp)
tell_user(stderr, "Using SFTP");
if (back != NULL && back->socket(backhandle) != NULL) {
char ch;
back->special(backhandle, TS_EOF);
- ssh_scp_recv(&ch, 1);
+ ssh_scp_recv((unsigned char *) &ch, 1);
}
if (gui_mode)
cfg.portfwd[0] = cfg.portfwd[1] = '\0';
/*
+ * Set up main and possibly fallback command depending on
+ * options specified by user.
* Attempt to start the SFTP subsystem as a first choice,
* falling back to the provided scp command if that fails.
*/
- strcpy(cfg.remote_cmd, "sftp");
- cfg.ssh_subsys = TRUE;
- cfg.remote_cmd_ptr2 = cmd;
- cfg.ssh_subsys2 = FALSE;
+ cfg.remote_cmd_ptr2 = NULL;
+ if (try_sftp) {
+ /* First choice is SFTP subsystem. */
+ main_cmd_is_sftp = 1;
+ strcpy(cfg.remote_cmd, "sftp");
+ cfg.ssh_subsys = TRUE;
+ if (try_scp) {
+ /* Fallback is to use the provided scp command. */
+ fallback_cmd_is_sftp = 0;
+ cfg.remote_cmd_ptr2 = cmd;
+ cfg.ssh_subsys2 = FALSE;
+ } else {
+ /* Since we're not going to try SCP, we may as well try
+ * harder to find an SFTP server, since in the current
+ * implementation we have a spare slot. */
+ fallback_cmd_is_sftp = 1;
+ /* see psftp.c for full explanation of this kludge */
+ cfg.remote_cmd_ptr2 =
+ "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n"
+ "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n"
+ "exec sftp-server";
+ cfg.ssh_subsys2 = FALSE;
+ }
+ } else {
+ /* Don't try SFTP at all; just try the scp command. */
+ main_cmd_is_sftp = 0;
+ cfg.remote_cmd_ptr = cmd;
+ cfg.ssh_subsys = FALSE;
+ }
cfg.nopty = TRUE;
back = &ssh_backend;
- err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,0);
+ err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,
+ 0, cfg.tcp_keepalives);
if (err != NULL)
bump("ssh_init: %s", err);
logctx = log_init(NULL, &cfg);
{
float ratebs;
unsigned long eta;
- char etastr[10];
+ char *etastr;
int pct;
int len;
int elap;
eta = size - done;
else
eta = (unsigned long) ((size - done) / ratebs);
- sprintf(etastr, "%02ld:%02ld:%02ld",
- eta / 3600, (eta % 3600) / 60, eta % 60);
+ etastr = dupprintf("%02ld:%02ld:%02ld",
+ eta / 3600, (eta % 3600) / 60, eta % 60);
pct = (int) (100 * (done * 1.0 / size));
if (gui_mode) {
- gui_update_stats(name, size, pct, elap, done, eta,
+ gui_update_stats(name, size, pct, elap, done, eta,
(unsigned long) ratebs);
} else {
len = printf("\r%-25.25s | %10ld kB | %5.1f kB/s | ETA: %8s | %3d%%",
fflush(stdout);
}
+
+ free(etastr);
}
/*
char ch, resp, rbuf[2048];
int p;
- if (ssh_scp_recv(&resp, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &resp, 1) <= 0)
bump("Lost connection");
p = 0;
case 1: /* error */
case 2: /* fatal error */
do {
- if (ssh_scp_recv(&ch, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
bump("Protocol error: Lost connection");
rbuf[p++] = ch;
} while (p < sizeof(rbuf) && ch != '\n');
int sftp_recvdata(char *buf, int len)
{
- return ssh_scp_recv(buf, len);
+ return ssh_scp_recv((unsigned char *) buf, len);
}
int sftp_senddata(char *buf, int len)
{
- back->send(backhandle, (unsigned char *) buf, len);
+ back->send(backhandle, buf, len);
return 1;
}
bufsize = 0;
while (!done) {
- if (ssh_scp_recv(&ch, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
return 1;
if (ch == '\n')
bump("Protocol error: Unexpected newline");
i = 0;
action = ch;
do {
- if (ssh_scp_recv(&ch, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
bump("Lost connection");
if (i >= bufsize) {
bufsize = i + 128;
return actuallen;
} else {
- return ssh_scp_recv(data, len);
+ return ssh_scp_recv((unsigned char *) data, len);
}
}
received = 0;
while (received < act.size) {
char transbuf[4096];
- int blksize, read;
+ unsigned long blksize;
+ int read;
blksize = 4096;
- if (blksize > (int)(act.size - received))
+ if (blksize > (act.size - received))
blksize = act.size - received;
- read = scp_recv_filedata(transbuf, blksize);
+ read = scp_recv_filedata(transbuf, (int)blksize);
if (read <= 0)
bump("Lost connection");
if (wrerror)
if (using_sftp) {
scp_sftp_listdir(src);
} else {
- while (ssh_scp_recv(&c, 1) > 0)
+ while (ssh_scp_recv((unsigned char *) &c, 1) > 0)
tell_char(stdout, c);
}
}
printf("Usage: pscp [options] [user@]host:source target\n");
printf
(" pscp [options] source [source...] [user@]host:target\n");
- printf(" pscp [options] -ls user@host:filespec\n");
+ printf(" pscp [options] -ls [user@]host:filespec\n");
printf("Options:\n");
printf(" -p preserve file attributes\n");
printf(" -q quiet, don't show statistics\n");
printf(" -i key private key file for authentication\n");
printf(" -batch disable all interactive prompts\n");
printf(" -unsafe allow server-side wildcards (DANGEROUS)\n");
+ printf(" -V print version information\n");
+ printf(" -sftp force use of SFTP protocol\n");
+ printf(" -scp force use of SCP protocol\n");
#if 0
/*
* -gui is an internal option, used by GUI front ends to get
cleanup_exit(1);
}
+void version(void)
+{
+ printf("pscp: %s\n", ver);
+ cleanup_exit(1);
+}
+
void cmdline_error(char *p, ...)
{
va_list ap;
statistics = 0;
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) {
usage();
+ } else if (strcmp(argv[i], "-V") == 0) {
+ version();
} else if (strcmp(argv[i], "-gui") == 0 && i + 1 < argc) {
gui_enable(argv[++i]);
gui_mode = 1;
console_batch_mode = 1;
} else if (strcmp(argv[i], "-unsafe") == 0) {
scp_unsafe_mode = 1;
+ } else if (strcmp(argv[i], "-sftp") == 0) {
+ try_scp = 0; try_sftp = 1;
+ } else if (strcmp(argv[i], "-scp") == 0) {
+ try_scp = 1; try_sftp = 0;
} else if (strcmp(argv[i], "--") == 0) {
i++;
break;
if (back != NULL && back->socket(backhandle) != NULL) {
char ch;
back->special(backhandle, TS_EOF);
- ssh_scp_recv(&ch, 1);
+ ssh_scp_recv((unsigned char *) &ch, 1);
}
random_save_seed();