Add humanize_number(3) and split the trimdomain(3) function out from
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 5 Nov 2004 17:05:26 +0000 (17:05 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 5 Nov 2004 17:05:26 +0000 (17:05 +0000)
logwtmp.

Submitted-by: "Douwe Kiela" <virtus@wanadoo.nl>
Taken-From: FreeBSD

lib/libutil/Makefile
lib/libutil/humanize_number.3 [new file with mode: 0644]
lib/libutil/humanize_number.c [new file with mode: 0644]
lib/libutil/libutil.h
lib/libutil/logwtmp.c
lib/libutil/trimdomain.c [new file with mode: 0644]

index 93e3d15..b334afc 100644 (file)
@@ -1,6 +1,6 @@
 #      @(#)Makefile    8.1 (Berkeley) 6/4/93
 #      $FreeBSD: src/lib/libutil/Makefile,v 1.33.2.4 2001/04/25 10:04:42 ru Exp $
 #      @(#)Makefile    8.1 (Berkeley) 6/4/93
 #      $FreeBSD: src/lib/libutil/Makefile,v 1.33.2.4 2001/04/25 10:04:42 ru Exp $
-#      $DragonFly: src/lib/libutil/Makefile,v 1.3 2004/09/22 05:06:57 joerg Exp $
+#      $DragonFly: src/lib/libutil/Makefile,v 1.4 2004/11/05 17:05:26 dillon Exp $
 
 LIB=   util
 SHLIB_MAJOR= 3
 
 LIB=   util
 SHLIB_MAJOR= 3
@@ -10,13 +10,15 @@ CFLAGS+=-DINET6
 SRCS=  login.c login_tty.c logout.c logwtmp.c pty.c \
        login_cap.c login_class.c login_auth.c login_times.c login_ok.c \
        login_crypt.c _secure_path.c uucplock.c property.c auth.c \
 SRCS=  login.c login_tty.c logout.c logwtmp.c pty.c \
        login_cap.c login_class.c login_auth.c login_times.c login_ok.c \
        login_crypt.c _secure_path.c uucplock.c property.c auth.c \
-       realhostname.c fparseln.c stub.c pidfile.c
+       realhostname.c fparseln.c stub.c pidfile.c trimdomain.c \
+       humanize_number.c
 INCS=  libutil.h login_cap.h
 
 MAN+=  login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \
        login_cap.3 login_class.3 login_times.3 login_ok.3 \
        _secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \
 INCS=  libutil.h login_cap.h
 
 MAN+=  login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \
        login_cap.3 login_class.3 login_times.3 login_ok.3 \
        _secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \
-       realhostname_sa.3 trimdomain.3 fparseln.3 pidfile.3
+       realhostname_sa.3 trimdomain.3 fparseln.3 pidfile.3 \
+       humanize_number.3
 MAN+=  login.conf.5 auth.conf.5
 MLINKS+= property.3 properties_read.3  property.3 properties_free.3
 MLINKS+= property.3 property_find.3
 MAN+=  login.conf.5 auth.conf.5
 MLINKS+= property.3 properties_read.3  property.3 properties_free.3
 MLINKS+= property.3 property_find.3
diff --git a/lib/libutil/humanize_number.3 b/lib/libutil/humanize_number.3
new file mode 100644 (file)
index 0000000..63fd513
--- /dev/null
@@ -0,0 +1,149 @@
+.\"    $NetBSD: humanize_number.3,v 1.4 2003/04/16 13:34:37 wiz Exp $
+.\" $FreeBSD: /repoman/r/ncvs/src/lib/libutil/humanize_number.3,v 1.4.2.1 2004/09/28 18:24:50 pjd Exp $
+.\" $DragonFly: src/lib/libutil/humanize_number.3,v 1.1 2004/11/05 17:05:26 dillon Exp $
+.\"
+.\" Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Luke Mewburn and by Tomas Svensson.
+.\"
+.\" 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. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"        This product includes software developed by the NetBSD
+.\"        Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\"    contributors may be used to endorse or promote products derived
+.\"    from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``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 FOUNDATION OR CONTRIBUTORS
+.\" 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.
+.\"
+.Dd May 25, 2004
+.Dt HUMANIZE_NUMBER 3
+.Os
+.Sh NAME
+.Nm humanize_number
+.Nd format a number into a human readable form
+.Sh LIBRARY
+.Lb libutil
+.Sh SYNOPSIS
+.In libutil.h
+.Ft int
+.Fo humanize_number
+.Fa "char *buf" "size_t len" "int64_t number" "const char *suffix"
+.Fa "int scale" "int flags"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn humanize_number
+function formats the signed 64-bit quantity given in
+.Fa number
+into
+.Fa buffer .
+A space and then
+.Fa suffix
+is appended to the end.
+The buffer pointed to by
+.Fa buffer
+must be at least
+.Fa len
+bytes bytes long.
+.Pp
+If the formatted number (including
+.Fa suffix )
+would be too long to fit into
+.Fa buffer ,
+then divide
+.Fa number
+by 1024 until it will.
+In this case, prefix
+.Fa suffix
+with the appropriate SI designator.
+.Pp
+The prefixes are:
+.Bl -column "Prefix" "Description" "Multiplier" -offset indent
+.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
+.It Li k Ta No kilo Ta 1024
+.It Li M Ta No mega Ta 1048576
+.It Li G Ta No giga Ta 1073741824
+.It Li T Ta No tera Ta 1099511627776
+.It Li P Ta No peta Ta 1125899906842624
+.It Li E Ta No exa Ta 1152921504606846976
+.El
+.Pp
+The
+.Fa len
+argument must be at least 4 plus the length of
+.Fa suffix ,
+in order to ensure a useful result is generated into
+.Fa buffer .
+To use a specific prefix, specify this as
+.Fa scale
+(multiplier = 1024 ^ scale).
+This cannot be combined with any of the
+.Fa scale
+flags below.
+.Pp
+The following flags may be passed in
+.Fa scale :
+.Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent
+.It Dv HN_AUTOSCALE
+Format the buffer using the lowest multiplier possible.
+.It Dv HN_GETSCALE
+Return the prefix index number (the number of times
+.Fa number
+must be divided to fit) instead of formatting it to the buffer.
+.El
+.Pp
+The following flags may be passed in
+.Fa flags :
+.Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent
+.It Dv HN_DECIMAL
+If the final result is less than 10, display it using one digit.
+.It Dv HN_NOSPACE
+Do not put a space between
+.Fa number
+and the prefix.
+.It Dv HN_B
+Use
+.Ql B
+(bytes) as prefix if the original result does not have a prefix.
+.It Dv HN_DIVISOR_1000
+Divide
+.Fa number
+with 1000 instead of 1024.
+.El
+.Sh RETURN VALUES
+The
+.Fn humanize_number
+function returns the number of characters stored in
+.Fa buffer
+(excluding the terminating
+.Dv NUL )
+upon success, or \-1 upon failure.
+If
+.Dv HN_GETSCALE
+is specified, the prefix index number will be returned instead.
+.Sh HISTORY
+The
+.Fn humanize_number
+function first appeared in
+.Nx 2.0 .
diff --git a/lib/libutil/humanize_number.c b/lib/libutil/humanize_number.c
new file mode 100644 (file)
index 0000000..a58e302
--- /dev/null
@@ -0,0 +1,149 @@
+/*     $NetBSD: humanize_number.c,v 1.8 2004/07/27 01:56:24 enami Exp $        */
+/* $DragonFly: src/lib/libutil/humanize_number.c,v 1.1 2004/11/05 17:05:26 dillon Exp $ */
+
+/*
+ * Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the NetBSD
+ *      Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/lib/libutil/humanize_number.c,v 1.1.2.1 2004/09/28 18:24:10 pjd Exp $
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <libutil.h>
+
+int
+humanize_number(char *buf, size_t len, int64_t bytes,
+    const char *suffix, int scale, int flags)
+{
+       const char *prefixes, *sep;
+       int     b, i, r, maxscale, s1, s2, sign;
+       int64_t divisor, max;
+       size_t  baselen;
+
+       assert(buf != NULL);
+       assert(suffix != NULL);
+       assert(scale >= 0);
+
+       if (flags & HN_DIVISOR_1000) {
+               /* SI for decimal multiplies */
+               divisor = 1000;
+               if (flags & HN_B)
+                       prefixes = "B\0k\0M\0G\0T\0P\0E";
+               else
+                       prefixes = "\0\0k\0M\0G\0T\0P\0E";
+       } else {
+               /*
+                * binary multiplies
+                * XXX IEC 60027-2 recommends Ki, Mi, Gi...
+                */
+               divisor = 1024;
+               if (flags & HN_B)
+                       prefixes = "B\0K\0M\0G\0T\0P\0E";
+               else
+                       prefixes = "\0\0K\0M\0G\0T\0P\0E";
+       }
+
+#define        SCALE2PREFIX(scale)     (&prefixes[(scale) << 1])
+       maxscale = 7;
+
+       if (scale >= maxscale &&
+           (scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
+               return (-1);
+
+       if (buf == NULL || suffix == NULL)
+               return (-1);
+
+       if (len > 0)
+               buf[0] = '\0';
+       if (bytes < 0) {
+               sign = -1;
+               bytes *= -100;
+               baselen = 3;            /* sign, digit, prefix */
+       } else {
+               sign = 1;
+               bytes *= 100;
+               baselen = 2;            /* digit, prefix */
+       }
+       if (flags & HN_NOSPACE)
+               sep = "";
+       else {
+               sep = " ";
+               baselen++;
+       }
+       baselen += strlen(suffix);
+
+       /* Check if enough room for `x y' + suffix + `\0' */
+       if (len < baselen + 1)
+               return (-1);
+
+       if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
+               /* See if there is additional columns can be used. */
+               for (max = 100, i = len - baselen; i-- > 0;)
+                       max *= 10;
+
+               for (i = 0; bytes >= max && i < maxscale; i++)
+                       bytes /= divisor;
+
+               if (scale & HN_GETSCALE)
+                       return (i);
+       } else
+               for (i = 0; i < scale && i < maxscale; i++)
+                       bytes /= divisor;
+
+       /* If a value <= 9.9 after rounding and ... */
+       if (bytes < 995 && i > 0 && flags & HN_DECIMAL) {
+               /* baselen + \0 + .N */
+               if (len < baselen + 1 + 2)
+                       return (-1);
+               b = ((int)bytes + 5) / 10;
+               s1 = b / 10;
+               s2 = b % 10;
+               r = snprintf(buf, len, "%d%s%d%s%s%s",
+                   sign * s1, localeconv()->decimal_point, s2,
+                   sep, SCALE2PREFIX(i), suffix);
+       } else
+               r = snprintf(buf, len, "%lld%s%s%s",
+                   /* LONGLONG */
+                   (long long)(sign * ((bytes + 50) / 100)),
+                   sep, SCALE2PREFIX(i), suffix);
+
+       return (r);
+}
index 291504e..a7cc58e 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libutil/libutil.h,v 1.26.2.3 2000/11/22 03:49:49 murray Exp $
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libutil/libutil.h,v 1.26.2.3 2000/11/22 03:49:49 murray Exp $
- * $DragonFly: src/lib/libutil/libutil.h,v 1.4 2004/09/22 05:06:57 joerg Exp $
+ * $DragonFly: src/lib/libutil/libutil.h,v 1.5 2004/11/05 17:05:26 dillon Exp $
  */
 
 #ifndef _LIBUTIL_H_
  */
 
 #ifndef _LIBUTIL_H_
