]> andersk Git - openssh.git/commitdiff
- (djm) [configure.ac mux.c sftp.c openbsd-compat/Makefile.in]
authordjm <djm>
Mon, 19 May 2008 22:57:06 +0000 (22:57 +0000)
committerdjm <djm>
Mon, 19 May 2008 22:57:06 +0000 (22:57 +0000)
   [openbsd-compat/fmt_scaled.c openbsd-compat/openbsd-compat.h]
   Fix compilation on Linux, including pulling in fmt_scaled(3)
   implementation from OpenBSD's libutil.

ChangeLog
configure.ac
mux.c
openbsd-compat/Makefile.in
openbsd-compat/fmt_scaled.c [new file with mode: 0644]
openbsd-compat/openbsd-compat.h
sftp.c

index cc1ce98b014ab1e07191d259d80092d1677a73ab..48a4e29293577272c813bba9f0c50c61868078bb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+20080519
+ - (djm) [configure.ac mux.c sftp.c openbsd-compat/Makefile.in]
+   [openbsd-compat/fmt_scaled.c openbsd-compat/openbsd-compat.h]
+   Fix compilation on Linux, including pulling in fmt_scaled(3)
+   implementation from OpenBSD's libutil.
+
 20080518
  - (djm) OpenBSD CVS Sync
    - djm@cvs.openbsd.org 2008/04/04 05:14:38
index cbb847b1ac9ebc3693cefc6f6bdbad34dc0c0fb7..b387e47ea235e5f64688b1dd403cbf65c11b4c0c 100644 (file)
@@ -1034,7 +1034,7 @@ dnl    Checks for libutil functions
 AC_CHECK_HEADERS(libutil.h)
 AC_SEARCH_LIBS(login, util bsd, [AC_DEFINE(HAVE_LOGIN, 1,
        [Define if your libraries define login()])])
-AC_CHECK_FUNCS(logout updwtmp logwtmp)
+AC_CHECK_FUNCS(fmt_scaled logout updwtmp logwtmp)
 
 AC_FUNC_STRFTIME
 
diff --git a/mux.c b/mux.c
index 78ba6315344baa949132129ad9674fcc781c3503..b4465b017e32f0933d503c71ea45b8cd97f4db01 100644 (file)
--- a/mux.c
+++ b/mux.c
@@ -17,6 +17,8 @@
 
 /* ssh session multiplexing support */
 
+#include "includes.h"
+
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <util.h>
 #include <paths.h>
 
+#ifdef HAVE_UTIL_H
+# include <util.h>
+#endif
+
+#ifdef HAVE_LIBUTIL_H
+# include <libutil.h>
+#endif
+
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
 #include "log.h"
index 1e13be7e1bbb3ddb65c52cdab56c9304f3de3e65..10b255374f99dd0f30ed90e96bef267760021f08 100644 (file)
@@ -16,7 +16,7 @@ RANLIB=@RANLIB@
 INSTALL=@INSTALL@
 LDFLAGS=-L. @LDFLAGS@
 
-OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
+OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
 
 COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
 
diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c
new file mode 100644 (file)
index 0000000..edd682a
--- /dev/null
@@ -0,0 +1,274 @@
+/*     $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $     */
+
+/*
+ * Copyright (c) 2001, 2002, 2003 Ian F. Darwin.  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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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 ORIGINAL: lib/libutil/fmt_scaled.c */
+
+/*
+ * fmt_scaled: Format numbers scaled for human comprehension
+ * scan_scaled: Scan numbers in this format.
+ *
+ * "Human-readable" output uses 4 digits max, and puts a unit suffix at
+ * the end.  Makes output compact and easy-to-read esp. on huge disks.
+ * Formatting code was originally in OpenBSD "df", converted to library routine.
+ * Scanning code written for OpenBSD libutil.
+ */
+
+#include "includes.h"
+
+#ifndef HAVE_FMT_SCALED
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+
+typedef enum {
+       NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6
+} unit_type;
+
+/* These three arrays MUST be in sync!  XXX make a struct */
+static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA };
+static char scale_chars[] = "BKMGTPE";
+static long long scale_factors[] = {
+       1LL,
+       1024LL,
+       1024LL*1024,
+       1024LL*1024*1024,
+       1024LL*1024*1024*1024,
+       1024LL*1024*1024*1024*1024,
+       1024LL*1024*1024*1024*1024*1024,
+};
+#define        SCALE_LENGTH (sizeof(units)/sizeof(units[0]))
+
+#define MAX_DIGITS (SCALE_LENGTH * 3)  /* XXX strlen(sprintf("%lld", -1)? */
+
+/** Convert the given input string "scaled" into numeric in "result".
+ * Return 0 on success, -1 and errno set on error.
+ */
+int
+scan_scaled(char *scaled, long long *result)
+{
+       char *p = scaled;
+       int sign = 0;
+       unsigned int i, ndigits = 0, fract_digits = 0;
+       long long scale_fact = 1, whole = 0, fpart = 0;
+
+       /* Skip leading whitespace */
+       while (isascii(*p) && isspace(*p))
+               ++p;
+
+       /* Then at most one leading + or - */
+       while (*p == '-' || *p == '+') {
+               if (*p == '-') {
+                       if (sign) {
+                               errno = EINVAL;
+                               return -1;
+                       }
+                       sign = -1;
+                       ++p;
+               } else if (*p == '+') {
+                       if (sign) {
+                               errno = EINVAL;
+                               return -1;
+                       }
+                       sign = +1;
+                       ++p;
+               }
+       }
+
+       /* Main loop: Scan digits, find decimal point, if present.
+        * We don't allow exponentials, so no scientific notation
+        * (but note that E for Exa might look like e to some!).
+        * Advance 'p' to end, to get scale factor.
+        */
+       for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
+               if (*p == '.') {
+                       if (fract_digits > 0) { /* oops, more than one '.' */
+                               errno = EINVAL;
+                               return -1;
+                       }
+                       fract_digits = 1;
+                       continue;
+               }
+
+               i = (*p) - '0';                 /* whew! finally a digit we can use */
+               if (fract_digits > 0) {
+                       if (fract_digits >= MAX_DIGITS-1)
+                               /* ignore extra fractional digits */
+                               continue;
+                       fract_digits++;         /* for later scaling */
+                       fpart *= 10;
+                       fpart += i;
+               } else {                                /* normal digit */
+                       if (++ndigits >= MAX_DIGITS) {
+                               errno = ERANGE;
+                               return -1;
+                       }
+                       whole *= 10;
+                       whole += i;
+               }
+       }
+
+       if (sign) {
+               whole *= sign;
+               fpart *= sign;
+       }
+
+       /* If no scale factor given, we're done. fraction is discarded. */
+       if (!*p) {
+               *result = whole;
+               return 0;
+       }
+
+       /* Validate scale factor, and scale whole and fraction by it. */
+       for (i = 0; i < SCALE_LENGTH; i++) {
+
+               /** Are we there yet? */
+               if (*p == scale_chars[i] ||
+                       *p == tolower(scale_chars[i])) {
+
+                       /* If it ends with alphanumerics after the scale char, bad. */
+                       if (isalnum(*(p+1))) {
+                               errno = EINVAL;
+                               return -1;
+                       }
+                       scale_fact = scale_factors[i];
+
+                       /* scale whole part */
+                       whole *= scale_fact;
+
+                       /* truncate fpart so it does't overflow.
+                        * then scale fractional part.
+                        */
+                       while (fpart >= LLONG_MAX / scale_fact) {
+                               fpart /= 10;
+                               fract_digits--;
+                       }
+                       fpart *= scale_fact;
+                       if (fract_digits > 0) {
+                               for (i = 0; i < fract_digits -1; i++)
+                                       fpart /= 10;
+                       }
+                       whole += fpart;
+                       *result = whole;
+                       return 0;
+               }
+       }
+       errno = ERANGE;
+       return -1;
+}
+
+/* Format the given "number" into human-readable form in "result".
+ * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE.
+ * Return 0 on success, -1 and errno set if error.
+ */
+int
+fmt_scaled(long long number, char *result)
+{
+       long long abval, fract = 0;
+       unsigned int i;
+       unit_type unit = NONE;
+
+       abval = (number < 0LL) ? -number : number;      /* no long long_abs yet */
+
+       /* Not every negative long long has a positive representation.
+        * Also check for numbers that are just too darned big to format
+        */
+       if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) {
+               errno = ERANGE;
+               return -1;
+       }
+
+       /* scale whole part; get unscaled fraction */
+       for (i = 0; i < SCALE_LENGTH; i++) {
+               if (abval/1024 < scale_factors[i]) {
+                       unit = units[i];
+                       fract = (i == 0) ? 0 : abval % scale_factors[i];
+                       number /= scale_factors[i];
+                       if (i > 0)
+                               fract /= scale_factors[i - 1];
+                       break;
+               }
+       }
+
+       fract = (10 * fract + 512) / 1024;
+       /* if the result would be >= 10, round main number */
+       if (fract == 10) {
+               if (number >= 0)
+                       number++;
+               else
+                       number--;
+               fract = 0;
+       }
+
+       if (number == 0)
+               strlcpy(result, "0B", FMT_SCALED_STRSIZE);
+       else if (unit == NONE || number >= 100 || number <= -100) {
+               if (fract >= 5) {
+                       if (number >= 0)
+                               number++;
+                       else
+                               number--;
+               }
+               (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c",
+                       number, scale_chars[unit]);
+       } else
+               (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c",
+                       number, fract, scale_chars[unit]);
+
+       return 0;
+}
+
+#ifdef MAIN
+/*
+ * This is the original version of the program in the man page.
+ * Copy-and-paste whatever you need from it.
+ */
+int
+main(int argc, char **argv)
+{
+       char *cinput = "1.5K", buf[FMT_SCALED_STRSIZE];
+       long long ninput = 10483892, result;
+
+       if (scan_scaled(cinput, &result) == 0)
+               printf("\"%s\" -> %lld\n", cinput, result);
+       else
+               perror(cinput);
+
+       if (fmt_scaled(ninput, buf) == 0)
+               printf("%lld -> \"%s\"\n", ninput, buf);
+       else
+               fprintf(stderr, "%lld invalid (%s)\n", ninput, strerror(errno));
+
+       return 0;
+}
+#endif
+
+#endif /* HAVE_FMT_SCALED */
index f65a797a9983802c83a991d1f382b658c4b94696..2bcd4a1ce1bcdbd7d6d62544665c9eea59717040 100644 (file)
@@ -101,6 +101,11 @@ int daemon(int nochdir, int noclose);
 char *dirname(const char *path);
 #endif
 
+#ifndef HAVE_FMT_SCALED
+#define        FMT_SCALED_STRSIZE      7
+int    fmt_scaled(long long number, char *result);
+#endif
+
 #if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
 char *inet_ntoa(struct in_addr in);
 #endif
diff --git a/sftp.c b/sftp.c
index 0745baf08136579e2b032c18043eb161140fe068..ffc35cb83c75273e742527c68be20a4708c24ef7 100644 (file)
--- a/sftp.c
+++ b/sftp.c
@@ -43,9 +43,16 @@ typedef void EditLine;
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <util.h>
 #include <stdarg.h>
 
+#ifdef HAVE_UTIL_H
+# include <util.h>
+#endif
+
+#ifdef HAVE_LIBUTIL_H
+# include <libutil.h>
+#endif
+
 #include "xmalloc.h"
 #include "log.h"
 #include "pathnames.h"
This page took 0.0669 seconds and 5 git commands to generate.