* Update configure.ac / Makefile.am to build for Windows using Cygwin.
* Update build.sh to build for Windows.
* Base port of the daemon.
* Include gnulib as a submodule.
--- /dev/null
+[submodule "gnulib"]
+ path = gnulib
+ url = git://git.savannah.gnu.org/gnulib.git
ACLOCAL_AMFLAGS = -I m4
AM_YFLAGS = -d
+if BUILD_WIN32
+pkgdatadir=$(datadir)
+pkglibdir=$(libdir)/plugins
+pkglocalstatedir=${localstatedir}
+else
+pkglocalstatedir=${localstatedir}/lib/${PACKAGE_NAME}
+endif
BUILT_SOURCES = \
src/libcollectdclient/collectd/lcc_features.h \
lib_LTLIBRARIES = libcollectdclient.la
+if BUILD_WIN32
+# TODO: Build all executables on Windows as well.
+sbin_PROGRAMS = \
+ collectd
+bin_PROGRAMS =
+else
sbin_PROGRAMS = \
collectd \
collectdmon
collectd-nagios \
collectd-tg \
collectdctl
+endif # BUILD_WIN32
-noinst_LTLIBRARIES = \
+EXTRA_LTLIBRARIES = \
libavltree.la \
libcmds.la \
libcommon.la \
-module \
-avoid-version \
-export-symbols-regex '\<module_register\>'
+if BUILD_WIN32
+PLUGIN_LDFLAGS += -shared -no-undefined -lcollectd -L.
+endif
AM_CPPFLAGS = \
-DPREFIX='"${prefix}"' \
-DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' \
-DLOCALSTATEDIR='"${localstatedir}"' \
- -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"' \
+ -DPKGLOCALSTATEDIR='"${pkglocalstatedir}"' \
-DPLUGINDIR='"${pkglibdir}"' \
-DPKGDATADIR='"${pkgdatadir}"'
+if BUILD_WIN32
+AM_CPPFLAGS += -DNOGDI
+endif
+COMMON_DEPS =
+if BUILD_WIN32
+COMMON_DEPS += collectd.exe
+endif
# Link to these libraries..
COMMON_LIBS = $(PTHREAD_LIBS)
+if BUILD_WIN32
+COMMON_LIBS += -lws2_32
+endif
+if BUILD_WITH_GNULIB
+COMMON_LIBS += -lgnu
+endif
if BUILD_WITH_CAPABILITY
COMMON_LIBS += -lcap
endif
collectd_SOURCES = \
- src/daemon/cmd.c \
src/daemon/cmd.h \
src/daemon/collectd.c \
src/daemon/collectd.h \
$(COMMON_LIBS) \
$(DLOPEN_LIBS)
+if BUILD_WIN32
+collectd_SOURCES += src/daemon/cmd_windows.c
+collectd_LDFLAGS += -ldl -Wl,--out-implib,libcollectd.a
+else
+collectd_SOURCES += src/daemon/cmd.c
+endif
+
if BUILD_FEATURE_DAEMON
collectd_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"'
endif
collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
endif
+if BUILD_WIN32
+collectd_LDFLAGS += -Wl,--out-implib,libcollectd.a
+endif
collectdmon_SOURCES = src/collectdmon.c
-I$(srcdir)/src/daemon
libcollectdclient_la_LDFLAGS = -version-info 2:0:1
libcollectdclient_la_LIBADD = -lm
+if BUILD_WIN32
+libcollectdclient_la_LDFLAGS += -shared -no-undefined
+libcollectdclient_la_LIBADD += -lgnu -lws2_32 -liphlpapi
+endif
if BUILD_WITH_LIBGCRYPT
libcollectdclient_la_CPPFLAGS += $(GCRYPT_CPPFLAGS)
libcollectdclient_la_LDFLAGS += $(GCRYPT_LDFLAGS)
pkglib_LTLIBRARIES += logfile.la
logfile_la_SOURCES = src/logfile.c
logfile_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+logfile_la_DEPENDENCIES = $(COMMON_DEPS)
endif
if BUILD_PLUGIN_LOG_LOGSTASH
endif
if HAVE_LIBMNL
-noinst_LTLIBRARIES += libtaskstats.la
+EXTRA_LTLIBRARIES += libtaskstats.la
libtaskstats_la_SOURCES = \
src/utils_taskstats.c \
src/utils_taskstats.h
jar_DATA = collectd-api.jar generic-jmx.jar
endif
+
The `build.sh' script takes no arguments.
+Building on Windows
+-----------------------------------------------
+
+Collectd can be built on Windows using Cygwin, and the result is a binary that
+runs natively on Windows. That is, Cygwin is only needed for building, not running,
+collectd.
+
+You will need to install the following Cygwin packages:
+- automake
+- bison
+- flex
+- git
+- libtool
+- make
+- mingw64-x86_64-dlfcn
+- mingw64-x86_64-gcc-core
+- mingw64-x86_64-zlib
+- pkg-config
+
+To build, just run the `build.sh' script in your Cygwin terminal. By default, it installs
+to "C:/Program Files/collectd". You can change the location by setting the INSTALL_DIR
+variable:
+
+$ export INSTALL_DIR="C:/some/other/install/directory"
+$ ./build.sh
+
+or:
+
+$ INSTALL_DIR="C:/some/other/install/directory" ./build.sh
+
+
Crosscompiling
--------------
done
}
-check_for_application lex bison autoheader aclocal automake autoconf pkg-config
-
-libtoolize=""
-libtoolize --version >/dev/null 2>/dev/null
-if test $? -eq 0; then
- libtoolize=libtoolize
-else
- glibtoolize --version >/dev/null 2>/dev/null
+setup_libtool()
+{
+ libtoolize=""
+ libtoolize --version >/dev/null 2>/dev/null
if test $? -eq 0; then
- libtoolize=glibtoolize
+ libtoolize=libtoolize
else
- cat >&2 <<EOF
+ glibtoolize --version >/dev/null 2>/dev/null
+ if test $? -eq 0; then
+ libtoolize=glibtoolize
+ else
+ cat >&2 <<EOF
WARNING: Neither \`libtoolize' nor \`glibtoolize' have been found!
Please make sure that one of them is installed and is in one of the
directories listed in the PATH environment variable.
EOF
- GLOBAL_ERROR_INDICATOR=1
+ GLOBAL_ERROR_INDICATOR=1
+ fi
fi
- fi
-if test "$GLOBAL_ERROR_INDICATOR" != "0"; then
- exit 1
-fi
+ if test "$GLOBAL_ERROR_INDICATOR" != "0"; then
+ exit 1
+ fi
+}
+
+build()
+{
+ echo "Building..."
+ check_for_application lex bison autoheader aclocal automake autoconf pkg-config
+ setup_libtool
+
+ set -x
+ autoheader \
+ && aclocal -I m4 \
+ && $libtoolize --copy --force \
+ && automake --add-missing --copy \
+ && autoconf
+}
+
+build_cygwin()
+{
+ echo "Building for Cygwin..."
+ check_for_application aclocal autoconf autoheader automake bison flex git make pkg-config x86_64-w64-mingw32-gcc
+ setup_libtool
+
+ set -e
+
+ : ${INSTALL_DIR:="C:/PROGRA~1/collectd"}
+ : ${LIBDIR:="${INSTALL_DIR}"}
+ : ${BINDIR:="${INSTALL_DIR}"}
+ : ${SBINDIR:="${INSTALL_DIR}"}
+ : ${SYSCONFDIR:="${INSTALL_DIR}"}
+ : ${LOCALSTATEDIR:="${INSTALL_DIR}"}
+ : ${DATAROOTDIR:="${INSTALL_DIR}"}
+ : ${DATADIR:="${INSTALL_DIR}"}
-set -x
+ echo "Installing collectd to ${INSTALL_DIR}."
+ TOP_SRCDIR=$(pwd)
+ MINGW_ROOT="$(x86_64-w64-mingw32-gcc -print-sysroot)/mingw"
+ GNULIB_DIR="${TOP_SRCDIR}/gnulib/build/gllib"
+
+ export CC="x86_64-w64-mingw32-gcc"
+
+ if [ -d "${TOP_SRCDIR}/gnulib/build" ]; then
+ echo "Assuming that gnulib is already built, because gnulib/build exists."
+ else
+ git submodule init
+ git submodule update
+ cd gnulib
+ ./gnulib-tool \
+ --create-testdir \
+ --source-base=lib \
+ --dir=${TOP_SRCDIR}/gnulib/build \
+ canonicalize-lgpl \
+ fcntl-h \
+ getsockopt \
+ gettimeofday \
+ nanosleep \
+ netdb \
+ net_if \
+ poll \
+ recv \
+ regex \
+ sendto \
+ setlocale \
+ strtok_r \
+ sys_resource \
+ sys_socket \
+ sys_stat \
+ sys_wait \
+ time_r
+
+ cd ${TOP_SRCDIR}/gnulib/build
+ ./configure --host="mingw32" LIBS="-lws2_32 -lpthread"
+ make
+ cd gllib
+
+ # We have to rebuild libgnu.a to get the list of *.o files to build a dll later
+ rm libgnu.a
+ OBJECT_LIST=`make V=1 | grep "ar" | cut -d' ' -f4-`
+ $CC -shared -o libgnu.dll $OBJECT_LIST -lws2_32 -lpthread
+ rm libgnu.a # get rid of it, to use libgnu.dll
+ fi
+ cd "${TOP_SRCDIR}"
+
+ set -x
+ autoreconf --install
+
+ export LDFLAGS="-L${GNULIB_DIR}"
+ export LIBS="-lgnu"
+ export CFLAGS="-Drestrict=__restrict -I${GNULIB_DIR}"
+
+ ./configure \
+ --prefix="${INSTALL_DIR}" \
+ --libdir="${LIBDIR}" \
+ --bindir="${BINDIR}" \
+ --sbindir="${SBINDIR}" \
+ --sysconfdir="${SYSCONFDIR}" \
+ --localstatedir="${LOCALSTATEDIR}" \
+ --datarootdir="${DATAROOTDIR}" \
+ --datarootdir="${DATADIR}" \
+ --disable-all-plugins \
+ --host="mingw32" \
+ --enable-logfile
+
+ cp ${GNULIB_DIR}/../config.h src/gnulib_config.h
+ echo "#include <config.h.in>" >> src/gnulib_config.h
+
+ cp libtool libtool_bak
+ sed -i "s%\$LTCC \$LTCFLAGS\(.*cwrapper.*\)%\$LTCC \1%" libtool
+
+ make
+ make install
+
+ cp "${GNULIB_DIR}/libgnu.dll" "${INSTALL_DIR}"
+ cp "${MINGW_ROOT}/bin/zlib1.dll" "${INSTALL_DIR}"
+ cp "${MINGW_ROOT}/bin/libwinpthread-1.dll" "${INSTALL_DIR}"
+ cp "${MINGW_ROOT}/bin/libdl.dll" "${INSTALL_DIR}"
+
+ echo "Done."
+}
+
+os_name="$(uname)"
+if test "${os_name#CYGWIN}" != "$os_name"; then
+ build_cygwin
+else
+ build
+fi
-autoheader \
-&& aclocal -I m4 \
-&& $libtoolize --copy --force \
-&& automake --add-missing --copy \
-&& autoconf
AC_DEFINE([KERNEL_SOLARIS], [1], [True if program is to be compiled for a Solaris kernel])
ac_system="Solaris"
;;
+ *mingw32*)
+ AC_DEFINE([KERNEL_WIN32], [1], [True if program is to be compiled for a Windows kernel])
+ ac_system="Windows"
+ ;;
*)
ac_system="unknown"
;;
AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"])
AM_CONDITIONAL([BUILD_OPENBSD], [test "x$ac_system" = "xOpenBSD"])
AM_CONDITIONAL([BUILD_SOLARIS], [test "x$ac_system" = "xSolaris"])
+AM_CONDITIONAL([BUILD_WIN32], [test "x$ac_system" = "xWindows"])
if test "x$ac_system" = "xSolaris"; then
AC_DEFINE([_POSIX_PTHREAD_SEMANTICS], [1], [Define to enforce POSIX thread semantics under Solaris.])
getaddrinfo \
getgrnam_r \
getnameinfo \
+ getpwnam \
getpwnam_r \
gettimeofday \
if_indextoname \
[
AC_CHECK_LIB([socket], [socket],
[socket_needs_socket="yes"],
- [AC_MSG_ERROR([cannot find socket() in libsocket])]
+ [
+ AC_CHECK_LIB([gnu], [rpl_socket],
+ [socket_needs_gnulib="yes"],
+ [AC_MSG_ERROR([cannot find socket() in libsocket])]
+ )
+ ]
)
]
)
AM_CONDITIONAL([BUILD_WITH_LIBSOCKET], [test "x$socket_needs_socket" = "xyes"])
+AM_CONDITIONAL([BUILD_WITH_GNULIB], [test "x$socket_needs_gnulib" = "xyes"])
clock_gettime_needs_posix4="no"
AC_CHECK_FUNCS([clock_gettime],
fi
# vim: set fdm=marker sw=2 sts=2 ts=2 et :
+
--- /dev/null
+Subproject commit 2f8140bc8ce5501e31dcc665b42b5df64f84c20c
--- /dev/null
+/**\r
+ * collectd - src/collectd_windows.c\r
+ * Copyright (C) 2017 Google LLC\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+ * DEALINGS IN THE SOFTWARE.\r
+ **/\r
+\r
+#include "cmd.h"\r
+#include "plugin.h"\r
+#include <stdio.h>\r
+#include <windows.h>\r
+\r
+int main(int argc, char **argv) {\r
+ WSADATA wsaData;\r
+ WORD wVersionRequested = MAKEWORD(2, 2);\r
+ int err = WSAStartup(wVersionRequested, &wsaData);\r
+ if (err != 0) {\r
+ ERROR("WSAStartup failed with error: %d\n", err);\r
+ return 1;\r
+ }\r
+\r
+ struct cmdline_config config = init_config(argc, argv);\r
+ return run_loop(config.test_readall);\r
+}\r
#define COLLECTD_LOCALE "C"
#endif
+#ifdef WIN32
+#undef COLLECT_DAEMON
+#include <unistd.h>
+#undef gethostname
+#include <locale.h>
+#include <winsock2.h>
+#endif
+
static int loop;
static int init_hostname(void) {
return 0;
}
+#ifdef WIN32
+ long hostname_len = NI_MAXHOST;
+#else
long hostname_len = sysconf(_SC_HOST_NAME_MAX);
if (hostname_len == -1) {
hostname_len = NI_MAXHOST;
}
+#endif /* WIN32 */
char hostname[hostname_len];
if (gethostname(hostname, hostname_len) != 0) {
#ifndef COLLECTD_H
#define COLLECTD_H
+#ifdef WIN32
+typedef int uid_t;
+#include "gnulib_config.h"
+#endif
+
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/isa_defs.h>
#endif
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
#ifndef BYTE_ORDER
#if defined(_BYTE_ORDER)
#define BYTE_ORDER _BYTE_ORDER
#endif
#endif
-#if HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
#ifndef PACKAGE_NAME
#define PACKAGE_NAME "collectd"
#endif
* Michał Mirosław <mirq-linux at rere.qmqm.pl>
**/
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "collectd.h"
#include "common.h"
extern kstat_ctl_t *kc;
#endif
+#if !defined(MSG_DONTWAIT)
+#if defined(MSG_NONBLOCK)
/* AIX doesn't have MSG_DONTWAIT */
-#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT MSG_NONBLOCK
-#endif
+#else
+/* Windows doesn't have MSG_DONTWAIT or MSG_NONBLOCK */
+#define MSG_DONTWAIT 0
+#endif /* defined(MSG_NONBLOCK) */
+#endif /* !defined(MSG_DONTWAIT) */
-#if !HAVE_GETPWNAM_R
+#if !HAVE_GETPWNAM_R && defined(HAVE_GETPWNAM)
static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
#if !HAVE_GETPWNAM_R
int getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen,
struct passwd **pwbufp) {
+#ifndef HAVE_GETPWNAM
+ return -1;
+#else
int status = 0;
struct passwd *pw;
pthread_mutex_unlock(&getpwnam_r_lock);
return status;
+#endif /* HAVE_GETPWNAM */
} /* int getpwnam_r */
#endif /* !HAVE_GETPWNAM_R */
int parse_value_file(char const *path, value_t *ret_value, int ds_type);
#if !HAVE_GETPWNAM_R
+struct passwd;
int getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen,
struct passwd **pwbufp);
#endif
#endif
#ifndef PRIsz
+#ifdef WIN32
+#define PRIsz "Iu"
+#else
#define PRIsz "zu"
-#endif /* PRIsz */
+#endif /* WIN32 */
+#endif /* !PRIsz */
/* Type for time as used by "utils_time.h" */
typedef uint64_t cdtime_t;
#include "utils_random.h"
#include "utils_time.h"
+#ifdef WIN32
+#define EXPORT __declspec(dllexport)
+#include <sys/stat.h>
+#include <unistd.h>
+#else
+#define EXPORT
+#endif
+
#if HAVE_PTHREAD_NP_H
#include <pthread_np.h> /* for pthread_set_name_np(3) */
#endif
}
char name[THREAD_NAME_MAX];
- snprintf(name, sizeof(name), "reader#%" PRIsz, read_threads_num);
+ snprintf(name, sizeof(name), "reader#%" PRIu64, (uint64_t)read_threads_num);
set_thread_name(read_threads[read_threads_num], name);
read_threads_num++;
}
char name[THREAD_NAME_MAX];
- snprintf(name, sizeof(name), "writer#%" PRIsz, write_threads_num);
+ snprintf(name, sizeof(name), "writer#%" PRIu64,
+ (uint64_t)write_threads_num);
set_thread_name(write_threads[write_threads_num], name);
write_threads_num++;
}
#define BUFSIZE 512
+#ifdef WIN32
+#define SHLIB_SUFFIX ".dll"
+#else
+#define SHLIB_SUFFIX ".so"
+#endif
int plugin_load(char const *plugin_name, bool global) {
DIR *dh;
const char *dir;
(strcasecmp("python", plugin_name) == 0))
global = true;
- /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the
+ /* `cpu' should not match `cpufreq'. To solve this we add SHLIB_SUFFIX to the
* type when matching the filename */
- status = snprintf(typename, sizeof(typename), "%s.so", plugin_name);
+ status = snprintf(typename, sizeof(typename), "%s" SHLIB_SUFFIX, plugin_name);
if ((status < 0) || ((size_t)status >= sizeof(typename))) {
- WARNING("plugin_load: Filename too long: \"%s.so\"", plugin_name);
+ WARNING("plugin_load: Filename too long: \"%s" SHLIB_SUFFIX "\"",
+ plugin_name);
return -1;
}
/*
* The `register_*' functions follow
*/
-int plugin_register_config(const char *name,
- int (*callback)(const char *key, const char *val),
- const char **keys, int keys_num) {
+EXPORT int plugin_register_config(const char *name,
+ int (*callback)(const char *key,
+ const char *val),
+ const char **keys, int keys_num) {
cf_register(name, callback, keys, keys_num);
return 0;
} /* int plugin_register_config */
-int plugin_register_complex_config(const char *type,
- int (*callback)(oconfig_item_t *)) {
+EXPORT int plugin_register_complex_config(const char *type,
+ int (*callback)(oconfig_item_t *)) {
return cf_register_complex(type, callback);
} /* int plugin_register_complex_config */
-int plugin_register_init(const char *name, int (*callback)(void)) {
+EXPORT int plugin_register_init(const char *name, int (*callback)(void)) {
return create_register_callback(&list_init, name, (void *)callback, NULL);
} /* plugin_register_init */
return 0;
} /* int plugin_insert_read */
-int plugin_register_read(const char *name, int (*callback)(void)) {
+EXPORT int plugin_register_read(const char *name, int (*callback)(void)) {
read_func_t *rf;
int status;
return status;
} /* int plugin_register_read */
-int plugin_register_complex_read(const char *group, const char *name,
- plugin_read_cb callback, cdtime_t interval,
- user_data_t const *user_data) {
+EXPORT int plugin_register_complex_read(const char *group, const char *name,
+ plugin_read_cb callback,
+ cdtime_t interval,
+ user_data_t const *user_data) {
read_func_t *rf;
int status;
return status;
} /* int plugin_register_complex_read */
-int plugin_register_write(const char *name, plugin_write_cb callback,
- user_data_t const *ud) {
+EXPORT int plugin_register_write(const char *name, plugin_write_cb callback,
+ user_data_t const *ud) {
return create_register_callback(&list_write, name, (void *)callback, ud);
} /* int plugin_register_write */
return flush_name;
} /* static char *plugin_flush_callback_name */
-int plugin_register_flush(const char *name, plugin_flush_cb callback,
- user_data_t const *ud) {
+EXPORT int plugin_register_flush(const char *name, plugin_flush_cb callback,
+ user_data_t const *ud) {
int status;
plugin_ctx_t ctx = plugin_get_ctx();
return 0;
} /* int plugin_register_flush */
-int plugin_register_missing(const char *name, plugin_missing_cb callback,
- user_data_t const *ud) {
+EXPORT int plugin_register_missing(const char *name, plugin_missing_cb callback,
+ user_data_t const *ud) {
return create_register_callback(&list_missing, name, (void *)callback, ud);
} /* int plugin_register_missing */
-int plugin_register_shutdown(const char *name, int (*callback)(void)) {
+EXPORT int plugin_register_shutdown(const char *name, int (*callback)(void)) {
return create_register_callback(&list_shutdown, name, (void *)callback, NULL);
} /* int plugin_register_shutdown */
data_sets = NULL;
} /* void plugin_free_data_sets */
-int plugin_register_data_set(const data_set_t *ds) {
+EXPORT int plugin_register_data_set(const data_set_t *ds) {
data_set_t *ds_copy;
if ((data_sets != NULL) && (c_avl_get(data_sets, ds->type, NULL) == 0)) {
return c_avl_insert(data_sets, (void *)ds_copy->type, (void *)ds_copy);
} /* int plugin_register_data_set */
-int plugin_register_log(const char *name, plugin_log_cb callback,
- user_data_t const *ud) {
+EXPORT int plugin_register_log(const char *name, plugin_log_cb callback,
+ user_data_t const *ud) {
return create_register_callback(&list_log, name, (void *)callback, ud);
} /* int plugin_register_log */
-int plugin_register_notification(const char *name,
- plugin_notification_cb callback,
- user_data_t const *ud) {
+EXPORT int plugin_register_notification(const char *name,
+ plugin_notification_cb callback,
+ user_data_t const *ud) {
return create_register_callback(&list_notification, name, (void *)callback,
ud);
} /* int plugin_register_log */
-int plugin_unregister_config(const char *name) {
+EXPORT int plugin_unregister_config(const char *name) {
cf_unregister(name);
return 0;
} /* int plugin_unregister_config */
-int plugin_unregister_complex_config(const char *name) {
+EXPORT int plugin_unregister_complex_config(const char *name) {
cf_unregister_complex(name);
return 0;
} /* int plugin_unregister_complex_config */
-int plugin_unregister_init(const char *name) {
+EXPORT int plugin_unregister_init(const char *name) {
return plugin_unregister(list_init, name);
}
-int plugin_unregister_read(const char *name) /* {{{ */
+EXPORT int plugin_unregister_read(const char *name) /* {{{ */
{
llentry_t *le;
read_func_t *rf;
return 0;
} /* }}} int plugin_unregister_read */
-void plugin_log_available_writers(void) {
+EXPORT void plugin_log_available_writers(void) {
log_list_callbacks(&list_write, "Available write targets:");
}
return strcmp(rf->rf_group, (const char *)group);
} /* }}} int compare_read_func_group */
-int plugin_unregister_read_group(const char *group) /* {{{ */
+EXPORT int plugin_unregister_read_group(const char *group) /* {{{ */
{
llentry_t *le;
read_func_t *rf;
return 0;
} /* }}} int plugin_unregister_read_group */
-int plugin_unregister_write(const char *name) {
+EXPORT int plugin_unregister_write(const char *name) {
return plugin_unregister(list_write, name);
}
-int plugin_unregister_flush(const char *name) {
+EXPORT int plugin_unregister_flush(const char *name) {
plugin_ctx_t ctx = plugin_get_ctx();
if (ctx.flush_interval != 0) {
return plugin_unregister(list_flush, name);
}
-int plugin_unregister_missing(const char *name) {
+EXPORT int plugin_unregister_missing(const char *name) {
return plugin_unregister(list_missing, name);
}
-int plugin_unregister_shutdown(const char *name) {
+EXPORT int plugin_unregister_shutdown(const char *name) {
return plugin_unregister(list_shutdown, name);
}
-int plugin_unregister_data_set(const char *name) {
+EXPORT int plugin_unregister_data_set(const char *name) {
data_set_t *ds;
if (data_sets == NULL)
return 0;
} /* int plugin_unregister_data_set */
-int plugin_unregister_log(const char *name) {
+EXPORT int plugin_unregister_log(const char *name) {
return plugin_unregister(list_log, name);
}
-int plugin_unregister_notification(const char *name) {
+EXPORT int plugin_unregister_notification(const char *name) {
return plugin_unregister(list_notification, name);
}
-int plugin_init_all(void) {
+EXPORT int plugin_init_all(void) {
char const *chain_name;
llentry_t *le;
int status;
} /* void plugin_init_all */
/* TODO: Rename this function. */
-void plugin_read_all(void) {
+EXPORT void plugin_read_all(void) {
uc_check_timeout();
return;
} /* void plugin_read_all */
/* Read function called when the `-T' command line argument is given. */
-int plugin_read_all_once(void) {
+EXPORT int plugin_read_all_once(void) {
int status;
int return_status = 0;
return return_status;
} /* int plugin_read_all_once */
-int plugin_write(const char *plugin, /* {{{ */
- const data_set_t *ds, const value_list_t *vl) {
+EXPORT int plugin_write(const char *plugin, /* {{{ */
+ const data_set_t *ds, const value_list_t *vl) {
llentry_t *le;
int status;
return status;
} /* }}} int plugin_write */
-int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier) {
+EXPORT int plugin_flush(const char *plugin, cdtime_t timeout,
+ const char *identifier) {
llentry_t *le;
if (list_flush == NULL)
return 0;
} /* int plugin_flush */
-int plugin_shutdown_all(void) {
+EXPORT int plugin_shutdown_all(void) {
llentry_t *le;
int ret = 0; // Assume success.
return ret;
} /* void plugin_shutdown_all */
-int plugin_dispatch_missing(const value_list_t *vl) /* {{{ */
+EXPORT int plugin_dispatch_missing(const value_list_t *vl) /* {{{ */
{
if (list_missing == NULL)
return 0;
return false;
} /* }}} bool check_drop_value */
-int plugin_dispatch_values(value_list_t const *vl) {
+EXPORT int plugin_dispatch_values(value_list_t const *vl) {
int status;
static pthread_mutex_t statistics_lock = PTHREAD_MUTEX_INITIALIZER;
return failed;
} /* }}} int plugin_dispatch_multivalue */
-int plugin_dispatch_notification(const notification_t *notif) {
+EXPORT int plugin_dispatch_notification(const notification_t *notif) {
llentry_t *le;
/* Possible TODO: Add flap detection here */
return 0;
} /* int plugin_dispatch_notification */
-void plugin_log(int level, const char *format, ...) {
+EXPORT void plugin_log(int level, const char *format, ...) {
char msg[1024];
va_list ap;
llentry_t *le;
return log_level;
} /* int parse_log_severity */
-int parse_notif_severity(const char *severity) {
+EXPORT int parse_notif_severity(const char *severity) {
int notif_severity = -1;
if (strcasecmp(severity, "FAILURE") == 0)
return notif_severity;
} /* int parse_notif_severity */
-const data_set_t *plugin_get_ds(const char *name) {
+EXPORT const data_set_t *plugin_get_ds(const char *name) {
data_set_t *ds;
if (data_sets == NULL) {
return ctx;
} /* int plugin_ctx_create */
-void plugin_init_ctx(void) {
+EXPORT void plugin_init_ctx(void) {
pthread_key_create(&plugin_ctx_key, plugin_ctx_destructor);
plugin_ctx_key_initialized = true;
} /* void plugin_init_ctx */
-plugin_ctx_t plugin_get_ctx(void) {
+EXPORT plugin_ctx_t plugin_get_ctx(void) {
plugin_ctx_t *ctx;
assert(plugin_ctx_key_initialized);
return *ctx;
} /* plugin_ctx_t plugin_get_ctx */
-plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) {
+EXPORT plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) {
plugin_ctx_t *c;
plugin_ctx_t old;
return old;
} /* void plugin_set_ctx */
-cdtime_t plugin_get_interval(void) {
+EXPORT cdtime_t plugin_get_interval(void) {
cdtime_t interval;
interval = plugin_get_ctx().interval;
#include "meta_data.h"
#include "utils_time.h"
+#include <inttypes.h>
#include <pthread.h>
#define DS_TYPE_COUNTER 0
* Florian octo Forster <octo at collectd.org>
**/
+#include "collectd.h"
+
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <pthread.h>
+#ifdef WIN32
+double erand48(unsigned short unused[3]) {
+ return (double)rand() / (double)RAND_MAX;
+}
+
+long int jrand48(unsigned short unused[3]) { return rand(); }
+#endif
+
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static bool have_seed;
static unsigned short seed[3];
seed[1] = (unsigned short)(t >> 16);
seed[2] = (unsigned short)(t >> 32);
+#ifdef WIN32
+ srand((unsigned)t);
+#endif
+
have_seed = true;
}
* Florian octo Forster <octo at collectd.org>
**/
+#ifdef WIN32
+#include "gnulib_config.h"
+#include <winsock2.h>
+#endif
+
#include "config.h"
#if !defined(__GNUC__) || !__GNUC__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/socket.h>
#include <sys/types.h>
-#include <sys/un.h>
#include <unistd.h>
+#ifndef WIN32
+#include <sys/socket.h>
+#include <sys/un.h>
+#endif
+
#include "collectd/client.h"
/* NI_MAXHOST has been obsoleted by RFC 3493 which is a reason for SunOS 5.11
#endif
#endif
+#ifdef WIN32
+#define AI_ADDRCONFIG 0
+#endif
+
/* Secure/static macros. They work like `strcpy' and `strcat', but assure null
* termination. They work for static buffers only, because they use `sizeof'.
* The `SSTRCATF' combines the functionality of `snprintf' and `strcat' which
static int lcc_open_unixsocket(lcc_connection_t *c, const char *path) /* {{{ */
{
+#ifdef WIN32
+ lcc_set_errno(c, ENOTSUP);
+ return -1;
+#else
struct sockaddr_un sa = {0};
int fd;
int status;
}
return 0;
+#endif /* WIN32 */
} /* }}} int lcc_open_unixsocket */
static int lcc_open_netsocket(lcc_connection_t *c, /* {{{ */
#include <inttypes.h>
#include <stdint.h>
+#ifdef WIN32
+extern unsigned int if_nametoindex(const char *interface_name);
+#endif
+
#define NET_DEFAULT_V4_ADDR "239.192.74.66"
#define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42"
#define NET_DEFAULT_PORT "25826"
/* Configure servers */
int lcc_server_set_ttl(lcc_server_t *srv, uint8_t ttl);
-int lcc_server_set_interface(lcc_server_t *srv, char const *interface);
+int lcc_server_set_interface(lcc_server_t *srv, char const *iface);
int lcc_server_set_security_level(lcc_server_t *srv, lcc_security_level_t level,
const char *username, const char *password);
/* interface is the name of the interface to use when subscribing to a
* multicast group. Has no effect when using unicast. */
- char *interface;
+ char *iface;
} lcc_listener_t;
/* lcc_listen_and_write listens on the provided UDP socket (or opens one using
#include <net/if.h>
#endif
+#ifdef WIN32
+#define AI_ADDRCONFIG 0
+#endif
+
#include "collectd/network.h"
#include "collectd/network_buffer.h"
return 0;
} /* }}} int lcc_server_set_ttl */
-int lcc_server_set_interface(lcc_server_t *srv, char const *interface) /* {{{ */
+int lcc_server_set_interface(lcc_server_t *srv, char const *iface) /* {{{ */
{
unsigned int if_index;
int status;
- if ((srv == NULL) || (interface == NULL))
+ if ((srv == NULL) || (iface == NULL))
return EINVAL;
- if_index = if_nametoindex(interface);
+ if_index = if_nametoindex(iface);
if (if_index == 0)
return ENOENT;
/* else: Not a multicast interface. */
#if defined(SO_BINDTODEVICE)
- status = setsockopt(srv->fd, SOL_SOCKET, SO_BINDTODEVICE, interface,
- (socklen_t)(strlen(interface) + 1));
+ status = setsockopt(srv->fd, SOL_SOCKET, SO_BINDTODEVICE, iface,
+ (socklen_t)(strlen(iface) + 1));
if (status != 0)
return -1;
#endif
* Florian octo Forster <octo at collectd.org>
**/
+#ifdef WIN32
+#include "gnulib_config.h"
+#endif
+
#include "config.h"
#include <arpa/inet.h> /* htons */
* Florian octo Forster <octo at collectd.org>
**/
+#ifdef WIN32
+#include "gnulib_config.h"
+#endif
+
#include "config.h"
#if !defined(__GNUC__) || !__GNUC__
#include <stdio.h>
#define DEBUG(...) printf(__VA_ARGS__)
+#ifdef WIN32
+#include <ws2tcpip.h>
+#define AI_ADDRCONFIG 0
+#endif
+
static bool is_multicast(struct addrinfo const *ai) {
if (ai->ai_family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr;
struct ip_mreqn mreq = {
.imr_address.s_addr = INADDR_ANY,
.imr_multiaddr.s_addr = sa->sin_addr.s_addr,
- .imr_ifindex = if_nametoindex(srv->interface),
+ .imr_ifindex = if_nametoindex(srv->iface),
};
#else
+#ifdef WIN32
struct ip_mreq mreq = {
+ .imr_interface.s_addr = INADDR_ANY,
.imr_multiaddr.s_addr = sa->sin_addr.s_addr,
};
-#endif
+#else
+ struct ip_mreq mreq = {
+ .imr_address.s_addr = INADDR_ANY, .imr_multiaddr.s_addr = sa->s_addr,
+ };
+#endif /* WIN32 */
+#endif /* HAVE_STRUCT_IP_MREQN_IMR_IFINDEX */
status = setsockopt(srv->conn, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq));
if (status == -1)
return errno;
struct ipv6_mreq mreq6 = {
- .ipv6mr_interface = if_nametoindex(srv->interface),
+ .ipv6mr_interface = if_nametoindex(srv->iface),
};
memmove(&mreq6.ipv6mr_multiaddr, &sa->sin6_addr, sizeof(struct in6_addr));
*/
%{
+#ifdef WIN32
+#include "gnulib_config.h"
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
#include "oconfig.h"