@@ -58,6 +58,8 @@ int   openpty (int *_amaster, int *_aslave, char *_name,
                     struct termios *_termp, struct winsize *_winp);
 int    forkpty (int *_amaster, char *_name,
                     struct termios *_termp, struct winsize *_winp);
                     struct termios *_termp, struct winsize *_winp);
 int    forkpty (int *_amaster, char *_name,
                     struct termios *_termp, struct winsize *_winp);
+int    humanize_number(char *_buf, size_t _len, int64_t _number, 
+               const char *_suffix, int _scale, int _flags); 
 const char *uu_lockerr (int _uu_lockresult);
 int    uu_lock (const char *_ttyname);
 int    uu_unlock (const char *_ttyname);
 const char *uu_lockerr (int _uu_lockresult);
 int    uu_lock (const char *_ttyname);
 int    uu_unlock (const char *_ttyname);
@@ -100,4 +102,12 @@ __END_DECLS
 #define        FPARSELN_UNESCREST      0x08
 #define        FPARSELN_UNESCALL       0x0f
 
 #define        FPARSELN_UNESCREST      0x08
 #define        FPARSELN_UNESCALL       0x0f
 
+/* humanize_number(3) */ 
+#define HN_DECIMAL             0x01 
+#define HN_NOSPACE             0x02 
+#define HN_B                   0x04 
+#define HN_DIVISOR_1000                0x08 
+#define HN_GETSCALE            0x10 
+#define HN_AUTOSCALE           0x20 
+
 #endif /* !_LIBUTIL_H_ */
 #endif /* !_LIBUTIL_H_ */
