summaryrefslogtreecommitdiffstats
path: root/include/clplumbing
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 /include/clplumbing
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 'include/clplumbing')
-rw-r--r--include/clplumbing/GSource.h236
-rw-r--r--include/clplumbing/GSource_internal.h111
-rw-r--r--include/clplumbing/Gmain_timeout.h44
-rw-r--r--include/clplumbing/Makefile.am59
-rw-r--r--include/clplumbing/apphb_cs.h75
-rw-r--r--include/clplumbing/base64.h50
-rw-r--r--include/clplumbing/cl_log.h99
-rw-r--r--include/clplumbing/cl_misc.h31
-rw-r--r--include/clplumbing/cl_pidfile.h25
-rw-r--r--include/clplumbing/cl_plugin.h29
-rw-r--r--include/clplumbing/cl_poll.h46
-rw-r--r--include/clplumbing/cl_quorum.h44
-rw-r--r--include/clplumbing/cl_quorumd.h48
-rw-r--r--include/clplumbing/cl_random.h81
-rw-r--r--include/clplumbing/cl_reboot.h6
-rw-r--r--include/clplumbing/cl_signal.h91
-rw-r--r--include/clplumbing/cl_syslog.h32
-rw-r--r--include/clplumbing/cl_tiebreaker.h35
-rw-r--r--include/clplumbing/cl_uuid.h40
-rw-r--r--include/clplumbing/coredumps.h36
-rw-r--r--include/clplumbing/cpulimits.h66
-rw-r--r--include/clplumbing/ipc.h788
-rw-r--r--include/clplumbing/loggingdaemon.h32
-rw-r--r--include/clplumbing/longclock.h143
-rw-r--r--include/clplumbing/lsb_exitcodes.h92
-rw-r--r--include/clplumbing/md5.h49
-rw-r--r--include/clplumbing/mkstemp_mode.h34
-rw-r--r--include/clplumbing/netstring.h48
-rw-r--r--include/clplumbing/proctrack.h120
-rw-r--r--include/clplumbing/realtime.h65
-rw-r--r--include/clplumbing/replytrack.h208
-rw-r--r--include/clplumbing/setproctitle.h64
-rw-r--r--include/clplumbing/timers.h23
-rw-r--r--include/clplumbing/uids.h32
34 files changed, 2982 insertions, 0 deletions
diff --git a/include/clplumbing/GSource.h b/include/clplumbing/GSource.h
new file mode 100644
index 0000000..2acc9eb
--- /dev/null
+++ b/include/clplumbing/GSource.h
@@ -0,0 +1,236 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CLPLUMBING_GSOURCE_H
+# define _CLPLUMBING_GSOURCE_H
+# include <clplumbing/ipc.h>
+
+typedef struct GFDSource_s GFDSource;
+typedef struct GCHSource_s GCHSource;
+typedef struct GWCSource_s GWCSource;
+typedef struct GSIGSource_s GSIGSource;
+typedef struct GTRIGSource_s GTRIGSource;
+
+
+void G_main_setmaxdispatchdelay(GSource* s, unsigned long delayms);
+void G_main_setmaxdispatchtime(GSource* s, unsigned long dispatchms);
+void G_main_setdescription(GSource* s, const char * description);
+
+void G_main_setmaxdispatchdelay_id(guint id, unsigned long delayms);
+void G_main_setmaxdispatchtime_id(guint id, unsigned long dispatchms);
+void G_main_setdescription_id(guint id, const char * description);
+void G_main_setall_id(guint id, const char * description, unsigned long delayms, unsigned long dispatchms);
+
+
+/***********************************************************************
+ * Functions for interfacing input to the mainloop
+ ***********************************************************************/
+
+GSource*
+G_main_add_input(int priority,
+ gboolean can_recurse,
+ GSourceFuncs* funcs);
+
+/***********************************************************************
+ * Functions for interfacing "raw" file descriptors to the mainloop
+ ***********************************************************************/
+/*
+* Add a file descriptor to the gmainloop world...
+ */
+GFDSource* G_main_add_fd(int priority, int fd, gboolean can_recurse
+, gboolean (*dispatch)(int fd, gpointer user_data)
+, gpointer userdata
+, GDestroyNotify notify);
+
+/*
+ * Delete a file descriptor from the gmainloop world...
+ * Note: destroys the GFDSource object.
+ */
+gboolean G_main_del_fd(GFDSource* fdp);
+
+/*
+ * Notify us that a file descriptor is blocked on output.
+ * (i.e., we should poll for output events)
+ */
+void g_main_output_is_blocked(GFDSource* fdp);
+
+
+/**************************************************************
+ * Functions for interfacing IPC_Channels to the mainloop
+ **************************************************************/
+/*
+ * Add an IPC_channel to the gmainloop world...
+ */
+GCHSource* G_main_add_IPC_Channel(int priority, IPC_Channel* ch
+, gboolean can_recurse
+, gboolean (*dispatch)(IPC_Channel* source_data
+, gpointer user_data)
+, gpointer userdata
+, GDestroyNotify notify);
+
+/*
+ * the events in this source is paused/resumed
+ */
+
+void G_main_IPC_Channel_pause(GCHSource* chp);
+void G_main_IPC_Channel_resume(GCHSource* chp);
+
+
+/*
+ * Delete an IPC_channel from the gmainloop world...
+ * Note: destroys the GCHSource object, and the IPC_Channel
+ * object automatically.
+ */
+gboolean G_main_del_IPC_Channel(GCHSource* chp);
+
+
+/*
+ * Set the destroy notify function
+ *
+ */
+void set_IPC_Channel_dnotify(GCHSource* chp,
+ GDestroyNotify notify);
+
+
+/*********************************************************************
+ * Functions for interfacing IPC_WaitConnections to the mainloop
+ ********************************************************************/
+/*
+ * Add an IPC_WaitConnection to the gmainloop world...
+ * Note that the dispatch function is called *after* the
+ * connection is accepted.
+ */
+GWCSource* G_main_add_IPC_WaitConnection(int priority, IPC_WaitConnection* ch
+, IPC_Auth* auth_info
+, gboolean can_recurse
+, gboolean (*dispatch)(IPC_Channel* source_data
+, gpointer user_data)
+, gpointer userdata
+, GDestroyNotify notify);
+
+/*
+ * Delete an IPC_WaitConnection from the gmainloop world...
+ * Note: destroys the GWCSource object, and the IPC_WaitConnection
+ * object automatically.
+ */
+gboolean G_main_del_IPC_WaitConnection(GWCSource* wcp);
+
+
+/**************************************************************
+ * Functions for interfacing Signals to the mainloop
+ **************************************************************/
+/*
+ * Add an Signal to the gmainloop world...
+ */
+GSIGSource* G_main_add_SignalHandler(
+ int priority, int signal,
+ gboolean (*dispatch)(int nsig, gpointer user_data),
+ gpointer userdata, GDestroyNotify notify);
+
+/*
+ * Delete an signal from the gmainloop world...
+ * Note: destroys the GSIGSource object, and the removes the
+ * Signal Handler automatically.
+ */
+gboolean G_main_del_SignalHandler(GSIGSource* chp);
+
+
+/*
+ * Set the destroy notify function
+ *
+ */
+void set_SignalHandler_dnotify(GSIGSource* chp, GDestroyNotify notify);
+
+
+/* manage child process death using sig source*/
+#define DEFAULT_MAXDISPATCHTIME 30 /* in ms */
+void set_sigchld_proctrack(int priority, unsigned long maxdisptime);
+
+
+
+/**************************************************************
+ * Functions for interfacing Manual triggers to the mainloop
+ **************************************************************/
+/*
+ * Add an Trigger to the gmainloop world...
+ */
+GTRIGSource* G_main_add_TriggerHandler(
+ int priority, gboolean (*dispatch)(gpointer user_data),
+ gpointer userdata, GDestroyNotify notify);
+
+/*
+ * Delete an signal from the gmainloop world...
+ * Note: destroys the GTRIGSource object, and the removes the
+ * Trigger Handler automatically.
+ */
+gboolean G_main_del_TriggerHandler(GTRIGSource* chp);
+
+
+/*
+ * Set the destroy notify function
+ *
+ */
+void set_TriggerHandler_dnotify(GTRIGSource* chp, GDestroyNotify notify);
+
+
+void G_main_set_trigger(GTRIGSource* man_src);
+
+/*
+ * Create a trigger for triggering an action in a short-lived (temporary)
+ * child process.
+ *
+ * The name isn't wonderful, but we couldn't think of a better one.
+ */
+GTRIGSource* G_main_add_tempproc_trigger(int priority
+, int (*fun)(gpointer p) /* What to do? */
+ /* Called in child process */
+, const char * procname /* What do we call this process? */
+, gpointer userdata /* Passed to 'triggerfun' */
+, void (*prefork)(gpointer p) /* Called before fork */
+, void (*postfork)(gpointer p) /* Called by parent process
+ * after fork(2) call.
+ * Each has 'userdata'
+ * passed to it.
+ */
+, void (*complete)(gpointer p, int status, int signo, int exitcode)); /* called after the child process completes */
+
+/*
+ * Special notes:
+ * - No more than one child process will be active at a time per trigger
+ * object.
+ *
+ * - If you trigger the action while this object has a child active,
+ * then it will be re-triggered after the currently running child
+ * completes. There is no necessary correlation between the
+ * number of times a the action is triggered and how many
+ * times it is executed. What is guaranteed is that after you
+ * trigger the action, it will happen (at least) once - as soon
+ * as the scheduler gets around to it at the priority you've
+ * assigned it. But if several are triggered while a child
+ * process is running, only one process will be instantiated to
+ * take the action requested by all the trigger calls.
+ *
+ * - Child processes are forked off at the priority of the trigger,
+ * not the priority of the SIGCHLD handler.
+ *
+ * - This is useful for writing out updates to a file for example.
+ * While we're writing one copy out, subsequent updates are
+ * held off until this one completes. When it completes, then
+ * the file is written again - but not "n" times - just the
+ * latest version available at the time the trigger is
+ * activated (run).
+ */
+#endif
diff --git a/include/clplumbing/GSource_internal.h b/include/clplumbing/GSource_internal.h
new file mode 100644
index 0000000..c20a9c9
--- /dev/null
+++ b/include/clplumbing/GSource_internal.h
@@ -0,0 +1,111 @@
+/*
+ * Author: Alan Robertson <alanr@unix.sh>
+ * Copyright (C) 2005 International Business Machines Inc.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <clplumbing/longclock.h>
+#include <clplumbing/GSource.h>
+
+#define MAG_GFDSOURCE 0xfeed0001U
+#define MAG_GCHSOURCE 0xfeed0002U
+#define MAG_GWCSOURCE 0xfeed0003U
+#define MAG_GSIGSOURCE 0xfeed0004U
+#define MAG_GTRIGSOURCE 0xfeed0005U
+#define MAG_GTIMEOUTSRC 0xfeed0006U
+
+#define IS_FDSOURCE(p) (p && (p)->magno == MAG_GFDSOURCE)
+#define IS_CHSOURCE(p) (p && (p)->magno == MAG_GCHSOURCE)
+#define IS_WCSOURCE(p) (p && (p)->magno == MAG_GWCSOURCE)
+#define IS_SIGSOURCE(p) (p && (p)->magno == MAG_GSIGSOURCE)
+#define IS_TRIGSOURCE(p) (p && (p)->magno == MAG_GTRIGSOURCE)
+#define IS_TIMEOUTSRC(p) (p && (p)->magno == MAG_GTIMEOUTSRC)
+
+#define IS_ONEOFOURS(p) (IS_CHSOURCE(p)|IS_FDSOURCE(p)|IS_WCSOURCE(p)|| \
+ IS_SIGSOURCE(p)|IS_TRIGSOURCE(p)||IS_TIMEOUTSRC(p))
+
+
+#define DEFAULT_MAXDISPATCH 0
+#define DEFAULT_MAXDELAY 0
+#define OTHER_MAXDELAY 100
+
+#define COMMON_STRUCTSTART \
+GSource source; /* Common glib struct - must be 1st */ \
+unsigned magno; /* Magic number */ \
+long maxdispatchms; /* Time limit for dispatch function */ \
+long maxdispatchdelayms; /* Max delay before processing */ \
+char detecttime[sizeof(longclock_t)]; \
+ /* Time last input detected */ \
+void* udata; /* User-defined data */ \
+guint gsourceid; /* Source id of this source */ \
+const char * description; /* Description of this source */ \
+GDestroyNotify dnotify
+
+struct GFDSource_s {
+ COMMON_STRUCTSTART;
+ gboolean (*dispatch)(int fd, gpointer user_data);
+ GPollFD gpfd;
+};
+
+
+typedef gboolean (*GCHdispatch)(IPC_Channel* ch, gpointer user_data);
+
+struct GCHSource_s {
+ COMMON_STRUCTSTART;
+ IPC_Channel* ch;
+ gboolean fd_fdx;
+ GPollFD infd;
+ GPollFD outfd;
+ gboolean dontread; /* TRUE when we don't want to read
+ * more input for a while - we're
+ * flow controlling the writer off
+ */
+ gboolean (*dispatch)(IPC_Channel* ch, gpointer user_data);
+};
+
+struct GWCSource_s {
+ COMMON_STRUCTSTART;
+ GPollFD gpfd;
+ IPC_WaitConnection* wch;
+ IPC_Auth* auth_info;
+ gboolean (*dispatch)(IPC_Channel* accept_ch, gpointer udata);
+};
+
+struct GSIGSource_s {
+ COMMON_STRUCTSTART;
+ clock_t sh_detecttime;
+ int signal;
+ gboolean signal_triggered;
+ gboolean (*dispatch)(int signal, gpointer user_data);
+};
+
+struct GTRIGSource_s {
+ COMMON_STRUCTSTART;
+ gboolean manual_trigger;
+ gboolean (*dispatch)(gpointer user_data);
+};
+
+/************************************************************
+ * Functions for IPC_Channels
+ ***********************************************************/
+gboolean G_CH_prepare_int(GSource* source, gint* timeout);
+gboolean G_CH_check_int(GSource* source);
+gboolean G_CH_dispatch_int(GSource* source, GSourceFunc callback,
+ gpointer user_data);
+void G_CH_destroy_int(GSource* source);
+GCHSource*
+G_main_IPC_Channel_constructor(GSource* source, IPC_Channel* ch
+, gpointer userdata, GDestroyNotify notify);
diff --git a/include/clplumbing/Gmain_timeout.h b/include/clplumbing/Gmain_timeout.h
new file mode 100644
index 0000000..c696a9d
--- /dev/null
+++ b/include/clplumbing/Gmain_timeout.h
@@ -0,0 +1,44 @@
+#ifndef _CLPLUMBING_GMAIN_TIMEOUT_H
+#define _CLPLUMBING_GMAIN_TIMEOUT_H
+#include <glib.h>
+/*
+ * 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
+ *
+ */
+/*
+ * These functions must work correctly even if someone resets the
+ * time-of-day clock. The g_main_timeout_add() function does not have
+ * this property, since it relies on gettimeofday().
+ *
+ * Our functions have the same semantics - except they always work ;-)
+ *
+ * This is because we use longclock_t for our time values.
+ */
+guint Gmain_timeout_add(guint interval
+, GSourceFunc function
+, gpointer data);
+
+guint Gmain_timeout_add_full(gint priority
+, guint interval
+, GSourceFunc function
+, gpointer data
+, GDestroyNotify notify);
+
+void Gmain_timeout_remove(guint tag);
+#endif
diff --git a/include/clplumbing/Makefile.am b/include/clplumbing/Makefile.am
new file mode 100644
index 0000000..599b24c
--- /dev/null
+++ b/include/clplumbing/Makefile.am
@@ -0,0 +1,59 @@
+#
+# linux-ha: Linux-HA heartbeat code
+#
+# Copyright (C) 2002 International Business Machines.
+# Author: Alan Robertson <alanr@unix.sh>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#
+MAINTAINERCLEANFILES = Makefile.in
+
+idir=$(includedir)/clplumbing
+
+i_HEADERS = \
+ Gmain_timeout.h \
+ GSource.h \
+ GSource_internal.h \
+ apphb_cs.h \
+ base64.h \
+ cl_log.h \
+ cl_poll.h \
+ cl_signal.h \
+ cl_pidfile.h \
+ cl_random.h \
+ cl_reboot.h \
+ cl_syslog.h \
+ cl_uuid.h \
+ coredumps.h \
+ cpulimits.h \
+ ipc.h \
+ lsb_exitcodes.h \
+ loggingdaemon.h \
+ longclock.h \
+ mkstemp_mode.h \
+ netstring.h \
+ proctrack.h \
+ realtime.h \
+ replytrack.h \
+ setproctitle.h \
+ timers.h \
+ uids.h \
+ cl_misc.h \
+ md5.h \
+ cl_plugin.h \
+ cl_tiebreaker.h \
+ cl_quorum.h \
+ cl_quorumd.h
diff --git a/include/clplumbing/apphb_cs.h b/include/clplumbing/apphb_cs.h
new file mode 100644
index 0000000..9506db6
--- /dev/null
+++ b/include/clplumbing/apphb_cs.h
@@ -0,0 +1,75 @@
+/*
+ * 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
+ *
+ */
+
+#ifndef _CLPLUMBING_APPHB_CS_H
+#define _CLPLUMBING_APPHB_CS_H
+
+/* Internal client-server messages for APP heartbeat service */
+
+#ifndef HA_VARRUNDIR
+#define HA_VARRUNDIR "/var/run"
+#endif
+#define APPHBSOCKPATH HA_VARRUNDIR "/heartbeat/apphb.comm"
+
+#define APPHB_TLEN 8
+#define APPHB_OLEN 256
+
+#define REGISTER "reg"
+#define UNREGISTER "unreg"
+#define HEARTBEAT "hb"
+#define SETINTERVAL "setint"
+#define SETWARNTIME "setwarn"
+#define SETREBOOT "setboot"
+
+/*
+ * These messages are really primitive.
+ * They don't have any form of version control, they're in host byte order,
+ * and they're all in binary...
+ *
+ * Fortunately, this is a very simple local service ;-)
+ */
+
+/* Generic (no parameter) App heartbeat message */
+struct apphb_msg {
+ char msgtype [APPHB_TLEN];
+};
+
+/* App heartbeat Registration message */
+struct apphb_signupmsg {
+ char msgtype [APPHB_TLEN];
+ char appname [APPHB_OLEN];
+ char appinstance [APPHB_OLEN];
+ char curdir [APPHB_OLEN];
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+};
+
+/* App heartbeat setinterval / setwarn message */
+struct apphb_msmsg {
+ char msgtype [APPHB_TLEN];
+ unsigned long ms;
+};
+
+/* App heartbeat server return code (errno) */
+struct apphb_rc {
+ int rc;
+};
+#endif
diff --git a/include/clplumbing/base64.h b/include/clplumbing/base64.h
new file mode 100644
index 0000000..4ea6810
--- /dev/null
+++ b/include/clplumbing/base64.h
@@ -0,0 +1,50 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CLPLUMBING_BASE64_H
+# define _CLPLUMBING_BASE64_H
+/*
+ *
+ * Base64 conversion functions.
+ * They convert from a binary array into a single string
+ * in base 64. This is almost (but not quite) like section 5.2 of RFC 1341
+ * The only difference is that we don't care about line lengths.
+ * We do use their encoding algorithm.
+ *
+ */
+
+#define B64inunit 3
+#define B64outunit 4
+
+/* How long will the base64 string be for a particular binary object size? */
+/* This is like strlen() and doesn't include the '\0' byte at the end */
+#define B64_stringlen(bytes) \
+ ((((bytes)+(B64inunit-1))/B64inunit)*B64outunit)
+
+/* How many bytes to you need to malloc to store a base64 string? */
+/* (includes space for the '\0' terminator byte) */
+#define B64_stringspace(bytes) (B64_stringlen(bytes)+1)
+
+/* How many bytes will a base64 string take up back in binary? */
+/* Note: This may be as much as two 2 bytes more than strictly needed */
+#define B64_maxbytelen(slen) (((slen) / B64outunit)*B64inunit)
+
+/* Returns strlen() of base64 string returned in "output" */
+int binary_to_base64(const void * data, int nbytes, char * output, int outlen);
+
+/* Returns the size of the binary object we returned in "output" */
+int base64_to_binary(const char * input, int inlen, void * output, int outlen);
+#endif
diff --git a/include/clplumbing/cl_log.h b/include/clplumbing/cl_log.h
new file mode 100644
index 0000000..aa30fcd
--- /dev/null
+++ b/include/clplumbing/cl_log.h
@@ -0,0 +1,99 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CLPLUMBING_CL_LOG_H
+# define _CLPLUMBING_CL_LOG_H
+# include <glib.h>
+# include <syslog.h>
+
+#define TIME_T unsigned long
+#define HA_FAIL 0
+#define HA_OK 1
+#define MAXLINE (512*10)
+
+/* this is defined by the caller */
+struct logspam {
+ const char *id; /* identifier */
+ int max; /* maximum number of messages ... */
+ time_t window; /* ... within this timeframe */
+ time_t reset_time; /* log new messages after this time */
+ const char *advice; /* what to log in case messages get suppressed */
+};
+
+/* this is internal (oblique to the caller) */
+struct msg_ctrl {
+ struct logspam *lspam; /* */
+ time_t *msg_slots; /* msg slot root (space for lspam->max) */
+ int last; /* last used msg slot [0..lspam->max-1]; -1 on init */
+ int cnt; /* current msg count [0..lspam->max] */
+ time_t suppress_t; /* messages blocked since this time */
+};
+
+struct IPC_CHANNEL;
+
+extern int debug_level;
+#define ANYDEBUG (debug_level)
+#define DEBUGDETAILS (debug_level >= 2)
+#define DEBUGAUTH (debug_level >=3)
+#define DEBUGMODULE (debug_level >=3)
+#define DEBUGPKT (debug_level >= 4)
+#define DEBUGPKTCONT (debug_level >= 5)
+
+void cl_direct_log(int priority, const char* buf, gboolean, const char*, int, TIME_T);
+void cl_log(int priority, const char * fmt, ...) G_GNUC_PRINTF(2,3);
+void cl_limit_log(struct msg_ctrl *ml, int priority, const char * fmt, ...) G_GNUC_PRINTF(3,4);
+struct msg_ctrl *cl_limit_log_new(struct logspam *lspam);
+void cl_limit_log_destroy(struct msg_ctrl *ml);
+void cl_limit_log_reset(struct msg_ctrl *ml);
+void cl_perror(const char * fmt, ...) G_GNUC_PRINTF(1,2);
+void cl_log_enable_stderr(int truefalse);
+void cl_log_enable_stdout(int truefalse);
+gboolean cl_log_test_logd(void);
+void cl_log_set_uselogd(int truefalse);
+void cl_log_enable_syslog_filefmt(int truefalse);
+void cl_log_use_buffered_io(int truefalse);
+gboolean cl_log_get_uselogd(void);
+void cl_log_set_facility(int facility);
+void cl_log_set_entity(const char * entity);
+void cl_log_set_syslogprefix(const char *prefix);
+void cl_log_set_logfile(const char * path);
+void cl_log_set_debugfile(const char * path);
+void cl_inherit_logging_environment(int maxqlen);
+int cl_log_set_logd_channel_source( void (*create_callback)(struct IPC_CHANNEL* chan),
+ GDestroyNotify destroy_callback);
+int cl_log_get_logdtime(void);
+void cl_log_set_logdtime(int logdintval);
+
+char * ha_timestamp(TIME_T t);
+void cl_glib_msg_handler(const gchar *log_domain
+, GLogLevelFlags log_level, const gchar *message
+, gpointer user_data);
+
+void cl_flush_logs(void);
+void cl_log_args(int argc, char **argv);
+int cl_log_is_logd_fd(int fd);
+const char * prio2str(int priority);
+
+/* cl_log_use_buffered_io and cl_log_do_fflush as optimization for logd,
+ * so it may buffer a few message lines, then fflush them out in one write.
+ * Set do_fsync != 0, if you even want it to fsync. */
+void cl_log_do_fflush(int do_fsync);
+void cl_log_use_buffered_io(int truefalse);
+/* We now keep the file handles open for a potentially very long time.
+ * Sometimes we may need to close them explicitly. */
+void cl_log_close_log_files(void);
+
+#endif
diff --git a/include/clplumbing/cl_misc.h b/include/clplumbing/cl_misc.h
new file mode 100644
index 0000000..6f698b5
--- /dev/null
+++ b/include/clplumbing/cl_misc.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CLPLUMBING_CL_MISC_H
+#define _CLPLUMBING_CL_MISC_H
+int cl_str_to_boolean(const char*, int*);
+
+int cl_file_exists(const char* filename);
+
+char* cl_get_env(const char* env_name);
+
+int cl_binary_to_int(const char* data, int len);
+
+long cl_get_msec(const char * input); /* string to msec */
+
+#endif
diff --git a/include/clplumbing/cl_pidfile.h b/include/clplumbing/cl_pidfile.h
new file mode 100644
index 0000000..3dba50f
--- /dev/null
+++ b/include/clplumbing/cl_pidfile.h
@@ -0,0 +1,25 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _LOCKFILE_H_
+#define _LOCKFILE_H_
+
+int cl_read_pidfile(const char *filename);
+int cl_read_pidfile_no_checking(const char *filename);
+int cl_lock_pidfile(const char *filename);
+int cl_unlock_pidfile(const char *filename);
+
+#endif
diff --git a/include/clplumbing/cl_plugin.h b/include/clplumbing/cl_plugin.h
new file mode 100644
index 0000000..e2431bf
--- /dev/null
+++ b/include/clplumbing/cl_plugin.h
@@ -0,0 +1,29 @@
+
+
+/*
+ * cl_manage_plugin.c: This file handle plugin loading and deleting
+ *
+ * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __CL_PLUGIN__
+#define __CL_PLUGIN__
+
+int cl_remove_plugin(const char* type, const char* pluginname);
+void* cl_load_plugin(const char* type, const char* pluginname);
+
+#endif
diff --git a/include/clplumbing/cl_poll.h b/include/clplumbing/cl_poll.h
new file mode 100644
index 0000000..1b1908f
--- /dev/null
+++ b/include/clplumbing/cl_poll.h
@@ -0,0 +1,46 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#ifndef CLPLUMBING_CL_POLL_H
+# define CLPLUMBING_CL_POLL_H
+
+#include <glib.h>
+#include <sys/poll.h>
+
+/*
+ * Poll the file descriptors described by the NFDS structures starting at
+ * FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for
+ * an event to occur; if TIMEOUT is -1, block until an event occurs.
+ * Returns the number of file descriptors with events, zero if timed out,
+ * or -1 for errors.
+ *
+ * When available, this function uses POSIX signals, and Linux F_SETSIG()
+ * calls to provide this capability. When it is not available it
+ * uses the real poll() call.
+ *
+ */
+int cl_poll(struct pollfd *fds, unsigned int nfds, int timeout_ms);
+
+/*
+ * Call cl_poll_ignore() when you close a file descriptor you monitored
+ * via cl_poll() before, or if you don't want it monitored any more.
+ */
+int cl_poll_ignore(int fd);
+
+/* Select the signal you want us to use (must be a RT signal) */
+int cl_poll_setsig(int nsig);
+
+int cl_glibpoll(GPollFD* ufds, guint nfsd, gint timeout);
+#endif
diff --git a/include/clplumbing/cl_quorum.h b/include/clplumbing/cl_quorum.h
new file mode 100644
index 0000000..b7798ba
--- /dev/null
+++ b/include/clplumbing/cl_quorum.h
@@ -0,0 +1,44 @@
+/*
+ * quorum.h: head file for quorum module
+ *
+ * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _QUORUM_H_
+#define _QUORUM_H_
+
+#define HB_QUORUM_TYPE quorum
+#define HB_QUORUM_TYPE_S "quorum"
+
+#define QUORUM_YES 0
+#define QUORUM_NO 1
+#define QUORUM_TIE 2
+typedef void(*callback_t)(void);
+/*
+ * List of functions provided by implementations of the quorum interface.
+ */
+struct hb_quorum_fns {
+
+ int (*getquorum) (const char* cluster
+ , int member_count, int member_quorum_votes
+ , int total_node_count, int total_quorum_votes);
+ int (*init) (callback_t notify, const char* cluster, const char* quorum_server);
+ void (*stop) (void);
+};
+
+
+#endif
diff --git a/include/clplumbing/cl_quorumd.h b/include/clplumbing/cl_quorumd.h
new file mode 100644
index 0000000..6d282b3
--- /dev/null
+++ b/include/clplumbing/cl_quorumd.h
@@ -0,0 +1,48 @@
+/*
+ * quorum.h: head file for quorum module
+ *
+ * Author: Huang Zhen <zhenhltc@cn.ibm.com>
+ * Copyright (C) 2006 International Business Machines
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _QUORUMD_H_
+#define _QUORUMD_H_
+
+#define HB_QUORUMD_TYPE quorumd
+#define HB_QUORUMD_TYPE_S "quorumd"
+
+#define CONFIGFILE HA_HBCONF_DIR"/quorumd.conf"
+#define MAX_DN_LEN 256
+#define quorum_log(priority, fmt...); \
+ cl_log(priority, fmt); \
+
+#define quorum_debug(priority, fmt...); \
+ if ( debug_level > 0 ) { \
+ cl_log(priority, fmt); \
+ }
+
+/* List of functions provided by implementations of the quorumd interface. */
+struct hb_quorumd_fns {
+ int (*test) (void);
+ int (*init) (void);
+ int (*load_config_file) (void);
+ int (*dump_data) (int priority);
+ int (*on_connect) (int sock, gnutls_session session, const char* CN);
+};
+
+
+#endif
diff --git a/include/clplumbing/cl_random.h b/include/clplumbing/cl_random.h
new file mode 100644
index 0000000..d1e37ce
--- /dev/null
+++ b/include/clplumbing/cl_random.h
@@ -0,0 +1,81 @@
+
+/*
+ * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu>
+ * Copyright (C) 2005 International Business Machines Inc.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+
+/* Intended usage is srand(cl_randseed()).
+ * This returns on "as good as it gets" random number usually taken from
+ * /dev/urandom to have a nice seed for future random numbers generated by
+ * rand(). */
+unsigned int cl_randseed(void);
+
+/* get_next_random() currently rand() based.
+ *
+ * You probably want to use cl_rand_from_interval instead.
+ *
+ * You don't need to srand(), it will seed once with cl_randseed internally.
+ *
+ * It is called that way, because it was exposed in the header file for a long
+ * time, and used to be coded in an attempt to pregenerate a queue of random
+ * numbers from the mainloop, and it would shift the next random number from
+ * that queue and trigger generation of new random numbers "at idle time" to
+ * refill that queue.
+ * Only that functionality never actually worked, is not interessting anymore
+ * anyways (rand() is cheap enough), and is now ripped out.
+ *
+ * So it now does srand(cl_randseed()) once internally,
+ * and from there on is equivalent to calling rand() directly,
+ * and could be called cl_rand().
+ *
+ * If you want your own specific rand seed to re-generate a particular
+ * sequence, call it once, throw away the return code, then call
+ * srand(yourseed). Or don't use it anywhere in your code. */
+int get_next_random(void);
+
+/* generate some random number in the range [a;b];
+ * typically used to randomly delay messages. */
+#define HAVE_CL_RAND_FROM_INTERVAL 1
+static inline
+int cl_rand_from_interval(const int a, const int b)
+{
+ /*
+ * Be careful here, you don't know RAND_MAX at coding time,
+ * only at compile time. If you think
+ * (int)(a + (rand()*(b-a)+(RAND_MAX/2))/RAND_MAX);
+ * was correct, think again with RAND_MAX = INT_MAX,
+ * which is the case for many rand() implementations nowadays.
+ *
+ * Don't do modulo, either, as that will skew the distribution, and
+ * still has possible wraparounds, or an insufficient input set for too
+ * small RAND_MAX.
+ *
+ * Rather do the whole calculation in 64 bit, which should be correct
+ * as long as r, a, b, and RAND_MAX are all int.
+ * Of course, if you prefer, you can do it with floating point as well.
+ */
+#if 1 /* use long long */
+ long long r = get_next_random();
+ r = a + (r * (b-a) + RAND_MAX/2)/RAND_MAX;
+#else /* use floating point */
+ int r = get_next_random();
+ r = a + (int)(1.0 / RAND_MAX * r * (b-a) + 0.5);
+#endif
+ return r;
+}
diff --git a/include/clplumbing/cl_reboot.h b/include/clplumbing/cl_reboot.h
new file mode 100644
index 0000000..1c759c8
--- /dev/null
+++ b/include/clplumbing/cl_reboot.h
@@ -0,0 +1,6 @@
+#ifndef CLPLUMBING_CL_REBOOT_H
+#define CLPLUMBING_CL_REBOOT_H 1
+#include <glib.h>
+void cl_enable_coredump_before_reboot(gboolean yesno); /* not implemented in all OSes */
+void cl_reboot(int msdelaybeforereboot, const char * reason);
+#endif
diff --git a/include/clplumbing/cl_signal.h b/include/clplumbing/cl_signal.h
new file mode 100644
index 0000000..1a13a6b
--- /dev/null
+++ b/include/clplumbing/cl_signal.h
@@ -0,0 +1,91 @@
+/*
+ * cl_signal.h: signal handling routines to be used by Linux-HA programmes
+ *
+ * Copyright (C) 2002 Horms <horms@verge.net.au>
+ *
+ * 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
+ *
+ */
+#ifndef _CL_SIGNAL_H
+#define _CL_SIGNAL_H
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/signal.h>
+
+typedef struct {
+ int sig;
+ void (*handler)(int);
+ int interrupt;
+} cl_signal_mode_t;
+
+#define CL_SIGNAL(_sig, _handler) \
+ cl_signal_set_simple_handler((_sig), (_handler), NULL)
+#if HAVE_SIGIGNORE
+#define CL_IGNORE_SIG(_sig) sigignore((_sig))
+#else
+#define CL_IGNORE_SIG(_sig) CL_SIGNAL((_sig), SIG_IGN)
+#endif
+#define CL_DEFAULT_SIG(_sig) CL_SIGNAL((_sig), SIG_DFL)
+
+#define CL_SIGINTERRUPT(_sig, _flag) siginterrupt((_sig), (_flag))
+
+#define CL_SIGACTION(_signum, _act, _oldact) \
+ sigaction((_signum), (_act), (_oldact))
+#define CL_SIGPROCMASK(_how, _set, _oldset) \
+ cl_signal_block_set((_how), (_set), (_oldset))
+#define CL_SIGPENDING(_set) sigpending(_set)
+#define CL_SIGSUSPEND(_mask) sigsuspend(_mask)
+
+#define CL_SIGEMPTYSET(_set) sigemptyset(_set)
+#define CL_SIGFILLSET(_set) sigfillset(_set)
+#define CL_SIGADDSET(_set, _signum) sigaddset((_set), (_signum))
+#define CL_SIGDELSET(_set, _signum) sigdelset((_set), (_signum))
+#define CL_SIGISMEMBER(_set, _signum) sigmember((_set), (_signum))
+
+#define CL_KILL(_pid, _sig) kill((_pid), (_sig))
+
+#define CL_PID_EXISTS(_pid) ( CL_KILL((_pid), 0) >= 0 || errno != ESRCH )
+
+int
+cl_signal_set_handler(int sig, void (*handler)(int), sigset_t *mask
+, int flags, struct sigaction *oldact);
+
+int
+cl_signal_set_simple_handler(int sig, void (*handler)(int)
+, struct sigaction *oldact);
+
+int
+cl_signal_set_action(int sig, void (*action)(int, siginfo_t *, void *)
+, sigset_t *mask, int flags, struct sigaction *oldact);
+
+int
+cl_signal_set_simple_action(int sig, void (*action)(int, siginfo_t *, void *)
+, struct sigaction *oldact);
+
+int
+cl_signal_set_interrupt(int sig, int flag);
+
+int
+cl_signal_block(int how, int signal, sigset_t *oldset);
+
+int
+cl_signal_block_set(int how, const sigset_t *set, sigset_t *oldset);
+
+int
+cl_signal_set_handler_mode(const cl_signal_mode_t *mode, sigset_t *set);
+
+
+#endif /* _CL_SIGNAL_H */
diff --git a/include/clplumbing/cl_syslog.h b/include/clplumbing/cl_syslog.h
new file mode 100644
index 0000000..a7c1bfa
--- /dev/null
+++ b/include/clplumbing/cl_syslog.h
@@ -0,0 +1,32 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Functions to support syslog.
+ * David Lee (c) 2005
+ */
+
+#ifndef _CLPLUMBING_CL_SYSLOG_H
+#define _CLPLUMBING_CL_SYSLOG_H
+
+/* Convert string "auth" to equivalent number "LOG_AUTH" etc. */
+int cl_syslogfac_str2int(const char *);
+
+/* Convert number "LOG_AUTH" to equivalent string "auth" etc. */
+/* Returns static string; caller must NOT free. */
+const char *cl_syslogfac_int2str(int);
+
+#endif /* _CLPLUMBING_CL_SYSLOG_H */
diff --git a/include/clplumbing/cl_tiebreaker.h b/include/clplumbing/cl_tiebreaker.h
new file mode 100644
index 0000000..11c10c4
--- /dev/null
+++ b/include/clplumbing/cl_tiebreaker.h
@@ -0,0 +1,35 @@
+/*
+ * cl_tiebreaker.h: head file for tiebreaker module
+ *
+ * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CL_TIEBREAKER_H_
+#define _CL_TIEBREAKER_H_
+
+#define HB_TIEBREAKER_TYPE tiebreaker
+#define HB_TIEBREAKER_TYPE_S "tiebreaker"
+
+/*
+ * List of functions provided by implementations of tiebreaker interface.
+ */
+struct hb_tiebreaker_fns {
+ gboolean (*break_tie) (int, int);
+};
+
+
+#endif
diff --git a/include/clplumbing/cl_uuid.h b/include/clplumbing/cl_uuid.h
new file mode 100644
index 0000000..12542cd
--- /dev/null
+++ b/include/clplumbing/cl_uuid.h
@@ -0,0 +1,40 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CL_UUID_H_
+#define _CL_UUID_H_
+#include <glib.h>
+
+typedef struct cl_uuid_s{
+ unsigned char uuid[16];
+}cl_uuid_t;
+
+void cl_uuid_copy(cl_uuid_t* dst, cl_uuid_t* src);
+void cl_uuid_clear(cl_uuid_t* uu);
+int cl_uuid_compare(const cl_uuid_t* uu1, const cl_uuid_t* uu2);
+void cl_uuid_generate(cl_uuid_t* out);
+int cl_uuid_is_null(cl_uuid_t* uu);
+int cl_uuid_parse( char *in, cl_uuid_t* uu);
+#define UU_UNPARSE_SIZEOF 37 /* Including NULL byte */
+void cl_uuid_unparse(const cl_uuid_t* uu, char *out);
+
+/* Suitable for ues as a GHashFunc from glib */
+guint cl_uuid_g_hash(gconstpointer uuid_ptr);
+/* Suitable for ues as a GEqualFunc from glib */
+gboolean cl_uuid_g_equal(gconstpointer uuid_ptr_a, gconstpointer uuid_ptr_b);
+
+
+#endif
diff --git a/include/clplumbing/coredumps.h b/include/clplumbing/coredumps.h
new file mode 100644
index 0000000..4d5ce79
--- /dev/null
+++ b/include/clplumbing/coredumps.h
@@ -0,0 +1,36 @@
+/*
+ * Basic Core dump control functions.
+ *
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * 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
+ *
+ */
+#ifndef _CLPLUMBING_COREFILES_H
+# define _CLPLUMBING_COREFILES_H 1
+ /* Set the root directory of our core directory hierarchy */
+int cl_set_corerootdir(const char * dir);
+ /* Change directory to the directory our core file needs to go in */
+ /* Call after you establish the userid you're running under */
+int cl_cdtocoredir(void);
+ /* Enable/disable core dumps for ourselves and our child processes */
+int cl_enable_coredumps(int truefalse);
+void cl_untaint_coredumps(void);
+void cl_set_coredump_signal_handler(int nsig);
+void cl_set_all_coredump_signal_handlers(void);
+
+#endif
diff --git a/include/clplumbing/cpulimits.h b/include/clplumbing/cpulimits.h
new file mode 100644
index 0000000..f7dd875
--- /dev/null
+++ b/include/clplumbing/cpulimits.h
@@ -0,0 +1,66 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Functions to put limits on CPU consumption.
+ * This allows us to better catch runaway realtime processes that
+ * might otherwise hang the whole system.
+ *
+ * The process is basically this:
+ * - Set the CPU percentage limit with cl_cpu_limit_setpercent()
+ * according to what you expect the CPU percentage to top out at
+ * measured over an interval at >= 10 seconds
+ * - Call cl_cpu_limit_ms_interval() to figure out how often to update
+ * the CPU limit (it returns milliseconds)
+ * - At least as often as indicated above, call cl_cpu_limit_update()
+ * to update our current CPU limit.
+ *
+ * These limits are approximate, so be a little conservative.
+ * If you've gone into an infinite loop, it'll likely get caught ;-)
+ *
+ * Note that exceeding the soft CPU limits we set here will cause a
+ * SIGXCPU signal to be sent.
+ *
+ * The default action for this signal is to cause a core dump.
+ * This is a good choice ;-)
+ *
+ * As of this writing, this code will never set the soft CPU limit less
+ * than two seconds, or greater than 10 seconds.
+ *
+ * It will currrently return a limit update interval between 10000 and
+ * 400000 milliseconds.
+ *
+ */
+
+/*
+ * Set expected CPU percentage upper bound
+ */
+int cl_cpu_limit_setpercent(int ipercent);
+
+/*
+ * Update the current CPU limit
+ */
+int cl_cpu_limit_update(void);
+
+/*
+ * How often should we call cl_cpu_limit_update()?
+ *
+ * Note: return result is in milliseconds
+ */
+int cl_cpu_limit_ms_interval(void);
+
+/* Disable further CPU limits... */
+int cl_cpu_limit_disable(void);
diff --git a/include/clplumbing/ipc.h b/include/clplumbing/ipc.h
new file mode 100644
index 0000000..4a5e151
--- /dev/null
+++ b/include/clplumbing/ipc.h
@@ -0,0 +1,788 @@
+/*
+ * ipc.h IPC abstraction data structures.
+ *
+ * author Xiaoxiang Liu <xiliu@ncsa.uiuc.edu>,
+ * Alan Robertson <alanr@unix.sh>
+ *
+ *
+ * Copyright (c) 2002 International Business Machines
+ * Copyright (c) 2002 Xiaoxiang Liu <xiliu@ncsa.uiuc.edu>
+ *
+ * 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
+ *
+ */
+
+#ifndef _IPC_H_
+#define _IPC_H_
+#include <glib.h>
+#undef MIN
+#undef MAX
+#include <sys/types.h>
+#include <sys/poll.h>
+
+#ifdef IPC_TIME_DEBUG
+#include <clplumbing/longclock.h>
+#define MAXIPCTIME 3000
+
+#endif
+
+/* constants */
+#define DEFAULT_MAX_QLEN 64
+#define MAX_MSGPAD 128
+/* channel and connection status */
+#define IPC_CONNECT 1 /* Connected: can read, write */
+#define IPC_WAIT 2 /* Waiting for connection */
+#define IPC_DISCONNECT 3 /* Disconnected, can't read or write*/
+#define IPC_DISC_PENDING 4 /* Disconnected, can't write but */
+ /* may be more data to read */
+
+#define MAXFAILREASON 128
+
+#define IPC_SERVER 1
+#define IPC_CLIENT 2
+#define IPC_PEER 3
+
+#define IPC_ISRCONN(ch) ((ch)->ch_status == IPC_CONNECT \
+ || (ch)->ch_status == IPC_DISC_PENDING)
+
+#define IPC_ISWCONN(ch) ((ch)->ch_status == IPC_CONNECT)
+
+/* general return values */
+#define IPC_OK 0
+#define IPC_FAIL 1
+#define IPC_BROKEN 2
+#define IPC_INTR 3
+#define IPC_TIMEOUT 4
+
+/*
+ * IPC: Sockets-like Interprocess Communication Abstraction
+ *
+ * We have two fundamental abstractions which we maintain.
+ * Everything else is in support of these two abstractions.
+ *
+ * These two main abstractions are:
+ *
+ * IPC_WaitConnection:
+ * A server-side abstraction for waiting for someone to connect.
+ *
+ * IPC_Channel:
+ * An abstraction for an active communications channel.
+ *
+ * All the operations on these two abstractions are carried out
+ * via function tables (channel->ops). Below we refer to the
+ * function pointers in these tables as member functions.
+ *
+ * On the server side, everything starts up with a call to
+ * ipc_wait_conn_constructor(), which returns an IPC_WaitConnection.
+ *
+ * Once the server has the IPC_WaitConnection object in hand,
+ * it can give the result of the get_select_fd() member function
+ * to poll or select to inform you when someone tries to connect.
+ *
+ * Once select tells you someone is trying to connect, you then
+ * use the accept_connection() member function to accept
+ * the connection. accept_connection() returns an IPC_Channel.
+ *
+ * With that, the server can talk to the client, and away they
+ * go ;-)
+ *
+ * On the client side, everything starts up with a call to
+ * ipc_channel_constructor() which we use to talk to the server.
+ * The client is much easier ;-)
+ */
+
+
+typedef struct IPC_WAIT_CONNECTION IPC_WaitConnection;
+typedef struct IPC_CHANNEL IPC_Channel;
+
+typedef struct IPC_MESSAGE IPC_Message;
+typedef struct IPC_QUEUE IPC_Queue;
+typedef struct IPC_AUTH IPC_Auth;
+
+typedef struct IPC_OPS IPC_Ops;
+typedef struct IPC_WAIT_OPS IPC_WaitOps;
+
+
+
+/* wait connection structure. */
+struct IPC_WAIT_CONNECTION{
+ int ch_status; /* wait conn. status.*/
+ void * ch_private; /* wait conn. private data. */
+ IPC_WaitOps *ops; /* wait conn. function table .*/
+};
+
+
+typedef void(*flow_callback_t)(IPC_Channel*, void*);
+
+/* channel structure.*/
+struct IPC_CHANNEL{
+ int ch_status; /* identify the status of channel.*/
+ int refcount; /* reference count */
+ pid_t farside_pid; /* far side pid */
+ void* ch_private; /* channel private data. */
+ /* (may contain conn. info.) */
+ IPC_Ops* ops; /* IPC_Channel function table.*/
+
+ /* number of bytes needed
+ * at the begginging of <ipcmessage>->msg_body
+ * it's for msg head needed to tranmit in wire
+ */
+ unsigned int msgpad;
+
+ /* the number of bytes remainng to send for the first message in send queue
+ 0 means nothing has been sent thus all bytes needs to be send
+ n != 0 means there are still n bytes needs to be sent
+ */
+ unsigned int bytes_remaining;
+
+
+ /* is the send blocking or nonblocking*/
+ gboolean should_send_block;
+
+ /* if send would block, should an error be returned or not */
+ gboolean should_block_fail;
+
+/* There are two queues in channel. One is for sending and the other
+ * is for receiving.
+ * Those two queues are channel's internal queues. They should not be
+ * accessed directly.
+ */
+ /* private: */
+ IPC_Queue* send_queue;
+ IPC_Queue* recv_queue;
+
+ /* buffer pool for receive in this channel*/
+ struct ipc_bufpool* pool;
+
+ /* the follwing is for send flow control*/
+ int high_flow_mark;
+ int low_flow_mark;
+ void* high_flow_userdata;
+ void* low_flow_userdata;
+ flow_callback_t high_flow_callback;
+ flow_callback_t low_flow_callback;
+
+ int conntype;
+
+ char failreason[MAXFAILREASON];
+
+ /* New members to support Multi-level ACLs for the CIB,
+ * available since libplumb.so.2.1.0, added at the
+ * end of the struct to maintain backwards ABI compatibility.
+ *
+ * If you don't like to care for library versions,
+ * create your IPC channels with
+ * c = ipc_wait_conn_constructor(IPC_UDS_CRED, ...),
+ * and these members will be available.
+ */
+ uid_t farside_uid; /* far side uid */
+ gid_t farside_gid; /* far side gid */
+};
+
+struct IPC_QUEUE{
+ size_t current_qlen; /* Current qlen */
+ size_t max_qlen; /* Max allowed qlen */
+ GList* queue; /* List of messages */
+ /* keep the time of the last max queue warning */
+ time_t last_maxqlen_warn;
+ /* and the number of messages lost */
+ unsigned maxqlen_cnt;
+};
+
+/* authentication information : set of gids and uids */
+struct IPC_AUTH {
+ GHashTable * uid; /* hash table for user id */
+ GHashTable * gid; /* hash table for group id */
+};
+
+
+/* Message structure. */
+struct IPC_MESSAGE{
+ size_t msg_len;
+ void* msg_buf;
+ void* msg_body;
+/*
+ * IPC_MESSAGE::msg_done
+ * the callback function pointer which can be called after this
+ * message is sent, received or otherwise processed.
+ *
+ * Parameter:
+ * msg: the back pointer to the message which contains this
+ * function pointer.
+ *
+ */
+ void (* msg_done)(IPC_Message * msg);
+ void* msg_private; /* the message private data. */
+ /* Belongs to message creator */
+ /* May be used by callback function. */
+ IPC_Channel * msg_ch; /* Channel the */
+ /* message is from/in */
+
+};
+
+struct IPC_WAIT_OPS{
+/*
+ * IPC_WAIT_OPS::destroy
+ * destroy the wait connection and free the memory space used by
+ * this wait connection.
+ *
+ * Parameters:
+ * wait_conn (IN): the pointer to the wait connection.
+ *
+ */
+ void (* destroy)(IPC_WaitConnection *wait_conn);
+/*
+ * IPC_WAIT_OPS::get_select_fd
+ * provide a fd which user can listen on for a new coming connection.
+ *
+ * Parameters:
+ * wait_conn (IN) : the pointer to the wait connection which
+ * we're supposed to return the file descriptor for
+ * (the file descriptor can be used with poll too ;-))
+ *
+ * Return values:
+ * integer >= 0 : the select_fd.
+ * -1 : can't get the select fd.
+ *
+ */
+ int (* get_select_fd)(IPC_WaitConnection *wait_conn);
+/*
+ * IPC_WAIT_OPS::accept_connection
+ * accept and create a new connection and verify the authentication.
+ *
+ * Parameters:
+ * wait_conn (IN) : the waiting connection which will accept
+ * create the new connection.
+ * auth_info (IN) : the authentication information which will be
+ * verified for the new connection.
+ *
+ * Return values:
+ * the pointer to the new IPC channel; NULL if the creation or
+ * authentication fails.
+ *
+ */
+ IPC_Channel * (* accept_connection)
+ (IPC_WaitConnection * wait_conn, IPC_Auth *auth_info);
+};
+
+/* Standard IPC channel operations */
+
+struct IPC_OPS{
+/*
+ * IPC_OPS::destroy
+ * brief destroy the channel object.
+ *
+ * Parameters:
+ * ch (IN) : the pointer to the channel which will be destroyed.
+ *
+ */
+ void (*destroy) (IPC_Channel * ch);
+/*
+ * IPC_OPS::initiate_connection
+ * used by service user side to set up a connection.
+ *
+ * Parameters:
+ * ch (IN) : the pointer to channel used to initiate the connection.
+ *
+ * Return values:
+ * IPC_OK : the channel set up the connection successfully.
+ * IPC_FAIL : the connection initiation fails.
+ *
+ */
+ int (* initiate_connection) (IPC_Channel * ch);
+/*
+ * IPC_OPS::verify_auth
+ * used by either side to verify the identity of peer on connection.
+ *
+ * Parameters
+ * ch (IN) : the pointer to the channel.
+ *
+ * Return values:
+ * IPC_OK : the peer is trust.
+ * IPC_FAIL : verifying authentication fails.
+ */
+ int (* verify_auth) (IPC_Channel * ch, IPC_Auth* info);
+/*
+ * IPC_OPS::assert_auth
+ * service user asserts to be certain qualified service user.
+ *
+ * Parameters:
+ * ch (IN): the active channel.
+ * auth (IN): the hash table which contains the asserting information.
+ *
+ * Return values:
+ * IPC_OK : assert the authentication successfully.
+ * IPC_FAIL : assertion fails.
+ *
+ * NOTE: This operation is a bit obscure. It isn't needed with
+ * UNIX domain sockets at all. The intent is that some kinds
+ * of IPC (like FIFOs), do not have an intrinsic method to
+ * authenticate themselves except through file permissions.
+ * The idea is that you must tell it how to chown/grp your
+ * FIFO so that the other side and see that if you can write
+ * this, you can ONLY be the user/group they expect you to be.
+ * But, I think the parameters may be wrong for this ;-)
+ */
+ int (* assert_auth) (IPC_Channel * ch, GHashTable * auth);
+/*
+ * IPC_OPS::send
+ * send the message through the sending connection.
+ *
+ * Parameters:
+ * ch (IN) : the channel which contains the connection.
+ * msg (IN) : pointer to the sending message. User must
+ * allocate the message space.
+ *
+ * Return values:
+ * IPC_OK : the message was either sent out successfully or
+ * appended to the send_queue.
+ * IPC_FAIL : the send operation failed.
+ * IPC_BROKEN : the channel is broken.
+ *
+*/
+ int (* send) (IPC_Channel * ch, IPC_Message* msg);
+
+/*
+ * IPC_OPS::recv
+ * receive the message through receving queue.
+ *
+ * Parameters:
+ * ch (IN) : the channel which contains the connection.
+ * msg (OUT): the IPC_MESSAGE** pointer which contains the pointer
+ * to the received message or NULL if there is no
+ * message available.
+ *
+ * Return values:
+ * IPC_OK : receive operation is completed successfully.
+ * IPC_FAIL : operation failed.
+ * IPC_BROKEN : the channel is broken (disconnected)
+ *
+ * Note:
+ * return value IPC_OK doesn't mean the message is already
+ * sent out to (or received by) the peer. It may be pending
+ * in the send_queue. In order to make sure the message is no
+ * longer needed, please specify the msg_done function in the
+ * message structure and once this function is called, the
+ * message is no longer needed.
+ *
+ * is_sending_blocked() is another way to check if there is a message
+ * pending in the send_queue.
+ *
+ */
+ int (* recv) (IPC_Channel * ch, IPC_Message** msg);
+
+/*
+ * IPC_OPS::waitin
+ * Wait for input to become available
+ *
+ * Parameters:
+ * ch (IN) : the channel which contains the connection.
+ *
+ * Side effects:
+ * If output becomes unblocked while waiting, it will automatically
+ * be resumed without comment.
+ *
+ * Return values:
+ * IPC_OK : a message is pending or output has become unblocked.
+ * IPC_FAIL : operation failed.
+ * IPC_BROKEN : the channel is broken (disconnected)
+ * IPC_INTR : waiting was interrupted by a signal
+ */
+ int (* waitin) (IPC_Channel * ch);
+/*
+ * IPC_OPS::waitout
+ * Wait for output to finish
+ *
+ * Parameters:
+ * ch (IN) : the channel which contains the connection.
+ *
+ * Side effects:
+ * If input becomes available while waiting, it will automatically
+ * be read into the channel queue without comment.
+ *
+ * Return values:
+ * IPC_OK : output no longer blocked
+ * IPC_FAIL : operation failed.
+ * IPC_BROKEN : the channel is broken (disconnected)
+ * IPC_INTR : waiting was interrupted by a signal
+ */
+ int (* waitout) (IPC_Channel * ch);
+
+/*
+ * IPC_OPS::is_message_pending
+ * check to see if there is any messages ready to read, or hangup has
+ * occurred.
+ *
+ * Parameters:
+ * ch (IN) : the pointer to the channel.
+ *
+ * Return values:
+ * TRUE : there are messages ready to read, or hangup.
+ * FALSE: there are no messages ready to be read.
+ */
+ gboolean (* is_message_pending) (IPC_Channel * ch);
+
+/*
+ * IPC_OPS::is_sending_blocked
+ * check the send_queue to see if there are any messages blocked.
+ *
+ * Parameters:
+ * ch (IN) : the pointer to the channel.
+ *
+ * Return values:
+ * TRUE : there are messages blocked (waiting) in the send_queue.
+ * FALSE: there are no message blocked (waiting) in the send_queue.
+ *
+ * See also:
+ * get_send_select_fd()
+ */
+ gboolean (* is_sending_blocked) (IPC_Channel *ch);
+
+/*
+ * IPC_OPS::resume_io
+ * Resume all possible IO operations through the IPC transport
+ *
+ * Parameters:
+ * the pointer to the channel.
+ *
+ * Return values:
+ * IPC_OK : resume all the possible I/O operation successfully.
+ * IPC_FAIL : the operation fails.
+ * IPC_BROKEN : the channel is broken.
+ *
+ */
+ int (* resume_io) (IPC_Channel *ch);
+/*
+ * IPC_OPS::get_send_select_fd()
+ * return a file descriptor which can be given to select/poll. This fd
+ * is used by the IPC code for sending. It is intended that this be
+ * ONLY used with select, poll, or similar mechanisms, not for direct I/O.
+ * Note that due to select(2) and poll(2) semantics, you must check
+ * is_sending_blocked() to see whether you should include this FD in
+ * your poll for writability, or you will loop very fast in your
+ * select/poll loop ;-)
+ *
+ * Parameters:
+ * ch (IN) : the pointer to the channel.
+ *
+ * Return values:
+ * integer >= 0 : the send fd for selection.
+ * -1 : there is no send fd.
+ *
+ * See also:
+ * is_sending_blocked()
+ */
+ int (* get_send_select_fd) (IPC_Channel * ch);
+/*
+ * IPC_OPS::get_recv_select_fd
+ * return a file descriptor which can be given to select. This fd
+ * is for receiving. It is intended that this be ONLY used with select,
+ * poll, or similar mechanisms, NOT for direct I/O.
+ *
+ * Parameters:
+ * ch (IN) : the pointer to the channel.
+ *
+ * Return values:
+ * integer >= 0 : the recv fd for selection.
+ * -1 : there is no recv fd.
+ *
+ * NOTE: This file descriptor is often the same as the send
+ * file descriptor.
+ */
+ int (* get_recv_select_fd) (IPC_Channel * ch);
+/*
+ * IPC_OPS::set_send_qlen
+ * allow user to set the maximum send_queue length.
+ *
+ * Parameters
+ * ch (IN) : the pointer to the channel.
+ * q_len (IN) : the max length for the send_queue.
+ *
+ * Return values:
+ * IPC_OK : set the send queue length successfully.
+ * IPC_FAIL : there is no send queue. (This isn't supposed
+ * to happen).
+ * It means something bad happened.
+ *
+ */
+ int (* set_send_qlen) (IPC_Channel * ch, int q_len);
+/*
+ * IPC_OPS::set_recv_qlen
+ * allow user to set the maximum recv_queue length.
+ *
+ * Parameters:
+ * ch (IN) : the pointer to the channel.
+ * q_len (IN) : the max length for the recv_queue.
+ *
+ * Return values:
+ * IPC_OK : set the recv queue length successfully.
+ * IPC_FAIL : there is no recv queue.
+ *
+ */
+ int (* set_recv_qlen) (IPC_Channel * ch, int q_len);
+
+
+/*
+ * IPC_OPS: set callback for high/low flow mark
+ * ch (IN) : the pointer to the channel
+ * callback (IN) : the callback function
+ * user_data(IN) : a pointer to user_data
+ * callback will be called with channel and
+ * this user_data as parameters
+ *
+ * Return values:
+ * void
+ *
+ */
+
+
+ void (* set_high_flow_callback) (IPC_Channel* ch ,
+ flow_callback_t callback,
+ void* user_data);
+
+ void (* set_low_flow_callback) (IPC_Channel* ch ,
+ flow_callback_t callback,
+ void* user_data);
+
+/*
+ * IPC_OPS::new_ipcmsg
+ * ch (IN) : the pointer to the channel
+ * data (IN) : data to be copied to the message body
+ * len (IN) : data len
+ * private (IN): the pointer value to set as in the message
+ *
+ * Return values:
+ * the pointer to a new created message will be
+ * returned if success or NULL if failure
+ *
+ */
+
+ IPC_Message* (*new_ipcmsg)(IPC_Channel* ch, const void* data,
+ int len, void* private);
+
+
+/*
+ * IPC_OPS::nget_chan_status
+ * ch (IN) : the pointer to the channel
+ *
+ * Return value:
+ * channel status.
+ *
+ */
+ int (*get_chan_status)(IPC_Channel* ch);
+
+
+/*
+ * These two functions returns true if the corresponding queue
+ * is full, otherwise it returns false
+ */
+
+ gboolean (*is_sendq_full)(struct IPC_CHANNEL * ch);
+ gboolean (*is_recvq_full)(struct IPC_CHANNEL * ch);
+
+
+ /* Get the connection type for the channel
+ * it can be IPC_SERVER, IPC_CLIENT, IPC_PEER
+ */
+
+ int (*get_conntype)(struct IPC_CHANNEL* ch);
+
+ int (*disconnect)(struct IPC_CHANNEL* ch);
+
+};
+
+
+/*
+ * ipc_wait_conn_constructor:
+ * the common constructor for ipc waiting connection.
+ * Use ch_type to identify the connection type. Usually it's only
+ * needed by server side.
+ *
+ * Parameters:
+ * ch_type (IN) : the type of the waiting connection to create.
+ * ch_attrs (IN) : the hash table which contains the attributes
+ * needed by this waiting connection in name/value
+ * pair format.
+ *
+ * For example, the only attribute needed by UNIX
+ * domain sockets is path name.
+ *
+ * Return values:
+ * the pointer to a new waiting connection or NULL if the connection
+ * can't be created.
+ * Note:
+ * current implementation supports
+ * IPC_ANYTYPE: This is what program code should typically use.
+ * Internally it is an alias to IPC_UDS_CRED.
+ * IPC_UDS_CRED: Unix Domain Sockets,
+ * farside uid + gid credentials is available.
+ * Available since libplumb.so.2.1.0.
+ * IPC_DOMAIN_SOCKET: An other alias to Unix Domain Sockets;
+ * internally it is equivalent to both above.
+ * Using this explicitly, your code will work
+ * even with libplumb.so.2.0.0.
+ * Which also means that you MUST NOT use the
+ * farside_uid/gid functionality then.
+ */
+extern IPC_WaitConnection * ipc_wait_conn_constructor(const char * ch_type
+, GHashTable* ch_attrs);
+
+/*
+ * ipc_channel_constructor:
+ * brief the common constructor for ipc channel.
+ * Use ch_type to identify the channel type.
+ * Usually this function is only called by client side.
+ *
+ * Parameters:
+ * ch_type (IN): the type of the channel you want to create.
+ * ch_attrs (IN): the hash table which contains the attributes needed
+ * by this channel.
+ * For example, the only attribute needed by UNIX domain
+ * socket is path name.
+ *
+ * Return values:
+ * the pointer to the new channel whose status is IPC_DISCONNECT
+ * or NULL if the channel can't be created.
+ *
+ * Note:
+ * See comments for ipc_wait_conn_constructor above
+ * for currently implemented ch_type channel types.
+ */
+extern IPC_Channel * ipc_channel_constructor(const char * ch_type
+, GHashTable* ch_attrs);
+
+/*
+ * ipc_channel_pair:
+ * Construct a pair of connected IPC channels in a fashion analogous
+ * to pipe(2) or socketpair(2).
+ *
+ * Parameters:
+ * channels: an array of two IPC_Channel pointers for return result
+ */
+int ipc_channel_pair(IPC_Channel* channels[2]);
+
+/*
+ * ipc_set_auth:
+ * A helper function used to convert array of uid and gid into
+ * an authentication structure (IPC_Auth)
+ *
+ * Parameters:
+ * a_uid (IN): the array of a set of user ids.
+ * a_gid (IN): the array of a set of group ids.
+ * num_uid (IN): the number of user ids.
+ * num_gid (IN): the number of group ids.
+ *
+ * Return values:
+ * the pointer to the authentication structure which contains the
+ * set of uid and the set of gid. Or NULL if this structure can't
+ * be created.
+ *
+ */
+
+
+IPC_Auth* ipc_str_to_auth(const char * uidlist, int, const char * gidlist, int);
+
+extern IPC_Auth * ipc_set_auth(uid_t * a_uid, gid_t * a_gid
+, int num_uid, int num_gid);
+
+/* Destroys an object constructed by ipc_set_auth or ipc_str_to_auth() */
+extern void ipc_destroy_auth(IPC_Auth * auth);
+
+extern void ipc_set_pollfunc(int (*)(struct pollfd*, unsigned int, int));
+extern void ipc_bufpool_dump_stats(void);
+
+#ifdef IPC_TIME_DEBUG
+
+enum MSGPOS_IN_IPC{
+ MSGPOS_ENQUEUE,
+ MSGPOS_SEND,
+ MSGPOS_RECV,
+ MSGPOS_DEQUEUE
+};
+
+#endif
+
+
+struct SOCKET_MSG_HEAD{
+ int msg_len;
+ unsigned int magic;
+#ifdef IPC_TIME_DEBUG
+ longclock_t enqueue_time;
+ longclock_t send_time;
+ longclock_t recv_time;
+ longclock_t dequeue_time;
+#endif
+
+};
+
+
+/* MAXMSG is the maximum final message size on the wire. */
+#define MAXMSG (256*1024)
+/* MAXUNCOMPRESSED is the maximum, raw data size prior to compression. */
+/* 1:8 compression ratio is to be expected on data such as xml */
+#define MAXUNCOMPRESSED (2048*1024)
+#define HEADMAGIC 0xabcd
+#define POOL_SIZE (4*1024)
+struct ipc_bufpool{
+
+ int refcount;
+ char* currpos;
+ char* consumepos;
+ char* startpos;
+ char* endpos;
+ int size;
+};
+
+struct ipc_bufpool* ipc_bufpool_new(int);
+
+void ipc_bufpool_del(struct ipc_bufpool* pool);
+
+int ipc_bufpool_spaceleft(struct ipc_bufpool* pool);
+
+int ipc_bufpool_update(struct ipc_bufpool* pool,
+ struct IPC_CHANNEL * ch,
+ int msg_len,
+ IPC_Queue* rqueue);
+
+gboolean ipc_bufpool_full(struct ipc_bufpool* pool,
+ struct IPC_CHANNEL* ch,
+ int*);
+int ipc_bufpool_partial_copy(struct ipc_bufpool* dstpool,
+ struct ipc_bufpool* srcpool);
+
+void ipc_bufpool_ref(struct ipc_bufpool* pool);
+
+void ipc_bufpool_unref(struct ipc_bufpool* pool);
+
+void set_ipc_time_debug_flag(gboolean flag);
+
+/* pathname attribute */
+#define IPC_PATH_ATTR "path"
+/* socket mode attribute */
+#define IPC_MODE_ATTR "sockmode"
+/* Unix domain socket, used by old code.
+ * See also the comment block above ipc_wait_conn_constructor() */
+#define IPC_DOMAIN_SOCKET "uds"
+/* Unix domain socket with farside uid + gid credentials.
+ * Available since libplumb.so.2.1.0 */
+#define IPC_UDS_CRED "uds_c"
+
+#ifdef IPC_UDS_CRED
+# define IPC_ANYTYPE IPC_UDS_CRED
+#else
+# error "No IPC types defined(!)"
+#endif
+
+#endif
diff --git a/include/clplumbing/loggingdaemon.h b/include/clplumbing/loggingdaemon.h
new file mode 100644
index 0000000..ba986f5
--- /dev/null
+++ b/include/clplumbing/loggingdaemon.h
@@ -0,0 +1,32 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Messages sent to the logging daemon */
+#define LD_LOGIT 2
+#define MAXENTITY 64
+
+/* Message contains following header, followed by the text (char[]) itself */
+struct LogDaemonMsgHdr_s {
+ int msgtype;
+ int facility;
+ int priority;
+ int msglen;
+ gboolean use_pri_str;
+ int entity_pid;
+ char entity[MAXENTITY];
+ TIME_T timestamp;
+};
+typedef struct LogDaemonMsgHdr_s LogDaemonMsgHdr;
diff --git a/include/clplumbing/longclock.h b/include/clplumbing/longclock.h
new file mode 100644
index 0000000..ae95b28
--- /dev/null
+++ b/include/clplumbing/longclock.h
@@ -0,0 +1,143 @@
+/*
+ * Longclock operations
+ *
+ * Copyright (c) 2002 International Business Machines
+ * Author: Alan Robertson <alanr@unix.sh>
+ *
+ * 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
+ *
+ */
+
+#ifndef _LONGCLOCK_H
+# define _LONGCLOCK_H
+/*
+ * A longclock_t object is a lot like a clock_t object, except that it
+ * won't wrap in the lifetime of the earth. It is guaranteed to be at
+ * least 64 bits. This means it should go for around 2 billion years.
+ *
+ * It is also supposed to be proof against changes in the local time on
+ * the computer. This is easy if you have a properly-working times(2)
+ * for us to use.
+ *
+ * longclock_t's are definitely not comparable between computers, and in
+ * some implementations, not even between processes on the same computer.
+ *
+ *
+ * The functions provided here are:
+ *
+ * unsigned long cl_times(void);
+ * A rational wrapper for the times(2) call
+ * for those cases where only the return value
+ * is wanted.
+ * longclock_t time_longclock(void);
+ * Returns current time as a longclock_t.
+ *
+ * longclock_t msto_longclock(unsigned long);
+ * Converts quantity in milliseconds to longclock_t
+ *
+ * unsigned long longclockto_ms(longclock_t);
+ * Converts quantity in longclock_t to milliseconds
+ * NOTE: Can overflow!
+ *
+ * unsigned long longclockto_long(longclock_t);
+ * Converts quantity in longclock_t to clock_t
+ * NOTE: Can overflow!
+ *
+ * longclock_t secsto_longclock(unsigned long);
+ * Converts quantity in seconds to longclock_t
+ *
+ * longclock_t add_longclock(longclock_t l, longclock_t r);
+ * Adds two longclock_t values
+ *
+ * int cmp_longclock(longclock_t l, longclock_t r);
+ * Returns negative, zero or positive value
+ *
+ * longclock_t sub_longclock(longclock_t l, longclock_t r);
+ * Subtracts two longclock_t values
+ * NOTE: Undefined if l is < r
+ *
+ * longclock_t dsecsto_longclock(double);
+ * Converts quantity in seconds (as a double)
+ * to a longclock_t
+ *
+ * unsigned hz_longclock(void);
+ * Returns frequency of longclock_t clock.
+ *
+ * We provide this constant:
+ *
+ * extern const longclock_t zero_longclock;
+ */
+extern unsigned long cl_times(void);
+
+#ifdef CLOCK_T_IS_LONG_ENOUGH
+# ifndef HAVE_LONGCLOCK_ARITHMETIC
+# define HAVE_LONGCLOCK_ARITHMETIC
+# endif
+
+# include <sys/times.h>
+
+ typedef clock_t longclock_t;
+
+#else /* clock_t isn't at least 64 bits */
+ typedef unsigned long long longclock_t;
+#endif
+
+longclock_t time_longclock(void);
+
+extern const longclock_t zero_longclock;
+
+unsigned hz_longclock(void);
+longclock_t secsto_longclock(unsigned long);
+longclock_t dsecsto_longclock(double);
+longclock_t msto_longclock(unsigned long);
+unsigned long longclockto_ms(longclock_t); /* Can overflow! */
+long longclockto_long(longclock_t); /* May overflow! */
+
+
+#ifndef HAVE_LONGCLOCK_ARITHMETIC
+
+longclock_t add_longclock(longclock_t l, longclock_t r);
+
+ /* Undefined if l is < r according to cmp_longclock() */
+longclock_t sub_longclock(longclock_t l, longclock_t r);
+
+int cmp_longclock(longclock_t l, longclock_t r);
+
+
+#else /* We HAVE_LONGCLOCK_ARITHMETIC */
+
+# define longclockto_long(lc) ((long)(lc))
+
+# define add_longclock(l,r) \
+ ((longclock_t)(l) + (longclock_t)(r))
+
+# define sub_longclock(l,r) \
+ ((longclock_t)(l) - (longclock_t)(r))
+
+# define cmp_longclock(l,r) \
+ (((longclock_t)(l) < (longclock_t)(r)) \
+ ? -1 \
+ : (((longclock_t)(l) > (longclock_t)(r)) \
+ ? +1 : 0))
+#endif
+
+
+/* N.B: Possibly not the best place for this, but it will do for now */
+/* This is consistent with OpenBSD, and is a good choice anyway */
+#define TIME_T unsigned long
+#define TIME_F "%lu"
+#define TIME_X "%lx"
+
+#endif
diff --git a/include/clplumbing/lsb_exitcodes.h b/include/clplumbing/lsb_exitcodes.h
new file mode 100644
index 0000000..e46b5be
--- /dev/null
+++ b/include/clplumbing/lsb_exitcodes.h
@@ -0,0 +1,92 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* LSB status exit codes.
+ *
+ * All of these and the supporting text are taken from the LSB.
+ *
+ * If the status command is given, the init script will return
+ * the following exit status codes.
+ *
+ * 0 program is running or service is OK
+ * 1 program is dead and /var/run pid file exists
+ * 2 program is dead and /var/lock lock file exists
+ * 3 program is stopped
+ * 4 program or service status is unknown
+ * 5-99 reserved for future LSB use
+ * 100-149 reserved for distribution use
+ * 150-199 reserved for application use
+ * 200-254 reserved
+ */
+
+#define LSB_STATUS_OK 0
+#define LSB_STATUS_VAR_PID 1
+#define LSB_STATUS_VAR_LOCK 2
+#define LSB_STATUS_STOPPED 3
+#define LSB_STATUS_UNKNOWN 4
+#define LSB_STATUS_LSBRESERVED 5
+#define LSB_STATUS_DISTRESERVED 100
+#define LSB_STATUS_APPRESERVED 150
+#define LSB_STATUS_RESERVED 200
+/*
+ *
+ * In the case of init script commands other than "status"
+ * (i.e., "start", "stop", "restart", "reload", and "force-reload"),
+ * the init script must return an exit status of zero if the action
+ * described by the argument has been successful. Otherwise, the
+ * exit status shall be non-zero, as defined below. In addition
+ * to straightforward success, the following situations are also
+ * to be considered successful:
+ *
+ * restarting a service (instead of reloading it) with the
+ * "force-reload" argument
+ * running "start" on a service already running
+ * running "stop" on a service already stopped or not running
+ * running "restart" on a service already stopped or not running
+ * In case of an error, while processing any init script action
+ * except for "status", the init script must print an error
+ * message and return one of the following non-zero exit
+ * status codes.
+ *
+ * 1 generic or unspecified error (current practice)
+ * 2 invalid or excess argument(s)
+ * 3 unimplemented feature (for example, "reload")
+ * 4 user had insufficient privilege
+ * 5 program is not installed
+ * 6 program is not configured
+ * 7 program is not running
+ * 8-99 reserved for future LSB use
+ * 100-149 reserved for distribution use
+ * 150-199 reserved for application use
+ * 200-254 reserved
+ *
+ * All error messages must be printed on standard error.
+ * All status messages must be printed on standard output.
+ * (This does not prevent scripts from calling the logging
+ * functions such as log_failure_msg).
+ */
+#define LSB_EXIT_OK 0
+#define LSB_EXIT_GENERIC 1
+#define LSB_EXIT_EINVAL 2
+#define LSB_EXIT_ENOTSUPPORTED 3
+#define LSB_EXIT_EPERM 4
+#define LSB_EXIT_NOTINSTALLED 5
+#define LSB_EXIT_NOTCONFIGED 6
+#define LSB_EXIT_NOTRUNNING 7
+#define LSB_EXIT_LSBRESERVED 8
+#define LSB_EXIT_DISTRESERVED 100
+#define LSB_EXIT_APPRESERVED 150
+#define LSB_EXIT_RESERVED 200
diff --git a/include/clplumbing/md5.h b/include/clplumbing/md5.h
new file mode 100644
index 0000000..95b2c33
--- /dev/null
+++ b/include/clplumbing/md5.h
@@ -0,0 +1,49 @@
+/*
+ * md5.h: MD5 and keyed-MD5 algorithms
+ *
+ * Author: Sun Jiang Dong <sunjd@cn.ibm.com>
+ * Copyright (c) 2005 International Business Machines
+ *
+ * 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
+ *
+ */
+
+#ifndef _MD5_H_
+#define _MD5_H__
+
+/*
+ * MD5: The MD5 Message-Digest Algorithm ( RFC 1321 )
+ * return value: 0 - success
+ * <0 - fail
+ * Note: The digest buffer should be not less than 16.
+ *
+ */
+int MD5( const unsigned char *data
+ , unsigned long data_len
+ , unsigned char * digest);
+
+/*
+ * HMAC: Keyed-Hashing for Message Authentication
+ * return value: 0 - success
+ * <0 - fail
+ * Note: The digest buffer should be not less than 16.
+ */
+int HMAC( const unsigned char * key
+ , unsigned int key_len
+ , const unsigned char * data
+ , unsigned long data_len
+ , unsigned char * digest);
+
+#endif
diff --git a/include/clplumbing/mkstemp_mode.h b/include/clplumbing/mkstemp_mode.h
new file mode 100644
index 0000000..ff5f893
--- /dev/null
+++ b/include/clplumbing/mkstemp_mode.h
@@ -0,0 +1,34 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * A slightly safer version of mkstemp(3)
+ *
+ * In this version, the file is initially created mode 0, (using umask) and
+ * then chmod-ed to the requested permissions after calling mkstemp(3).
+ * This guarantees that the file is not even momentarily open beyond the
+ * requested permissions.
+ *
+ * Return values:
+ *
+ * Like mkstemp, it returns the file descriptor of the open file, or -1
+ * on error.
+ *
+ * In addition to the errno values documented for mkstemp(3), this functio
+ * can also fail with any of the errno values documented for chmod(2).
+ *
+ */
+int mkstemp_mode(char* template, mode_t requested_filemode);
diff --git a/include/clplumbing/netstring.h b/include/clplumbing/netstring.h
new file mode 100644
index 0000000..ef24e8f
--- /dev/null
+++ b/include/clplumbing/netstring.h
@@ -0,0 +1,48 @@
+/*
+ * Intracluster message object (struct ha_msg)
+ *
+ * Copyright (C) 1999, 2000 Guochun Shi<gshi@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
+ *
+ */
+
+#ifndef NET_STRING_H
+#define NET_STRING_H
+#include <stdlib.h>
+#include <stdio.h>
+#include <ha_msg.h>
+
+extern gboolean cl_msg_quiet_fmterr;
+
+/* Convert a message to netstring data */
+char* msg2netstring(const struct ha_msg*, size_t*);
+char * msg2netstring_noauth(const struct ha_msg *m, size_t * slen);
+
+/* Convert netstring data to a message */
+struct ha_msg * netstring2msg(const char*, size_t, int);
+
+/* Is this netstring authentic? */
+int is_auth_netstring(const char* datap, size_t datalen,
+ const char* authstring, size_t authlen);
+
+void cl_set_authentication_computation_method(int (*method)(int authmethod
+, const void * data
+, size_t datalen
+, char * authstr
+, size_t authlen));
+
+#endif
diff --git a/include/clplumbing/proctrack.h b/include/clplumbing/proctrack.h
new file mode 100644
index 0000000..975ff1b
--- /dev/null
+++ b/include/clplumbing/proctrack.h
@@ -0,0 +1,120 @@
+/*
+ * Process tracking object.
+ *
+ * Copyright (c) 2002 International Business Machines
+ * Author: Alan Robertson <alanr@unix.sh>
+ *
+ * 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
+ *
+ */
+
+#ifndef _PROCTRACK_H
+# define _PROCTRACK_H
+#include <sys/types.h>
+#include <sys/times.h>
+#include <clplumbing/longclock.h>
+
+/*
+ * We track processes, mainly so we can do something appropriate
+ * when they die, and find processes should we need to kill them...
+ */
+
+typedef struct _ProcTrack ProcTrack;
+typedef struct _ProcTrack_ops ProcTrack_ops;
+typedef struct _ProcTrackKillInfo ProcTrackKillInfo;
+
+/*
+ * The levels of logging possible for our process
+ */
+enum _ProcTrackLogType {
+ PT_LOGNONE = 2, /* Exits never automatically logged */
+ PT_LOGNORMAL, /* Automatically log abnormal exits */
+ PT_LOGVERBOSE /* Automatically log every exit */
+};
+typedef enum _ProcTrackLogType ProcTrackLogType;
+
+#define proctrack_pid(p) (p)->pid
+#define proctrack_data(p) (p)->privatedata
+#define reset_proctrack_data(p) (p)->privatedata = NULL
+#define proctrack_timedout(p) ((p)->timeoutseq > 0)
+
+struct _ProcTrack {
+ pid_t pid;
+ int isapgrp;
+ ProcTrackLogType loglevel;
+ void * privatedata;
+ ProcTrack_ops* ops;
+
+ longclock_t startticks;
+ TIME_T starttime;
+ unsigned timerid;
+ int timeoutseq;
+ ProcTrackKillInfo* killinfo;
+};
+
+/*
+ * The set of operations to perform on our tracked processes.
+ */
+struct _ProcTrack_ops {
+
+ /* Called when a process dies */
+ void (*procdied)
+ (ProcTrack* p, int status, int signo, int exitcode
+ , int waslogged);
+
+ /* Called when a process registers */
+ void (*procregistered)
+ (ProcTrack*p);
+
+ /* Returns a "name" for a process (for messages) */
+ /* (may have to be copied, because it may be a static value) */
+ const char *
+ (*proctype)
+ (ProcTrack* p);
+};
+
+struct _ProcTrackKillInfo {
+ long mstimeout; /* Timeout in milliseconds */
+ int signalno; /* Signal number to issue @ timeout */
+};
+
+/* A function for calling by the process table iterator */
+typedef void (*ProcTrackFun) (ProcTrack* p, void * data);
+
+/* Call this function to activate the procdied member function */
+/* Returns TRUE if 'pid' was registered */
+int ReportProcHasDied(int pid, int status);
+
+/* Create/Log a new tracked process */
+void NewTrackedProc(pid_t pid, int isapgrp, ProcTrackLogType loglevel
+, void * privatedata , ProcTrack_ops* ops);
+
+/* "info" is 0-terminated (terminated by a 0 signal) */
+int SetTrackedProcTimeouts(pid_t pid, ProcTrackKillInfo* info);
+void RemoveTrackedProcTimeouts(pid_t pid);
+
+/* Return information associated with the given PID (or NULL) */
+ProcTrack* GetProcInfo(pid_t pid);
+
+/*
+ * Iterate over the set of tracked processes.
+ * If proctype is NULL, then walk through them all, otherwise only those
+ * of the given type ("f")
+ */
+void ForEachProc(ProcTrack_ops* proctype, ProcTrackFun f, void * data);
+
+void DisableProcLogging(void); /* Useful for shutdowns */
+void EnableProcLogging(void);
+#endif
diff --git a/include/clplumbing/realtime.h b/include/clplumbing/realtime.h
new file mode 100644
index 0000000..45eb76c
--- /dev/null
+++ b/include/clplumbing/realtime.h
@@ -0,0 +1,65 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CLPLUMBING_REALTIME_H
+# define _CLPLUMBING_REALTIME_H
+# include <sched.h>
+
+#if defined(SCHED_RR) && defined(_POSIX_PRIORITY_SCHEDULING) && !defined(ON_DARWIN)
+# define DEFAULT_REALTIME_POLICY SCHED_RR
+#endif
+
+/*
+ *
+ * make_realtime() will make the current process a soft realtime process
+ * and lock it into memory after growing the heap by heapgrowK*1024 bytes
+ *
+ * If you set spolicy or priority to <= 0, then defaults will be used.
+ * Otherwise you need to use a value for spolicy from <sched.h>
+ * and use an appropriate priority for the given spolicy.
+ *
+ * WARNING: badly behaved programs which use the make_realtime() function
+ * can easily hang the machine.
+ */
+
+void cl_make_realtime
+( int spolicy, /* SCHED_RR or SCHED_FIFO (or SCHED_OTHER) */
+ int priority, /* typically 1-99 */
+ int stackgrowK, /* Amount to grow stack by */
+ int heapgrowK /* Amount to grow heap by */
+);
+
+void cl_make_normaltime(void);
+
+/* Cause calls to make_realtime() to be ignored */
+void cl_disable_realtime(void);
+
+/* Cause calls to make_realtime() to be accepted.
+ * This is the default behaviour */
+void cl_enable_realtime(void);
+
+/* Sleep a really short (the shortest) time */
+int cl_shortsleep(void);
+
+/* Print messages if we've done (more) non-realtime mallocs */
+void cl_realtime_malloc_check(void);
+
+/* Number of times we "go to the well" for memory after becoming realtime */
+int cl_nonrealtime_malloc_count(void);
+/* Number of bytes we "got from the well" for memory after becoming realtime */
+unsigned long cl_nonrealtime_malloc_size(void);
+
+#endif
diff --git a/include/clplumbing/replytrack.h b/include/clplumbing/replytrack.h
new file mode 100644
index 0000000..f98fe48
--- /dev/null
+++ b/include/clplumbing/replytrack.h
@@ -0,0 +1,208 @@
+/*
+ * Process tracking object.
+ *
+ * Copyright (c) 2007 Alan Robertson
+ * Author: Alan Robertson <alanr@unix.sh>
+ *
+ * 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
+ *
+ */
+
+#ifndef _REPLYTRACK_H
+# define _REPLYTRACK_H
+#include <sys/types.h>
+#include <sys/times.h>
+#include <clplumbing/longclock.h>
+#include <clplumbing/cl_uuid.h>
+
+/*
+ * We track replies - so we can tell when all expected replies were received.
+ *
+ * There is a problem in clusters where a message is sent to each node, and a
+ * reply is expected from each node of knowing when all the replies have been
+ * received.
+ *
+ * If all nodes are up, it's easy to see when all replies are received.
+ * But, if some nodes are down, we really don't want to wait for a timeout
+ * before we decide that we've gotten all the replies we're going to get,
+ * since nodes can be down for potentially very long periods of time, and
+ * waiting for a long timeout can delay things a great deal again and
+ * again - causing significant delays and user frustration.
+ *
+ * That's where these functions come in!
+ * Instead, inform these functions what nodes are up and what ones are down,
+ * and when you receive a reply, and it will tell you when you've gotten
+ * them all - managing all that tedious bookwork for you.
+ */
+
+typedef enum _replytrack_completion_type replytrack_completion_type_t;
+typedef enum _nodetrack_change nodetrack_change_t;
+typedef struct _replytrack replytrack_t;
+typedef struct _nodetrack nodetrack_t;
+typedef struct _nodetrack_intersection nodetrack_intersection_t;
+
+/*
+ * The levels of logging possible for our process
+ */
+enum _replytrack_completion_type {
+ REPLYT_ALLRCVD = 2, /* All replies received */
+ REPLYT_TIMEOUT, /* Timeout occurred with replies missing */
+};
+
+
+typedef void (*replytrack_callback_t)
+( replytrack_t * rl
+, gpointer user_data
+, replytrack_completion_type_t reason);
+
+typedef void (*replytrack_iterator_t)
+( replytrack_t* rl
+, gpointer user_data
+, const char* node
+, cl_uuid_t uuid);
+
+typedef void (*nodetrack_iterator_t)
+( nodetrack_t* rl
+, gpointer user_data
+, const char* node
+, cl_uuid_t uuid);
+
+
+/*
+ * Note:
+ * If you use the timeout feature of this code, it relies on you using glib mainloop
+ * for your scheduling. timeout_ms should be zero for no timeout.
+ */
+replytrack_t* replytrack_new(nodetrack_t* membership
+, replytrack_callback_t callback
+, unsigned long timeout_ms
+, gpointer user_data);
+
+void replytrack_del(replytrack_t *rl);
+gboolean replytrack_gotreply(replytrack_t *rl
+, const char * node
+, cl_uuid_t uuid);
+ /* Returns TRUE if this was the final expected reply */
+/*
+ * Iterate over the set of outstanding replies:
+ * return count of how many items in the iteration
+ */
+int replytrack_outstanding_iterate(replytrack_t* rl
+, replytrack_iterator_t i, gpointer user_data);
+int replytrack_outstanding_count(replytrack_t* rl);
+
+/*
+ * The functions above operate using a view of membership which is established
+ * through the functions below.
+ *
+ * This can either be through the heartbeat low-level membership API, or any
+ * other view of membership you wish. Mentioning a node as either up or down
+ * will automatically add that node to our view of potential membership.
+ *
+ * These functions only support one view of membership per process.
+ *
+ * The general idea of how to use these functions:
+ * Initially:
+ * 1) iterate through init membership and call nodetrack_node(up|down) for
+ * each node to start things off.
+ *
+ * On an ongoing basis:
+ * 2) call nodetrack_node_up whenever a node comes up
+ * We expect a reply from nodes that are up.
+ * 3) call nodetrack_node_down whenever a node goes down
+ * We don't expect a reply from nodes that are down.
+ *
+ * For each set of replies you want tracked:
+ * 4) Create a replytrack_t for a set of expected replies
+ * 5) call replytrack_gotreply() each time you get an expected reply
+ * 6) replist_gotreply() returns TRUE when the final message was received.
+ * (it does this by comparing against the membership as defined below)
+ * 7) you will get a callback when timeout occurs or final message is received
+ * n. b.:
+ * No callback function => manage timeouts yourself
+ * 8) call replytrack_del() when you're done with the reply list
+ * n. b.:
+ * If you have replies outstanding, and you have a timeout and
+ * a callback function set, you will get a warning for destroying
+ * a replytrack_t object 'prematurely'.
+ * You will also log a warning if you call replytrack_gotreply() after
+ * all replies were received or a timeout occurred.
+ *
+ */
+
+/*
+ * The levels of logging possible for our process
+ */
+enum _nodetrack_change {
+ NODET_UP = 2, /* This node came up */
+ NODET_DOWN, /* This node went down */
+};
+
+typedef void (*nodetrack_callback_t)
+( nodetrack_t * mbr
+, const char * node
+, cl_uuid_t u
+, nodetrack_change_t reason
+, gpointer user_data);
+
+nodetrack_t* nodetrack_new(nodetrack_callback_t callback
+, gpointer user_data);
+void nodetrack_del(nodetrack_t*);
+gboolean nodetrack_nodeup(nodetrack_t* mbr, const char * node
+, cl_uuid_t u);
+gboolean nodetrack_nodedown(nodetrack_t* mbr, const char * node
+, cl_uuid_t u);
+gboolean nodetrack_ismember(nodetrack_t* mbr, const char * node
+, cl_uuid_t u);
+int nodetrack_iterate(nodetrack_t* mbr
+, nodetrack_iterator_t i, gpointer user_data);
+
+/* An intesection nodetrack table
+ * A node is put into the "intersection" nodetrack_t table when it is in all
+ * the underlying constituent nodetrack_t tables, and removed when it is
+ * removed from any of them.
+ * Note that you can set a callback to be informed when these "intersection"
+ * membership changes occur.
+ */
+nodetrack_intersection_t*
+ nodetrack_intersection_new(nodetrack_t** tables, int ntables
+, nodetrack_callback_t callback, gpointer user_data);
+void nodetrack_intersection_del(nodetrack_intersection_t*);
+nodetrack_t* nodetrack_intersection_table(nodetrack_intersection_t*);
+
+#if 0
+/*
+ * I don't know if this should be in this library, or just in
+ * the CCM. Probably only the CCM _should_ be using it (when I write it)
+ */
+/*
+ * Use of the nodetrack_hb_* functions implies you're using the heartbeat
+ * peer-connectivity information as your source of information. This is
+ * really only suitable if you're using heartbeat's low-level group membership
+ * for your source of who to expect replies from.
+ * If you're using nodetrack_hb_init, this replaces step (1) above.
+ */
+void nodetrack_hb_init(void)
+/*
+ * If you're using nodetrack_hb_statusmsg, just pass it all status messages
+ * and all peer-connectivity status messages or even all heartbeat messages
+ * (non-status messages will be ignored).
+ * This replaces steps (2) and (3) above _if_ you're using heartbeat low
+ * level membership for your source of who to expect replies from.
+ */
+void nodetrack_hb_statusmsg(struct ha_msg* statusmsg);
+#endif /*0*/
+
+#endif
diff --git a/include/clplumbing/setproctitle.h b/include/clplumbing/setproctitle.h
new file mode 100644
index 0000000..5caeef0
--- /dev/null
+++ b/include/clplumbing/setproctitle.h
@@ -0,0 +1,64 @@
+/*
+ * setproctitle.h
+ *
+ * The code in this file, setproctitle.h is heavily based on code from
+ * proftpd, please see the licening information below.
+ *
+ * This file added to the heartbeat tree by Horms <horms@vergenet.net>
+ *
+ * Code to portably change the title of a programme as displayed
+ * by ps(1).
+ *
+ * heartbeat: Linux-HA heartbeat code
+ *
+ * Copyright (C) 1999,2000,2001 Alan Robertson <alanr@unix.sh>
+ *
+ * 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.
+ */
+
+/*
+ * ProFTPD - FTP server daemon
+ * Copyright (c) 1997, 1998 Public Flood Software
+ * Copyright (C) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
+ *
+ * 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.
+ *
+ * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu
+ * and other respective copyright holders give permission to link this program
+ * with OpenSSL, and distribute the resulting executable, without including
+ * the source code for OpenSSL in the source distribution.
+ */
+
+#ifndef _HA_SETPROCTITLE_H
+#define _HA_SETPROCTITLE_H
+
+#include <glib.h>
+int init_set_proc_title(int argc, char *argv[], char *envp[]);
+
+void set_proc_title(const char *fmt,...) G_GNUC_PRINTF(1,2);
+
+#endif /* _HA_SETPROCTITLE_H */
diff --git a/include/clplumbing/timers.h b/include/clplumbing/timers.h
new file mode 100644
index 0000000..669ac21
--- /dev/null
+++ b/include/clplumbing/timers.h
@@ -0,0 +1,23 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CLPLUMBING_TIMERS_H
+# define _CLPLUMBING_TIMERS_H
+int setmsrepeattimer(long ms);
+int setmsalarm(long ms);
+int cancelmstimer(void);
+long mssleep(long ms);
+#endif
diff --git a/include/clplumbing/uids.h b/include/clplumbing/uids.h
new file mode 100644
index 0000000..89ba303
--- /dev/null
+++ b/include/clplumbing/uids.h
@@ -0,0 +1,32 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef CLPLUMBING_UIDS_H
+# define CLPLUMBING_UIDS_H
+#include <sys/types.h>
+
+/* Tell us who you want to be - or zero for nobody */
+int drop_privs(uid_t uid, gid_t gid);
+
+/* Return to original privileged state */
+int return_to_orig_privs(void);
+
+/* Drop down to (probably nobody) privileges again */
+int return_to_dropped_privs(void);
+
+/* Return TRUE if we have full privileges at the moment */
+int cl_have_full_privs(void);
+#endif