mirror of
https://github.com/clearml/dropbear
synced 2025-05-29 09:28:36 +00:00
Update to scp from OpenSSH portable 4.3p2
--HG-- extra : convert_revision : e2bccdd6ba49edd575b1d0272c7dfee5f9f7acf6
This commit is contained in:
parent
a7a5365af2
commit
3a5c4b68bb
@ -252,6 +252,8 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
|
|||||||
|
|
||||||
#define _PATH_TTY "/dev/tty"
|
#define _PATH_TTY "/dev/tty"
|
||||||
|
|
||||||
|
#define _PATH_CP "/bin/cp"
|
||||||
|
|
||||||
/* Timeouts in seconds */
|
/* Timeouts in seconds */
|
||||||
#define SELECT_TIMEOUT 20
|
#define SELECT_TIMEOUT 20
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
/*RCSID("OpenBSD: progressmeter.c,v 1.15 2003/08/31 12:14:22 markus Exp ");*/
|
/*RCSID("$OpenBSD: progressmeter.c,v 1.24 2005/06/07 13:25:23 jaredy Exp $");*/
|
||||||
|
|
||||||
#include "progressmeter.h"
|
#include "progressmeter.h"
|
||||||
#include "atomicio.h"
|
#include "atomicio.h"
|
||||||
@ -43,21 +43,26 @@ static int can_output(void);
|
|||||||
static void format_size(char *, int, off_t);
|
static void format_size(char *, int, off_t);
|
||||||
static void format_rate(char *, int, off_t);
|
static void format_rate(char *, int, off_t);
|
||||||
|
|
||||||
|
/* window resizing */
|
||||||
|
static void sig_winch(int);
|
||||||
|
static void setscreensize(void);
|
||||||
|
|
||||||
/* updates the progressmeter to reflect the current state of the transfer */
|
/* updates the progressmeter to reflect the current state of the transfer */
|
||||||
void refresh_progress_meter(void);
|
void refresh_progress_meter(void);
|
||||||
|
|
||||||
/* signal handler for updating the progress meter */
|
/* signal handler for updating the progress meter */
|
||||||
static void update_progress_meter(int);
|
static void update_progress_meter(int);
|
||||||
|
|
||||||
static time_t start; /* start progress */
|
static time_t start; /* start progress */
|
||||||
static time_t last_update; /* last progress update */
|
static time_t last_update; /* last progress update */
|
||||||
static char *file; /* name of the file being transferred */
|
static char *file; /* name of the file being transferred */
|
||||||
static off_t end_pos; /* ending position of transfer */
|
static off_t end_pos; /* ending position of transfer */
|
||||||
static off_t cur_pos; /* transfer position as of last refresh */
|
static off_t cur_pos; /* transfer position as of last refresh */
|
||||||
static volatile off_t *counter; /* progress counter */
|
static volatile off_t *counter; /* progress counter */
|
||||||
static long stalled; /* how long we have been stalled */
|
static long stalled; /* how long we have been stalled */
|
||||||
static int bytes_per_second; /* current speed in bytes per second */
|
static int bytes_per_second; /* current speed in bytes per second */
|
||||||
static int win_size; /* terminal window size */
|
static int win_size; /* terminal window size */
|
||||||
|
static volatile sig_atomic_t win_resized; /* for window resizing */
|
||||||
|
|
||||||
/* units for format_size */
|
/* units for format_size */
|
||||||
static const char unit[] = " KMGT";
|
static const char unit[] = " KMGT";
|
||||||
@ -81,8 +86,8 @@ format_rate(char *buf, int size, off_t bytes)
|
|||||||
bytes = (bytes + 512) / 1024;
|
bytes = (bytes + 512) / 1024;
|
||||||
}
|
}
|
||||||
snprintf(buf, size, "%3lld.%1lld%c%s",
|
snprintf(buf, size, "%3lld.%1lld%c%s",
|
||||||
(int64_t) bytes / 100,
|
(long long) (bytes + 5) / 100,
|
||||||
(int64_t) (bytes + 5) / 10 % 10,
|
(long long) (bytes + 5) / 10 % 10,
|
||||||
unit[i],
|
unit[i],
|
||||||
i ? "B" : " ");
|
i ? "B" : " ");
|
||||||
}
|
}
|
||||||
@ -95,7 +100,7 @@ format_size(char *buf, int size, off_t bytes)
|
|||||||
for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++)
|
for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++)
|
||||||
bytes = (bytes + 512) / 1024;
|
bytes = (bytes + 512) / 1024;
|
||||||
snprintf(buf, size, "%4lld%c%s",
|
snprintf(buf, size, "%4lld%c%s",
|
||||||
(int64_t) bytes,
|
(long long) bytes,
|
||||||
unit[i],
|
unit[i],
|
||||||
i ? "B" : " ");
|
i ? "B" : " ");
|
||||||
}
|
}
|
||||||
@ -108,7 +113,7 @@ refresh_progress_meter(void)
|
|||||||
off_t transferred;
|
off_t transferred;
|
||||||
double elapsed;
|
double elapsed;
|
||||||
int percent;
|
int percent;
|
||||||
int bytes_left;
|
off_t bytes_left;
|
||||||
int cur_speed;
|
int cur_speed;
|
||||||
int hours, minutes, seconds;
|
int hours, minutes, seconds;
|
||||||
int i, len;
|
int i, len;
|
||||||
@ -121,14 +126,18 @@ refresh_progress_meter(void)
|
|||||||
|
|
||||||
if (bytes_left > 0)
|
if (bytes_left > 0)
|
||||||
elapsed = now - last_update;
|
elapsed = now - last_update;
|
||||||
else
|
else {
|
||||||
elapsed = now - start;
|
elapsed = now - start;
|
||||||
|
/* Calculate true total speed when done */
|
||||||
|
transferred = end_pos;
|
||||||
|
bytes_per_second = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* calculate speed */
|
/* calculate speed */
|
||||||
if (elapsed != 0)
|
if (elapsed != 0)
|
||||||
cur_speed = (transferred / elapsed);
|
cur_speed = (transferred / elapsed);
|
||||||
else
|
else
|
||||||
cur_speed = 0;
|
cur_speed = transferred;
|
||||||
|
|
||||||
#define AGE_FACTOR 0.9
|
#define AGE_FACTOR 0.9
|
||||||
if (bytes_per_second != 0) {
|
if (bytes_per_second != 0) {
|
||||||
@ -144,6 +153,8 @@ refresh_progress_meter(void)
|
|||||||
len = snprintf(buf, file_len + 1, "\r%s", file);
|
len = snprintf(buf, file_len + 1, "\r%s", file);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
len = 0;
|
len = 0;
|
||||||
|
if (len >= file_len + 1)
|
||||||
|
len = file_len;
|
||||||
for (i = len; i < file_len; i++ )
|
for (i = len; i < file_len; i++ )
|
||||||
buf[i] = ' ';
|
buf[i] = ' ';
|
||||||
buf[file_len] = '\0';
|
buf[file_len] = '\0';
|
||||||
@ -164,7 +175,7 @@ refresh_progress_meter(void)
|
|||||||
|
|
||||||
/* bandwidth usage */
|
/* bandwidth usage */
|
||||||
format_rate(buf + strlen(buf), win_size - strlen(buf),
|
format_rate(buf + strlen(buf), win_size - strlen(buf),
|
||||||
bytes_per_second);
|
(off_t)bytes_per_second);
|
||||||
strlcat(buf, "/s ", win_size);
|
strlcat(buf, "/s ", win_size);
|
||||||
|
|
||||||
/* ETA */
|
/* ETA */
|
||||||
@ -201,7 +212,7 @@ refresh_progress_meter(void)
|
|||||||
strlcat(buf, " ", win_size);
|
strlcat(buf, " ", win_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
atomicio(vwrite, STDOUT_FILENO, buf, win_size);
|
atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
|
||||||
last_update = now;
|
last_update = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +223,10 @@ update_progress_meter(int ignore)
|
|||||||
|
|
||||||
save_errno = errno;
|
save_errno = errno;
|
||||||
|
|
||||||
|
if (win_resized) {
|
||||||
|
setscreensize();
|
||||||
|
win_resized = 0;
|
||||||
|
}
|
||||||
if (can_output())
|
if (can_output())
|
||||||
refresh_progress_meter();
|
refresh_progress_meter();
|
||||||
|
|
||||||
@ -221,32 +236,22 @@ update_progress_meter(int ignore)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
start_progress_meter(char *f, off_t filesize, off_t *stat)
|
start_progress_meter(char *f, off_t filesize, off_t *ctr)
|
||||||
{
|
{
|
||||||
struct winsize winsize;
|
|
||||||
|
|
||||||
start = last_update = time(NULL);
|
start = last_update = time(NULL);
|
||||||
file = f;
|
file = f;
|
||||||
end_pos = filesize;
|
end_pos = filesize;
|
||||||
cur_pos = 0;
|
cur_pos = 0;
|
||||||
counter = stat;
|
counter = ctr;
|
||||||
stalled = 0;
|
stalled = 0;
|
||||||
bytes_per_second = 0;
|
bytes_per_second = 0;
|
||||||
|
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
|
setscreensize();
|
||||||
winsize.ws_col != 0) {
|
|
||||||
if (winsize.ws_col > MAX_WINSIZE)
|
|
||||||
win_size = MAX_WINSIZE;
|
|
||||||
else
|
|
||||||
win_size = winsize.ws_col;
|
|
||||||
} else
|
|
||||||
win_size = DEFAULT_WINSIZE;
|
|
||||||
win_size += 1; /* trailing \0 */
|
|
||||||
|
|
||||||
if (can_output())
|
if (can_output())
|
||||||
refresh_progress_meter();
|
refresh_progress_meter();
|
||||||
|
|
||||||
signal(SIGALRM, update_progress_meter);
|
signal(SIGALRM, update_progress_meter);
|
||||||
|
signal(SIGWINCH, sig_winch);
|
||||||
alarm(UPDATE_INTERVAL);
|
alarm(UPDATE_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,4 +269,26 @@ stop_progress_meter(void)
|
|||||||
|
|
||||||
atomicio(vwrite, STDOUT_FILENO, "\n", 1);
|
atomicio(vwrite, STDOUT_FILENO, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sig_winch(int sig)
|
||||||
|
{
|
||||||
|
win_resized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setscreensize(void)
|
||||||
|
{
|
||||||
|
struct winsize winsize;
|
||||||
|
|
||||||
|
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
|
||||||
|
winsize.ws_col != 0) {
|
||||||
|
if (winsize.ws_col > MAX_WINSIZE)
|
||||||
|
win_size = MAX_WINSIZE;
|
||||||
|
else
|
||||||
|
win_size = winsize.ws_col;
|
||||||
|
} else
|
||||||
|
win_size = DEFAULT_WINSIZE;
|
||||||
|
win_size += 1; /* trailing \0 */
|
||||||
|
}
|
||||||
#endif /* PROGRESS_METER */
|
#endif /* PROGRESS_METER */
|
||||||
|
343
scp.c
343
scp.c
@ -71,40 +71,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
/*RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");*/
|
||||||
|
|
||||||
#include "atomicio.h"
|
#include "atomicio.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "scpmisc.h"
|
#include "scpmisc.h"
|
||||||
#include "progressmeter.h"
|
#include "progressmeter.h"
|
||||||
|
|
||||||
#define _PATH_CP "/bin/cp"
|
|
||||||
|
|
||||||
#ifndef TIMEVAL_TO_TIMESPEC
|
|
||||||
#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
|
|
||||||
(ts)->tv_sec = (tv)->tv_sec; \
|
|
||||||
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef timersub
|
|
||||||
#define timersub(tvp, uvp, vvp) \
|
|
||||||
do { \
|
|
||||||
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
|
|
||||||
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
|
|
||||||
if ((vvp)->tv_usec < 0) { \
|
|
||||||
(vvp)->tv_sec--; \
|
|
||||||
(vvp)->tv_usec += 1000000; \
|
|
||||||
} \
|
|
||||||
} while (/* CONSTCOND */ 0)
|
|
||||||
#endif /* timersub */
|
|
||||||
|
|
||||||
|
|
||||||
void bwlimit(int);
|
void bwlimit(int);
|
||||||
|
|
||||||
/* Struct for addargs */
|
/* Struct for addargs */
|
||||||
arglist args;
|
arglist args;
|
||||||
|
|
||||||
/* Bandwidth limit */
|
/* Bandwidth limit */
|
||||||
off_t limitbw = 0;
|
off_t limit_rate = 0;
|
||||||
|
|
||||||
/* Name of current file being transferred. */
|
/* Name of current file being transferred. */
|
||||||
char *curfile;
|
char *curfile;
|
||||||
@ -112,10 +92,8 @@ char *curfile;
|
|||||||
/* This is set to non-zero to enable verbose mode. */
|
/* This is set to non-zero to enable verbose mode. */
|
||||||
int verbose_mode = 0;
|
int verbose_mode = 0;
|
||||||
|
|
||||||
#ifdef PROGRESS_METER
|
|
||||||
/* This is set to zero if the progressmeter is not desired. */
|
/* This is set to zero if the progressmeter is not desired. */
|
||||||
int showprogress = 1;
|
int showprogress = 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is the program to execute for the secured connection. ("ssh" or -S) */
|
/* This is the program to execute for the secured connection. ("ssh" or -S) */
|
||||||
char *ssh_program = _PATH_SSH_PROGRAM;
|
char *ssh_program = _PATH_SSH_PROGRAM;
|
||||||
@ -126,10 +104,56 @@ pid_t do_cmd_pid = -1;
|
|||||||
static void
|
static void
|
||||||
killchild(int signo)
|
killchild(int signo)
|
||||||
{
|
{
|
||||||
if (do_cmd_pid > 1)
|
if (do_cmd_pid > 1) {
|
||||||
kill(do_cmd_pid, signo);
|
kill(do_cmd_pid, signo ? signo : SIGTERM);
|
||||||
|
waitpid(do_cmd_pid, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
_exit(1);
|
if (signo)
|
||||||
|
_exit(1);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_local_cmd(arglist *a)
|
||||||
|
{
|
||||||
|
u_int i;
|
||||||
|
int status;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (a->num == 0)
|
||||||
|
fatal("do_local_cmd: no arguments");
|
||||||
|
|
||||||
|
if (verbose_mode) {
|
||||||
|
fprintf(stderr, "Executing:");
|
||||||
|
for (i = 0; i < a->num; i++)
|
||||||
|
fprintf(stderr, " %s", a->list[i]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
if ((pid = fork()) == -1)
|
||||||
|
fatal("do_local_cmd: fork: %s", strerror(errno));
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
execvp(a->list[0], a->list);
|
||||||
|
perror(a->list[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_cmd_pid = pid;
|
||||||
|
signal(SIGTERM, killchild);
|
||||||
|
signal(SIGINT, killchild);
|
||||||
|
signal(SIGHUP, killchild);
|
||||||
|
|
||||||
|
while (waitpid(pid, &status, 0) == -1)
|
||||||
|
if (errno != EINTR)
|
||||||
|
fatal("do_local_cmd: waitpid: %s", strerror(errno));
|
||||||
|
|
||||||
|
do_cmd_pid = -1;
|
||||||
|
|
||||||
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -156,11 +180,10 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
pipe(reserved);
|
pipe(reserved);
|
||||||
|
|
||||||
/* Create a socket pair for communicating with ssh. */
|
/* Create a socket pair for communicating with ssh. */
|
||||||
if (pipe(pin) < 0 || pipe(pout) < 0)
|
if (pipe(pin) < 0)
|
||||||
{
|
fatal("pipe: %s", strerror(errno));
|
||||||
fprintf(stderr, "Fatal error: pipe: %s\n", strerror(errno));
|
if (pipe(pout) < 0)
|
||||||
exit(1);
|
fatal("pipe: %s", strerror(errno));
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the reserved descriptors. */
|
/* Free the reserved descriptors. */
|
||||||
close(reserved[0]);
|
close(reserved[0]);
|
||||||
@ -169,19 +192,20 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
/* uClinux needs to build the args here before vforking,
|
/* uClinux needs to build the args here before vforking,
|
||||||
otherwise we do it later on. */
|
otherwise we do it later on. */
|
||||||
#ifdef __uClinux__
|
#ifdef __uClinux__
|
||||||
args.list[0] = ssh_program;
|
replacearg(&args, 0, "%s", ssh_program);
|
||||||
if (remuser != NULL)
|
if (remuser != NULL)
|
||||||
addargs(&args, "-l%s", remuser);
|
addargs(&args, "-l%s", remuser);
|
||||||
addargs(&args, "%s", host);
|
addargs(&args, "%s", host);
|
||||||
addargs(&args, "%s", cmd);
|
addargs(&args, "%s", cmd);
|
||||||
#endif /* __uClinux__ */
|
#endif /* __uClinux__ */
|
||||||
|
|
||||||
/* Fork a child to execute the command on the remote host using ssh. */
|
/* Fork a child to execute the command on the remote host using ssh. */
|
||||||
#ifdef __uClinux__
|
#ifndef __uClinux__
|
||||||
do_cmd_pid = vfork();
|
do_cmd_pid = vfork();
|
||||||
#else
|
#else
|
||||||
do_cmd_pid = fork();
|
do_cmd_pid = fork();
|
||||||
#endif /* __uClinux__ */
|
#endif /* __uClinux__ */
|
||||||
|
|
||||||
if (do_cmd_pid == 0) {
|
if (do_cmd_pid == 0) {
|
||||||
/* Child. */
|
/* Child. */
|
||||||
close(pin[1]);
|
close(pin[1]);
|
||||||
@ -192,38 +216,39 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
close(pout[1]);
|
close(pout[1]);
|
||||||
|
|
||||||
#ifndef __uClinux__
|
#ifndef __uClinux__
|
||||||
args.list[0] = ssh_program;
|
replacearg(&args, 0, "%s", ssh_program);
|
||||||
if (remuser != NULL) {
|
if (remuser != NULL)
|
||||||
addargs(&args, "-l");
|
addargs(&args, "-l%s", remuser);
|
||||||
addargs(&args, "%s", remuser);
|
|
||||||
}
|
|
||||||
addargs(&args, "%s", host);
|
addargs(&args, "%s", host);
|
||||||
addargs(&args, "%s", cmd);
|
addargs(&args, "%s", cmd);
|
||||||
#endif
|
#endif /* __uClinux__ */
|
||||||
|
|
||||||
execvp(ssh_program, args.list);
|
execvp(ssh_program, args.list);
|
||||||
perror(ssh_program);
|
perror(ssh_program);
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (do_cmd_pid == -1) {
|
} else if (do_cmd_pid == -1) {
|
||||||
fprintf(stderr, "Fatal error: fork: %s\n", strerror(errno));
|
fatal("fork: %s", strerror(errno));
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __uClinux__
|
#ifdef __uClinux__
|
||||||
/* clean up command */
|
/* clean up command */
|
||||||
/* pop cmd */
|
/* pop cmd */
|
||||||
xfree(args->list[--args->num]);
|
xfree(args->list[args->num-1]);
|
||||||
args->list[args->num]=NULL;
|
args->list[args->num-1]=NULL;
|
||||||
|
args->num--;
|
||||||
/* pop host */
|
/* pop host */
|
||||||
xfree(args->list[--args->num-1]);
|
xfree(args->list[args->num-1]);
|
||||||
args->list[args->num]=NULL;
|
args->list[args->num-1]=NULL;
|
||||||
|
args->num--;
|
||||||
/* pop user */
|
/* pop user */
|
||||||
if (remuser != NULL) {
|
if (remuser != NULL) {
|
||||||
xfree(args->list[--args->num-1]);
|
xfree(args->list[args->num-1]);
|
||||||
args->list[args->num]=NULL;
|
args->list[args->num-1]=NULL;
|
||||||
|
args->num--;
|
||||||
}
|
}
|
||||||
#endif /* __uClinux__ */
|
#endif /* __uClinux__ */
|
||||||
|
|
||||||
/* Parent. Close the other side, and return the local side. */
|
/* Parent. Close the other side, and return the local side. */
|
||||||
close(pin[0]);
|
close(pin[0]);
|
||||||
*fdout = pin[1];
|
*fdout = pin[1];
|
||||||
@ -236,7 +261,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int cnt;
|
size_t cnt;
|
||||||
char *buf;
|
char *buf;
|
||||||
} BUF;
|
} BUF;
|
||||||
|
|
||||||
@ -267,6 +292,7 @@ void usage(void);
|
|||||||
#if defined(DBMULTI_scp) && defined(DROPBEAR_MULTI)
|
#if defined(DBMULTI_scp) && defined(DROPBEAR_MULTI)
|
||||||
int scp_main(int argc, char **argv)
|
int scp_main(int argc, char **argv)
|
||||||
#else
|
#else
|
||||||
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@ -276,10 +302,15 @@ main(int argc, char **argv)
|
|||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind;
|
extern int optind;
|
||||||
|
|
||||||
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||||
|
sanitise_stdfd();
|
||||||
|
|
||||||
|
memset(&args, '\0', sizeof(args));
|
||||||
args.list = NULL;
|
args.list = NULL;
|
||||||
addargs(&args, "ssh"); /* overwritten with ssh_program */
|
addargs(&args, "%s", ssh_program);
|
||||||
addargs(&args, "-x");
|
addargs(&args, "-x");
|
||||||
addargs(&args, "-oForwardAgent no");
|
addargs(&args, "-oForwardAgent no");
|
||||||
|
addargs(&args, "-oPermitLocalCommand no");
|
||||||
addargs(&args, "-oClearAllForwardings yes");
|
addargs(&args, "-oClearAllForwardings yes");
|
||||||
|
|
||||||
fflag = tflag = 0;
|
fflag = tflag = 0;
|
||||||
@ -309,7 +340,7 @@ main(int argc, char **argv)
|
|||||||
speed = strtod(optarg, &endp);
|
speed = strtod(optarg, &endp);
|
||||||
if (speed <= 0 || *endp != '\0')
|
if (speed <= 0 || *endp != '\0')
|
||||||
usage();
|
usage();
|
||||||
limitbw = speed * 1024;
|
limit_rate = speed * 1024;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pflag = 1;
|
pflag = 1;
|
||||||
@ -326,6 +357,7 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
#ifdef PROGRESS_METER
|
#ifdef PROGRESS_METER
|
||||||
case 'q':
|
case 'q':
|
||||||
|
addargs(&args, "-q");
|
||||||
showprogress = 0;
|
showprogress = 0;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -351,14 +383,11 @@ main(int argc, char **argv)
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
if ((pwd = getpwuid(userid = getuid())) == NULL) {
|
if ((pwd = getpwuid(userid = getuid())) == NULL)
|
||||||
fprintf(stderr, "unknown user %u", (u_int) userid);
|
fatal("unknown user %u", (u_int) userid);
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PROGRESS_METER
|
|
||||||
if (!isatty(STDERR_FILENO))
|
if (!isatty(STDERR_FILENO))
|
||||||
showprogress = 0;
|
showprogress = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
remin = STDIN_FILENO;
|
remin = STDIN_FILENO;
|
||||||
remout = STDOUT_FILENO;
|
remout = STDOUT_FILENO;
|
||||||
@ -392,9 +421,9 @@ main(int argc, char **argv)
|
|||||||
if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
|
if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
|
||||||
toremote(targ, argc, argv);
|
toremote(targ, argc, argv);
|
||||||
else {
|
else {
|
||||||
tolocal(argc, argv); /* Dest is local host. */
|
|
||||||
if (targetshouldbedirectory)
|
if (targetshouldbedirectory)
|
||||||
verifydir(argv[argc - 1]);
|
verifydir(argv[argc - 1]);
|
||||||
|
tolocal(argc, argv); /* Dest is local host. */
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Finally check the exit status of the ssh process, if one was forked
|
* Finally check the exit status of the ssh process, if one was forked
|
||||||
@ -414,78 +443,76 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
exit(errs != 0);
|
exit(errs != 0);
|
||||||
}
|
}
|
||||||
#endif /* DBMULTI stuff */
|
#endif /* DBMULTI_scp stuff */
|
||||||
|
|
||||||
void
|
void
|
||||||
toremote(char *targ, int argc, char **argv)
|
toremote(char *targ, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, len;
|
int i, len;
|
||||||
char *bp, *host, *src, *suser, *thost, *tuser;
|
char *bp, *host, *src, *suser, *thost, *tuser, *arg;
|
||||||
|
arglist alist;
|
||||||
|
|
||||||
|
memset(&alist, '\0', sizeof(alist));
|
||||||
|
alist.list = NULL;
|
||||||
|
|
||||||
*targ++ = 0;
|
*targ++ = 0;
|
||||||
if (*targ == 0)
|
if (*targ == 0)
|
||||||
targ = ".";
|
targ = ".";
|
||||||
|
|
||||||
if ((thost = strrchr(argv[argc - 1], '@'))) {
|
arg = xstrdup(argv[argc - 1]);
|
||||||
|
if ((thost = strrchr(arg, '@'))) {
|
||||||
/* user@host */
|
/* user@host */
|
||||||
*thost++ = 0;
|
*thost++ = 0;
|
||||||
tuser = argv[argc - 1];
|
tuser = arg;
|
||||||
if (*tuser == '\0')
|
if (*tuser == '\0')
|
||||||
tuser = NULL;
|
tuser = NULL;
|
||||||
} else {
|
} else {
|
||||||
thost = argv[argc - 1];
|
thost = arg;
|
||||||
tuser = NULL;
|
tuser = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tuser != NULL && !okname(tuser)) {
|
||||||
|
xfree(arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc - 1; i++) {
|
for (i = 0; i < argc - 1; i++) {
|
||||||
src = colon(argv[i]);
|
src = colon(argv[i]);
|
||||||
if (src) { /* remote to remote */
|
if (src) { /* remote to remote */
|
||||||
static char *ssh_options =
|
freeargs(&alist);
|
||||||
"-x -o'ClearAllForwardings yes'";
|
addargs(&alist, "%s", ssh_program);
|
||||||
|
if (verbose_mode)
|
||||||
|
addargs(&alist, "-v");
|
||||||
|
addargs(&alist, "-x");
|
||||||
|
addargs(&alist, "-oClearAllForwardings yes");
|
||||||
|
addargs(&alist, "-n");
|
||||||
|
|
||||||
*src++ = 0;
|
*src++ = 0;
|
||||||
if (*src == 0)
|
if (*src == 0)
|
||||||
src = ".";
|
src = ".";
|
||||||
host = strrchr(argv[i], '@');
|
host = strrchr(argv[i], '@');
|
||||||
len = strlen(ssh_program) + strlen(argv[i]) +
|
|
||||||
strlen(src) + (tuser ? strlen(tuser) : 0) +
|
|
||||||
strlen(thost) + strlen(targ) +
|
|
||||||
strlen(ssh_options) + CMDNEEDS + 20;
|
|
||||||
bp = xmalloc(len);
|
|
||||||
if (host) {
|
if (host) {
|
||||||
*host++ = 0;
|
*host++ = 0;
|
||||||
host = cleanhostname(host);
|
host = cleanhostname(host);
|
||||||
suser = argv[i];
|
suser = argv[i];
|
||||||
if (*suser == '\0')
|
if (*suser == '\0')
|
||||||
suser = pwd->pw_name;
|
suser = pwd->pw_name;
|
||||||
else if (!okname(suser)) {
|
else if (!okname(suser))
|
||||||
xfree(bp);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
addargs(&alist, "-l");
|
||||||
if (tuser && !okname(tuser)) {
|
addargs(&alist, "%s", suser);
|
||||||
xfree(bp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
snprintf(bp, len,
|
|
||||||
"%s%s %s -n "
|
|
||||||
"-l %s %s %s %s '%s%s%s:%s'",
|
|
||||||
ssh_program, verbose_mode ? " -v" : "",
|
|
||||||
ssh_options, suser, host, cmd, src,
|
|
||||||
tuser ? tuser : "", tuser ? "@" : "",
|
|
||||||
thost, targ);
|
|
||||||
} else {
|
} else {
|
||||||
host = cleanhostname(argv[i]);
|
host = cleanhostname(argv[i]);
|
||||||
snprintf(bp, len,
|
|
||||||
"exec %s%s %s -n %s "
|
|
||||||
"%s %s '%s%s%s:%s'",
|
|
||||||
ssh_program, verbose_mode ? " -v" : "",
|
|
||||||
ssh_options, host, cmd, src,
|
|
||||||
tuser ? tuser : "", tuser ? "@" : "",
|
|
||||||
thost, targ);
|
|
||||||
}
|
}
|
||||||
if (verbose_mode)
|
addargs(&alist, "%s", host);
|
||||||
fprintf(stderr, "Executing: %s\n", bp);
|
addargs(&alist, "%s", cmd);
|
||||||
(void) system(bp);
|
addargs(&alist, "%s", src);
|
||||||
(void) xfree(bp);
|
addargs(&alist, "%s%s%s:%s",
|
||||||
|
tuser ? tuser : "", tuser ? "@" : "",
|
||||||
|
thost, targ);
|
||||||
|
if (do_local_cmd(&alist) != 0)
|
||||||
|
errs = 1;
|
||||||
} else { /* local to remote */
|
} else { /* local to remote */
|
||||||
if (remin == -1) {
|
if (remin == -1) {
|
||||||
len = strlen(targ) + CMDNEEDS + 20;
|
len = strlen(targ) + CMDNEEDS + 20;
|
||||||
@ -509,20 +536,23 @@ tolocal(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int i, len;
|
int i, len;
|
||||||
char *bp, *host, *src, *suser;
|
char *bp, *host, *src, *suser;
|
||||||
|
arglist alist;
|
||||||
|
|
||||||
|
memset(&alist, '\0', sizeof(alist));
|
||||||
|
alist.list = NULL;
|
||||||
|
|
||||||
for (i = 0; i < argc - 1; i++) {
|
for (i = 0; i < argc - 1; i++) {
|
||||||
if (!(src = colon(argv[i]))) { /* Local to local. */
|
if (!(src = colon(argv[i]))) { /* Local to local. */
|
||||||
len = strlen(_PATH_CP) + strlen(argv[i]) +
|
freeargs(&alist);
|
||||||
strlen(argv[argc - 1]) + 20;
|
addargs(&alist, "%s", _PATH_CP);
|
||||||
bp = xmalloc(len);
|
if (iamrecursive)
|
||||||
(void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
|
addargs(&alist, "-r");
|
||||||
iamrecursive ? " -r" : "", pflag ? " -p" : "",
|
if (pflag)
|
||||||
argv[i], argv[argc - 1]);
|
addargs(&alist, "-p");
|
||||||
if (verbose_mode)
|
addargs(&alist, "%s", argv[i]);
|
||||||
fprintf(stderr, "Executing: %s\n", bp);
|
addargs(&alist, "%s", argv[argc-1]);
|
||||||
if (system(bp))
|
if (do_local_cmd(&alist))
|
||||||
++errs;
|
++errs;
|
||||||
(void) xfree(bp);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*src++ = 0;
|
*src++ = 0;
|
||||||
@ -559,8 +589,9 @@ source(int argc, char **argv)
|
|||||||
struct stat stb;
|
struct stat stb;
|
||||||
static BUF buffer;
|
static BUF buffer;
|
||||||
BUF *bp;
|
BUF *bp;
|
||||||
off_t i, amt, result, statbytes;
|
off_t i, amt, statbytes;
|
||||||
int fd, haderr, indx;
|
size_t result;
|
||||||
|
int fd = -1, haderr, indx;
|
||||||
char *last, *name, buf[2048];
|
char *last, *name, buf[2048];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@ -614,7 +645,7 @@ syserr: run_err("%s: %s", name, strerror(errno));
|
|||||||
#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
|
#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
|
||||||
snprintf(buf, sizeof buf, "C%04o %lld %s\n",
|
snprintf(buf, sizeof buf, "C%04o %lld %s\n",
|
||||||
(u_int) (stb.st_mode & FILEMODEMASK),
|
(u_int) (stb.st_mode & FILEMODEMASK),
|
||||||
(int64_t)stb.st_size, last);
|
(long long)stb.st_size, last);
|
||||||
if (verbose_mode) {
|
if (verbose_mode) {
|
||||||
fprintf(stderr, "Sending file modes: %s", buf);
|
fprintf(stderr, "Sending file modes: %s", buf);
|
||||||
}
|
}
|
||||||
@ -622,10 +653,13 @@ syserr: run_err("%s: %s", name, strerror(errno));
|
|||||||
if (response() < 0)
|
if (response() < 0)
|
||||||
goto next;
|
goto next;
|
||||||
if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
|
if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
|
||||||
next: (void) close(fd);
|
next: if (fd != -1) {
|
||||||
|
(void) close(fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef PROGRESS_METER
|
#if PROGRESS_METER
|
||||||
if (showprogress)
|
if (showprogress)
|
||||||
start_progress_meter(curfile, stb.st_size, &statbytes);
|
start_progress_meter(curfile, stb.st_size, &statbytes);
|
||||||
#endif
|
#endif
|
||||||
@ -637,17 +671,17 @@ next: (void) close(fd);
|
|||||||
if (!haderr) {
|
if (!haderr) {
|
||||||
result = atomicio(read, fd, bp->buf, amt);
|
result = atomicio(read, fd, bp->buf, amt);
|
||||||
if (result != amt)
|
if (result != amt)
|
||||||
haderr = result >= 0 ? EIO : errno;
|
haderr = errno;
|
||||||
}
|
}
|
||||||
if (haderr)
|
if (haderr)
|
||||||
(void) atomicio(vwrite, remout, bp->buf, amt);
|
(void) atomicio(vwrite, remout, bp->buf, amt);
|
||||||
else {
|
else {
|
||||||
result = atomicio(vwrite, remout, bp->buf, amt);
|
result = atomicio(vwrite, remout, bp->buf, amt);
|
||||||
if (result != amt)
|
if (result != amt)
|
||||||
haderr = result >= 0 ? EIO : errno;
|
haderr = errno;
|
||||||
statbytes += result;
|
statbytes += result;
|
||||||
}
|
}
|
||||||
if (limitbw)
|
if (limit_rate)
|
||||||
bwlimit(amt);
|
bwlimit(amt);
|
||||||
}
|
}
|
||||||
#ifdef PROGRESS_METER
|
#ifdef PROGRESS_METER
|
||||||
@ -655,8 +689,11 @@ next: (void) close(fd);
|
|||||||
stop_progress_meter();
|
stop_progress_meter();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (close(fd) < 0 && !haderr)
|
if (fd != -1) {
|
||||||
haderr = errno;
|
if (close(fd) < 0 && !haderr)
|
||||||
|
haderr = errno;
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
if (!haderr)
|
if (!haderr)
|
||||||
(void) atomicio(vwrite, remout, "", 1);
|
(void) atomicio(vwrite, remout, "", 1);
|
||||||
else
|
else
|
||||||
@ -723,7 +760,7 @@ bwlimit(int amount)
|
|||||||
{
|
{
|
||||||
static struct timeval bwstart, bwend;
|
static struct timeval bwstart, bwend;
|
||||||
static int lamt, thresh = 16384;
|
static int lamt, thresh = 16384;
|
||||||
uint64_t wait;
|
u_int64_t waitlen;
|
||||||
struct timespec ts, rm;
|
struct timespec ts, rm;
|
||||||
|
|
||||||
if (!timerisset(&bwstart)) {
|
if (!timerisset(&bwstart)) {
|
||||||
@ -741,10 +778,10 @@ bwlimit(int amount)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
lamt *= 8;
|
lamt *= 8;
|
||||||
wait = (double)1000000L * lamt / limitbw;
|
waitlen = (double)1000000L * lamt / limit_rate;
|
||||||
|
|
||||||
bwstart.tv_sec = wait / 1000000L;
|
bwstart.tv_sec = waitlen / 1000000L;
|
||||||
bwstart.tv_usec = wait % 1000000L;
|
bwstart.tv_usec = waitlen % 1000000L;
|
||||||
|
|
||||||
if (timercmp(&bwstart, &bwend, >)) {
|
if (timercmp(&bwstart, &bwend, >)) {
|
||||||
timersub(&bwstart, &bwend, &bwend);
|
timersub(&bwstart, &bwend, &bwend);
|
||||||
@ -781,8 +818,9 @@ sink(int argc, char **argv)
|
|||||||
YES, NO, DISPLAYED
|
YES, NO, DISPLAYED
|
||||||
} wrerr;
|
} wrerr;
|
||||||
BUF *bp;
|
BUF *bp;
|
||||||
off_t i, j;
|
off_t i;
|
||||||
int amt, count, exists, first, mask, mode, ofd, omode;
|
size_t j, count;
|
||||||
|
int amt, exists, first, mask, mode, ofd, omode;
|
||||||
off_t size, statbytes;
|
off_t size, statbytes;
|
||||||
int setimes, targisdir, wrerrno = 0;
|
int setimes, targisdir, wrerrno = 0;
|
||||||
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
|
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
|
||||||
@ -790,7 +828,7 @@ sink(int argc, char **argv)
|
|||||||
|
|
||||||
#define atime tv[0]
|
#define atime tv[0]
|
||||||
#define mtime tv[1]
|
#define mtime tv[1]
|
||||||
#define SCREWUP(str) do { why = str; goto screwup; } while (0)
|
#define SCREWUP(str) { why = str; goto screwup; }
|
||||||
|
|
||||||
setimes = targisdir = 0;
|
setimes = targisdir = 0;
|
||||||
mask = umask(0);
|
mask = umask(0);
|
||||||
@ -809,7 +847,7 @@ sink(int argc, char **argv)
|
|||||||
targisdir = 1;
|
targisdir = 1;
|
||||||
for (first = 1;; first = 0) {
|
for (first = 1;; first = 0) {
|
||||||
cp = buf;
|
cp = buf;
|
||||||
if (atomicio(read, remin, cp, 1) <= 0)
|
if (atomicio(read, remin, cp, 1) != 1)
|
||||||
return;
|
return;
|
||||||
if (*cp++ == '\n')
|
if (*cp++ == '\n')
|
||||||
SCREWUP("unexpected <newline>");
|
SCREWUP("unexpected <newline>");
|
||||||
@ -819,6 +857,8 @@ sink(int argc, char **argv)
|
|||||||
*cp++ = ch;
|
*cp++ = ch;
|
||||||
} while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
|
} while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
|
||||||
*cp = 0;
|
*cp = 0;
|
||||||
|
if (verbose_mode)
|
||||||
|
fprintf(stderr, "Sink: %s", buf);
|
||||||
|
|
||||||
if (buf[0] == '\01' || buf[0] == '\02') {
|
if (buf[0] == '\01' || buf[0] == '\02') {
|
||||||
if (iamremote == 0)
|
if (iamremote == 0)
|
||||||
@ -882,9 +922,13 @@ sink(int argc, char **argv)
|
|||||||
size = size * 10 + (*cp++ - '0');
|
size = size * 10 + (*cp++ - '0');
|
||||||
if (*cp++ != ' ')
|
if (*cp++ != ' ')
|
||||||
SCREWUP("size not delimited");
|
SCREWUP("size not delimited");
|
||||||
|
if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) {
|
||||||
|
run_err("error: unexpected filename: %s", cp);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
if (targisdir) {
|
if (targisdir) {
|
||||||
static char *namebuf;
|
static char *namebuf;
|
||||||
static int cursize;
|
static size_t cursize;
|
||||||
size_t need;
|
size_t need;
|
||||||
|
|
||||||
need = strlen(targ) + strlen(cp) + 250;
|
need = strlen(targ) + strlen(cp) + 250;
|
||||||
@ -903,6 +947,8 @@ sink(int argc, char **argv)
|
|||||||
exists = stat(np, &stb) == 0;
|
exists = stat(np, &stb) == 0;
|
||||||
if (buf[0] == 'D') {
|
if (buf[0] == 'D') {
|
||||||
int mod_flag = pflag;
|
int mod_flag = pflag;
|
||||||
|
if (!iamrecursive)
|
||||||
|
SCREWUP("received directory without -r");
|
||||||
if (exists) {
|
if (exists) {
|
||||||
if (!S_ISDIR(stb.st_mode)) {
|
if (!S_ISDIR(stb.st_mode)) {
|
||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
@ -956,11 +1002,8 @@ bad: run_err("%s: %s", np, strerror(errno));
|
|||||||
amt = size - i;
|
amt = size - i;
|
||||||
count += amt;
|
count += amt;
|
||||||
do {
|
do {
|
||||||
j = read(remin, cp, amt);
|
j = atomicio(read, remin, cp, amt);
|
||||||
if (j == -1 && (errno == EINTR ||
|
if (j == 0) {
|
||||||
errno == EAGAIN)) {
|
|
||||||
continue;
|
|
||||||
} else if (j <= 0) {
|
|
||||||
run_err("%s", j ? strerror(errno) :
|
run_err("%s", j ? strerror(errno) :
|
||||||
"dropped connection");
|
"dropped connection");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -969,17 +1012,17 @@ bad: run_err("%s: %s", np, strerror(errno));
|
|||||||
cp += j;
|
cp += j;
|
||||||
statbytes += j;
|
statbytes += j;
|
||||||
} while (amt > 0);
|
} while (amt > 0);
|
||||||
|
|
||||||
if (limitbw)
|
if (limit_rate)
|
||||||
bwlimit(4096);
|
bwlimit(4096);
|
||||||
|
|
||||||
if (count == bp->cnt) {
|
if (count == bp->cnt) {
|
||||||
/* Keep reading so we stay sync'd up. */
|
/* Keep reading so we stay sync'd up. */
|
||||||
if (wrerr == NO) {
|
if (wrerr == NO) {
|
||||||
j = atomicio(vwrite, ofd, bp->buf, count);
|
if (atomicio(vwrite, ofd, bp->buf,
|
||||||
if (j != count) {
|
count) != count) {
|
||||||
wrerr = YES;
|
wrerr = YES;
|
||||||
wrerrno = j >= 0 ? EIO : errno;
|
wrerrno = errno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -991,9 +1034,9 @@ bad: run_err("%s: %s", np, strerror(errno));
|
|||||||
stop_progress_meter();
|
stop_progress_meter();
|
||||||
#endif
|
#endif
|
||||||
if (count != 0 && wrerr == NO &&
|
if (count != 0 && wrerr == NO &&
|
||||||
(j = atomicio(vwrite, ofd, bp->buf, count)) != count) {
|
atomicio(vwrite, ofd, bp->buf, count) != count) {
|
||||||
wrerr = YES;
|
wrerr = YES;
|
||||||
wrerrno = j >= 0 ? EIO : errno;
|
wrerrno = errno;
|
||||||
}
|
}
|
||||||
if (wrerr == NO && ftruncate(ofd, size) != 0) {
|
if (wrerr == NO && ftruncate(ofd, size) != 0) {
|
||||||
run_err("%s: truncate: %s", np, strerror(errno));
|
run_err("%s: truncate: %s", np, strerror(errno));
|
||||||
@ -1002,21 +1045,25 @@ bad: run_err("%s: %s", np, strerror(errno));
|
|||||||
if (pflag) {
|
if (pflag) {
|
||||||
if (exists || omode != mode)
|
if (exists || omode != mode)
|
||||||
#ifdef HAVE_FCHMOD
|
#ifdef HAVE_FCHMOD
|
||||||
if (fchmod(ofd, omode))
|
if (fchmod(ofd, omode)) {
|
||||||
#else /* HAVE_FCHMOD */
|
#else /* HAVE_FCHMOD */
|
||||||
if (chmod(np, omode))
|
if (chmod(np, omode)) {
|
||||||
#endif /* HAVE_FCHMOD */
|
#endif /* HAVE_FCHMOD */
|
||||||
run_err("%s: set mode: %s",
|
run_err("%s: set mode: %s",
|
||||||
np, strerror(errno));
|
np, strerror(errno));
|
||||||
|
wrerr = DISPLAYED;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!exists && omode != mode)
|
if (!exists && omode != mode)
|
||||||
#ifdef HAVE_FCHMOD
|
#ifdef HAVE_FCHMOD
|
||||||
if (fchmod(ofd, omode & ~mask))
|
if (fchmod(ofd, omode & ~mask)) {
|
||||||
#else /* HAVE_FCHMOD */
|
#else /* HAVE_FCHMOD */
|
||||||
if (chmod(np, omode & ~mask))
|
if (chmod(np, omode & ~mask)) {
|
||||||
#endif /* HAVE_FCHMOD */
|
#endif /* HAVE_FCHMOD */
|
||||||
run_err("%s: set mode: %s",
|
run_err("%s: set mode: %s",
|
||||||
np, strerror(errno));
|
np, strerror(errno));
|
||||||
|
wrerr = DISPLAYED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (close(ofd) == -1) {
|
if (close(ofd) == -1) {
|
||||||
wrerr = YES;
|
wrerr = YES;
|
||||||
@ -1084,8 +1131,8 @@ void
|
|||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"usage: scp [-pqrvBC1246] [-F config] [-S program] [-P port]\n"
|
"usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||||
" [-c cipher] [-i identity] [-l limit] [-o option]\n"
|
" [-l limit] [-o ssh_option] [-P port] [-S program]\n"
|
||||||
" [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
|
" [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -1126,7 +1173,7 @@ verifydir(char *cp)
|
|||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
}
|
}
|
||||||
run_err("%s: %s", cp, strerror(errno));
|
run_err("%s: %s", cp, strerror(errno));
|
||||||
exit(1);
|
killchild(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
95
scpmisc.c
95
scpmisc.c
@ -140,12 +140,15 @@ void
|
|||||||
addargs(arglist *args, char *fmt, ...)
|
addargs(arglist *args, char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char buf[1024];
|
char *cp;
|
||||||
int nalloc;
|
u_int nalloc;
|
||||||
|
int r;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
r = vasprintf(&cp, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
if (r == -1)
|
||||||
|
fatal("addargs: argument too long");
|
||||||
|
|
||||||
nalloc = args->nalloc;
|
nalloc = args->nalloc;
|
||||||
if (args->list == NULL) {
|
if (args->list == NULL) {
|
||||||
@ -156,6 +159,90 @@ addargs(arglist *args, char *fmt, ...)
|
|||||||
|
|
||||||
args->list = xrealloc(args->list, nalloc * sizeof(char *));
|
args->list = xrealloc(args->list, nalloc * sizeof(char *));
|
||||||
args->nalloc = nalloc;
|
args->nalloc = nalloc;
|
||||||
args->list[args->num++] = xstrdup(buf);
|
args->list[args->num++] = cp;
|
||||||
args->list[args->num] = NULL;
|
args->list[args->num] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
replacearg(arglist *args, u_int which, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
char *cp;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
r = vasprintf(&cp, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (r == -1)
|
||||||
|
fatal("replacearg: argument too long");
|
||||||
|
|
||||||
|
if (which >= args->num)
|
||||||
|
fatal("replacearg: tried to replace invalid arg %d >= %d",
|
||||||
|
which, args->num);
|
||||||
|
xfree(args->list[which]);
|
||||||
|
args->list[which] = cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
freeargs(arglist *args)
|
||||||
|
{
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
if (args->list != NULL) {
|
||||||
|
for (i = 0; i < args->num; i++)
|
||||||
|
xfree(args->list[i]);
|
||||||
|
xfree(args->list);
|
||||||
|
args->nalloc = args->num = 0;
|
||||||
|
args->list = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB. duplicate __progname in case it is an alias for argv[0]
|
||||||
|
* Otherwise it may get clobbered by setproctitle()
|
||||||
|
*/
|
||||||
|
char *ssh_get_progname(char *argv0)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (argv0 == NULL)
|
||||||
|
return ("unknown"); /* XXX */
|
||||||
|
p = strrchr(argv0, '/');
|
||||||
|
if (p == NULL)
|
||||||
|
p = argv0;
|
||||||
|
else
|
||||||
|
p++;
|
||||||
|
|
||||||
|
return (xstrdup(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fatal(char* fmt,...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
exit(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sanitise_stdfd(void)
|
||||||
|
{
|
||||||
|
int nullfd, dupfd;
|
||||||
|
|
||||||
|
if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
|
||||||
|
fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
while (++dupfd <= 2) {
|
||||||
|
/* Only clobber closed fds */
|
||||||
|
if (fcntl(dupfd, F_GETFL, 0) >= 0)
|
||||||
|
continue;
|
||||||
|
if (dup2(nullfd, dupfd) == -1) {
|
||||||
|
fprintf(stderr, "dup2: %s", strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nullfd > 2)
|
||||||
|
close(nullfd);
|
||||||
|
}
|
||||||
|
@ -34,6 +34,8 @@ struct arglist {
|
|||||||
int nalloc;
|
int nalloc;
|
||||||
};
|
};
|
||||||
void addargs(arglist *, char *, ...);
|
void addargs(arglist *, char *, ...);
|
||||||
|
void replacearg(arglist *, u_int, char *, ...);
|
||||||
|
void freeargs(arglist *);
|
||||||
|
|
||||||
/* from xmalloc.h */
|
/* from xmalloc.h */
|
||||||
void *xmalloc(size_t);
|
void *xmalloc(size_t);
|
||||||
@ -41,4 +43,6 @@ void *xrealloc(void *, size_t);
|
|||||||
void xfree(void *);
|
void xfree(void *);
|
||||||
char *xstrdup(const char *);
|
char *xstrdup(const char *);
|
||||||
|
|
||||||
|
char *ssh_get_progname(char *);
|
||||||
|
void fatal(char* fmt,...);
|
||||||
|
void sanitise_stdfd(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user