summaryrefslogtreecommitdiffstats
path: root/replace
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 06:40:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 06:40:13 +0000
commite9be59e1502a41bab9891d96d753102a7dafef0b (patch)
treec3b2da87c414881f4b53d0964f407c83492d813e /replace
parentInitial commit. (diff)
downloadcluster-glue-upstream.tar.xz
cluster-glue-upstream.zip
Adding upstream version 1.0.12.upstream/1.0.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'replace')
-rw-r--r--replace/Makefile.am29
-rw-r--r--replace/NoSuchFunctionName.c31
-rw-r--r--replace/alphasort.c53
-rw-r--r--replace/daemon.c83
-rw-r--r--replace/inet_pton.c245
-rw-r--r--replace/scandir.c236
-rw-r--r--replace/setenv.c50
-rw-r--r--replace/strerror.c37
-rw-r--r--replace/strlcat.c33
-rw-r--r--replace/strlcpy.c32
-rw-r--r--replace/strndup.c38
-rw-r--r--replace/strnlen.c31
-rw-r--r--replace/unsetenv.c51
-rw-r--r--replace/uuid_parse.c519
14 files changed, 1468 insertions, 0 deletions
diff --git a/replace/Makefile.am b/replace/Makefile.am
new file mode 100644
index 0000000..52892ba
--- /dev/null
+++ b/replace/Makefile.am
@@ -0,0 +1,29 @@
+#
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
+ -I$(top_srcdir)/linux-ha -I$(top_builddir)/linux-ha
+
+QUIET_LIBTOOL_OPTS = @QUIET_LIBTOOL_OPTS@
+LIBTOOL = @LIBTOOL@ @QUIET_LIBTOOL_OPTS@
+
+
+noinst_LTLIBRARIES = libreplace.la
+libreplace_la_SOURCES =
+libreplace_la_LIBADD = @LTLIBOBJS@
diff --git a/replace/NoSuchFunctionName.c b/replace/NoSuchFunctionName.c
new file mode 100644
index 0000000..373eabd
--- /dev/null
+++ b/replace/NoSuchFunctionName.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2002 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+void nosuchfunctionname(void);
+
+/*
+ * This is a completely useless function put here only to make OpenBSD make
+ * procedures happy. I hope no one ever makes such a function ;-)
+ */
+void
+nosuchfunctionname(void)
+{
+ return;
+}
diff --git a/replace/alphasort.c b/replace/alphasort.c
new file mode 100644
index 0000000..94cd811
--- /dev/null
+++ b/replace/alphasort.c
@@ -0,0 +1,53 @@
+/*
+ *
+ * alphasort - replacement for alphasort functions.
+ *
+ * Matt Soffen
+
+ * Copyright (C) 2001 Matt Soffen <matt@soffen.com>
+ *
+ * Taken from the FreeBSD file (with copyright notice)
+ * /usr/src/gnu/lib/libdialog/dir.c
+ ***************************************************************************
+ * Program: dir.c
+ * Author: Marc van Kempen
+ * desc: Directory routines, sorting and reading
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ ***************************************************************************
+ */
+
+#include <lha_internal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <unistd.h> /* XXX for _POSIX_VERSION ifdefs */
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#if !defined sgi && !defined _POSIX_VERSION
+#include <sys/dir.h>
+#endif
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+int alphasort(const void *dirent1, const void *dirent2) {
+ return(strcmp((*(const struct dirent **)dirent1)->d_name,
+ (*(const struct dirent **)dirent2)->d_name));
+}
diff --git a/replace/daemon.c b/replace/daemon.c
new file mode 100644
index 0000000..7697113
--- /dev/null
+++ b/replace/daemon.c
@@ -0,0 +1,83 @@
+/*-
+ *
+ * daemon - replacement for daemon function.
+ *
+ * Matt Soffen
+ * Copyright (C) 2004 Matt Soffen <matt@soffen.com>
+ *
+ * Taken from the FreeBSD file (with copyright notice)
+ * ------------------------------------------------------------
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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: src/lib/libc/gen/daemon.c,v 1.3 2000/01/27 23:06:14 jasone Exp $
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <lha_internal.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+daemon(nochdir, noclose)
+ int nochdir, noclose;
+{
+ int fd;
+
+ switch (fork()) {
+ case -1:
+ return (-1);
+ case 0:
+ break;
+ default:
+ exit(0);
+ }
+
+ if (setsid() == -1)
+ return (-1);
+
+ if (!nochdir)
+ (void)chdir("/");
+
+ if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)dup2(fd, STDOUT_FILENO);
+ (void)dup2(fd, STDERR_FILENO);
+ if (fd > 2)
+ (void)close(fd);
+ }
+ return (0);
+}
diff --git a/replace/inet_pton.c b/replace/inet_pton.c
new file mode 100644
index 0000000..f5aa93b
--- /dev/null
+++ b/replace/inet_pton.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/* Chris Wright <chris@wirex.com> June 22, 2001
+ * Merged contents of inet_pton.c from Apache2.0.16 and BIND8
+ * The Apache base is more portable within heartbeat's envrionment,
+ * however, the BIND8 version has two small logic changes that are
+ * newer.
+ */
+
+#include <lha_internal.h>
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#ifndef IN6ADDRSZ
+#define IN6ADDRSZ 16
+#endif
+
+#ifndef INT16SZ
+#define INT16SZ sizeof(short)
+#endif
+
+#ifndef INADDRSZ
+#define INADDRSZ 4
+#endif
+
+#ifndef __P
+#define __P(x) x
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4 __P((const char *src, unsigned char *dst));
+#if HAVE_IPV6
+static int inet_pton6 __P((const char *src, unsigned char *dst));
+#endif
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+inet_pton(int af, const char *src, void *dst)
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+#if HAVE_IPV6
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+#endif
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst)
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ unsigned int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+
+ memcpy(dst, tmp, INADDRSZ);
+ return (1);
+}
+
+#if HAVE_IPV6
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst)
+{
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ unsigned int val;
+
+ memset((tp = tmp), '\0', IN6ADDRSZ);
+ endp = tp + IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ } else if (*src == '\0') {
+ return (0);
+ }
+ if (tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ if (tp == endp)
+ return (0);
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, IN6ADDRSZ);
+ return (1);
+}
+#endif /* HAVE_IPV6 */
diff --git a/replace/scandir.c b/replace/scandir.c
new file mode 100644
index 0000000..528f544
--- /dev/null
+++ b/replace/scandir.c
@@ -0,0 +1,236 @@
+/* scandir: Scan a directory, collecting all (selected) items into a an array.
+ *
+ * This code borrowed from 'libit', which can be found here:
+ *
+ * http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/
+ *
+ * The original author put this code in the public domain.
+ * It has been modified slightly to get rid of warnings, etc.
+ *
+ * Below is the email I received from pinard@iro.umontreal.ca (François Pinard)
+ * when I sent him an email asking him about the license, etc. of this
+ * code which I obtained from his site.
+ *
+ * I think the correct spelling of his name is Rich Salz. I think he's now
+ * rsalz@datapower.com...
+ * --
+ * Rich Salz, Chief Security Architect
+ * DataPower Technology http://www.datapower.com
+ * XS40 XML Security Gateway http://www.datapower.com/products/xs40.html
+ *
+ * Copyright(C): none (public domain)
+ * License: none (public domain)
+ * Author: Rich Salz <rsalz@datapower.com>
+ *
+ *
+ *
+ * -- Alan Robertson
+ * alanr@unix.sh
+ *
+ **************************************************************************
+ *
+ * Subject: Re: Scandir replacement function
+ * Date: 18 May 2001 12:00:48 -0400
+ * From: pinard@iro.umontreal.ca (François Pinard)
+ * To: Alan Robertson <alanr@unix.sh>
+ * References: 1
+ *
+ *
+ * [Alan Robertson]
+ *
+ * > Hi, I'd like to use your scandir replacement function found here:
+ * > http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/ But, it does
+ * > not indicate authorship or licensing terms in it. Could you tell me
+ * > who wrote this code, under what license you distribute it, and whether
+ * > and under what terms I may further distribute it?
+ *
+ * Hello, Alan. These are (somewhat) explained in UNSHAR.HDR found in the
+ * same directory. The routines have been written by Rick Saltz (I'm not
+ * completely sure of the spelling) a long while ago. I think that nowadays,
+ * Rick is better known as the main author of the nice INN package.
+ *
+ **************************************************************************
+ *
+ * I spent a little time verifying this with Rick Salz.
+ * The results are below:
+ *
+ **************************************************************************
+ *
+ * Date: Tue, 20 Sep 2005 21:52:09 -0400 (EDT)
+ * From: Rich Salz <rsalz@datapower.com>
+ * To: Alan Robertson <alanr@unix.sh>
+ * Subject: Re: Verifying permissions/licenses/etc on some old code of yours -
+ * scandir.c
+ * In-Reply-To: <433071CA.8000107@unix.sh>
+ * Message-ID: <Pine.LNX.4.44L0.0509202151270.9198-100000@smtp.datapower.com>
+ * Content-Type: TEXT/PLAIN; charset=US-ASCII
+ *
+ * yes, it's most definitely in the public domain.
+ *
+ * I'm glad you find it useful. I'm surprised it hasn't been replaced by,
+ * e.g,. something in GLibC. Ii'm impressed you tracked me down.
+ *
+ * /r$
+ *
+ * --
+ * Rich Salz Chief Security Architect
+ * DataPower Technology http://www.datapower.com
+ * XS40 XML Security Gateway http://www.datapower.com/products/xs40.html
+ * ---------------------------------------------------------------------->
+ * Subject: scandir, ftw REDUX
+ * Date: 1 Jan 88 00:47:01 GMT
+ * From: rsalz@pebbles.bbn.com
+ * Newsgroups: comp.sources.misc
+ *
+ *
+ * Forget my previous message -- I just decided for completeness's sake to
+ * implement the SysV ftw(3) routine, too.
+ *
+ * To repeat, these are public-domain implementations of the SystemV ftw()
+ * routine, the BSD scandir() and alphasort() routines, and documentation for
+ * same. The FTW manpage could be more readable, but so it goes.
+ *
+ * Anyhow, feel free to post these, and incorporate them into your existing
+ * packages. I have readdir() routiens for MSDOS and the Amiga if anyone
+ * wants them, and should have them for VMS by the end of January; let me
+ * know if you want copies.
+ *
+ * Yours in filesystems,
+ * /r$
+ *
+ * Anyhow, feel free to post
+ * ----------------------------------------------------------------------<
+ *
+ */
+
+#include <lha_internal.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#ifndef NULL
+# define NULL ((void *) 0)
+#endif
+
+/* Initial guess at directory allocated. */
+#define INITIAL_ALLOCATION 20
+
+int
+scandir (const char *directory_name,
+ struct dirent ***array_pointer,
+ int (*select_function) (const struct dirent *),
+
+#ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT
+ /* This is what the Linux man page says */
+ int (*compare_function) (const struct dirent**, const struct dirent**)
+#else
+ /* This is what the Linux header file says ... */
+ int (*compare_function) (const void *, const void *)
+#endif
+ );
+
+int
+scandir (const char *directory_name,
+ struct dirent ***array_pointer,
+ int (*select_function) (const struct dirent *),
+#ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT
+ /* This is what the linux man page says */
+ int (*compare_function) (const struct dirent**, const struct dirent**)
+#else
+ /* This is what the linux header file says ... */
+ int (*compare_function) (const void *, const void *)
+#endif
+ )
+{
+ DIR *directory;
+ struct dirent **array;
+ struct dirent *entry;
+ struct dirent *copy;
+ int allocated = INITIAL_ALLOCATION;
+ int counter = 0;
+
+ /* Get initial list space and open directory. */
+
+ if (directory = opendir (directory_name), directory == NULL)
+ return -1;
+
+ if (array = (struct dirent **) malloc (allocated * sizeof (struct dirent *)),
+ array == NULL)
+ return -1;
+
+ /* Read entries in the directory. */
+
+ while (entry = readdir (directory), entry)
+ if (select_function == NULL || (*select_function) (entry))
+ {
+ /* User wants them all, or he wants this one. Copy the entry. */
+
+ /*
+ * On some OSes the declaration of "entry->d_name" is a minimal-length
+ * placeholder. Example: Solaris:
+ * /usr/include/sys/dirent.h:
+ * "char d_name[1];"
+ * man page "dirent(3)":
+ * The field d_name is the beginning of the character array
+ * giving the name of the directory entry. This name is
+ * null terminated and may have at most MAXNAMLEN chars.
+ * So our malloc length may need to be increased accordingly.
+ * sizeof(entry->d_name): space (possibly minimal) in struct.
+ * strlen(entry->d_name): actual length of the entry.
+ *
+ * John Kavadias <john_kavadias@hotmail.com>
+ * David Lee <t.d.lee@durham.ac.uk>
+ */
+ int namelength = strlen(entry->d_name) + 1; /* length with NULL */
+ int extra = 0;
+
+ if (sizeof(entry->d_name) <= namelength) {
+ /* allocated space <= required space */
+ extra += namelength - sizeof(entry->d_name);
+ }
+
+ if (copy = (struct dirent *) malloc (sizeof (struct dirent) + extra),
+ copy == NULL)
+ {
+ closedir (directory);
+ free (array);
+ return -1;
+ }
+ copy->d_ino = entry->d_ino;
+ copy->d_reclen = entry->d_reclen;
+ strcpy (copy->d_name, entry->d_name);
+
+ /* Save the copy. */
+
+ if (counter + 1 == allocated)
+ {
+ allocated <<= 1;
+ array = (struct dirent **)
+ realloc ((char *) array, allocated * sizeof (struct dirent *));
+ if (array == NULL)
+ {
+ closedir (directory);
+ free (array);
+ free (copy);
+ return -1;
+ }
+ }
+ array[counter++] = copy;
+ }
+
+ /* Close things off. */
+
+ array[counter] = NULL;
+ *array_pointer = array;
+ closedir (directory);
+
+ /* Sort? */
+
+ if (counter > 1 && compare_function)
+ qsort ((char *) array, counter, sizeof (struct dirent *)
+ , (int (*)(const void *, const void *))(compare_function));
+
+ return counter;
+}
diff --git a/replace/setenv.c b/replace/setenv.c
new file mode 100644
index 0000000..e8cafb1
--- /dev/null
+++ b/replace/setenv.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2001 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <lha_internal.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+ * Small replacement function for setenv()
+ */
+int
+setenv(const char *name, const char * value, int why)
+{
+ int rc = -1;
+
+ if ( name && value ) {
+ char * envp = NULL;
+ envp = malloc(strlen(name)+strlen(value)+2);
+ if (envp) {
+ /*
+ * Unfortunately, the putenv API guarantees memory leaks when
+ * changing environment variables repeatedly... :-(
+ */
+
+ sprintf(envp, "%s=%s", name, value);
+
+ /* Cannot free envp (!) */
+ rc = putenv(envp);
+ }
+
+ }
+ return(rc);
+}
diff --git a/replace/strerror.c b/replace/strerror.c
new file mode 100644
index 0000000..477239f
--- /dev/null
+++ b/replace/strerror.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2002 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <lha_internal.h>
+#include <errno.h>
+#include <stdio.h>
+extern const char * sys_err[];
+extern int sys_nerr;
+char *
+strerror(int errnum)
+{
+ static char whaterr[32];
+
+ if (errnum < 0) {
+ return "negative errno";
+ }
+ if (errnum >= sys_nerr) {
+ snprintf(whaterr, sizeof(whaterr),"error %d", errnum);
+ return whaterr;
+ }
+ return sys_err[sys_nerr];
+}
diff --git a/replace/strlcat.c b/replace/strlcat.c
new file mode 100644
index 0000000..8b909f9
--- /dev/null
+++ b/replace/strlcat.c
@@ -0,0 +1,33 @@
+#include <lha_internal.h>
+#include <string.h>
+/*
+ * Copyright (C) 2007 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+size_t
+strlcat(char *dest, const char * src, size_t maxlen)
+{
+ size_t curlen = strlen(dest);
+ size_t addlen = strlen(src);
+ size_t appendlen = (maxlen-1) - curlen;
+ if (appendlen > 0) {
+ strlcpy(dest+curlen, src, maxlen-curlen);
+ }
+ return curlen + addlen;
+}
diff --git a/replace/strlcpy.c b/replace/strlcpy.c
new file mode 100644
index 0000000..661d02e
--- /dev/null
+++ b/replace/strlcpy.c
@@ -0,0 +1,32 @@
+#include <lha_internal.h>
+#include <string.h>
+/*
+ * Copyright (C) 2007 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+size_t
+strlcpy(char *dest, const char * src, size_t maxlen)
+{
+ size_t srclen = strlen(src);
+ if (maxlen > 0) {
+ strncpy(dest, src, maxlen);
+ dest[maxlen-1]=EOS;
+ }
+ return srclen;
+}
diff --git a/replace/strndup.c b/replace/strndup.c
new file mode 100644
index 0000000..4312743
--- /dev/null
+++ b/replace/strndup.c
@@ -0,0 +1,38 @@
+#include <lha_internal.h>
+#include <stdlib.h>
+#include <string.h>
+/*
+ * Copyright (C) 2004 Matt Soffen <sirgeek-ha@mrsucko.org>
+ * This software licensed under the GNU LGPL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* Taken from the GlibC implementation of strndup */
+
+char *strndup(const char *str, size_t len)
+{
+ size_t n = strnlen(str,len);
+ char *new = (char *) malloc (len+1);
+
+ if (NULL == new) {
+ return NULL;
+ }
+
+ new[n] = '\0';
+ return (char *)memcpy (new, str, len);
+}
+
diff --git a/replace/strnlen.c b/replace/strnlen.c
new file mode 100644
index 0000000..8b3bcd2
--- /dev/null
+++ b/replace/strnlen.c
@@ -0,0 +1,31 @@
+#include <lha_internal.h>
+#include <string.h>
+/*
+ * Copyright (C) 2003 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+size_t
+strnlen(const char *s, size_t maxlen)
+{
+ const char * eospos;
+
+ eospos = memchr(s, (int)'\0', maxlen);
+
+ return (eospos == NULL ? maxlen : (size_t)(eospos-s));
+}
diff --git a/replace/unsetenv.c b/replace/unsetenv.c
new file mode 100644
index 0000000..aeb84a3
--- /dev/null
+++ b/replace/unsetenv.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2001 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <lha_internal.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define __environ environ
+#ifndef HAVE_ENVIRON_DECL
+extern char **environ;
+#endif
+
+int
+unsetenv (const char *name)
+{
+ const size_t len = strlen (name);
+ char **ep;
+
+ for (ep = __environ; *ep; ++ep) {
+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=') {
+ /* Found it. */
+ /* Remove this pointer by moving later ones back. */
+ char **dp = ep;
+ do
+ dp[0] = dp[1];
+ while (*dp++);
+ /* Continue the loop in case NAME appears again. */
+ }
+ }
+ return 0;
+}
diff --git a/replace/uuid_parse.c b/replace/uuid_parse.c
new file mode 100644
index 0000000..beecac6
--- /dev/null
+++ b/replace/uuid_parse.c
@@ -0,0 +1,519 @@
+/*
+ * uuid: emulation of e2fsprogs interface if implementation lacking.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Original uuid implementation: copyright (C) Theodore Ts'o
+ *
+ * This importation into heartbeat:
+ * Copyright (C) 2004 David Lee <t.d.lee@durham.ac.uk>
+ *
+ */
+
+#include <lha_internal.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#include <replace_uuid.h>
+
+/*
+ * Local "replace" implementation of uuid functions.
+ */
+
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+/* UUID Variant definitions */
+#define UUID_VARIANT_NCS 0
+#define UUID_VARIANT_DCE 1
+#define UUID_VARIANT_MICROSOFT 2
+#define UUID_VARIANT_OTHER 3
+
+/* UUID Type definitions */
+#define UUID_TYPE_DCE_TIME 1
+#define UUID_TYPE_DCE_RANDOM 4
+
+
+
+/* For uuid_compare() */
+#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
+
+/************************************
+ * Private types
+ ************************************/
+
+#define longlong long long
+
+/*
+ * Offset between 15-Oct-1582 and 1-Jan-70
+ */
+#define TIME_OFFSET_HIGH 0x01B21DD2
+#define TIME_OFFSET_LOW 0x13814000
+
+#if (SIZEOF_INT == 4)
+typedef unsigned int __u32;
+#elif (SIZEOF_LONG == 4)
+typedef unsigned long __u32;
+#endif
+
+#if (SIZEOF_INT == 2)
+typedef int __s16;
+typedef unsigned int __u16;
+#elif (SIZEOF_SHORT == 2)
+typedef short __s16;
+typedef unsigned short __u16;
+#endif
+
+typedef unsigned char __u8;
+
+struct uuid {
+ __u32 time_low;
+ __u16 time_mid;
+ __u16 time_hi_and_version;
+ __u16 clock_seq;
+ __u8 node[6];
+};
+
+/************************************
+ * internal routines
+ ************************************/
+static void uuid_pack(const struct uuid *uu, uuid_t ptr)
+{
+ __u32 tmp;
+ unsigned char *out = ptr;
+
+ tmp = uu->time_low;
+ out[3] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[2] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[1] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[0] = (unsigned char) tmp;
+
+ tmp = uu->time_mid;
+ out[5] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[4] = (unsigned char) tmp;
+
+ tmp = uu->time_hi_and_version;
+ out[7] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[6] = (unsigned char) tmp;
+
+ tmp = uu->clock_seq;
+ out[9] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[8] = (unsigned char) tmp;
+
+ memcpy(out+10, uu->node, 6);
+}
+
+static void uuid_unpack(const uuid_t in, struct uuid *uu)
+{
+ const __u8 *ptr = in;
+ __u32 tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_low = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_mid = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_hi_and_version = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->clock_seq = tmp;
+
+ memcpy(uu->node, ptr, 6);
+}
+
+/************************************
+ * Main routines, except uuid_generate*()
+ ************************************/
+void
+uuid_clear(uuid_t uu)
+{
+ memset(uu, 0, 16);
+}
+
+int
+uuid_compare(const uuid_t uu1, const uuid_t uu2)
+{
+ struct uuid uuid1, uuid2;
+
+ uuid_unpack(uu1, &uuid1);
+ uuid_unpack(uu2, &uuid2);
+
+ UUCMP(uuid1.time_low, uuid2.time_low);
+ UUCMP(uuid1.time_mid, uuid2.time_mid);
+ UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
+ UUCMP(uuid1.clock_seq, uuid2.clock_seq);
+ return memcmp(uuid1.node, uuid2.node, 6);
+}
+
+void
+uuid_copy(uuid_t dst, const uuid_t src)
+{
+ unsigned char *cp1;
+ const unsigned char *cp2;
+ int i;
+
+ for (i=0, cp1 = dst, cp2 = src; i < 16; i++)
+ *cp1++ = *cp2++;
+}
+
+/* if uu is the null uuid, return 1 else 0 */
+int
+uuid_is_null(const uuid_t uu)
+{
+ const unsigned char *cp;
+ int i;
+
+ for (i=0, cp = uu; i < 16; i++)
+ if (*cp++)
+ return 0;
+ return 1;
+}
+
+/* 36byte-string=>uuid */
+int
+uuid_parse(const char *in, uuid_t uu)
+{
+ struct uuid uuid;
+ int i;
+ const char *cp;
+ char buf[3];
+
+ if (strlen(in) != 36)
+ return -1;
+ for (i=0, cp = in; i <= 36; i++,cp++) {
+ if ((i == 8) || (i == 13) || (i == 18) ||
+ (i == 23)) {
+ if (*cp == '-')
+ continue;
+ else
+ return -1;
+ }
+ if (i== 36)
+ if (*cp == 0)
+ continue;
+ if (!isxdigit((int) *cp))
+ return -1;
+ }
+ uuid.time_low = strtoul(in, NULL, 16);
+ uuid.time_mid = strtoul(in+9, NULL, 16);
+ uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
+ uuid.clock_seq = strtoul(in+19, NULL, 16);
+ cp = in+24;
+ buf[2] = 0;
+ for (i=0; i < 6; i++) {
+ buf[0] = *cp++;
+ buf[1] = *cp++;
+ uuid.node[i] = strtoul(buf, NULL, 16);
+ }
+
+ uuid_pack(&uuid, uu);
+ return 0;
+}
+
+/* uuid=>36byte-string-with-null */
+void
+uuid_unparse(const uuid_t uu, char *out)
+{
+ struct uuid uuid;
+
+ uuid_unpack(uu, &uuid);
+ sprintf(out,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+ uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+ uuid.node[0], uuid.node[1], uuid.node[2],
+ uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
+
+/************************************
+ * Main routines: uuid_generate*()
+ ************************************/
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_SRANDOM
+#define srand(x) srandom(x)
+#define rand() random()
+#endif
+
+static int get_random_fd(void)
+{
+ struct timeval tv;
+ static int fd = -2;
+ int i;
+
+ if (fd == -2) {
+ gettimeofday(&tv, 0);
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1)
+ fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
+ srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+ }
+ /* Crank the random number generator a few times */
+ gettimeofday(&tv, 0);
+ for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
+ rand();
+ return fd;
+}
+
+/*
+ * Generate a series of random bytes. Use /dev/urandom if possible,
+ * and if not, use srandom/random.
+ */
+static void get_random_bytes(void *buf, int nbytes)
+{
+ int i, n = nbytes, fd = get_random_fd();
+ int lose_counter = 0;
+ unsigned char *cp = (unsigned char *) buf;
+
+ if (fd >= 0) {
+ while (n > 0) {
+ i = read(fd, cp, n);
+ if (i <= 0) {
+ if (lose_counter++ > 16)
+ break;
+ continue;
+ }
+ n -= i;
+ cp += i;
+ lose_counter = 0;
+ }
+ }
+
+ /*
+ * We do this all the time, but this is the only source of
+ * randomness if /dev/random/urandom is out to lunch.
+ */
+ for (cp = buf, i = 0; i < nbytes; i++)
+ *cp++ ^= (rand() >> 7) & 0xFF;
+ return;
+}
+
+/*
+ * Get the ethernet hardware address, if we can find it...
+ */
+static int get_node_id(unsigned char *node_id)
+{
+#ifdef HAVE_NET_IF_H
+ int sd;
+ struct ifreq ifr, *ifrp;
+ struct ifconf ifc;
+ char buf[1024];
+ int n, i;
+ unsigned char *a;
+
+/*
+ * BSD 4.4 defines the size of an ifreq to be
+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+ * However, under earlier systems, sa_len isn't present, so the size is
+ * just sizeof(struct ifreq)
+ */
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+ sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif /* HAVE_SA_LEN*/
+
+ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (sd < 0) {
+ return -1;
+ }
+ memset(buf, 0, sizeof(buf));
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+ if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
+ close(sd);
+ return -1;
+ }
+ n = ifc.ifc_len;
+ for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
+ ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
+ strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
+#ifdef SIOCGIFHWADDR
+ if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+#else
+#ifdef SIOCGENADDR
+ if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) ifr.ifr_enaddr;
+#else
+ /*
+ * XXX we don't have a way of getting the hardware
+ * address
+ */
+ close(sd);
+ return 0;
+#endif /* SIOCGENADDR */
+#endif /* SIOCGIFHWADDR */
+ if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+ continue;
+ if (node_id) {
+ memcpy(node_id, a, 6);
+ close(sd);
+ return 1;
+ }
+ }
+ close(sd);
+#endif
+ return 0;
+}
+
+/* Assume that the gettimeofday() has microsecond granularity */
+#define MAX_ADJUSTMENT 10
+
+static int
+get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq)
+{
+ static int adjustment = 0;
+ static struct timeval last = {0, 0};
+ static __u16 clock_seq;
+ struct timeval tv;
+ unsigned longlong clock_reg;
+
+try_again:
+ gettimeofday(&tv, 0);
+ if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
+ get_random_bytes(&clock_seq, sizeof(clock_seq));
+ clock_seq &= 0x1FFF;
+ last = tv;
+ last.tv_sec--;
+ }
+ if ((tv.tv_sec < last.tv_sec) ||
+ ((tv.tv_sec == last.tv_sec) &&
+ (tv.tv_usec < last.tv_usec))) {
+ clock_seq = (clock_seq+1) & 0x1FFF;
+ adjustment = 0;
+ last = tv;
+ } else if ((tv.tv_sec == last.tv_sec) &&
+ (tv.tv_usec == last.tv_usec)) {
+ if (adjustment >= MAX_ADJUSTMENT)
+ goto try_again;
+ adjustment++;
+ } else {
+ adjustment = 0;
+ last = tv;
+ }
+
+ clock_reg = tv.tv_usec*10 + adjustment;
+ clock_reg += ((unsigned longlong) tv.tv_sec)*10000000;
+ clock_reg += (((unsigned longlong) 0x01B21DD2) << 32) + 0x13814000;
+
+ *clock_high = clock_reg >> 32;
+ *clock_low = clock_reg;
+ *ret_clock_seq = clock_seq;
+ return 0;
+}
+
+/* create a new uuid, based on randomness */
+void
+uuid_generate_random(uuid_t out)
+{
+ uuid_t buf;
+ struct uuid uu;
+
+ get_random_bytes(buf, sizeof(buf));
+ uuid_unpack(buf, &uu);
+
+ uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
+ uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
+ uuid_pack(&uu, out);
+}
+
+/* create a new uuid, based on time */
+static void
+uuid_generate_time(uuid_t out)
+{
+ static unsigned char node_id[6];
+ static int has_init = 0;
+ struct uuid uu;
+ __u32 clock_mid;
+
+ if (!has_init) {
+ if (get_node_id(node_id) <= 0) {
+ get_random_bytes(node_id, 6);
+ /*
+ * Set multicast bit, to prevent conflicts
+ * with IEEE 802 addresses obtained from
+ * network cards
+ */
+ node_id[0] |= 0x80;
+ }
+ has_init = 1;
+ }
+ get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
+ uu.clock_seq |= 0x8000;
+ uu.time_mid = (__u16) clock_mid;
+ uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
+ memcpy(uu.node, node_id, 6);
+ uuid_pack(&uu, out);
+}
+
+void
+uuid_generate(uuid_t out)
+{
+ if (get_random_fd() >= 0) {
+ uuid_generate_random(out);
+ }else{
+ uuid_generate_time(out);
+ }
+}