diff options
author | jp161948 <none@none> | 2007-09-19 05:03:12 -0700 |
---|---|---|
committer | jp161948 <none@none> | 2007-09-19 05:03:12 -0700 |
commit | 90685d2c52744c6540828f16cdd2db815d467e37 (patch) | |
tree | d0b643cf07d9886649691973b48b865d32a93f19 /usr/src/cmd/ssh/libssh | |
parent | 1fceb383a3f0b59711832b9dc4e8329d7f216604 (diff) | |
download | illumos-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.com | 139 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/atomicio.c | 54 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/buffer.c | 64 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/llib-lssh | 9 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/misc.c | 126 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/progressmeter.c | 308 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/sftp-common.c | 52 |
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); } |