[Libguestfs] [PATCH nbdkit 3/9] server: Add general replacements for missing functions using LIBOBJS.

Richard W.M. Jones
2020-08-18T10:50:07Z

Especially on Windows, some common functions are missing.  Use the
autoconf LIBOBJS mechanism to replace these functions.

This includes replacement functions for:

  Function names     Implementation   Origin

  getdelim, getline  general purpose  NetBSD under a compatible license

  openlog, syslog,   Win32            written by me
  vsyslog

  realpath           Win32            written by me

  strndup            general purpose  written by me

This should do nothing on existing supported platforms.  It is only
intended in preparation for porting nbdkit to Windows.
---
 configure.ac                            | 22 +++++++
 Makefile.am                             |  1 +
 common/replacements/Makefile.am         | 53 ++++++++++++++++
 common/replacements/win32/Makefile.am   | 46 ++++++++++++++
 server/Makefile.am                      |  3 +
 common/replacements/getline.h           | 50 +++++++++++++++
 common/replacements/realpath.h          | 50 +++++++++++++++
 common/replacements/strndup.h           | 49 +++++++++++++++
 common/replacements/syslog.h            | 67 ++++++++++++++++++++
 server/crypto.c                         |  2 +-
 server/log-syslog.c                     |  2 +-
 server/main.c                           |  9 +--
 server/public.c                         |  2 +
 common/replacements/getdelim.c          | 84 +++++++++++++++++++++++++
 common/replacements/getline.c           | 46 ++++++++++++++
 common/replacements/openlog.c           | 62 ++++++++++++++++++
 common/replacements/realpath.c          | 81 ++++++++++++++++++++++++
 common/replacements/strndup.c           | 64 +++++++++++++++++++
 common/replacements/syslog.c            | 62 ++++++++++++++++++
 common/replacements/vsyslog.c           | 74 ++++++++++++++++++++++
 common/replacements/win32/nbdkit-cat.mc |  6 ++
 .gitignore                              |  4 ++
 22 files changed, 833 insertions(+), 6 deletions(-)

diff --git a/configure.ac b/configure.ac
index 1ac0eab7..aa586997 100644
--- a/configure.ac
+++ b/configure.ac
@@ -337,6 +337,17 @@ AC_CHECK_FUNCS([\
 	ppoll \
 	posix_fadvise])

