summaryrefslogtreecommitdiff
path: root/net/openbgpd/files/patch-bgpctl_fmt_scaled.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openbgpd/files/patch-bgpctl_fmt_scaled.c')
-rw-r--r--net/openbgpd/files/patch-bgpctl_fmt_scaled.c126
1 files changed, 119 insertions, 7 deletions
diff --git a/net/openbgpd/files/patch-bgpctl_fmt_scaled.c b/net/openbgpd/files/patch-bgpctl_fmt_scaled.c
index fb39929e296b..66e5b90ef4c9 100644
--- a/net/openbgpd/files/patch-bgpctl_fmt_scaled.c
+++ b/net/openbgpd/files/patch-bgpctl_fmt_scaled.c
@@ -1,7 +1,7 @@
--- /dev/null 1 Jan 1970 00:00:00 -0000
-+++ bgpctl/fmt_scaled.c 8 Feb 2007 10:32:19 -0000
-@@ -0,0 +1,152 @@
-+/* $OpenBSD: fmt_scaled.c,v 1.8 2005/10/19 18:48:11 deraadt Exp $ */
++++ bgpctl/fmt_scaled.c 2008-03-18 13:27:29.000000000 +0100
+@@ -0,0 +1,268 @@
++/* $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.
@@ -68,6 +68,122 @@
+
+#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.
@@ -153,7 +269,3 @@
+ return 0;
+}
+#endif
-Index: util.h
-===================================================================
-RCS file: util.h
-diff -N util.h