summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ssh/libssh
diff options
context:
space:
mode:
authorjp161948 <none@none>2007-09-19 05:03:12 -0700
committerjp161948 <none@none>2007-09-19 05:03:12 -0700
commit90685d2c52744c6540828f16cdd2db815d467e37 (patch)
treed0b643cf07d9886649691973b48b865d32a93f19 /usr/src/cmd/ssh/libssh
parent1fceb383a3f0b59711832b9dc4e8329d7f216604 (diff)
downloadillumos-gate-90685d2c52744c6540828f16cdd2db815d467e37.tar.gz
PSARC/2007/033 sftp resync with OpenSSH
6481668 sftp(1)/sftp-server(1m) needs a resync with OpenSSH --HG-- rename : usr/src/cmd/ssh/include/sftp-glob.h => deleted_files/usr/src/cmd/ssh/include/sftp-glob.h rename : usr/src/cmd/ssh/include/sftp-int.h => deleted_files/usr/src/cmd/ssh/include/sftp-int.h rename : usr/src/cmd/ssh/sftp/sftp-int.c => deleted_files/usr/src/cmd/ssh/sftp/sftp-int.c
Diffstat (limited to 'usr/src/cmd/ssh/libssh')
-rw-r--r--usr/src/cmd/ssh/libssh/Makefile.com139
-rw-r--r--usr/src/cmd/ssh/libssh/common/atomicio.c54
-rw-r--r--usr/src/cmd/ssh/libssh/common/buffer.c64
-rw-r--r--usr/src/cmd/ssh/libssh/common/llib-lssh9
-rw-r--r--usr/src/cmd/ssh/libssh/common/misc.c126
-rw-r--r--usr/src/cmd/ssh/libssh/common/progressmeter.c308
-rw-r--r--usr/src/cmd/ssh/libssh/common/sftp-common.c52
7 files changed, 643 insertions, 109 deletions
diff --git a/usr/src/cmd/ssh/libssh/Makefile.com b/usr/src/cmd/ssh/libssh/Makefile.com
index b8f4d30de9..ed02ab1de2 100644
--- a/usr/src/cmd/ssh/libssh/Makefile.com
+++ b/usr/src/cmd/ssh/libssh/Makefile.com
@@ -24,94 +24,95 @@
# ident "%Z%%M% %I% %E% SMI"
#
-LIBRARY= libssh.a
-VERS= .1
+LIBRARY = libssh.a
+VERS = .1
-OBJECTS= \
- atomicio.o \
- authfd.o \
- authfile.o \
- bufaux.o \
- buffer.o \
- canohost.o \
- channels.o \
- cipher.o \
- cipher-ctr.o \
- compat.o \
- compress.o \
- crc32.o \
- deattack.o \
- dh.o \
- dispatch.o \
- fatal.o \
- g11n.o \
- mac.o \
- msg.o \
- hostfile.o \
- key.o \
- kex.o \
- kexdh.o \
- kexdhc.o \
- kexdhs.o \
- kexgex.o \
- kexgexc.o \
- kexgexs.o \
- kexgssc.o \
- kexgsss.o \
- log.o \
- match.o \
- misc.o \
- mpaux.o \
- nchan.o \
- packet.o \
- radix.o \
- entropy.o \
- readpass.o \
- rsa.o \
- scard.o \
- scard-opensc.o \
- ssh-dss.o \
- ssh-gss.o \
- ssh-rsa.o \
- tildexpand.o \
- ttymodes.o \
- uidswap.o \
- uuencode.o \
- xlist.o \
- xmalloc.o \
- monitor_wrap.o \
- monitor_fdpass.o \
- readconf.o \
- sftp-common.o \
- proxy-io.o
+OBJECTS = \
+ atomicio.o \
+ authfd.o \
+ authfile.o \
+ bufaux.o \
+ buffer.o \
+ canohost.o \
+ channels.o \
+ cipher.o \
+ cipher-ctr.o \
+ compat.o \
+ compress.o \
+ crc32.o \
+ deattack.o \
+ dh.o \
+ dispatch.o \
+ fatal.o \
+ g11n.o \
+ mac.o \
+ msg.o \
+ hostfile.o \
+ key.o \
+ kex.o \
+ kexdh.o \
+ kexdhc.o \
+ kexdhs.o \
+ kexgex.o \
+ kexgexc.o \
+ kexgexs.o \
+ kexgssc.o \
+ kexgsss.o \
+ log.o \
+ match.o \
+ misc.o \
+ mpaux.o \
+ nchan.o \
+ packet.o \
+ progressmeter.o \
+ radix.o \
+ entropy.o \
+ readpass.o \
+ rsa.o \
+ scard.o \
+ scard-opensc.o \
+ ssh-dss.o \
+ ssh-gss.o \
+ ssh-rsa.o \
+ tildexpand.o \
+ ttymodes.o \
+ uidswap.o \
+ uuencode.o \
+ xlist.o \
+ xmalloc.o \
+ monitor_wrap.o \
+ monitor_fdpass.o \
+ readconf.o \
+ sftp-common.o \
+ proxy-io.o
include $(SRC)/lib/Makefile.lib
-BUILD.AR= $(RM) $@ ; $(AR) $(ARFLAGS) $@ $(AROBJS)
+BUILD.AR = $(RM) $@ ; $(AR) $(ARFLAGS) $@ $(AROBJS)
-SRCDIR= ../common
-SRCS= $(OBJECTS:%.o=../common/%.c)
+SRCDIR = ../common
+SRCS = $(OBJECTS:%.o=../common/%.c)
LIBS = $(LIBRARY) $(LINTLIB)
# definitions for lint
# Until libz is compiled against unsigned uid/gid ON bits.
-#LINTFLAGS += $(OPENSSL_LDFLAGS) -lcrypto -lz -lsocket -lnsl -lc
-LINTFLAGS += $(OPENSSL_LDFLAGS) -lcrypto -lsocket -lnsl -lc
-$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+#LINTFLAGS += $(OPENSSL_LDFLAGS) -lcrypto -lz -lsocket -lnsl -lc
+LINTFLAGS += $(OPENSSL_LDFLAGS) -lcrypto -lsocket -lnsl -lc
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
-POFILE_DIR= ../..
+POFILE_DIR = ../..
.KEEP_STATE:
-all: $(LIBS)
+all: $(LIBS)
# lint requires the (not installed) lint library
-lint: $(LINTLIB) .WAIT lintcheck
+lint: $(LINTLIB) .WAIT lintcheck
include $(SRC)/lib/Makefile.targ
-objs/%.o: $(SRCDIR)/%.c
+objs/%.o: $(SRCDIR)/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
diff --git a/usr/src/cmd/ssh/libssh/common/atomicio.c b/usr/src/cmd/ssh/libssh/common/atomicio.c
index 806876e24e..f4a7945702 100644
--- a/usr/src/cmd/ssh/libssh/common/atomicio.c
+++ b/usr/src/cmd/ssh/libssh/common/atomicio.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (c) 2006 Damien Miller. All rights reserved.
+ * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
* All rights reserved.
*
@@ -62,3 +64,55 @@ atomicio(f, fd, _s, n)
}
return (pos);
}
+
+/*
+ * ensure all of data on socket comes through. f==readv || f==writev
+ */
+size_t
+atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
+ const struct iovec *_iov, int iovcnt)
+{
+ size_t pos = 0, rem;
+ ssize_t res;
+ struct iovec iov_array[IOV_MAX], *iov = iov_array;
+
+ if (iovcnt > IOV_MAX) {
+ errno = EINVAL;
+ return 0;
+ }
+ /* Make a copy of the iov array because we may modify it below */
+ memcpy(iov, _iov, iovcnt * sizeof(*_iov));
+
+ for (; iovcnt > 0 && iov[0].iov_len > 0;) {
+ res = (f) (fd, iov, iovcnt);
+ switch (res) {
+ case -1:
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ return 0;
+ case 0:
+ errno = EPIPE;
+ return pos;
+ default:
+ rem = (size_t)res;
+ pos += rem;
+ /* skip completed iov entries */
+ while (iovcnt > 0 && rem >= iov[0].iov_len) {
+ rem -= iov[0].iov_len;
+ iov++;
+ iovcnt--;
+ }
+ /* This shouldn't happen... */
+ if (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) {
+ errno = EFAULT;
+ return 0;
+ }
+ if (iovcnt == 0)
+ break;
+ /* update pointer in partially complete iov */
+ iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
+ iov[0].iov_len -= rem;
+ }
+ }
+ return pos;
+}
diff --git a/usr/src/cmd/ssh/libssh/common/buffer.c b/usr/src/cmd/ssh/libssh/common/buffer.c
index 9d95851d68..45d6860157 100644
--- a/usr/src/cmd/ssh/libssh/common/buffer.c
+++ b/usr/src/cmd/ssh/libssh/common/buffer.c
@@ -11,15 +11,20 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-#include "includes.h"
-RCSID("$OpenBSD: buffer.c,v 1.23 2005/03/14 11:46:56 markus Exp $");
+/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */
#pragma ident "%Z%%M% %I% %E% SMI"
+#include "includes.h"
+
#include "xmalloc.h"
#include "buffer.h"
#include "log.h"
+#define BUFFER_MAX_CHUNK 0x100000
+#define BUFFER_MAX_LEN 0xa00000
+#define BUFFER_ALLOCSZ 0x008000
+
/* Initializes the buffer structure. */
void
@@ -68,6 +73,23 @@ buffer_append(Buffer *buffer, const void *data, u_int len)
memcpy(p, data, len);
}
+static int
+buffer_compact(Buffer *buffer)
+{
+ /*
+ * If the buffer is quite empty, but all data is at the end, move the
+ * data to the beginning.
+ */
+ if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
+ memmove(buffer->buf, buffer->buf + buffer->offset,
+ buffer->end - buffer->offset);
+ buffer->end -= buffer->offset;
+ buffer->offset = 0;
+ return (1);
+ }
+ return (0);
+}
+
/*
* Appends space to the buffer, expanding the buffer if necessary. This does
* not actually copy the data into the buffer, but instead returns a pointer
@@ -95,20 +117,13 @@ restart:
buffer->end += len;
return p;
}
- /*
- * If the buffer is quite empty, but all data is at the end, move the
- * data to the beginning and retry.
- */
- if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
- memmove(buffer->buf, buffer->buf + buffer->offset,
- buffer->end - buffer->offset);
- buffer->end -= buffer->offset;
- buffer->offset = 0;
+
+ /* Compact data back to the start of the buffer if necessary */
+ if (buffer_compact(buffer))
goto restart;
- }
+
/* Increase the size of the buffer and retry. */
-
- newlen = buffer->alloc + len + 32768;
+ newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
if (newlen > BUFFER_MAX_LEN)
fatal("buffer_append_space: alloc %u not supported",
newlen);
@@ -118,6 +133,27 @@ restart:
/* NOTREACHED */
}
+/*
+ * Check whether an allocation of 'len' will fit in the buffer
+ * This must follow the same math as buffer_append_space
+ */
+int
+buffer_check_alloc(Buffer *buffer, u_int len)
+{
+ if (buffer->offset == buffer->end) {
+ buffer->offset = 0;
+ buffer->end = 0;
+ }
+ restart:
+ if (buffer->end + len < buffer->alloc)
+ return (1);
+ if (buffer_compact(buffer))
+ goto restart;
+ if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN)
+ return (1);
+ return (0);
+}
+
/* Returns the number of bytes of data in the buffer. */
u_int
diff --git a/usr/src/cmd/ssh/libssh/common/llib-lssh b/usr/src/cmd/ssh/libssh/common/llib-lssh
index 321ed7d2e3..f827580891 100644
--- a/usr/src/cmd/ssh/libssh/common/llib-lssh
+++ b/usr/src/cmd/ssh/libssh/common/llib-lssh
@@ -5,9 +5,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
*
* CDDL HEADER END
*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -110,8 +109,6 @@
#include <setproctitle.h>
#include <sftp-common.h>
#include <sftp.h>
-#include <sftp-int.h>
-#include <sftp-glob.h>
#include <sftp-client.h>
#include <sigact.h>
#include <ssh1.h>
diff --git a/usr/src/cmd/ssh/libssh/common/misc.c b/usr/src/cmd/ssh/libssh/common/misc.c
index 9fe8d8c1b8..21b683c3cd 100644
--- a/usr/src/cmd/ssh/libssh/common/misc.c
+++ b/usr/src/cmd/ssh/libssh/common/misc.c
@@ -363,6 +363,26 @@ addargs(arglist *args, char *fmt, ...)
}
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;
@@ -376,6 +396,32 @@ freeargs(arglist *args)
}
}
+/*
+ * Ensure that file descriptors 0, 1 and 2 are open or directed to /dev/null,
+ * do not touch those that are already open.
+ */
+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);
+}
+
char *
tohex(const void *vp, size_t l)
{
@@ -395,6 +441,86 @@ tohex(const void *vp, size_t l)
return (r);
}
+u_int64_t
+get_u64(const void *vp)
+{
+ const u_char *p = (const u_char *)vp;
+ u_int64_t v;
+
+ v = (u_int64_t)p[0] << 56;
+ v |= (u_int64_t)p[1] << 48;
+ v |= (u_int64_t)p[2] << 40;
+ v |= (u_int64_t)p[3] << 32;
+ v |= (u_int64_t)p[4] << 24;
+ v |= (u_int64_t)p[5] << 16;
+ v |= (u_int64_t)p[6] << 8;
+ v |= (u_int64_t)p[7];
+
+ return (v);
+}
+
+u_int32_t
+get_u32(const void *vp)
+{
+ const u_char *p = (const u_char *)vp;
+ u_int32_t v;
+
+ v = (u_int32_t)p[0] << 24;
+ v |= (u_int32_t)p[1] << 16;
+ v |= (u_int32_t)p[2] << 8;
+ v |= (u_int32_t)p[3];
+
+ return (v);
+}
+
+u_int16_t
+get_u16(const void *vp)
+{
+ const u_char *p = (const u_char *)vp;
+ u_int16_t v;
+
+ v = (u_int16_t)p[0] << 8;
+ v |= (u_int16_t)p[1];
+
+ return (v);
+}
+
+void
+put_u64(void *vp, u_int64_t v)
+{
+ u_char *p = (u_char *)vp;
+
+ p[0] = (u_char)(v >> 56) & 0xff;
+ p[1] = (u_char)(v >> 48) & 0xff;
+ p[2] = (u_char)(v >> 40) & 0xff;
+ p[3] = (u_char)(v >> 32) & 0xff;
+ p[4] = (u_char)(v >> 24) & 0xff;
+ p[5] = (u_char)(v >> 16) & 0xff;
+ p[6] = (u_char)(v >> 8) & 0xff;
+ p[7] = (u_char)v & 0xff;
+}
+
+void
+put_u32(void *vp, u_int32_t v)
+{
+ u_char *p = (u_char *)vp;
+
+ p[0] = (u_char)(v >> 24) & 0xff;
+ p[1] = (u_char)(v >> 16) & 0xff;
+ p[2] = (u_char)(v >> 8) & 0xff;
+ p[3] = (u_char)v & 0xff;
+}
+
+
+void
+put_u16(void *vp, u_int16_t v)
+{
+ u_char *p = (u_char *)vp;
+
+ p[0] = (u_char)(v >> 8) & 0xff;
+ p[1] = (u_char)v & 0xff;
+}
+
mysig_t
mysignal(int sig, mysig_t act)
{
diff --git a/usr/src/cmd/ssh/libssh/common/progressmeter.c b/usr/src/cmd/ssh/libssh/common/progressmeter.c
new file mode 100644
index 0000000000..65d28fb596
--- /dev/null
+++ b/usr/src/cmd/ssh/libssh/common/progressmeter.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2003 Nils Nordman. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* $OpenBSD: progressmeter.c,v 1.37 2006/08/03 03:34:42 deraadt Exp $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "progressmeter.h"
+#include "atomicio.h"
+#include "misc.h"
+
+#define DEFAULT_WINSIZE 80
+#define MAX_WINSIZE 512
+#define PADDING 1 /* padding between the progress indicators */
+#define UPDATE_INTERVAL 1 /* update the progress meter every second */
+#define STALL_TIME 5 /* we're stalled after this many seconds */
+
+/* determines whether we can output to the terminal */
+static int can_output(void);
+
+/* formats and inserts the specified size into the given buffer */
+static void format_size(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 */
+void refresh_progress_meter(void);
+
+/* signal handler for updating the progress meter */
+static void update_progress_meter(int);
+
+static time_t start; /* start progress */
+static time_t last_update; /* last progress update */
+static char *file; /* name of the file being transferred */
+static off_t end_pos; /* ending position of transfer */
+static off_t cur_pos; /* transfer position as of last refresh */
+static volatile off_t *counter; /* progress counter */
+static long stalled; /* how long we have been stalled */
+static int bytes_per_second; /* current speed in bytes per second */
+static int win_size; /* terminal window size */
+static volatile sig_atomic_t win_resized; /* for window resizing */
+
+/* units for format_size */
+static const char unit[] = " KMGT";
+
+static int
+can_output(void)
+{
+ return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
+}
+
+static void
+format_rate(char *buf, int size, off_t bytes)
+{
+ int i;
+
+ bytes *= 100;
+ for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++)
+ bytes = (bytes + 512) / 1024;
+ if (i == 0) {
+ i++;
+ bytes = (bytes + 512) / 1024;
+ }
+ snprintf(buf, size, "%3lld.%1lld%c%s",
+ (long long) (bytes + 5) / 100,
+ (long long) (bytes + 5) / 10 % 10,
+ unit[i],
+ i ? "B" : " ");
+}
+
+static void
+format_size(char *buf, int size, off_t bytes)
+{
+ int i;
+
+ for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++)
+ bytes = (bytes + 512) / 1024;
+ snprintf(buf, size, "%4lld%c%s",
+ (long long) bytes,
+ unit[i],
+ i ? "B" : " ");
+}
+
+void
+refresh_progress_meter(void)
+{
+ char buf[MAX_WINSIZE + 1];
+ time_t now;
+ off_t transferred;
+ double elapsed;
+ int percent;
+ off_t bytes_left;
+ int cur_speed;
+ int hours, minutes, seconds;
+ int i, len;
+ int file_len;
+
+ transferred = *counter - cur_pos;
+ cur_pos = *counter;
+ now = time(NULL);
+ bytes_left = end_pos - cur_pos;
+
+ if (bytes_left > 0)
+ elapsed = now - last_update;
+ else {
+ elapsed = now - start;
+ /* Calculate true total speed when done */
+ transferred = end_pos;
+ bytes_per_second = 0;
+ }
+
+ /* calculate speed */
+ if (elapsed != 0)
+ cur_speed = (int)(transferred / elapsed);
+ else
+ cur_speed = transferred;
+
+#define AGE_FACTOR 0.9
+ if (bytes_per_second != 0) {
+ bytes_per_second = (int)((bytes_per_second * AGE_FACTOR) +
+ (cur_speed * (1.0 - AGE_FACTOR)));
+ } else
+ bytes_per_second = cur_speed;
+
+ /* filename */
+ buf[0] = '\0';
+ file_len = win_size - 35;
+ if (file_len > 0) {
+ len = snprintf(buf, file_len + 1, "\r%s", file);
+ if (len < 0)
+ len = 0;
+ if (len >= file_len + 1)
+ len = file_len;
+ for (i = len; i < file_len; i++)
+ buf[i] = ' ';
+ buf[file_len] = '\0';
+ }
+
+ /* percent of transfer done */
+ if (end_pos != 0)
+ percent = (int)(((float)cur_pos / end_pos) * 100);
+ else
+ percent = 100;
+ snprintf(buf + strlen(buf), win_size - strlen(buf),
+ " %3d%% ", percent);
+
+ /* amount transferred */
+ format_size(buf + strlen(buf), win_size - strlen(buf),
+ cur_pos);
+ strlcat(buf, " ", win_size);
+
+ /* bandwidth usage */
+ format_rate(buf + strlen(buf), win_size - strlen(buf),
+ (off_t)bytes_per_second);
+ strlcat(buf, "/s ", win_size);
+
+ /* ETA */
+ if (!transferred)
+ stalled += elapsed;
+ else
+ stalled = 0;
+
+ if (stalled >= STALL_TIME)
+ strlcat(buf, "- stalled -", win_size);
+ else if (bytes_per_second == 0 && bytes_left)
+ strlcat(buf, " --:-- ETA", win_size);
+ else {
+ if (bytes_left > 0)
+ seconds = bytes_left / bytes_per_second;
+ else
+ seconds = (int)elapsed;
+
+ hours = seconds / 3600;
+ seconds -= hours * 3600;
+ minutes = seconds / 60;
+ seconds -= minutes * 60;
+
+ if (hours != 0)
+ snprintf(buf + strlen(buf), win_size - strlen(buf),
+ "%d:%02d:%02d", hours, minutes, seconds);
+ else
+ snprintf(buf + strlen(buf), win_size - strlen(buf),
+ " %02d:%02d", minutes, seconds);
+
+ if (bytes_left > 0)
+ strlcat(buf, " ETA", win_size);
+ else
+ strlcat(buf, " ", win_size);
+ }
+
+ atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
+ last_update = now;
+}
+
+/*ARGSUSED*/
+static void
+update_progress_meter(int ignore)
+{
+ int save_errno;
+
+ save_errno = errno;
+
+ if (win_resized) {
+ setscreensize();
+ win_resized = 0;
+ }
+ if (can_output())
+ refresh_progress_meter();
+
+ signal(SIGALRM, update_progress_meter);
+ alarm(UPDATE_INTERVAL);
+ errno = save_errno;
+}
+
+void
+start_progress_meter(char *f, off_t filesize, off_t *ctr)
+{
+ start = last_update = time(NULL);
+ file = f;
+ end_pos = filesize;
+ cur_pos = 0;
+ counter = ctr;
+ stalled = 0;
+ bytes_per_second = 0;
+
+ setscreensize();
+ if (can_output())
+ refresh_progress_meter();
+
+ signal(SIGALRM, update_progress_meter);
+ signal(SIGWINCH, sig_winch);
+ alarm(UPDATE_INTERVAL);
+}
+
+void
+stop_progress_meter(void)
+{
+ alarm(0);
+
+ if (!can_output())
+ return;
+
+ /* Ensure we complete the progress */
+ if (cur_pos != end_pos)
+ refresh_progress_meter();
+
+ atomicio(vwrite, STDOUT_FILENO, "\n", 1);
+}
+
+/*ARGSUSED*/
+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 */
+}
diff --git a/usr/src/cmd/ssh/libssh/common/sftp-common.c b/usr/src/cmd/ssh/libssh/common/sftp-common.c
index 7cbe72c44c..ead9e2406f 100644
--- a/usr/src/cmd/ssh/libssh/common/sftp-common.c
+++ b/usr/src/cmd/ssh/libssh/common/sftp-common.c
@@ -23,15 +23,27 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "includes.h"
-RCSID("$OpenBSD: sftp-common.c,v 1.7 2002/09/11 22:41:50 djm Exp $");
+/* $OpenBSD: sftp-common.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
#pragma ident "%Z%%M% %I% %E% SMI"
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <stdarg.h>
+
+#include "xmalloc.h"
#include "buffer.h"
#include "bufaux.h"
#include "log.h"
-#include "xmalloc.h"
#include "sftp.h"
#include "sftp-common.h"
@@ -51,7 +63,7 @@ attrib_clear(Attrib *a)
/* Convert from struct stat to filexfer attribs */
void
-stat_to_attrib(struct stat *st, Attrib *a)
+stat_to_attrib(const struct stat *st, Attrib *a)
{
attrib_clear(a);
a->flags = 0;
@@ -69,7 +81,7 @@ stat_to_attrib(struct stat *st, Attrib *a)
/* Convert from filexfer attribs to struct stat */
void
-attrib_to_stat(Attrib *a, struct stat *st)
+attrib_to_stat(const Attrib *a, struct stat *st)
{
memset(st, 0, sizeof(*st));
@@ -126,7 +138,7 @@ decode_attrib(Buffer *b)
/* Encode attributes to buffer */
void
-encode_attrib(Buffer *b, Attrib *a)
+encode_attrib(Buffer *b, const Attrib *a)
{
buffer_put_int(b, a->flags);
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
@@ -149,25 +161,25 @@ fx2txt(int status)
{
switch (status) {
case SSH2_FX_OK:
- return("No error");
+ return(gettext("No error"));
case SSH2_FX_EOF:
- return("End of file");
+ return(gettext("End of file"));
case SSH2_FX_NO_SUCH_FILE:
- return("No such file or directory");
+ return(gettext("No such file or directory"));
case SSH2_FX_PERMISSION_DENIED:
- return("Permission denied");
+ return(gettext("Permission denied"));
case SSH2_FX_FAILURE:
- return("Failure");
+ return(gettext("Failure"));
case SSH2_FX_BAD_MESSAGE:
- return("Bad message");
+ return(gettext("Bad message"));
case SSH2_FX_NO_CONNECTION:
- return("No connection");
+ return(gettext("No connection"));
case SSH2_FX_CONNECTION_LOST:
- return("Connection lost");
+ return(gettext("Connection lost"));
case SSH2_FX_OP_UNSUPPORTED:
- return("Operation unsupported");
+ return(gettext("Operation unsupported"));
default:
- return("Unknown status");
+ return(gettext("Unknown status"));
}
/* NOTREACHED */
}
@@ -176,7 +188,7 @@ fx2txt(int status)
* drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh
*/
char *
-ls_file(char *name, struct stat *st, int remote)
+ls_file(const char *name, const struct stat *st, int remote)
{
int ulen, glen, sz = 0;
struct passwd *pw;
@@ -208,8 +220,8 @@ ls_file(char *name, struct stat *st, int remote)
tbuf[0] = '\0';
ulen = MAX(strlen(user), 8);
glen = MAX(strlen(group), 8);
- snprintf(buf, sizeof buf, "%s %3d %-*s %-*s %8llu %s %s", mode,
- st->st_nlink, ulen, user, glen, group,
- (u_int64_t)st->st_size, tbuf, name);
+ snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode,
+ (u_int)st->st_nlink, ulen, user, glen, group,
+ (unsigned long long)st->st_size, tbuf, name);
return xstrdup(buf);
}