+dnl Replacement functions that we provide for some platforms.
+AC_CONFIG_LIBOBJ_DIR([common/replacements])
+AC_REPLACE_FUNCS([\
+	getdelim \
+	getline \
+	openlog \
+	realpath \
+	strndup \
+	syslog \
+	vsyslog])
+
 dnl Check whether printf("%m") works
 AC_CACHE_CHECK([whether the printf family supports %m],
   [nbdkit_cv_func_printf_percent_m],
@@ -464,6 +475,15 @@ AS_CASE([$host_os],
 AC_MSG_RESULT([$is_windows])
 AC_SUBST([NO_UNDEFINED_ON_WINDOWS])
 AC_SUBST([LINK_LIBNBDKIT_ON_WINDOWS])
+AM_CONDITIONAL([IS_WINDOWS],[test "x$is_windows" = "xyes"])
+
+dnl For Windows, look for the mc/windmc utility.
+dnl XXX Do we need to check for mc.exe as well?
+AS_IF([test "x$is_windows" = "xyes"],[
+    AC_CHECK_TOOLS([MC],[windmc mc],[no])
+    AS_IF([test "x$MC" = "xno"],
+          [AC_MSG_ERROR([mc/windmc utility must be available when compiling for
Windows])])
+])

 AC_SEARCH_LIBS([getaddrinfo], [network socket])

@@ -1107,6 +1127,8 @@ AC_CONFIG_FILES([Makefile
                  common/include/Makefile
                  common/protocol/Makefile
                  common/regions/Makefile
+                 common/replacements/Makefile
+                 common/replacements/win32/Makefile
                  common/utils/Makefile
                  docs/Makefile
                  include/Makefile
diff --git a/Makefile.am b/Makefile.am
index 0ca53d64..a9d6d164 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -74,6 +74,7 @@ SUBDIRS = \
 	include \
 	common/include \
 	common/protocol \
+	common/replacements \
 	common/utils \
 	server \
 	$(NULL)
diff --git a/common/replacements/Makefile.am b/common/replacements/Makefile.am
new file mode 100644
index 00000000..5051099a
--- /dev/null
+++ b/common/replacements/Makefile.am
@@ -0,0 +1,53 @@
+# nbdkit
+# Copyright (C) 2019 Red Hat Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * 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.
+#
+# * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+
+include $(top_srcdir)/common-rules.mk
+
+SUBDIRS = win32
+
+noinst_LTLIBRARIES = libcompat.la
+# sources should be empty
+libcompat_la_SOURCES +libcompat_la_LIBADD = $(LTLIBOBJS)
+
+EXTRA_DIST = \
+	getdelim.c \
+	getline.c \
+	getline.h \
+	openlog.c \
+	realpath.c \
+	realpath.h \
+	strndup.c \
+	strndup.h \
+	syslog.c \
+	syslog.h \
+	vsyslog.c
diff --git a/common/replacements/win32/Makefile.am
b/common/replacements/win32/Makefile.am
new file mode 100644
index 00000000..f4ec025b
--- /dev/null
+++ b/common/replacements/win32/Makefile.am
@@ -0,0 +1,46 @@
+# nbdkit
+# Copyright (C) 2019 Red Hat Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * 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.
+#
+# * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+
+include $(top_srcdir)/common-rules.mk
+
+EXTRA_DIST = nbdkit-cat.mc
+
+if IS_WINDOWS
+
+# Build the message catalog.
+noinst_DATA = MSG00001.bin nbdkit-cat.h nbdkit-cat.rc
+
+$(noinst_DATA): nbdkit-cat.mc
+	rm -f $@
+	$(MC) $<
+
+endif
diff --git a/server/Makefile.am b/server/Makefile.am
index 8cfa0115..0b693f21 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -88,6 +88,7 @@ libnbdkit_la_CPPFLAGS = \
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/common/include \
 	-I$(top_srcdir)/common/protocol \
+	-I$(top_srcdir)/common/replacements \
 	-I$(top_srcdir)/common/utils \
 	$(NULL)
 libnbdkit_la_CFLAGS = \
@@ -103,6 +104,7 @@ libnbdkit_la_LIBADD = \
 	$(DL_LIBS) \
 	$(top_builddir)/common/protocol/libprotocol.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/replacements/libcompat.la \
 	$(NULL)
 libnbdkit_la_LDFLAGS = \
 	-shared $(NO_UNDEFINED_ON_WINDOWS) \
@@ -152,6 +154,7 @@ test_public_CPPFLAGS = \
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/common/include \
 	-I$(top_srcdir)/common/protocol \
+	-I$(top_srcdir)/common/replacements \
 	-I$(top_srcdir)/common/utils \
 	$(NULL)
 test_public_CFLAGS = $(WARNINGS_CFLAGS) $(VALGRIND_CFLAGS)
diff --git a/common/replacements/getline.h b/common/replacements/getline.h
new file mode 100644
index 00000000..a9e1024a
--- /dev/null
+++ b/common/replacements/getline.h
@@ -0,0 +1,50 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+#ifndef NBDKIT_GETLINE_H
+#define NBDKIT_GETLINE_H
+
+#include <config.h>
+
+#ifdef HAVE_GETLINE
+
+#include <stdio.h>
+
+#else
+
+ssize_t getline (char **lineptr, size_t *n, FILE *stream);
+ssize_t getdelim (char **lineptr, size_t *n, int delim, FILE *stream);
+
+#endif
+
+#endif /* NBDKIT_GETLINE_H */
diff --git a/common/replacements/realpath.h b/common/replacements/realpath.h
new file mode 100644
index 00000000..14fee810
--- /dev/null
+++ b/common/replacements/realpath.h
@@ -0,0 +1,50 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+#ifndef NBDKIT_REALPATH_H
+#define NBDKIT_REALPATH_H
+
+#include <config.h>
+
+#ifdef HAVE_REALPATH
+
+#include <limits.h>
+#include <stdlib.h>
+
+#else
+
+char *realpath (const char *path, char *out);
+
+#endif
+
+#endif /* NBDKIT_REALPATH_H */
diff --git a/common/replacements/strndup.h b/common/replacements/strndup.h
new file mode 100644
index 00000000..464ce954
--- /dev/null
+++ b/common/replacements/strndup.h
@@ -0,0 +1,49 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+#ifndef NBDKIT_STRNDUP_H
+#define NBDKIT_STRNDUP_H
+
+#include <config.h>
+
+#ifdef HAVE_STRNDUP
+
+#include <string.h>
+
+#else
+
+char *strndup(const char *s, size_t n);
+
+#endif
+
+#endif /* NBDKIT_STRNDUP_H */
diff --git a/common/replacements/syslog.h b/common/replacements/syslog.h
new file mode 100644
index 00000000..e4d76677
--- /dev/null
+++ b/common/replacements/syslog.h
@@ -0,0 +1,67 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+/* Replacement for syslog for platforms which lack it.  Note this only
+ * implements "just enough syslog" for nbdkit.  It's not a
general
+ * replacement.
+ */
+
+#ifndef NBDKIT_SYSLOG_H
+#define NBDKIT_SYSLOG_H
+
+#include <config.h>
+
+#ifdef HAVE_SYSLOG_H
+
+#include_next <syslog.h>
+
+#else
+
+#include <stdarg.h>
+
+/* Since the replacement function ignores the priority field, we only
+ * need to define these to any integer.
+ */
+#define LOG_PID 0
+#define LOG_ERR 0
+#define LOG_DAEMON 0
+
+extern void openlog (const char *ident, int option, int facility);
+extern void syslog (int pri, const char *fmt, ...)
+  __attribute__ ((format (printf, 2, 3)));
+extern void vsyslog (int pri, const char *fmt, va_list args)
+  __attribute__ ((format (printf, 2, 0)));
+
+#endif /* !HAVE_SYSLOG_H */
+
+#endif /* NBDKIT_SYSLOG_H */
diff --git a/server/crypto.c b/server/crypto.c
index d291f4e7..0d3d4e8c 100644
--- a/server/crypto.c
+++ b/server/crypto.c
@@ -41,12 +41,12 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <limits.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <assert.h>

 #include "internal.h"
+#include "realpath.h"

 #ifdef HAVE_GNUTLS

diff --git a/server/log-syslog.c b/server/log-syslog.c
index fdac45f1..6e9a1bfd 100644
--- a/server/log-syslog.c
+++ b/server/log-syslog.c
@@ -37,9 +37,9 @@
 #include <stdarg.h>
 #include <string.h>
 #include <errno.h>
-#include <syslog.h>

 #include "internal.h"
+#include "syslog.h"

 /* Tempted to use LOG_FTP instead of LOG_DAEMON! */
 static const int PRIORITY = LOG_DAEMON|LOG_ERR;
diff --git a/server/main.c b/server/main.c
index bb7f863e..a96ac88b 100644
--- a/server/main.c
+++ b/server/main.c
@@ -42,7 +42,6 @@
 #include <limits.h>
 #include <errno.h>
 #include <assert.h>
-#include <syslog.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
@@ -60,11 +59,13 @@
 #include <dlfcn.h>

 #include "ascii-string.h"
-
-#include "internal.h"
+#include "exit-with-parent.h"
 #include "nbd-protocol.h"
+#include "strndup.h"
+#include "syslog.h"
+
+#include "internal.h"
 #include "options.h"
-#include "exit-with-parent.h"

 #ifdef ENABLE_LIBFUZZER
 #define main fuzzer_main
diff --git a/server/public.c b/server/public.c
index d10d466e..1f7e1af0 100644
--- a/server/public.c
+++ b/server/public.c
@@ -54,6 +54,8 @@
 #include "ascii-ctype.h"
 #include "ascii-string.h"
 #include "get-current-dir-name.h"
+#include "getline.h"
+#include "realpath.h"

 #include "internal.h"

diff --git a/common/replacements/getdelim.c b/common/replacements/getdelim.c
new file mode 100644
index 00000000..97421cb5
--- /dev/null
+++ b/common/replacements/getdelim.c
@@ -0,0 +1,84 @@
+/*	$NetBSD: getdelim.c,v 1.2 2015/12/25 20:12:46 joerg Exp $	*/
+/*	NetBSD-src: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp 	*/
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef HAVE_GETDELIM
+
+#include "getline.h"
+
+ssize_t
+getdelim (char **buf, size_t *bufsiz, int delimiter, FILE *fp)
+{
+  char *ptr, *eptr;
+
+  if (*buf == NULL || *bufsiz == 0) {
+    *bufsiz = BUFSIZ;
+    if ((*buf = malloc (*bufsiz)) == NULL)
+      return -1;
+  }
+
+  for (ptr = *buf, eptr = *buf + *bufsiz;;) {
+    int c = fgetc (fp);
+    if (c == -1) {
+      if (feof (fp)) {
+        ssize_t diff = (ssize_t)(ptr - *buf);
+        if (diff != 0) {
+          *ptr = '\0';
+          return diff;
+        }
+      }
+      return -1;
+    }
+    *ptr++ = c;
+    if (c == delimiter) {
+      *ptr = '\0';
+      return ptr - *buf;
+    }
+    if (ptr + 2 >= eptr) {
+      char *nbuf;
+      size_t nbufsiz = *bufsiz * 2;
+      ssize_t d = ptr - *buf;
+      if ((nbuf = realloc (*buf, nbufsiz)) == NULL)
+        return -1;
+      *buf = nbuf;
+      *bufsiz = nbufsiz;
+      eptr = nbuf + nbufsiz;
+      ptr = nbuf + d;
+    }
+  }
+}
+
+#endif
diff --git a/common/replacements/getline.c b/common/replacements/getline.c
new file mode 100644
index 00000000..e9caf496
--- /dev/null
+++ b/common/replacements/getline.c
@@ -0,0 +1,46 @@
+/*	$NetBSD: getline.c,v 1.2 2015/12/25 20:12:46 joerg Exp $	*/
+/*	NetBSD-src: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp	*/
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+
+#ifndef HAVE_GETLINE
+
+#include "getline.h"
+
+ssize_t
+getline (char **buf, size_t *bufsiz, FILE *fp)
+{
+  return getdelim (buf, bufsiz, '\n', fp);
+}
+
+#endif
diff --git a/common/replacements/openlog.c b/common/replacements/openlog.c
new file mode 100644
index 00000000..2f601655
--- /dev/null
+++ b/common/replacements/openlog.c
@@ -0,0 +1,62 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifndef HAVE_OPENLOG_H
+
+#include "syslog.h"
+
+#ifdef WIN32
+
+/* Replacement openlog for Win32. */
+
+#include <windows.h>
+
+HANDLE event_source = INVALID_HANDLE_VALUE;
+
+void
+openlog (const char *ident, int option, int facility)
+{
+  event_source = RegisterEventSource (NULL, ident);
+}
+
+#else /* !WIN32 */
+#error "no replacement openlog is available on this platform"
+#endif
+
+#endif /* !HAVE_SYSLOG_H */
diff --git a/common/replacements/realpath.c b/common/replacements/realpath.c
new file mode 100644
index 00000000..622ee7ea
--- /dev/null
+++ b/common/replacements/realpath.c
@@ -0,0 +1,81 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+/* Replacement for realpath for platforms which lack this function. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifndef HAVE_REALPATH
+
+#include "realpath.h"
+
+#ifdef WIN32
+
+/* Replacement realpath for Win32.
+ *
+ * Note this is not thread-safe, but should be fine for all the
+ * uses in the server and ordinary plugins.
+ */
+
+#include <windows.h>
+
+char *
+realpath (const char *path, char *out)
+{
+  TCHAR buf[MAX_PATH];
+  int r;
+
+  r = GetFullPathNameA (path, MAX_PATH, buf, NULL);
+  if (r == 0) {
+    errno = GetLastError ();
+    return NULL;
+  }
+
+  out = malloc (r + 1);
+  if (out == NULL)
+    return NULL;
+  memcpy (out, buf, r);
+  out[r] = '\0';
+
+  return out;
+}
+
+#else /* !WIN32 */
+#error "no replacement realpath is available on this platform"
+#endif
+
+#endif /* !HAVE_REALPATH */
diff --git a/common/replacements/strndup.c b/common/replacements/strndup.c
new file mode 100644
index 00000000..de1c27c2
--- /dev/null
+++ b/common/replacements/strndup.c
@@ -0,0 +1,64 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+/* Replacement for strndup for platforms which lack this function. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef HAVE_STRNDUP
+
+#include "strndup.h"
+
+char *
+strndup(const char *s, size_t n)
+{
+  size_t len = strlen (s);
+  char *ret;
+
+  if (len > n)
+    len = n;
+
+  ret = malloc (len+1);
+  if (ret == NULL)
+    return NULL;
+  memcpy (ret, s, len);
+  ret[len] = '\0';
+
+  return ret;
+}
+
+#endif /* !HAVE_STRNDUP */
diff --git a/common/replacements/syslog.c b/common/replacements/syslog.c
new file mode 100644
index 00000000..6f41cbd8
--- /dev/null
+++ b/common/replacements/syslog.c
@@ -0,0 +1,62 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifndef HAVE_SYSLOG_H
+
+#include "syslog.h"
+
+#ifdef WIN32
+
+/* Replacement syslog for Win32. */
+
+void
+syslog (int pri, const char *fmt, ...)
+{
+  va_list args;
+
+  va_start (args, fmt);
+  vsyslog (pri, fmt, args);
+  va_end (args);
+}
+
+#else /* !WIN32 */
+#error "no replacement syslog is available on this platform"
+#endif
+
+#endif /* !HAVE_SYSLOG_H */
diff --git a/common/replacements/vsyslog.c b/common/replacements/vsyslog.c
new file mode 100644
index 00000000..331aba0f
--- /dev/null
+++ b/common/replacements/vsyslog.c
@@ -0,0 +1,74 @@
+/* nbdkit
+ * Copyright (C) 2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of Red Hat 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 RED HAT 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 RED HAT 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifndef HAVE_SYSLOG_H
+
+#include "syslog.h"
+
+#ifdef WIN32
+
+/* Replacement vsyslog for Win32. */
+
+#include <windows.h>
+
+#include "win32/nbdkit-cat.h"
+
+extern HANDLE event_source;
+
+void
+vsyslog (int pri, const char *fmt, va_list args)
+{
+  char *str;
+  const char *strs[1];
+
+  if (vasprintf (&str, fmt, args) == -1)
+    return;
+  strs[0] = str;
+
+  ReportEventA (event_source, EVENTLOG_ERROR_TYPE, 0,
+                NBDKIT_SYSLOG_ERROR, NULL, 1, 0, strs, NULL);
+
+  free (str);
+}
+
+#else /* !WIN32 */
+#error "no replacement vsyslog is available on this platform"
+#endif
+
+#endif /* !HAVE_SYSLOG_H */
diff --git a/common/replacements/win32/nbdkit-cat.mc
b/common/replacements/win32/nbdkit-cat.mc
new file mode 100644
index 00000000..687a835d
--- /dev/null
+++ b/common/replacements/win32/nbdkit-cat.mc
@@ -0,0 +1,6 @@
+MessageId=1
+Severity=Error
+SymbolicName=NBDKIT_SYSLOG_ERROR
+Language=English
+%1
+.
diff --git a/.gitignore b/.gitignore
index 2c463909..ca36d9c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,6 +46,10 @@ plugins/*/*.3
 /common/include/test-tvdiff
 /common/protocol/generate-protostrings.sh
 /common/protocol/protostrings.c
+/common/replacements/libcompat.a
+/common/replacements/win32/MSG00001.bin
+/common/replacements/win32/nbdkit-cat.h
+/common/replacements/win32/nbdkit-cat.rc
 /common/utils/test-quotes
 /common/utils/test-vector
 /compile
--
2.27.0