index 6d94d1f..b37152c 100644 (file)
  *
  * @(#)logwtmp.c       8.1 (Berkeley) 6/4/93
  * $FreeBSD: src/lib/libutil/logwtmp.c,v 1.14 2000/01/15 03:26:54 shin Exp $
  *
  * @(#)logwtmp.c       8.1 (Berkeley) 6/4/93
  * $FreeBSD: src/lib/libutil/logwtmp.c,v 1.14 2000/01/15 03:26:54 shin Exp $
- * $DragonFly: src/lib/libutil/logwtmp.c,v 1.2 2003/06/17 04:26:52 dillon Exp $
+ * $DragonFly: src/lib/libutil/logwtmp.c,v 1.3 2004/11/05 17:05:26 dillon Exp $
  */
 
  */
 
+#include <sys/cdefs.h>
 #include <sys/param.h>
 #include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/types.h>
 #include <sys/file.h>
 #include <sys/file.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
 
 #include <libutil.h>
 #include <netdb.h>
 
 #include <libutil.h>
 #include <netdb.h>
+#include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
 #define        NI_WITHSCOPEID  0
 #endif
 
 #define        NI_WITHSCOPEID  0
 #endif
 
-void
-trimdomain(char *fullhost, int hostsize)
-{
-    static char domain[MAXHOSTNAMELEN];
-    static int first = 1;
-    static size_t dlen;
-    char *s, *end;
-    int spn, ok;
-
-    if (first) {
-        first = 0;
-        if (gethostname(domain, sizeof(domain) - 1) == 0 &&
-            (s = strchr(domain, '.')))
-            memmove(domain, s + 1, strlen(s + 1) + 1);
-        else
-            domain[0] = '\0';
-        dlen = strlen(domain);
-    }
-
-    if (domain[0] != '\0') {
-       s = fullhost;
-        end = s + hostsize + 1;
-       for (; (s = memchr(s, '.', end - s)) != NULL; s++)
-            if (!strncasecmp(s + 1, domain, dlen)) {
-                if (s[dlen + 1] == '\0') {
-                           *s = '\0';    /* Found - lose the domain */
-                    break;
-                } else if (s[dlen + 1] == ':') {       /* $DISPLAY ? */
-                    ok = dlen + 2;
-                    spn = strspn(s + ok, "0123456789");
-                    if (spn > 0 && ok + spn - dlen <= end - s) {
-                        ok += spn;
-                        if (s[ok] == '\0') {
-                            /* host.domain:nn */
-                            memmove(s, s + dlen + 1, ok - dlen);
-                            break;
-                        } else if (s[ok] == '.') {
-                            ok++;
-                            spn = strspn(s + ok, "0123456789");
-                            if (spn > 0 && s[ok + spn] == '\0' &&
-                                ok + spn - dlen <= end - s) {
-                                /* host.domain:nn.nn */
-                                memmove(s, s + dlen + 1, ok + spn - dlen);
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-    }
-}
-
-#include <stdio.h>
 
 void
 
 void
-logwtmp(line, name, host)
-       const char *line;
-       const char *name;
-       const char *host;
+logwtmp(const char *line, const char *name, const char *host)
 {
        struct utmp ut;
        struct stat buf;
 {
        struct utmp ut;
        struct stat buf;
diff --git a/lib/libutil/trimdomain.c b/lib/libutil/trimdomain.c
new file mode 100644 (file)
index 0000000..1739fdc
--- /dev/null
@@ -0,0 +1,117 @@
+/* $DragonFly: src/lib/libutil/trimdomain.c,v 1.1 2004/11/05 17:05:26 dillon Exp $ */
+/*
+ * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
+ *   Based on original work by Atsushi Murai <amurai@FreeBSD.org>
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/lib/libutil/trimdomain.c,v 1.5 2003/10/18 10:04:16 markm Exp $
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+#include <libutil.h>
+#include <string.h>
+#include <unistd.h>
+
+static int     isDISP(const char *);
+
+/*-
+ * Trim the current domain name from fullhost, but only if the result
+ * is less than or equal to hostsize in length.
+ *
+ * This function understands $DISPLAY type fullhosts.
+ *
+ * For example:
+ *
+ *     trimdomain("abcde.my.domain", 5)       ->   "abcde"
+ *     trimdomain("abcde.my.domain", 4)       ->   "abcde.my.domain"
+ *     trimdomain("abcde.my.domain:0.0", 9)   ->   "abcde:0.0"
+ *     trimdomain("abcde.my.domain:0.0", 8)   ->   "abcde.my.domain:0.0"
+ */
+void
+trimdomain(char *fullhost, int hostsize)
+{
+       static size_t dlen;
+       static int first = 1;
+       static char domain[MAXHOSTNAMELEN];
+       char *end, *s;
+       size_t len;
+
+       if (first) {
+               /* XXX: Should we assume that our domain is this persistent ? */
+               first = 0;
+               if (gethostname(domain, sizeof(domain) - 1) == 0 &&
+                   (s = strchr(domain, '.')) != NULL)
+                       memmove(domain, s + 1, strlen(s + 1) + 1);
+               else
+                       domain[0] = '\0';
+               dlen = strlen(domain);
+       }
+
+       if (domain[0] == '\0')
+               return;
+
+       s = fullhost;
+       end = s + hostsize + 1;
+       for (; (s = memchr(s, '.', (size_t)(end - s))) != NULL; s++) {
+               if (strncasecmp(s + 1, domain, dlen) == 0) {
+                       if (s[dlen + 1] == '\0') {
+                               /* Found -- lose the domain. */
+                               *s = '\0';
+                               break;
+                       } else if (s[dlen + 1] == ':' &&
+                           isDISP(s + dlen + 2) &&
+                           (len = strlen(s + dlen + 1)) < (size_t)(end - s)) {
+                               /* Found -- shuffle the DISPLAY back. */
+                               memmove(s, s + dlen + 1, len + 1);
+                               break;
+                       }
+               }
+       }
+}
+
+/*
+ * Is the given string NN or NN.NN where ``NN'' is an all-numeric string ?
+ */
+static int
+isDISP(const char *disp)
+{
+       size_t w;
+       int res;
+
+       w = strspn(disp, "0123456789");
+       res = 0;
+       if (w > 0) {
+               if (disp[w] == '\0')
+                       res = 1;        /* NN */
+               else if (disp[w] == '.') {
+                       disp += w + 1;
+                       w = strspn(disp, "0123456789");
+                       if (w > 0 && disp[w] == '\0')
+                               res = 1;        /* NN.NN */
+               }
+       }
+       return (res);
+}