summaryrefslogtreecommitdiffstats
path: root/include
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
parentInitial commit. (diff)
downloadcluster-glue-e9be59e1502a41bab9891d96d753102a7dafef0b.tar.xz
cluster-glue-e9be59e1502a41bab9891d96d753102a7dafef0b.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')
-rw-r--r--include/Makefile.am25
-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
-rw-r--r--include/compress.h50
-rw-r--r--include/glue_config.h.in104
-rw-r--r--include/ha_msg.h464
-rw-r--r--include/lha_internal.h182
-rw-r--r--include/lrm/Makefile.am22
-rw-r--r--include/lrm/lrm_api.h455
-rw-r--r--include/lrm/lrm_msg.h160
-rw-r--r--include/lrm/racommon.h29
-rw-r--r--include/lrm/raexec.h157
-rw-r--r--include/pils/Makefile.am25
-rw-r--r--include/pils/generic.h118
-rw-r--r--include/pils/interface.h159
-rw-r--r--include/pils/plugin.h.in736
-rw-r--r--include/replace_uuid.h50
-rw-r--r--include/stonith/Makefile.am25
-rw-r--r--include/stonith/expect.h61
-rw-r--r--include/stonith/st_ttylock.h21
-rw-r--r--include/stonith/stonith.h187
-rw-r--r--include/stonith/stonith_plugin.h125
54 files changed, 6137 insertions, 0 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..2e07275
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2008 Andrew Beekhof
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+MAINTAINERCLEANFILES = Makefile.in
+SUBDIRS = clplumbing pils stonith lrm
+
+idir=$(includedir)/heartbeat
+i_HEADERS = compress.h glue_config.h ha_msg.h
+
+noinst_HEADERS = config.h lha_internal.h replace_uuid.h
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
diff --git a/include/compress.h b/include/compress.h
new file mode 100644
index 0000000..9cd733c
--- /dev/null
+++ b/include/compress.h
@@ -0,0 +1,50 @@
+/*
+ * compress.h: Compression functions for Linux-HA
+ *
+ * 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 _COMPRESS_H_
+#define _COMPRESS_H_
+
+#define HB_COMPRESS_TYPE compress
+#define HB_COMPRESS_TYPE_S "compress"
+
+/*
+ * List of functions provided by implementations of the heartbeat
+ * compress interface.
+ */
+struct hb_compress_fns {
+ int (*compress) (char*, size_t*, const char*, size_t);
+ int (*decompress) (char*, size_t* , const char*, size_t);
+ const char* (*getname) (void);
+};
+
+struct ha_msg;
+
+/* set the compression method*/
+int cl_compress_remove_plugin(const char* pluginname);
+int cl_compress_load_plugin(const char* pluginname);
+struct hb_compress_fns* cl_get_compress_fns(void);
+int cl_set_compress_fns(const char*);
+char* cl_compressmsg(struct ha_msg*m, size_t* len);
+struct ha_msg* cl_decompressmsg(struct ha_msg* m);
+gboolean is_compressed_msg(struct ha_msg* m);
+int cl_compress_field(struct ha_msg* msg, int index, char* buf, size_t* buflen);
+int cl_decompress_field(struct ha_msg* msg, int index, char* buf, size_t* buflen);
+
+#endif
diff --git a/include/glue_config.h.in b/include/glue_config.h.in
new file mode 100644
index 0000000..0850a63
--- /dev/null
+++ b/include/glue_config.h.in
@@ -0,0 +1,104 @@
+/* include/config.h.in. Generated from configure.in by autoheader. */
+
+/* Location for daemons */
+#undef GLUE_DAEMON_DIR
+
+/* Group to run daemons as */
+#undef GLUE_DAEMON_GROUP
+
+/* User to run daemons as */
+#undef GLUE_DAEMON_USER
+
+/* Where to keep state files and sockets */
+#undef GLUE_STATE_DIR
+
+/* Location of shared data */
+#undef GLUE_SHARED_DIR
+
+/* User to run daemons as */
+#undef HA_CCMUSER
+
+/* Group to run daemons as */
+#undef HA_APIGROUP
+
+/* Location for daemons */
+#undef HA_LIBHBDIR
+
+/* top directory of area to drop core files in */
+#undef HA_COREDIR
+
+/* top directory for LRM related files */
+#undef LRM_VARLIBDIR
+
+/* CIB secrets */
+#undef LRM_CIBSECRETS
+
+/* Logging Daemon IPC socket name */
+#undef HA_LOGDAEMON_IPC
+
+/* Default logging facility */
+#undef HA_LOG_FACILITY
+
+/* Default plugin search path */
+#undef PILS_BASE_PLUGINDIR
+
+/* Where to find plugins */
+#undef HA_PLUGIN_DIR
+
+/* Location of system configuration files */
+#undef HA_SYSCONFDIR
+
+/* Web site base URL */
+#undef HA_URLBASE
+
+/* Whatever this used to mean */
+#undef HA_VARLIBHBDIR
+
+#undef HA_VARLIBDIR
+
+/* System lock directory */
+#undef HA_VARLOCKDIR
+
+/* Where Heartbeat keeps state files and sockets - old name */
+#undef HA_VARRUNDIR
+
+/* Location for v1 Heartbeat RAs */
+#undef HB_RA_DIR
+
+/* Where to find LRM plugins */
+#undef LRM_PLUGIN_DIR
+
+/* Location for LSB RAs */
+#undef LSB_RA_DIR
+
+/* Location for OCF RAs */
+#undef OCF_RA_DIR
+
+/* OCF root directory - specified by the OCF standard */
+#undef OCF_ROOT_DIR
+
+/* Compiling for Darwin platform */
+#undef ON_DARWIN
+
+/* Compiling for Linux platform */
+#undef ON_LINUX
+
+/* Current glue version */
+#undef GLUE_VERSION
+
+/* Build version */
+#undef GLUE_BUILD_VERSION
+
+/* Location of non-pluing stonith scripts */
+#undef STONITH_EXT_PLUGINDIR
+
+/* Location of RHCS stonith scripts */
+#undef STONITH_RHCS_PLUGINDIR
+
+/* Location of stonith plugins */
+#undef STONITH_MODULES
+
+/* Stonith plugin domain */
+#undef ST_TEXTDOMAIN
+
+#undef HA_HBCONF_DIR
diff --git a/include/ha_msg.h b/include/ha_msg.h
new file mode 100644
index 0000000..fcb6cf6
--- /dev/null
+++ b/include/ha_msg.h
@@ -0,0 +1,464 @@
+/*
+ * Intracluster message object (struct ha_msg)
+ *
+ * Copyright (C) 1999, 2000 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 _HA_MSG_H
+# define _HA_MSG_H 1
+#include <stdio.h>
+#include <clplumbing/cl_log.h>
+#include <clplumbing/ipc.h>
+#include <clplumbing/longclock.h>
+#include <clplumbing/cl_uuid.h>
+#include <compress.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+enum cl_netstring_type{
+ FT_STRING = 0,
+ FT_BINARY,
+ FT_STRUCT,
+ FT_LIST,
+ FT_COMPRESS,
+ FT_UNCOMPRESS
+};
+
+enum cl_msgfmt{
+ MSGFMT_NVPAIR,
+ MSGFMT_NETSTRING
+};
+
+
+#define NEEDHEAD 1
+#define NOHEAD 0
+#define HA_MSG_ASSERT(X) do{ if(!(X)){ \
+ cl_log(LOG_ERR, "Assertion failed on line %d in file \"%s\"" \
+ , __LINE__, __FILE__); \
+ abort(); \
+ } \
+ }while(0)
+
+typedef struct hb_msg_stats_s {
+ unsigned long totalmsgs; /* Total # of messages */
+ /* ever handled */
+ unsigned long allocmsgs; /* # Msgs currently allocated */
+ longclock_t lastmsg;
+}hb_msg_stats_t;
+
+struct ha_msg {
+ int nfields;
+ int nalloc;
+ char ** names;
+ size_t* nlens;
+ void ** values;
+ size_t* vlens;
+ int * types;
+};
+
+typedef struct ha_msg HA_Message;
+
+struct fieldtypefuncs_s{
+
+ /* memfree frees the memory involved*/
+ void (*memfree)(void*);
+
+ /* dup makes a complete copy of the field*/
+ void* (*dup)(const void*, size_t);
+
+ /* display printout the field*/
+ void (*display)(int, int, char* , void*, int);
+
+ /* add the field into a message*/
+ int (*addfield) (struct ha_msg* msg, char* name, size_t namelen,
+ void* value, size_t vallen, int depth);
+
+ /* return the string length required to add this field*/
+ int (*stringlen) (size_t namlen, size_t vallen, const void* value);
+
+ /* return the netstring length required to add this field*/
+ int (*netstringlen) (size_t namlen, size_t vallen, const void* value);
+
+ /* print the field into the provided buffer, convert it first */
+ /* if ncecessary*/
+ int (*tostring)(char*, char*, void* ,size_t,int);
+
+ /* print the field into the provided buffer*/
+ int (*tonetstring)(char*, char*, char*, size_t,
+ void*, size_t, int, size_t*);
+
+ /* convert the given string to a field
+ note: this functions involves allocate memory for
+ for the field
+ */
+ int (*stringtofield)(void*, size_t, int depth, void**, size_t* );
+
+ /* convert the given netstring to a field
+ note: this functions involves allocate memory for
+ for the field
+ */
+ int (*netstringtofield)(const void*, size_t, void**, size_t*);
+
+ /* action before packing*/
+ int (*prepackaction)(struct ha_msg* m, int index);
+
+ /* action before a user get the value of a field*/
+ int (*pregetaction)(struct ha_msg* m, int index);
+
+};
+
+#define NUM_MSG_TYPES 6
+extern struct fieldtypefuncs_s fieldtypefuncs[NUM_MSG_TYPES];
+
+#define MSG_NEEDAUTH 0x01
+#define MSG_ALLOWINTR 0X02
+#define MSG_NEEDCOMPRESS 0x04
+#define MSG_NOSIZECHECK 0x08
+
+#define IFACE "!^!\n"
+#define MSG_START ">>>\n"
+#define MSG_END "<<<\n"
+#define MSG_START_NETSTRING "###\n"
+#define MSG_END_NETSTRING "%%%\n"
+#define EQUAL "="
+
+#define MAXDEPTH 16 /* Maximum recursive message depth */
+#define MAXLENGTH 1024
+
+ /* Common field names for our messages */
+#define F_TYPE "t" /* Message type */
+#define F_SUBTYPE "subt" /* Message type */
+#define F_ORIG "src" /* Real Originator */
+#define F_ORIGUUID "srcuuid" /* Real Originator uuid*/
+#define F_NODE "node" /* Node being described */
+#define F_NODELIST "nodelist" /* Node list being described */
+#define F_DELNODELIST "delnodelist" /* Del node list being described */
+#define F_TO "dest" /* Destination (optional) */
+#define F_TOUUID "destuuid" /* Destination uuid(optional) */
+#define F_STATUS "st" /* New status (type = status) */
+#define F_WEIGHT "weight" /* weight of node */
+#define F_SITE "site" /* site of node */
+#define F_PROTOCOL "protocol" /* Protocol number for communication*/
+#define F_CLIENTNAME "cn" /* Client name */
+#define F_CLIENTSTATUS "cs" /* Client status */
+#define F_TIME "ts" /* Timestamp */
+#define F_SEQ "seq" /* Sequence number */
+#define F_LOAD "ld" /* Load average */
+#define F_COMMENT "info" /* Comment */
+#define F_TTL "ttl" /* Time To Live */
+#define F_AUTH "auth" /* Authentication string */
+#define F_HBGENERATION "hg" /* Heartbeat generation number */
+#define F_CLIENT_GENERATION "client_gen" /* client generation number*/
+#define F_FIRSTSEQ "firstseq" /* Lowest seq # to retransmit */
+#define F_LASTSEQ "lastseq" /* Highest seq # to retransmit */
+#define F_RESOURCES "rsc_hold" /* What resources do we hold? */
+#define F_FROMID "from_id" /* from Client id */
+#define F_TOID "to_id" /* To client id */
+#define F_PID "pid" /* PID of client */
+#define F_UID "uid" /* uid of client */
+#define F_GID "gid" /* gid of client */
+#define F_ISSTABLE "isstable" /* true/false for RESOURCES */
+#define F_APIREQ "reqtype" /* API request type for "hbapi" */
+#define F_APIRESULT "result" /* API request result code */
+#define F_IFNAME "ifname" /* Interface name */
+#define F_PNAME "pname" /* Parameter name */
+#define F_PVALUE "pvalue" /* Parameter name */
+#define F_DEADTIME "deadtime" /* Dead time interval in ms. */
+#define F_KEEPALIVE "keepalive" /* Keep alive time interval in ms. */
+#define F_LOGFACILITY "logfacility" /* Suggested cluster syslog facility */
+#define F_NODETYPE "nodetype" /* Type of node */
+#define F_NUMNODES "numnodes" /* num of total nodes(excluding ping nodes*/
+#define F_RTYPE "rtype" /* Resource type */
+#define F_ORDERSEQ "oseq" /* Order Sequence number */
+#define F_DT "dt" /* Dead time field for heartbeat*/
+#define F_ACKSEQ "ackseq" /* The seq number this msg is acking*/
+#define F_CRM_DATA "crm_xml"
+#define F_XML_TAGNAME "__name__"
+#define F_STATE "state" /*used in ccm for state info*/
+
+
+ /* Message types */
+#define T_STATUS "status" /* Status (heartbeat) */
+#define T_IFSTATUS "ifstat" /* Interface status */
+#define T_ASKRESOURCES "ask_resources" /* Let other node ask my resources */
+#define T_ASKRELEASE "ip-request" /* Please give up these resources... */
+#define T_ACKRELEASE "ip-request-resp"/* Resources given up... */
+#define T_QCSTATUS "query-cstatus" /* Query client status */
+#define T_RCSTATUS "respond-cstatus"/* Respond client status */
+#define T_STONITH "stonith" /* Stonith return code */
+#define T_SHUTDONE "shutdone" /* External Shutdown complete */
+#define T_CRM "crmd" /* Cluster resource manager message */
+#define T_ATTRD "attrd" /* Cluster resource manager message */
+#define T_ADDNODE "addnode" /* Add node message*/
+#define T_DELNODE "delnode" /* Delete node message*/
+#define T_SETWEIGHT "setweight" /* Set node weight*/
+#define T_SETSITE "setsite" /* Set node site*/
+#define T_REQNODES "reqnodes" /* Request node list */
+#define T_REPNODES "repnodes" /* reply node list rquest*/
+
+#define T_APIREQ "hbapi-req" /* Heartbeat API request */
+#define T_APIRESP "hbapi-resp" /* Heartbeat API response */
+#define T_APICLISTAT "hbapi-clstat" /* Client status notification" */
+
+#define NOSEQ_PREFIX "NS_" /* PREFIX: Give no sequence number */
+ /* Used for messages which can't be retransmitted */
+ /* Either they're protocol messages or from dumb (ping) endpoints */
+#define T_REXMIT NOSEQ_PREFIX "rexmit" /* Rexmit request */
+#define T_NAKREXMIT NOSEQ_PREFIX "nak_rexmit" /* NAK Rexmit request */
+#define T_NS_STATUS NOSEQ_PREFIX "st" /* ping status */
+#define T_ACKMSG NOSEQ_PREFIX "ackmsg" /* ACK message*/
+
+/* Messages associated with nice_failback */
+#define T_STARTING "starting" /* Starting Heartbeat */
+ /* (requesting resource report) */
+#define T_RESOURCES "resource" /* Resources report */
+
+/* Messages associated with stonith completion results */
+#define T_STONITH_OK "OK" /* stonith completed successfully */
+#define T_STONITH_BADHOST "badhost" /* stonith failed */
+#define T_STONITH_BAD "bad" /* stonith failed */
+#define T_STONITH_NOTCONFGD "n_stnth" /* no stonith device configured */
+#define T_STONITH_UNNEEDED "unneeded" /* STONITH not required */
+
+/* Set up message statistics area */
+
+int netstring_extra(int);
+int cl_msg_stats_add(longclock_t time, int size);
+
+void cl_msg_setstats(volatile hb_msg_stats_t* stats);
+void cl_dump_msgstats(void);
+void cl_set_compression_threshold(size_t threadhold);
+void cl_set_traditional_compression(gboolean value);
+
+/* Allocate new (empty) message */
+struct ha_msg * ha_msg_new(int nfields);
+
+/* Free message */
+void ha_msg_del(struct ha_msg *msg);
+
+/* Copy message */
+struct ha_msg* ha_msg_copy(const struct ha_msg *msg);
+
+int ha_msg_expand(struct ha_msg* msg );
+
+/*Add a null-terminated name and binary value to a message*/
+int ha_msg_addbin(struct ha_msg * msg, const char * name,
+ const void * value, size_t vallen);
+
+int ha_msg_adduuid(struct ha_msg * msg, const char * name,
+ const cl_uuid_t* uuid);
+
+/* Add null-terminated name and a value to the message */
+int ha_msg_add(struct ha_msg * msg
+ , const char* name, const char* value);
+
+int cl_msg_remove(struct ha_msg* msg, const char* name);
+int cl_msg_remove_value(struct ha_msg* msg, const void* value);
+int cl_msg_remove_offset(struct ha_msg* msg, int offset);
+
+/* Modify null-terminated name and a value to the message */
+int cl_msg_modstring(struct ha_msg * msg,
+ const char* name,
+ const char* value);
+int cl_msg_modbin(struct ha_msg * msg,
+ const char* name,
+ const void* value,
+ size_t vlen);
+
+int cl_msg_moduuid(struct ha_msg * msg, const char * name,
+ const cl_uuid_t* uuid);
+
+int cl_msg_modstruct(struct ha_msg * msg,
+ const char* name,
+ const struct ha_msg* value);
+#define ha_msg_mod(msg, name, value) cl_msg_modstring(msg, name, value)
+int cl_msg_replace(struct ha_msg* msg, int index,
+ const void* value, size_t vlen, int type);
+int cl_msg_replace_value(struct ha_msg* msg, const void *old_value,
+ const void* value, size_t vlen, int type);
+
+/* Add name, value (with known lengths) to the message */
+int ha_msg_nadd(struct ha_msg * msg, const char * name, int namelen
+ , const char * value, int vallen);
+
+/* Add a name/value/type to a message (with sizes for name and value) */
+int ha_msg_nadd_type(struct ha_msg * msg, const char * name, int namelen
+ , const char * value, int vallen, int type);
+
+/* Add name=value string to a message */
+int ha_msg_add_nv(struct ha_msg* msg, const char * nvline, const char * bufmax);
+
+
+/* Return value associated with particular name */
+#define ha_msg_value(m,name) cl_get_string(m, name)
+
+/* Call wait(in|out) but only for a finite time */
+int cl_ipc_wait_timeout(
+ IPC_Channel * chan, int (*waitfun)(IPC_Channel * chan), unsigned int timeout);
+
+/* Reads an IPC stream -- converts it into a message */
+struct ha_msg * msgfromIPC_timeout(IPC_Channel *ch, int flag, unsigned int timeout, int *rc_out);
+struct ha_msg * msgfromIPC(IPC_Channel * f, int flag);
+
+IPC_Message * ipcmsgfromIPC(IPC_Channel * ch);
+
+/* Reads a stream -- converts it into a message */
+struct ha_msg * msgfromstream(FILE * f);
+
+/* Reads a stream with string format--converts it into a message */
+struct ha_msg * msgfromstream_string(FILE * f);
+
+/* Reads a stream with netstring format--converts it into a message */
+struct ha_msg * msgfromstream_netstring(FILE * f);
+
+/* Same as above plus copying the iface name to "iface" */
+struct ha_msg * if_msgfromstream(FILE * f, char *iface);
+
+/* Writes a message into a stream */
+int msg2stream(struct ha_msg* m, FILE * f);
+
+/* Converts a message into a string and adds the iface name on start */
+char * msg2if_string(const struct ha_msg *m, const char * iface);
+
+/* Converts a string gotten via UDP into a message */
+struct ha_msg * string2msg(const char * s, size_t length);
+
+/* Converts a message into a string */
+char * msg2string(const struct ha_msg *m);
+
+/* Converts a message into a string in the provided buffer with certain
+depth and with or without start/end */
+int msg2string_buf(const struct ha_msg *m, char* buf,
+ size_t len, int depth, int needhead);
+
+/* Converts a message into wire format */
+char* msg2wirefmt(struct ha_msg *m, size_t* );
+char* msg2wirefmt_noac(struct ha_msg*m, size_t* len);
+
+/* Converts wire format data into a message */
+struct ha_msg* wirefmt2msg(const char* s, size_t length, int flag);
+
+/* Convets wire format data into an IPC message */
+IPC_Message* wirefmt2ipcmsg(void* p, size_t len, IPC_Channel* ch);
+
+/* Converts an ha_msg into an IPC message */
+IPC_Message* hamsg2ipcmsg(struct ha_msg* m, IPC_Channel* ch);
+
+/* Converts an IPC message into an ha_msg */
+struct ha_msg* ipcmsg2hamsg(IPC_Message*m);
+
+/* Outputs a message to an IPC channel */
+int msg2ipcchan(struct ha_msg*m, IPC_Channel*ch);
+
+/* Outpus a message to an IPC channel without authencating
+the message */
+struct ha_msg* msgfromIPC_noauth(IPC_Channel * ch);
+
+/* Reads from control fifo, and creates a new message from it */
+/* This adds the default sequence#, load avg, etc. to the message */
+struct ha_msg * controlfifo2msg(FILE * f);
+
+/* Check if the message is authenticated */
+gboolean isauthentic(const struct ha_msg * msg);
+
+/* Get the required string length for the given message */
+int get_stringlen(const struct ha_msg *m);
+
+/* Get the requried netstring length for the given message*/
+int get_netstringlen(const struct ha_msg *m);
+
+/* Add a child message to a message as a field */
+int ha_msg_addstruct(struct ha_msg * msg, const char * name, const void* ptr);
+
+int ha_msg_addstruct_compress(struct ha_msg*, const char*, const void*);
+
+/* Get binary data from a message */
+const void * cl_get_binary(const struct ha_msg *msg, const char * name, size_t * vallen);
+
+/* Get uuid data from a message */
+int cl_get_uuid(const struct ha_msg *msg, const char * name, cl_uuid_t* retval);
+
+/* Get string data from a message */
+const char * cl_get_string(const struct ha_msg *msg, const char *name);
+
+/* Get the type for a field from a message */
+int cl_get_type(const struct ha_msg *msg, const char *name);
+
+/* Get a child message from a message*/
+struct ha_msg *cl_get_struct(struct ha_msg *msg, const char* name);
+
+/* Log the contents of a message */
+void cl_log_message (int log_level, const struct ha_msg *m);
+
+/* Supply messaging system with old style authentication/authorization method */
+void cl_set_oldmsgauthfunc(gboolean (*authfunc)(const struct ha_msg*));
+
+/* Set default messaging format */
+void cl_set_msg_format(enum cl_msgfmt mfmt);
+
+/* Add a string to a list*/
+int cl_msg_list_add_string(struct ha_msg* msg, const char* name, const char* value);
+
+/* Return length of a list*/
+int cl_msg_list_length(struct ha_msg* msg, const char* name);
+
+/* Return nth element of a list*/
+void* cl_msg_list_nth_data(struct ha_msg* msg, const char* name, int n);
+
+/* Functions to add/mod/get an integer */
+int ha_msg_add_int(struct ha_msg * msg, const char * name, int value);
+int ha_msg_mod_int(struct ha_msg * msg, const char * name, int value);
+int ha_msg_value_int(const struct ha_msg * msg, const char * name, int* value);
+
+/* Functions to add/mod/get an unsigned long */
+int ha_msg_add_ul(struct ha_msg * msg, const char * name, unsigned long value);
+int ha_msg_mod_ul(struct ha_msg * msg, const char * name, unsigned long value);
+int ha_msg_value_ul(const struct ha_msg * msg, const char * name, unsigned long* value);
+
+/* Functions to add/get a string list*/
+GList* ha_msg_value_str_list(struct ha_msg * msg, const char * name);
+
+int cl_msg_add_list_int(struct ha_msg* msg, const char* name,
+ int* buf, size_t n);
+int cl_msg_get_list_int(struct ha_msg* msg, const char* name,
+ int* buf, size_t* n);
+GList* cl_msg_get_list(struct ha_msg* msg, const char* name);
+int cl_msg_add_list(struct ha_msg* msg, const char* name, GList* list);
+int cl_msg_add_list_str(struct ha_msg* msg, const char* name,
+ char** buf, size_t n);
+
+/* Function to add/get a string hash table*/
+GHashTable* ha_msg_value_str_table(struct ha_msg * msg, const char * name);
+int ha_msg_add_str_table(struct ha_msg * msg, const char * name,
+ GHashTable* hash_table);
+int ha_msg_mod_str_table(struct ha_msg * msg, const char * name,
+ GHashTable* hash_table);
+
+/*internal use for list type*/
+size_t string_list_pack_length(const GList* list);
+int string_list_pack(GList* list, char* buf, char* maxp);
+GList* string_list_unpack(const char* packed_str_list, size_t length);
+void list_cleanup(GList* list);
+
+gboolean must_use_netstring(const struct ha_msg*);
+
+
+#endif /* __HA_MSG_H */
diff --git a/include/lha_internal.h b/include/lha_internal.h
new file mode 100644
index 0000000..bae10a0
--- /dev/null
+++ b/include/lha_internal.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2001 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ */
+
+#ifndef LHA_INTERNAL_H
+# define LHA_INTERNAL_H
+
+#define EOS '\0'
+#define DIMOF(a) ((int) (sizeof(a)/sizeof(a[0])) )
+#define STRLEN_CONST(conststr) ((size_t)((sizeof(conststr)/sizeof(char))-1))
+#define STRNCMP_CONST(varstr, conststr) strncmp((varstr), conststr, STRLEN_CONST(conststr)+1)
+#define STRLEN(c) STRLEN_CONST(c)
+#define MALLOCT(t) ((t *) malloc(sizeof(t)))
+
+#define HADEBUGVAL "HA_DEBUG" /* current debug value (if nonzero) */
+#define HALOGD "HA_LOGD" /* whether we use logging daemon or not */
+
+/* Needs to be defined before any other includes, otherwise some system
+ * headers do not behave as expected! Major black magic... */
+#undef _GNU_SOURCE /* in case it was defined on the command line */
+#define _GNU_SOURCE
+
+/* Please leave this as the first #include - Solaris needs it there */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#ifdef BSD
+# define SCANSEL_CAST (void *)
+#else
+# define SCANSEL_CAST /* Nothing */
+#endif
+
+#if defined(ANSI_ONLY) && !defined(inline)
+# define inline /* nothing */
+# undef NETSNMP_ENABLE_INLINE
+# define NETSNMP_NO_INLINE 1
+#endif
+
+#ifndef HAVE_DAEMON
+ /* We supply a replacement function, but need a prototype */
+int daemon(int nochdir, int noclose);
+#endif /* HAVE_DAEMON */
+
+#ifndef HAVE_SETENV
+ /* We supply a replacement function, but need a prototype */
+int setenv(const char *name, const char * value, int why);
+#endif /* HAVE_SETENV */
+
+#ifndef HAVE_UNSETENV
+ /* We supply a replacement function, but need a prototype */
+int unsetenv(const char *name);
+#endif /* HAVE_UNSETENV */
+
+#ifndef HAVE_STRERROR
+ /* We supply a replacement function, but need a prototype */
+char * strerror(int errnum);
+#endif /* HAVE_STRERROR */
+
+#ifndef HAVE_SCANDIR
+ /* We supply a replacement function, but need a prototype */
+# include <dirent.h>
+int
+scandir (const char *directory_name,
+ struct dirent ***array_pointer,
+ int (*select_function) (const struct dirent *),
+#ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT
+ /* This is what the Linux man page says */
+ int (*compare_function) (const struct dirent**, const struct dirent**)
+#else
+ /* This is what the Linux header file says ... */
+ int (*compare_function) (const void *, const void *)
+#endif
+ );
+#endif /* HAVE_SCANDIR */
+
+#ifndef HAVE_ALPHASORT
+# include <dirent.h>
+int
+alphasort(const void *dirent1, const void *dirent2);
+#endif /* HAVE_ALPHASORT */
+
+#ifndef HAVE_INET_PTON
+ /* We supply a replacement function, but need a prototype */
+int
+inet_pton(int af, const char *src, void *dst);
+
+#endif /* HAVE_INET_PTON */
+
+#ifndef HAVE_STRNLEN
+ size_t strnlen(const char *s, size_t maxlen);
+#else
+# define USE_GNU
+#endif
+
+#ifndef HAVE_STRNDUP
+ char *strndup(const char *str, size_t len);
+#else
+# define USE_GNU
+#endif
+#ifndef HAVE_STRLCPY
+ size_t strlcpy(char * dest, const char *source, size_t len);
+#endif
+#ifndef HAVE_STRLCAT
+ size_t strlcat(char * dest, const char *source, size_t len);
+#endif
+
+#ifndef HAVE_NFDS_T
+ typedef unsigned int nfds_t;
+#endif
+
+#ifdef HAVE_STRUCT_UCRED_DARWIN
+# include <sys/utsname.h>
+# ifndef SYS_NMLN
+# define SYS_NMLN _SYS_NAMELEN
+# endif /* SYS_NMLN */
+#endif
+
+#define POINTER_TO_SIZE_T(p) ((size_t)(p)) /*pointer cast as size_t*/
+#define POINTER_TO_SSIZE_T(p) ((ssize_t)(p)) /*pointer cast as ssize_t*/
+#define POINTER_TO_ULONG(p) ((unsigned long)(p)) /*pointer cast as unsigned long*/
+ /* Sometimes we get a const g_something *, but need to pass it internally
+ * to other functions taking a non-const g_something *, which results
+ * with gcc and -Wcast-qual in a compile time warning, and with -Werror
+ * even to a compile time error.
+ * Workarounds have been to e.g. memcpy(&list, _list); or similar,
+ * the reason of which is non-obvious to the casual reader.
+ * This macro achieves the same, and annotates why it is done.
+ */
+#define UNCONST_CAST_POINTER(t, p) ((t)(unsigned long)(p))
+
+#define HAURL(url) HA_URLBASE url
+
+/*
+ * Some compilers may not have defined __FUNCTION__.
+ */
+#ifndef __FUNCTION__
+
+/* Sun studio compiler */
+# ifdef __SUNPRO_C
+# define __FUNCTION__ __func__
+# endif
+
+/* Similarly add your compiler here ... */
+
+#endif
+
+/* You may need to change this for your compiler */
+#ifdef HAVE_STRINGIZE
+# define ASSERT(X) {if(!(X)) ha_assert(#X, __LINE__, __FILE__);}
+#else
+# define ASSERT(X) {if(!(X)) ha_assert("X", __LINE__, __FILE__);}
+#endif
+
+/* shamelessly stolen from linux kernel */
+/* Force a compilation error if condition is true */
+#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))
+/* Force a compilation error if condition is true, but also produce a
+ * result (of value 0 and type size_t), so the expression can be used
+ * e.g. in a structure initializer (or where-ever else comma expressions
+ * aren't permitted). */
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
+#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
+
+#endif /* LHA_INTERNAL_H */
diff --git a/include/lrm/Makefile.am b/include/lrm/Makefile.am
new file mode 100644
index 0000000..ec4f5a5
--- /dev/null
+++ b/include/lrm/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Author: Sun Jiang Dong <sunjd@cn.ibm.com>
+# Copyright (c) 2004 International Business Machines
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+MAINTAINERCLEANFILES = Makefile.in
+
+idir=$(includedir)/heartbeat/lrm
+i_HEADERS = lrm_api.h lrm_msg.h racommon.h raexec.h
diff --git a/include/lrm/lrm_api.h b/include/lrm/lrm_api.h
new file mode 100644
index 0000000..cebff1b
--- /dev/null
+++ b/include/lrm/lrm_api.h
@@ -0,0 +1,455 @@
+/*
+ * Client-side Local Resource Manager API.
+ *
+ * Author: Huang Zhen <zhenh@cn.ibm.com>
+ * Copyright (C) 2004 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
+ *
+ */
+
+/*
+ *
+ * By Huang Zhen <zhenhltc@cn.ibm.com> 2004/2/23
+ *
+ * It is based on the works of Alan Robertson, Lars Marowsky Bree,
+ * Andrew Beekhof.
+ *
+ * The Local Resource Manager needs to provide the following functionalities:
+ * 1. Provide the information of the resources holding by the node to its
+ * clients, including listing the resources and their status.
+ * 2. Its clients can add new resources to lrm or remove from it.
+ * 3. Its clients can ask lrm to operate the resources, including start,
+ * restart, stop and so on.
+ * 4. Provide the information of the lrm itself, including what types of
+ * resource are supporting by lrm.
+ *
+ * The typical clients of lrm are crm and lrmadmin.
+ */
+
+ /*
+ * Notice:
+ * "status" indicates the exit status code of "status" operation
+ * its value is defined in LSB, OCF...
+ *
+ * "state" indicates the state of resource, maybe LRM_RSC_BUSY, LRM_RSC_IDLE
+ *
+ * "op_status" indicates how the op exit. like LRM_OP_DONE,LRM_OP_CANCELLED,
+ * LRM_OP_TIMEOUT,LRM_OP_NOTSUPPORTED.
+ *
+ * "rc" is the return code of an opertioan. it's value is in following enum
+ * which is defined in "raexec.h"
+ * enum UNIFORM_RET_EXECRA {
+ * EXECRA_EXEC_UNKNOWN_ERROR = -2,
+ * EXECRA_NO_RA = -1,
+ * EXECRA_OK = 0,
+ * EXECRA_UNKNOWN_ERROR = 1,
+ * EXECRA_INVALID_PARAM = 2,
+ * EXECRA_UNIMPLEMENT_FEATURE = 3,
+ * EXECRA_INSUFFICIENT_PRIV = 4,
+ * EXECRA_NOT_INSTALLED = 5,
+ * EXECRA_NOT_CONFIGURED = 6,
+ * EXECRA_NOT_RUNNING = 7,
+ *
+ * EXECRA_RA_DEAMON_DEAD1 = 11,
+ * EXECRA_RA_DEAMON_DEAD2 = 12,
+ * EXECRA_RA_DEAMON_STOPPED = 13,
+ * EXECRA_STATUS_UNKNOWN = 14
+ * };
+ */
+
+#ifndef __LRM_API_H
+#define __LRM_API_H 1
+
+#include <glib.h>
+#include <lrm/raexec.h>
+#include <clplumbing/GSource.h>
+
+#define LRM_PROTOCOL_MAJOR 0
+#define LRM_PROTOCOL_MINOR 1
+#define LRM_PROTOCOL_VERSION ((LRM_PROTCOL_MAJOR << 16) | LRM_PROTOCOL_MINOR)
+
+#define RID_LEN 128
+
+/*lrm's client uses this structure to access the resource*/
+typedef struct
+{
+ char* id;
+ char* type;
+ char* class;
+ char* provider;
+ GHashTable* params;
+ struct rsc_ops* ops;
+}lrm_rsc_t;
+
+
+/*used in struct lrm_op_t to show how an operation exits*/
+typedef enum {
+ LRM_OP_PENDING = -1,
+ LRM_OP_DONE,
+ LRM_OP_CANCELLED,
+ LRM_OP_TIMEOUT,
+ LRM_OP_NOTSUPPORTED,
+ LRM_OP_ERROR
+}op_status_t;
+
+/*for all timeouts: in milliseconds. 0 for no timeout*/
+
+/*this structure is the information of the operation.*/
+
+#define EVERYTIME -1
+#define CHANGED -2
+
+/* Notice the interval and target_rc
+ *
+ * when interval==0, the operation will be executed only once
+ * when interval>0, the operation will be executed repeatly with the interval
+ *
+ * when target_rc==EVERYTIME, the client will be notified every time the
+ * operation executed.
+ * when target_rc==CHANGED, the client will be notified when the return code
+ * is different with the return code of last execute of the operation
+ * when target_rc is other value, only when the return code is the same of
+ * target_rc, the client will be notified.
+ */
+
+typedef struct{
+ /*input fields*/
+ char* op_type;
+ GHashTable* params;
+ int timeout;
+ char* user_data;
+ int user_data_len;
+ int interval;
+ int start_delay;
+ int copyparams; /* copy parameters to the rsc */
+ int target_rc;
+
+ /*output fields*/
+ op_status_t op_status;
+ int rc;
+ int call_id;
+ char* output;
+ char* rsc_id;
+ char* app_name;
+ char* fail_reason;
+ unsigned long t_run; /* when did the op run (as age) */
+ unsigned long t_rcchange; /* last rc change (as age) */
+ unsigned long exec_time; /* time it took the op to run */
+ unsigned long queue_time; /* time spent in queue */
+ int rsc_deleted; /* resource just deleted? */
+}lrm_op_t;
+
+extern const lrm_op_t lrm_zero_op; /* an all-zeroes lrm_op_t value */
+
+lrm_op_t* lrm_op_new(void);
+void lrm_free_op(lrm_op_t* op);
+void lrm_free_rsc(lrm_rsc_t* rsc);
+void lrm_free_str_list(GList* list);
+void lrm_free_op_list(GList* list);
+void lrm_free_str_table(GHashTable* table);
+
+
+/*this enum is used in get_cur_state*/
+typedef enum {
+ LRM_RSC_IDLE,
+ LRM_RSC_BUSY
+}state_flag_t;
+
+/* defaults for the asynchronous resource failures */
+enum { DEFAULT_FAIL_RC = EXECRA_UNKNOWN_ERROR };
+#define DEFAULT_FAIL_REASON "asynchronous monitor error"
+#define ASYNC_OP_NAME "asyncmon"
+
+/* in addition to HA_OK and HA_FAIL */
+#define HA_RSCBUSY 2
+
+struct rsc_ops
+{
+/*
+ *perform_op: Performs the operation on the resource.
+ *Notice: op is the operation which need to pass to RA and done asyn
+ *
+ *op: the structure of the operation. Caller can create the op by
+ * lrm_op_new() and release the op using lrm_free_op()
+ *
+ *return: All operations will be asynchronous.
+ * The call will return the call id or failed code immediately.
+ * The call id will be passed to the callback function
+ * when the operation finished later.
+ */
+ int (*perform_op) (lrm_rsc_t*, lrm_op_t* op);
+
+
+/*
+ *cancel_op: cancel the operation on the resource.
+ *
+ *callid: the call id returned by perform_op()
+ *
+ *return: HA_OK for success, HA_FAIL for failure op not found
+ * or other failure
+ * NB: the client always gets a notification over callback
+ * even for operations which were idle (of course, if
+ * the request has been accepted for processing)
+ */
+ int (*cancel_op) (lrm_rsc_t*, int call_id);
+
+/*
+ *flush_ops: throw away all operations queued for this resource,
+ * and return them as cancelled.
+ *
+ *return: HA_OK for success, HA_FAIL for failure
+ * NB: op is not flushed unless it is idle;
+ * in that case this call will block
+ */
+ int (*flush_ops) (lrm_rsc_t*);
+
+/*
+ *get_cur_state:
+ * return the current state of the resource
+ *
+ *cur_state: current state of the resource
+ *
+ *return: cur_state should be in LRM_RSC_IDLE or LRM_RSC_BUSY.
+ * and the function returns a list of ops.
+ * the list includes:
+ * 1. last ops for each type (start/stop/etc) from current client
+ * 2. current pending ops
+ * 3. all recurring ops waiting to execute
+ * the list is sorted by the call_id of ops.
+ * client can release the list using lrm_free_op_list()
+ */
+ GList* (*get_cur_state) (lrm_rsc_t*, state_flag_t* cur_state);
+
+/*
+ *get_last_result:
+ * return the last op of given type from current client
+ *
+ *op_type: the given type
+ *
+ *return: the last op. if there is no such op, return NULL.
+ * client can release the op using lrm_free_op()
+ */
+ lrm_op_t* (*get_last_result)(lrm_rsc_t*, const char *op_type);
+};
+
+
+/*
+ *lrm_op_done_callback_t:
+ * this type of callback functions are called when some
+ * asynchronous operation is done.
+ * client can release op by lrm_free_op()
+ */
+typedef void (*lrm_op_done_callback_t) (lrm_op_t* op);
+
+
+typedef struct ll_lrm
+{
+ struct lrm_ops* lrm_ops;
+}ll_lrm_t;
+
+struct lrm_ops
+{
+ int (*signon) (ll_lrm_t*, const char * app_name);
+
+ int (*signoff) (ll_lrm_t*);
+
+ int (*delete) (ll_lrm_t*);
+
+ int (*set_lrm_callback) (ll_lrm_t*,
+ lrm_op_done_callback_t op_done_callback_func);
+
+/*
+ *set_lrmd_param: set lrmd parameter
+ *get_lrmd_param: get lrmd parameter
+ *
+ *return: HA_OK for success, HA_FAIL for failure
+ * NB: currently used only for max_child_count
+ */
+ int (*set_lrmd_param)(ll_lrm_t*, const char *name, const char *value);
+ char* (*get_lrmd_param)(ll_lrm_t*, const char *name);
+
+/*
+ int (*set_parameters)(ll_lrm_t*, const GHashTable* option);
+
+ GHashTable* (*get_all_parameters)(ll_lrm_t*);
+
+ char * (*get_parameter)(ll_lrm_t *, const char * paramname);
+
+ char * (*get_parameter_description)(ll_lrm_t*);
+*/
+
+/*
+ *get_rsc_class_supported:
+ * Returns the resource classes supported.
+ * e.g. ocf, heartbeat,lsb...
+ *
+ *return: a list of the names of supported resource classes.
+ * caller can release the list by lrm_free_str_list().
+ */
+ GList* (*get_rsc_class_supported)(ll_lrm_t*);
+
+/*
+ *get_rsc_type_supported:
+ * Returns the resource types supported of class rsc_class.
+ * e.g. drdb, apache,IPaddr...
+ *
+ *return: a list of the names of supported resource types.
+ * caller can release the list by lrm_free_str_list().
+ */
+ GList* (*get_rsc_type_supported)(ll_lrm_t*, const char* rsc_class);
+
+/*
+ *get_rsc_provider_supported:
+ * Returns the provider list of the given resource types
+ * e.g. heartbeat, failsafe...
+ *
+ *rsc_provider: if it is null, the default one will used.
+ *
+ *return: a list of the names of supported resource provider.
+ * caller can release the list by lrm_free_str_list().
+ */
+ GList* (*get_rsc_provider_supported)(ll_lrm_t*,
+ const char* rsc_class, const char* rsc_type);
+
+/*
+ *get_rsc_type_metadata:
+ * Returns the metadata of the resource type
+ *
+ *rsc_provider: if it is null, the default one will used.
+ *
+ *return: the metadata. use g_free() to free.
+ *
+ */
+ char* (*get_rsc_type_metadata)(ll_lrm_t*, const char* rsc_class,
+ const char* rsc_type, const char* rsc_provider);
+
+/*
+ *get_all_type_metadatas:
+ * Returns all the metadata of the resource type of the class
+ *
+ *return: A GHashtable, the key is the RA type,
+ * the value is the metadata.
+ * Now only default RA's metadata will be returned.
+ * please use lrm_free_str_table() to free the return value.
+ */
+ GHashTable* (*get_all_type_metadata)(ll_lrm_t*, const char* rsc_class);
+
+/*
+ *get_all_rscs:
+ * Returns all resources.
+ *
+ *return: a list of id of resources.
+ * caller can release the list by lrm_free_str_list().
+ */
+ GList* (*get_all_rscs)(ll_lrm_t*);
+
+
+/*
+ *get_rsc: Gets one resource pointer by the id
+ *
+ *return: the lrm_rsc_t type pointer, NULL for failure
+ * caller can release the pointer by lrm_free_rsc().
+ */
+ lrm_rsc_t* (*get_rsc)(ll_lrm_t*, const char* rsc_id);
+
+/*
+ *add_rsc: Adds a new resource to lrm.
+ * lrmd holds nothing when it starts.
+ * crm or lrmadmin should add resources to lrm using
+ * this function.
+ *
+ *rsc_id: An id which sould be generated by client,
+ * 128byte(include '\0') UTF8 string
+ *
+ *class: the class of the resource
+ *
+ *type: the type of the resource.
+ *
+ *rsc_provider: if it is null, the default provider will used.
+ *
+ *params: the parameters for the resource.
+ *
+ *return: HA_OK for success, HA_FAIL for failure
+ */
+ int (*add_rsc)(ll_lrm_t*, const char* rsc_id, const char* class,
+ const char* type, const char* provider, GHashTable* params);
+
+/*
+ *delete_rsc: delete the resource by the rsc_id
+ *
+ *return: HA_OK for success, HA_FAIL for failure
+ * NB: resource removal is delayed until all operations are
+ * removed; the client, however, gets the reply immediately
+ */
+ int (*delete_rsc)(ll_lrm_t*, const char* rsc_id);
+
+/*
+ *fail_rsc: fail a resource
+ * Allow asynchronous monitor failures. Notifies all clients
+ * which have operations defined for the resource.
+ * The fail_rc parameter should be set to one of the OCF
+ * return codes (if non-positive it defaults to
+ * OCF_ERR_GENERIC). The fail_reason parameter should
+ * contain the description of the failure (i.e. "daemon
+ * panicked" or similar). If NULL is passed or empty string,
+ * it defaults to "asynchronous monitor failure".
+ *
+ *return: HA_OK for success, HA_FAIL for failure
+ */
+ int (*fail_rsc)(ll_lrm_t* lrm, const char* rsc_id,
+ const int fail_rc, const char* fail_reason);
+/*
+ *ipcchan: Return the IPC channel which can be used for determining
+ * when messages are ready to be read.
+ *return: the IPC Channel
+ */
+
+ IPC_Channel* (*ipcchan)(ll_lrm_t*);
+
+/*
+ *msgready: Returns TRUE (1) when a message is ready to be read.
+ */
+ gboolean (*msgready)(ll_lrm_t*);
+
+/*
+ *rcvmsg: Cause the next message to be read - activating callbacks for
+ * processing the message. If no callback processes the message
+ * it will be ignored. The message is automatically disposed of.
+ *
+ *return: the count of message was received.
+ */
+ int (*rcvmsg)(ll_lrm_t*, int blocking);
+
+};
+
+/*
+ *ll_lrm_new:
+ * initializes the lrm client library.
+ *
+ *llctype: "lrm"
+ *
+ */
+ll_lrm_t* ll_lrm_new(const char * llctype);
+
+/*
+ *execra_code2string:
+ * Translate the return code of the operation to string
+ *
+ *code: the rc field in lrm_op_t structure
+ */
+const char *execra_code2string(uniform_ret_execra_t code);
+#endif /* __LRM_API_H */
+
diff --git a/include/lrm/lrm_msg.h b/include/lrm/lrm_msg.h
new file mode 100644
index 0000000..6f671e1
--- /dev/null
+++ b/include/lrm/lrm_msg.h
@@ -0,0 +1,160 @@
+/*
+ * Message Define For Local Resource Manager
+ *
+ * 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
+ *
+ */
+
+/*
+ * By Huang Zhen <zhenh@cn.ibm.com> 2004/2/23
+ *
+ */
+/*
+ * Notice:
+ *"status" indicates the exit status code of "status" operation
+ * its value is defined in LSB
+ *"state" indicates the state of resource, maybe LRM_RSC_BUSY, LRM_RSC_IDLE
+ *"opstate" indicates how the op exit.like LRM_OP_DONE,LRM_OP_CANCELLED,
+ * LRM_OP_TIMEOUT,LRM_OP_NOTSUPPORTED.
+ */
+#ifndef __LRM_MSG_H
+#define __LRM_MSG_H 1
+
+#include <lrm/lrm_api.h>
+
+#define LRM_CMDPATH HA_VARRUNDIR"/heartbeat/lrm_cmd_sock"
+#define LRM_CALLBACKPATH HA_VARRUNDIR"/heartbeat/lrm_callback_sock"
+
+/*define the field type used by lrm*/
+#define F_LRM_TYPE "lrm_t"
+#define F_LRM_APP "lrm_app"
+#define F_LRM_PID "lrm_pid"
+#define F_LRM_UID "lrm_uid"
+#define F_LRM_GID "lrm_gid"
+#define F_LRM_RID "lrm_rid"
+#define F_LRM_RTYPE "lrm_rtype"
+#define F_LRM_RTYPES "lrm_rtypes"
+#define F_LRM_RCLASS "lrm_rclass"
+#define F_LRM_RPROVIDER "lrm_rprovider"
+#define F_LRM_RPROVIDERS "lrm_rproviders"
+#define F_LRM_PARAM "lrm_param"
+#define F_LRM_COPYPARAMS "lrm_copyparams"
+#define F_LRM_TIMEOUT "lrm_timeout"
+#define F_LRM_OP "lrm_op"
+#define F_LRM_OPCNT "lrm_opcount"
+#define F_LRM_OPSTATUS "lrm_opstatus"
+#define F_LRM_RC "lrm_rc"
+#define F_LRM_RET "lrm_ret"
+#define F_LRM_CALLID "lrm_callid"
+#define F_LRM_RCOUNT "lrm_rcount"
+#define F_LRM_RIDS "lrm_rids"
+#define F_LRM_DATALEN "lrm_datalen"
+#define F_LRM_DATA "lrm_data"
+#define F_LRM_STATE "lrm_state"
+#define F_LRM_INTERVAL "lrm_interval"
+#define F_LRM_TARGETRC "lrm_targetrc"
+#define F_LRM_LASTRC "lrm_lastrc"
+#define F_LRM_STATUS "lrm_status"
+#define F_LRM_RSCDELETED "lrm_rscdeleted"
+#define F_LRM_METADATA "lrm_metadata"
+#define F_LRM_USERDATA "lrm_userdata"
+#define F_LRM_DELAY "lrm_delay"
+#define F_LRM_T_RUN "lrm_t_run"
+#define F_LRM_T_RCCHANGE "lrm_t_rcchange"
+#define F_LRM_EXEC_TIME "lrm_exec_time"
+#define F_LRM_QUEUE_TIME "lrm_queue_time"
+#define F_LRM_FAIL_REASON "lrm_fail_reason"
+#define F_LRM_ASYNCMON_RC "lrm_asyncmon_rc"
+#define F_LRM_LRMD_PARAM_NAME "lrm_lrmd_param_name"
+#define F_LRM_LRMD_PARAM_VAL "lrm_lrmd_param_val"
+
+#define PRINT printf("file:%s,line:%d\n",__FILE__,__LINE__);
+
+
+/*define the message typs between lrmd and client lib*/
+#define REGISTER "reg"
+#define GETRSCCLASSES "rclasses"
+#define GETRSCTYPES "rtypes"
+#define GETPROVIDERS "rproviders"
+#define GETRSCMETA "rmetadata"
+#define GETALLRCSES "getall"
+#define GETRSC "getrsc"
+#define GETLASTOP "getlastop"
+#define GETRSCSTATE "getstate"
+#define SETMONITOR "setmon"
+#define GETMONITORS "getmons"
+#define FLUSHRSC "flush"
+#define ADDRSC "addrsc"
+#define DELRSC "delrsc"
+#define FAILRSC "failrsc"
+#define PERFORMOP "op"
+#define ISOPSUPPORT "opspt"
+#define OPDONE "opdone"
+#define MONITOR "monitor"
+#define RETURN "return"
+#define FLUSHOPS "flushops"
+#define CANCELOP "cancelop"
+#define SETLRMDPARAM "setparam"
+#define GETLRMDPARAM "getparam"
+
+#define MAX_INT_LEN 64
+#define MAX_NAME_LEN 255
+#define MAX_VALUE_LEN 255
+#define MAX_PARAM_LEN 1024
+
+
+GHashTable* copy_str_table(GHashTable* hash_table);
+GHashTable* merge_str_tables(GHashTable* old, GHashTable* new);
+void free_str_table(GHashTable* hash_table);
+
+ /*
+ * message for no parameter, like unreg,types,getall
+ * they do not include any paramters
+ */
+struct ha_msg* create_lrm_msg(const char* msg);
+
+/*
+ * message for only one parameter - resource id,
+ * like getrsc,delrsc,flush,getstate,getmons
+ */
+struct ha_msg* create_lrm_rsc_msg(const char* rid, const char* msg);
+
+/* register client message */
+struct ha_msg* create_lrm_reg_msg(const char* app_name);
+
+/*
+ * add new resource
+ * according to the opinion of Lars, it is awkward that we combine all
+ * parameters in to one string. I think so too. So this call may changed soon
+ */
+struct ha_msg* create_lrm_addrsc_msg(const char* rid, const char* class,
+ const char* type, const char* provider, GHashTable* parameter);
+
+/*
+ *
+ *the return message from lrmd for reg,unreg,addrsc,delrsc,isopsupport.
+ *these return messages only include return code.
+ *
+ */
+struct ha_msg* create_lrm_ret(int rc, int fields);
+
+
+/*
+ * the return message for a status change monitoring.
+ */
+
+struct ha_msg* create_rsc_perform_op_msg (const char* rid, lrm_op_t* op);
+
+#endif /* __LRM_MSG_H */
diff --git a/include/lrm/racommon.h b/include/lrm/racommon.h
new file mode 100644
index 0000000..b16aa24
--- /dev/null
+++ b/include/lrm/racommon.h
@@ -0,0 +1,29 @@
+/*
+ * Author: Sun Jiang Dong <sunjd@cn.ibm.com>
+ * Copyright (c) 2004 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 RACOMMON_H
+#define RACOMMON_H
+
+void get_ra_pathname(const char* class_path, const char* type, const char* provider, char pathname[]);
+gboolean filtered(char * file_name);
+int get_runnable_list(const char* class_path, GList ** rsc_info);
+int get_failed_exec_rc(void);
+void closefiles(void);
+
+#endif /* RACOMMON_H */
diff --git a/include/lrm/raexec.h b/include/lrm/raexec.h
new file mode 100644
index 0000000..0b69831
--- /dev/null
+++ b/include/lrm/raexec.h
@@ -0,0 +1,157 @@
+/*
+ * raexec.h: The universal interface of RA Execution Plugin
+ *
+ * Author: Sun Jiang Dong <sunjd@cn.ibm.com>
+ * Copyright (c) 2004 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 RAEXEC_H
+#define RAEXEC_H
+#include <glib.h>
+#include <lrm/racommon.h>
+
+/* Uniform return value of executing RA */
+enum UNIFORM_RET_EXECRA {
+ EXECRA_EXEC_UNKNOWN_ERROR = -2,
+ EXECRA_NO_RA = -1,
+ EXECRA_OK = 0,
+ EXECRA_UNKNOWN_ERROR = 1,
+ EXECRA_INVALID_PARAM = 2,
+ EXECRA_UNIMPLEMENT_FEATURE = 3,
+ EXECRA_INSUFFICIENT_PRIV = 4,
+ EXECRA_NOT_INSTALLED = 5,
+ EXECRA_NOT_CONFIGURED = 6,
+ EXECRA_NOT_RUNNING = 7,
+ EXECRA_RUNNING_MASTER = 8,
+ EXECRA_FAILED_MASTER = 9,
+
+ /* For status command only */
+ EXECRA_RA_DEAMON_DEAD1 = 11,
+ EXECRA_RA_DEAMON_DEAD2 = 12,
+ EXECRA_RA_DEAMON_STOPPED = 13,
+ EXECRA_STATUS_UNKNOWN = 14
+};
+typedef enum UNIFORM_RET_EXECRA uniform_ret_execra_t;
+
+#define RA_MAX_NAME_LENGTH 240
+#define RA_MAX_DIRNAME_LENGTH 200
+#define RA_MAX_BASENAME_LENGTH 40
+
+/*
+ * RA Execution Interfaces
+ * The plugin usage is divided into two step. First to send out a command to
+ * execute a resource agent via calling function execra. Execra is a unblock
+ * function, always return at once. Then to call function post_query_result to
+ * get the RA exection result.
+*/
+struct RAExecOps {
+ /*
+ * Description:
+ * Launch a exection of a resource agent -- normally is a script
+ *
+ * Parameters:
+ * rsc_id: The resource instance id.
+ * rsc_type: The basename of a RA.
+ * op_type: The operation that hope RA to do, such as "start",
+ * "stop" and so on.
+ * cmd_params: The command line parameters need to be passed to
+ * the RA for a execution.
+ * env_params: The enviroment parameters need to be set for
+ * affecting the action of a RA execution. As for
+ * OCF style RA, it's the only way to pass
+ * parameter to the RA.
+ *
+ * Return Value:
+ * 0: RA execution is ok, while the exec_key is a valid value.
+ * -1: The RA don't exist.
+ * -2: There are invalid command line parameters.
+ * -3: Other unkown error when launching the execution.
+ */
+ int (*execra)(
+ const char * rsc_id,
+ const char * rsc_type,
+ const char * provider,
+ const char * op_type,
+ const int timeout,
+ GHashTable * params);
+
+ /*
+ * Description:
+ * Map the specific ret value to a uniform value.
+ *
+ * Parameters:
+ * ret_execra: the RA type specific ret value.
+ * op_type: the operation type
+ * std_output: the output which the RA write to stdout.
+ *
+ * Return Value:
+ * A uniform value without regarding RA type.
+ */
+ uniform_ret_execra_t (*map_ra_retvalue)(
+ int ret_execra
+ , const char * op_type
+ , const char * std_output);
+
+ /*
+ * Description:
+ * List all resource info of this class
+ *
+ * Parameters:
+ * rsc_info: a GList which item data type is rsc_info_t as
+ * defined above, containing all resource info of
+ * this class in the local machine.
+ *
+ * Return Value:
+ * >=0 : succeed. the RA type number of this RA class
+ * -1: failed due to invalid RA directory such as not existing.
+ * -2: failed due to other factors
+ */
+ int (*get_resource_list)(GList ** rsc_info);
+
+ /*
+ * Description:
+ * List all providers of this type
+ *
+ * Parameters:
+ * providers: a GList which item data type is string.
+ * the name of providers of the resource agent
+ *
+ * Return Value:
+ * >=0 : succeed. the provider number of this RA
+ * -1: failed due to invalid RA directory such as not existing.
+ * -2: failed due to other factors
+ */
+ int (*get_provider_list)(const char* ra_type, GList ** providers);
+
+ /*
+ * Description:
+ * List the metadata of the resource agent this class
+ *
+ * Parameters:
+ * rsc_type: the type of the ra
+ *
+ * Return Value:
+ * !NULL : succeed. the RA metadata.
+ * NULL: failed
+ */
+ char* (*get_resource_meta)(const char* rsc_type, const char* provider);
+};
+
+#define RA_EXEC_TYPE RAExec
+#define RA_EXEC_TYPE_S "RAExec"
+
+#endif /* RAEXEC_H */
diff --git a/include/pils/Makefile.am b/include/pils/Makefile.am
new file mode 100644
index 0000000..4b6c6a0
--- /dev/null
+++ b/include/pils/Makefile.am
@@ -0,0 +1,25 @@
+#
+# linux-ha: Linux-HA heartbeat code
+#
+# Copyright (C) 2001 Michael Moerz
+# This instance created by Horms
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+MAINTAINERCLEANFILES = Makefile.in
+
+idir=$(includedir)/pils
+
+i_HEADERS = generic.h interface.h plugin.h
diff --git a/include/pils/generic.h b/include/pils/generic.h
new file mode 100644
index 0000000..83bf3e3
--- /dev/null
+++ b/include/pils/generic.h
@@ -0,0 +1,118 @@
+#ifndef PILS_GENERIC_H
+#define PILS_GENERIC_H
+/*
+ * Copyright (C) 2000 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
+ *
+ *
+ * Generic interface (implementation) manager
+ *
+ * This manager will manage any number of types of interfaces.
+ *
+ * This means that when any implementations of our client interfaces register
+ * or unregister, it is us that makes their interfaces show up in the outside
+ * world.
+ *
+ * And, of course, we have to do this in a very generic way, since we have
+ * no idea about the client programs or interface types, or anything else.
+ *
+ * We do that by getting a parameter passed to us which tell us the names
+ * of the interface types we want to manage, and the address of a GHashTable
+ * for each type that we put the implementation in when they register
+ * themselves.
+ *
+ * So, each type of interface that we manage gets its own private
+ * GHashTable of the implementations of that type that are currently
+ * registered.
+ *
+ * For example, if we manage communication modules, their exported
+ * interfaces will be registered in a hash table. If we manage
+ * authentication modules, they'll have their (separate) hash table that
+ * their exported interfaces are registered in.
+ *
+ */
+#include <pils/interface.h>
+
+/*
+ * Header defintions for using the generic interface/implementation
+ * manager plugin.
+ */
+
+/*
+ * Notification types for the callback function.
+ */
+typedef enum {
+ PIL_REGISTER, /* Someone has registered an implementation */
+ PIL_UNREGISTER /* Someone has unregistered an implementation */
+}GenericPILCallbackType;
+
+/* A user callback for the generic interface manager */
+typedef int (*GenericPILCallback)
+( GenericPILCallbackType type /* Event type */
+, PILPluginUniv* univ /* pointer to plugin universe */
+, const char * iftype /* Interface type */
+, const char * ifname /* Implementation (interface) name */
+, void * userptr /* Whatever you want it to be ;-) */
+);
+
+/*
+ * Structures to declare the set of interface types we're managing.
+ */
+typedef struct {
+ const char * iftype; /* What type of interface is this? */
+ GHashTable** ifmap; /* Table with implementation info */
+ void* importfuns; /* Functions for interface to import */
+ GenericPILCallback callback; /* Function2call when events occur */
+ void* userptr; /* Passed to Callback function */
+}PILGenericIfMgmtRqst;
+/*
+ * What does this look like in practice?
+ *
+ * GHashTable* authmodules = NULL;
+ * GHashTable* commmodules = NULL;
+ * PILGenericIfMgmtRqst RegisterRequests[] =
+ * {
+ * {"auth", &authmodules, &authimports, NULL, NULL},
+ * {"comm", &commmodules, &commimports, NULL, NULL},
+ * {NULL, NULL, NULL, NULL, NULL}
+ // NULL entry must be here
+ * };
+ *
+ * PILPlugin* PluginUniverse;
+ *
+ * PluginUniverse = NewPILPlugin("/usr/lib/whatever/plugins");
+ *
+ * PILLoadPlugin(PluginUniverse, "InterfaceMgr", "generic", &RegisterRequests);
+ * // N. B.: Passing RegisterRequests as an argument is essential
+ *
+ * Then, when you load an auth module, its exported interface gets added
+ * to "authmodules". When you unload an auth module, it gets removed
+ * from authmodules.
+ *
+ * Then, when you load a comm module, its exported interfaces gets added
+ * to "commodules". When you unload a comm module, its exported
+ * interfaces get removed from "commodules"
+ *
+ * If there are simple changes that would be useful for this generic
+ * plugin manager, then "patches are being accepted" :-)
+ *
+ * On the other hand, If you don't like the way this plugin manager works
+ * in a broader way, you're free to write your own - it's just another
+ * plugin ;-)
+ */
+#endif
diff --git a/include/pils/interface.h b/include/pils/interface.h
new file mode 100644
index 0000000..5a5114e
--- /dev/null
+++ b/include/pils/interface.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2000 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 PILS_INTERFACE_H
+# define PILS_INTERFACE_H
+# ifndef PILS_PLUGIN_H
+# include <pils/plugin.h>
+# endif
+
+/*****************************************************************************
+ *
+ * The most basic interface type is the "IFManager" interface.
+ * Each interface manager registers and deals with interfaces of a given type.
+ *
+ * Such an interface must be loaded before any plugins of it's type can
+ * be loaded.
+ *
+ * In order to register any plugin of type "foo", we must load a interface of
+ * type "Interface" named "foo". This interface then manages the
+ * registration of all interfaces of type foo.
+ *
+ * To bootstrap, we load a interface of type "Interface" named "Interface"
+ * during the initialization of the plugin system.
+ *
+ * IFManagers will be autoloaded if certain conditions are met...
+ *
+ * If a IFManager is to be autoloaded, there must be one interface manager
+ * per file, and the file must be named according to the type of the
+ * interface it implements, and loaded in the directory named PI_IFMANAGER
+ * ("Interface").
+ *
+ */
+
+
+/*
+ * I'm unsure exactly which of the following structures
+ * are needed to write a interface, or a interface manager.
+ * We'll get that figured out and scope the defintions accordingly...
+ */
+
+/*
+ * PILInterface (AKA struct PILInterface_s) holds the information
+ * we use to track a single interface manager.
+ */
+
+
+struct PILInterface_s {
+ unsigned long MagicNum;
+ PILInterfaceType* interfacetype; /* Parent pointer */
+ char * interfacename; /* malloced interface name */
+ PILInterface* ifmanager; /* plugin managing us */
+ void* exports; /* Exported Functions */
+ /* for this interface */
+ PILInterfaceFun if_close; /* Interface close operation*/
+ void* ud_interface; /* per-interface user data */
+ int refcnt; /* Ref count for plugin */
+ PILPlugin* loadingpi; /* Plugin that loaded us */
+};
+/*
+ * PILInterfaceType (AKA struct PILInterfaceType_s) holds the info
+ * we use to track the set of all interfaces of a single kind.
+ */
+struct PILInterfaceType_s {
+ unsigned long MagicNum;
+ char* typename; /* Our interface type name */
+ GHashTable* interfaces; /* The set of interfaces
+ * of our type. The
+ * "values" are all
+ * PILInterface * objects
+ */
+ void* ud_if_type; /* per-interface-type user
+ data*/
+ PILInterfaceUniv* universe; /* Pointer to parent (up) */
+ PILInterface* ifmgr_ref; /* Pointer to our interface
+ manager */
+};
+
+/*
+ * PILInterfaceUniv (AKA struct PILInterfaceUniv_s) holds the information
+ * for all interfaces of all types. From our point of view this is
+ * our universe ;-)
+ */
+
+struct PILInterfaceUniv_s{
+ unsigned long MagicNum;
+ GHashTable* iftypes; /*
+ * Set of Interface Types
+ * The values are all
+ * PILInterfaceType objects
+ */
+ struct PILPluginUniv_s* piuniv; /* parallel universe of
+ * plugins
+ */
+};
+
+#ifdef ENABLE_PLUGIN_MANAGER_PRIVATE
+/*
+ * From here to the end is specific to interface managers.
+ * This data is only needed by interface managers, and the interface
+ * management system itself.
+ *
+ */
+typedef struct PILInterfaceOps_s PILInterfaceOps;
+
+
+/* Interfaces imported by a IFManager interface */
+struct PILInterfaceImports_s {
+
+ /* Return current reference count */
+ int (*RefCount)(PILInterface * eifinfo);
+
+ /* Incr/Decr reference count */
+ int (*ModRefCount)(PILInterface*eifinfo, int plusminus);
+
+ /* Unregister us as a interface */
+ void (*ForceUnRegister)(PILInterface *eifinfo);
+
+ /* For each client */
+ void (*ForEachClientDel)(PILInterface* manangerif
+ , gboolean(*f)(PILInterface* clientif, void * other)
+ , void* other);
+
+};
+
+/* Interfaces exported by an InterfaceManager interface */
+struct PILInterfaceOps_s{
+/*
+ * These are the interfaces exported by an InterfaceManager to the
+ * interface management infrastructure. These are not imported
+ * by interfaces - only the interface management infrastructure.
+ */
+
+ /* RegisterInterface - register this interface */
+ PIL_rc (*RegisterInterface)(PILInterface* newif
+ , void** imports);
+
+ PIL_rc (*UnRegisterInterface)(PILInterface*ifinfo); /* Unregister IF*/
+ /* And destroy PILInterface object */
+};
+
+#endif /* ENABLE_PLUGIN_MANAGER_PRIVATE */
+#endif /* PILS_INTERFACE_H */
diff --git a/include/pils/plugin.h.in b/include/pils/plugin.h.in
new file mode 100644
index 0000000..cb67d91
--- /dev/null
+++ b/include/pils/plugin.h.in
@@ -0,0 +1,736 @@
+/*
+ * Copyright (C) 2000 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 PILS_PLUGIN_H
+# define PILS_PLUGIN_H
+# include <ltdl.h>
+# include <glue_config.h>
+
+/* Glib headers generate warnings - so we make them go away */
+
+#define time FOOtime
+#define index FOOindex
+#include <glib.h>
+#undef index
+#undef time
+
+/*****************************************************************************
+ * PILS - Universal Plugin and Interface loading system
+ *****************************************************************************
+ *
+ * An Overview of PILS...
+ *
+ * PILS is fairly general and reasonably interesting plugin loading system.
+ * We manage both plugins and their interfaces
+ *
+ * This plugin / interface management system is quite general, and should be
+ * directly usable by basically any project on any platform on which it runs
+ * - which should be many, since everything is build with automake
+ * and libtool.
+ *
+ * Some terminology...
+ *
+ * There are two basic kinds of objects we deal with here:
+ *
+ * Plugins: dynamically loaded chunks of code which implement one or more
+ * interfaces. The system treats all plugins as the same.
+ * In UNIX, these are dynamically loaded ".so" files.
+ *
+ * Interface: A set of functions which implement a particular capability
+ * (or interface)
+ * Generally interfaces are registered as part of a plugin.
+ * The system treats all interfaces of the same type the same.
+ * It is common to have exactly one interface inside of each plugin.
+ * In this case, the interface name should match the plugin name.
+ *
+ * Each interface implementation exports certain functions for its clients
+ * to use. We refer to these those "Ops". Every interface of the same type
+ * "imports" the same interfaces from its interface manager,
+ * and exports the same "Ops".
+ *
+ * Each interface implementation is provided certain interfaces which it
+ * imports when it from its interface manager when it is registered.
+ * We refer to these as "Imports". Every interface of a given type
+ * imports the same interfaces.
+ *
+ * The story with plugins is a little different...
+ *
+ * Every plugin exports a certain set of interfaces, regardless of what type
+ * of interfaces is implemented by it. These are described in the
+ * PILPluginOps structure.
+ *
+ * Every plugin imports a certain set of interfaces, regardless of what type
+ * of interfaces it may implement. These are described by the
+ * PILPluginImports structure.
+ *
+ * In the function parameters below, the following notation will
+ * sometimes appear:
+ *
+ * (OP) == Output Parameter - a parameter which is modified by the
+ * function being called
+ *
+ *
+ *****************************************************************************
+ *
+ * The basic structures we maintain about plugins are as follows:
+ *
+ * PILPlugin The data which represents a plugin.
+ * PILPluginType The data common to all plugins of a given type
+ * PILPluginUniv The set of all plugin types in the Universe
+ * (well... at least *this* universe)
+ *
+ * The basic structures we maintain about interfaces are as follows:
+ * PILInterface The data which represents a interface
+ * PILInterfaceType The data which is common to all
+ * interfaces of a given type
+ * PILPluginUniv The set of all interface types in the Universe
+ * (well... at least *this* universe)
+ *
+ * Regarding "Universe"s. It is our intent that a given program can deal
+ * with plugins in more than one universe. This might occur if you have two
+ * independent libraries each of which uses the plugin loading environment
+ * to manage their own independent interface components. There should be
+ * no restriction in creating a program which uses both of these libraries.
+ * At least that's what we hope ;-)
+ *
+ *
+ ***************************************************************************
+ * SOME MORE DETAILS ABOUT PLUGINS...
+ ***************************************************************************
+ *
+ * Going back to more detailed data structures about plugins...
+ *
+ * PILPluginImports The set of standard functions all plugins
+ * import.
+ * This includes:
+ * register_plugin()
+ * unregister_plugin()
+ * register_interface()
+ * unregister_interface()
+ * load_plugin()
+ * log() Preferred logging function
+ *
+ * PILPluginOps The set of standard operations all plugins
+ * export.
+ * This includes:
+ * pluginversion()
+ * pluginname()
+ * getdebuglevel()
+ * setdebuglevel()
+ * close() Prepare for unloading...
+ *
+ * Although we treat plugins pretty much the same, they are still
+ * categorized into "types" - one type per directory. These types
+ * generally correspond to interface types.
+ *
+ * One can only cause a plugin to be loaded - not a interface. But it is
+ * common to assume that loading a plugin named foo of type bar will
+ * cause a interface named foo of type bar to be registered. If one
+ * wants to implement automatic plugin loading in a given interface type,
+ * this assumption is necessary.
+ *
+ * The general way this works is...
+ *
+ * - A request is made to load a particular plugin of a particular type.
+ *
+ * - The plugin is loaded from the appropriate directory for plugins
+ * of that type.
+ *
+ * - The ml_plugin_init() function is called once when the plugin is
+ * loaded.
+ *
+ * The ml_plugin_init() function is passed a vector of functions which
+ * point to functions it can call to register itself, etc.
+ * (it's of type PILPluginImports)
+ *
+ * The ml_plugin_init function then uses this set of imported functions
+ * to register itself and its interfaces.
+ *
+ * The mechanism of registering a interface is largely the same for
+ * every interface. However, the semantics of registering a interfaces
+ * is determined by the interface manager for the particular type of
+ * interface being discussed.
+ *
+ ***************************************************************************
+ * SOME MORE DETAILS ABOUT PLUGINS...
+ ***************************************************************************
+ *
+ * There is only one built in type of interface. That's the Interface
+ * manager interface.
+ * The interface manager for the interface of type "InterfaceMgr",
+ * named "InterfaceMgr" inserts itself into the system in order
+ * to bootstrap things...
+ *
+ * When an attempt is made to register a interface of an unknown type,
+ * then the appropriate Interface manager is loaded automatically.
+ *
+ * The name of an interface manager determines the type of
+ * interface it manages.
+ *
+ * It handles requests for interfaces whose type is the same
+ * as its interface name. If the interface manager's interface name
+ * is foo, then it is the interface manager for all interfaces whose
+ * type is foo.
+ *
+ * Types associated with interfaces of type Interface
+ *
+ * PILInterfaceOps The set of interfaces that every interface
+ * manager exports
+ * PILInterfaceImports The set of interfaces which are supplied to
+ * (imported by) every interface of type
+ * Interface. (that is, every interface
+ * manager).
+ *
+ *****************************************************************************
+ *
+ * Each plugin has only one entry point which is exported directly, regardless
+ * of what kind of interface(s) it may implement...
+ *
+ * This entrypoint is named ml_plugin_init() {more or less - see below}
+ *
+ * The ml_plugin_init() function is called once when the plugin is loaded.
+ *
+ *
+ * All other function pointers are registered (exported) through parameters
+ * passed to ml_plugin_init()
+ *
+ * It is the purpose of the Ml_plugin_init() to register the plugin,
+ * and all the interfaces which this plugin implements. A pointer to
+ * the registration function is in the parameters which are passed
+ * to ml_plugin_init().
+ *
+ *****************************************************************************
+ *
+ * THINGS IN THIS DESIGN WHICH ARE PROBABLY BROKEN...
+ *
+ * It may also be the case that the plugin loading environment needs
+ * to be able to have some kind of user_data passed to it which it can
+ * also pass along to any interface ...
+ *
+ * Maybe this should be handled by a sort of global user_data registration
+ * structure, so globals can be passed to interfaces when they're registered.
+ *
+ * A sort of "user_data" registry. One for each interface type and one
+ * for each interface... Or maybe it could be even more flexible...
+ *
+ * This is all so that these nice pristene, beautiful concepts can come out
+ * and work well in the real world where interfaces need to interact with
+ * some kind of global system view, and with each other...
+ *
+ * Probably need some better way of managing interface versions, etc.
+ *
+ ****************************************************************************
+ */
+
+/*
+ * If you want to use this funky export stuff, then you need to #define
+ * PIL_PLUGINTYPE and PIL_PLUGIN *before* including this file.
+ *
+ * The way to use this stuff is to declare your primary entry point this way:
+ *
+ * This example is for an plugin of type "auth" named "sha1"
+ *
+ * #define PIL_PLUGINTYPE auth
+ * #define PIL_PLUGIN sha1
+ * #include <upmls/PILPlugin.h>
+ *
+ * static const char* Ourpluginversion (void);
+ * static const char* Ourpluginname (void);
+ * static int Ourgetdebuglevel(void);
+ * static void Oursetdebuglevel(int);
+ * static void Ourclose (PILPlugin*);
+ *
+ * static struct PILPluginOps our_exported_plugin_operations =
+ * { Ourpluginversion,
+ * , Ourpluginname
+ * , Ourgetdebuglevel
+ * , Oursetdebuglevel
+ * , Ourclose
+ * };
+ *
+ * static const PILPluginImports* PluginOps;
+ * static PILPlugin* OurPlugin;
+ *
+ * // Our plugin initialization and registration function
+ * // It gets called when the plugin gets loaded.
+ * PIL_rc
+ * PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports)
+ * {
+ * PluginOps = imports;
+ * OurPlugin = us;
+ *
+ * // Register ourself as a plugin * /
+ * imports->register_plugin(us, &our_exported_plugin_operations);
+ *
+ * // Register our interfaces
+ * imports->register_interface(us, "interfacetype", "interfacename"
+ * // Be sure and define "OurExports" and OurImports
+ * // above...
+ * , &OurExports
+ * , &OurImports);
+ * // Repeat for all interfaces in this plugin...
+ *
+ * }
+ *
+ * Except for the PIL_PLUGINTYPE and the PIL_PLUGIN definitions, and changing
+ * the names of various static variables and functions, every single plugin is
+ * set up pretty much the same way
+ *
+ */
+
+/*
+ * No doubt there is a fancy preprocessor trick for avoiding these
+ * duplications but I don't have time to figure it out. Patches are
+ * being accepted...
+ */
+#define mlINIT_FUNC _pil_plugin_init
+#define mlINIT_FUNC_STR "_pil_plugin_init"
+#define PIL_INSERT _LTX_
+#define PIL_INSERT_STR "_LTX_"
+
+/*
+ * snprintf-style format string for initialization entry point name:
+ * arguments are: (plugintype, pluginname)
+ */
+#define PIL_FUNC_FMT "%s" PIL_INSERT_STR "%s" mlINIT_FUNC_STR
+
+#ifdef __STDC__
+# define EXPORTHELPER1(plugintype, insert, pluginname, function) \
+ plugintype##insert##pluginname##function
+#else
+# define EXPORTHELPER1(plugintype, insert, pluginname, function) \
+ plugintype/**/insert/**/pluginname/**/function
+#endif
+
+#define EXPORTHELPER2(a, b, c, d) EXPORTHELPER1(a, b, c, d)
+#define PIL_PLUGIN_INIT \
+ EXPORTHELPER2(PIL_PLUGINTYPE,PIL_INSERT,PIL_PLUGIN,mlINIT_FUNC)
+
+/*
+ * Plugin loading return codes. OK will always be zero.
+ *
+ * There are many ways to fail, but only one kind of success ;-)
+ */
+
+typedef enum {
+ PIL_OK=0, /* Success */
+ PIL_INVAL=1, /* Invalid Parameters */
+ PIL_BADTYPE=2, /* Bad plugin/interface type */
+ PIL_EXIST=3, /* Duplicate Plugin/Interface name */
+ PIL_OOPS=4, /* Internal Error */
+ PIL_NOPLUGIN=5 /* No such plugin or Interface */
+}PIL_rc; /* Return code from Plugin fns*/
+
+const char * PIL_strerror(PIL_rc rc);
+
+typedef struct PILPluginImports_s PILPluginImports;
+typedef struct PILPluginOps_s PILPluginOps;
+typedef struct PILPlugin_s PILPlugin;
+typedef struct PILPluginUniv_s PILPluginUniv;
+typedef struct PILPluginType_s PILPluginType;
+
+typedef struct PILInterface_s PILInterface;
+typedef struct PILInterfaceImports_s PILInterfaceImports;
+typedef struct PILInterfaceUniv_s PILInterfaceUniv;
+typedef struct PILInterfaceType_s PILInterfaceType;
+
+typedef PIL_rc(*PILInterfaceFun)(PILInterface*, void* ud_interface);
+
+#define PIL_MAGIC_PLUGIN 0xFEEDBEEFUL
+#define PIL_MAGIC_PLUGINTYPE 0xFEEDCEEFUL
+#define PIL_MAGIC_PLUGINUNIV 0xFEEDDEEFUL
+#define PIL_MAGIC_INTERFACE 0xFEEDEEEFUL
+#define PIL_MAGIC_INTERFACETYPE 0xFEEDFEEFUL
+#define PIL_MAGIC_INTERFACEUNIV 0xFEED0EEFUL
+
+#define IS_PILPLUGIN(s) ((s)->MagicNum == PIL_MAGIC_PLUGIN)
+#define IS_PILPLUGINTYPE(s) ((s)->MagicNum == PIL_MAGIC_PLUGINTYPE)
+#define IS_PILPLUGINUNIV(s) ((s)->MagicNum == PIL_MAGIC_PLUGINUNIV)
+#define IS_PILINTERFACE(s) ((s)->MagicNum == PIL_MAGIC_INTERFACE)
+#define IS_PILINTERFACETYPE(s) ((s)->MagicNum == PIL_MAGIC_INTERFACETYPE)
+#define IS_PILINTERFACEUNIV(s) ((s)->MagicNum == PIL_MAGIC_INTERFACEUNIV)
+
+/* The type of a Plugin Initialization Function */
+typedef PIL_rc (*PILPluginInitFun) (PILPlugin*us
+, PILPluginImports* imports
+, void* plugin_user_data);
+
+/*
+ * struct PILPluginOps_s (typedef PILPluginOps) defines the set of functions
+ * exported by all plugins...
+ */
+struct PILPluginOps_s {
+ const char* (*pluginversion) (void);
+ int (*getdebuglevel) (void);
+ void (*setdebuglevel) (int);
+ const char* (*license) (void);
+ const char* (*licenseurl) (void);
+ void (*close) (PILPlugin*);
+};
+
+/*
+ * Logging levels for the "standard" log interface.
+ */
+
+typedef enum {
+ PIL_FATAL= 1, /* BOOM! Causes program to stop */
+ PIL_CRIT = 2, /* Critical -- serious error */
+ PIL_WARN = 3, /* Warning */
+ PIL_INFO = 4, /* Informative message */
+ PIL_DEBUG= 5 /* Debug message */
+}PILLogLevel;
+typedef void (*PILLogFun)(PILLogLevel priority, const char * fmt, ...)
+ G_GNUC_PRINTF(2,3);
+
+/*
+ * The size glib2 type du jour?
+ * (once, this used to be size_t, so this change could break
+ * distributions with older glib2 versions; if so, just add an
+ * #ifelse below)
+ */
+#if GLIB_MINOR_VERSION <= 14
+ typedef gulong glib_size_t;
+#else
+ typedef gsize glib_size_t;
+#endif
+
+/*
+ * struct PILPluginImports_s (typedef PILPluginImports) defines
+ * the functions and capabilities that every plugin imports when it is loaded.
+ */
+
+
+struct PILPluginImports_s {
+ PIL_rc (*register_plugin)(PILPlugin* piinfo
+ , const PILPluginOps* commonops);
+ PIL_rc (*unregister_plugin)(PILPlugin* piinfo);
+/*
+ * A little explanation of the close_func parameter to register_interface
+ * is in order.
+ *
+ * It is an exported operation function, just like the Ops structure.
+ * However, the Ops vector is exported to applications that
+ * are using the interface. Unlike the Ops structure, close_func is
+ * exported only to the interface system, since applications shouldn't
+ * call it directly, but should manage the reference counts for the
+ * interfaces instead.
+ * The generic interface system doesn't have any idea how to call
+ * any functions in the operations vector. So, it's a separate
+ * parameter for two good reasons.
+ */
+ PIL_rc (*register_interface)(PILPlugin* piinfo
+ , const char * interfacetype /* Type of interface */
+ , const char * interfacename /* Name of interface */
+ , void* Ops /* Info (functions) exported
+ by this interface */
+ /* Function to call to shut down this interface */
+ , PILInterfaceFun close_func
+
+ , PILInterface** interfaceid /* Interface id (OP) */
+ , void** Imports
+ , void* ud_interface); /* interface user data */
+
+ PIL_rc (*unregister_interface)(PILInterface* interfaceid);
+ PIL_rc (*load_plugin)(PILPluginUniv* universe
+ , const char * plugintype, const char * pluginname
+ , void* plugin_private);
+
+ void (*log) (PILLogLevel priority, const char * fmt, ...)
+ G_GNUC_PRINTF(2,3);
+ gpointer (*alloc)(glib_size_t size);
+ gpointer (*mrealloc)(gpointer space, glib_size_t size);
+ void (*mfree)(gpointer space);
+ char* (*mstrdup)(const char *s);
+};
+
+/*
+ * Function for logging with the given logging function
+ * The reason why it's here is so we can get printf arg checking
+ * You can't get that when you call a function pointer directly.
+ */
+void PILCallLog(PILLogFun logfun, PILLogLevel priority, const char * fmt, ...)
+ G_GNUC_PRINTF(3,4);
+
+/*
+ * EXPORTED INTERFACES...
+ */
+
+/* Create a new plugin universe - start the plugin loading system up */
+PILPluginUniv* NewPILPluginUniv(const char * baseplugindirectory);
+
+/* Change memory allocation functions right after creating universe */
+void PilPluginUnivSetMemalloc(PILPluginUniv*
+, gpointer (*alloc)(glib_size_t size)
+, gpointer (*mrealloc)(gpointer, glib_size_t size)
+, void (*mfree)(void* space)
+, char* (*mstrdup)(const char *s));
+
+
+void PilPluginUnivSetLog(PILPluginUniv*
+, void (*log) (PILLogLevel priority, const char * fmt, ...)
+ G_GNUC_PRINTF(2,3));
+
+
+/* Delete a plugin universe - shut the plugin loading system down */
+/* Best if used carefully ;-) */
+void DelPILPluginUniv(PILPluginUniv*);
+
+/* Set the debug level for the plugin system itself */
+void PILpisysSetDebugLevel (int level);
+
+/* Return a list of plugins of the given type */
+char ** PILListPlugins(PILPluginUniv* u, const char *plugintype
+, int* plugincount /*can be NULL*/);
+
+/* Free the plugin list returned by PILFreeListPlugins */
+void PILFreePluginList(char ** pluginlist);
+
+/* Load the requested plugin */
+PIL_rc PILLoadPlugin(PILPluginUniv* piuniv
+, const char * plugintype
+, const char * pluginname
+, void * pi_private);
+
+/* Return PIL_OK if the given plugin exists */
+PIL_rc PILPluginExists(PILPluginUniv* piuniv
+, const char * plugintype
+, const char * pluginname);
+
+/* Either or both of pitype and piname may be NULL */
+void PILSetDebugLevel(PILPluginUniv*u, const char * pitype
+, const char * piname
+, int level);
+
+/* Neither pitype nor piname may be NULL */
+int PILGetDebugLevel(PILPluginUniv* u, const char * pitype
+, const char * piname);
+
+PIL_rc PILIncrIFRefCount(PILPluginUniv* piuniv
+, const char * interfacetype
+, const char * interfacename
+, int plusminus);
+
+int PILGetIFRefCount(PILPluginUniv* piuniv
+, const char * interfacetype
+, const char * interfacename);
+
+void PILLogMemStats(void);
+/* The plugin/interface type of a interface manager */
+
+#define PI_IFMANAGER "InterfaceMgr"
+#define PI_IFMANAGER_TYPE InterfaceMgr
+
+/*
+ * These functions are standard exported functions for all plugins.
+ */
+
+#define PIL_PLUGIN_BOILERPLATE_PROTOTYPES_GENERIC(PluginVersion, DebugName) \
+/* \
+ * Prototypes for boilerplate functions \
+ */ \
+static const char* Ourpluginversion(void); \
+static int GetOurDebugLevel(void); \
+static void SetOurDebugLevel(int); \
+static const char * ReturnOurLicense(void); \
+static const char * ReturnOurLicenseURL(void);
+
+#define PIL_PLUGIN_BOILERPLATE_FUNCS(PluginVersion, DebugName) \
+/* \
+ * Definitions of boilerplate functions \
+ */ \
+static const char* \
+Ourpluginversion(void) \
+{ return PluginVersion; } \
+ \
+static int DebugName = 0; \
+ \
+static int \
+GetOurDebugLevel(void) \
+{ return DebugName; } \
+ \
+static void \
+SetOurDebugLevel(int level) \
+{ DebugName = level; } \
+ \
+static const char * \
+ReturnOurLicense(void) \
+{ return PIL_PLUGINLICENSE; } \
+ \
+static const char * \
+ReturnOurLicenseURL(void) \
+{ return PIL_PLUGINLICENSEURL; }
+
+#define PIL_PLUGIN_BOILERPLATE(PluginVersion, DebugName, CloseName) \
+PIL_PLUGIN_BOILERPLATE_PROTOTYPES_GENERIC(PluginVersion, DebugName) \
+static void CloseName(PILPlugin*); \
+/* \
+ * Initialize Plugin Exports structure \
+ */ \
+static PILPluginOps OurPIExports = \
+{ Ourpluginversion \
+, GetOurDebugLevel \
+, SetOurDebugLevel \
+, ReturnOurLicense \
+, ReturnOurLicenseURL \
+, CloseName \
+}; \
+PIL_PLUGIN_BOILERPLATE_FUNCS(PluginVersion, DebugName)
+
+#define PIL_PLUGIN_BOILERPLATE2(PluginVersion, DebugName) \
+PIL_PLUGIN_BOILERPLATE_PROTOTYPES_GENERIC(PluginVersion, DebugName) \
+/* \
+ * Initialize Plugin Exports structure \
+ */ \
+static PILPluginOps OurPIExports = \
+{ Ourpluginversion \
+, GetOurDebugLevel \
+, SetOurDebugLevel \
+, ReturnOurLicense \
+, ReturnOurLicenseURL \
+, NULL \
+}; \
+PIL_PLUGIN_BOILERPLATE_FUNCS(PluginVersion, DebugName)
+
+
+/* A few sample licenses and URLs. We can easily add to this */
+
+#define LICENSE_GPL "gpl"
+#define URL_GPL "http://www.fsf.org/licenses/gpl.html"
+
+#define LICENSE_LGPL "lgpl"
+#define URL_LGPL "http://www.fsf.org/licenses/lgpl.html"
+
+#define LICENSE_X11 "x11"
+#define URL_X11 "http://www.x.org/terms.htm"
+
+#define LICENSE_PUBDOM "publicdomain"
+#define URL_PUBDOM "file:///dev/null"
+
+#define LICENSE_MODBSD "modbsd"
+#define URL_MODBSD "http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5"
+
+#define LICENSE_OLDBSD "origbsd"
+#define URL_OLDBSD "http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6"
+
+#define LICENSE_EXPAT "expat"
+#define URL_EXPAT "http://www.jclark.com/xml/copying.txt"
+
+#define LICENSE_ZLIB "zlib"
+#define URL_ZLIB "http://www.gzip.org/zlib/zlib_license.html"
+
+#define LICENSE_APACHE_10 "apache1_0"
+#define URL_APACHE_10 "http://www.apache.org/LICENSE-1.0"
+
+#define LICENSE_APACHE_11 "apache1_1"
+#define URL_APACHE_11 "http://www.apache.org/LICENSE-1.1"
+
+#define LICENSE_MPL "mpl"
+#define URL_MPL "http://www.mozilla.org/MPL/MPL-1.1.html"
+
+#define LICENSE_PROP "proprietary"
+#define URL_PROP ""
+
+#define LICENSE_IBMPL "ibmpl"
+#define URL_IBMPL "http://oss.software.ibm.com/developerworks/opensource/license10.html"
+
+#ifdef ENABLE_PIL_DEFS_PRIVATE
+/* Perhaps these should be moved to a different header file */
+
+/*
+ * PILPluginType is the "class" for the basic plugin loading mechanism.
+ *
+ * To enable loading of plugins from a particular plugin type
+ * one calls NewPILPluginType with the plugin type name, the plugin
+ * base directory, and the set of functions to be imported to the plugin.
+ *
+ *
+ * The general idea of these structures is as follows:
+ *
+ * The PILPluginUniv object contains information about all plugins of
+ * all types.
+ *
+ * The PILPluginType object contains information about all the plugins of a
+ * specific type.
+ *
+ * Note: for plugins which implement a single interface, the plugin type name
+ * should be the same as the interface type name.
+ *
+ * For other plugins that implement more than one interface, one of
+ * the interface names should normally match the plugin name.
+ */
+
+
+/*
+ * struct PILPlugin_s (typedef PILPlugin) is the structure which
+ * represents/defines a plugin, and is used to identify which plugin is
+ * being referred to in various function calls.
+ *
+ * NOTE: It may be the case that this definition should be moved to
+ * another header file - since no one ought to be messing with them anyway ;-)
+ *
+ * I'm not sure that we're putting the right stuff in here, either...
+ */
+
+struct PILPlugin_s {
+ unsigned long MagicNum;
+ char* plugin_name;
+ PILPluginType* plugintype; /* Parent structure */
+ int refcnt; /* Reference count for this plugin */
+ lt_dlhandle dlhandle; /* Reference to D.L. object */
+ PILPluginInitFun dlinitfun; /* Initialization function */
+ const PILPluginOps* pluginops; /* Exported plugin operations */
+
+ void* ud_plugin; /* Plugin-Private data */
+ /* Other stuff goes here ... (?) */
+};
+
+/*
+ * PILPluginType Information about all plugins of a given type.
+ * (i.e., in a given directory)
+ * (AKA struct PILPluginType_s)
+ */
+
+struct PILPluginType_s {
+ unsigned long MagicNum;
+ char * plugintype;
+ PILPluginUniv* piuniv; /* The universe to which we belong */
+ GHashTable* Plugins;
+ /* Key is plugin type, value is PILPlugin */
+
+ char** (*listplugins)(PILPluginType*, int* listlen);
+};
+
+/*
+ * PILPluginUniv (aka struct PILPluginUniv_s) is the structure which
+ * represents the universe of all PILPluginType objects.
+ * There is one PILPluginType object for each Plugin type.
+ */
+
+struct PILPluginUniv_s {
+ unsigned long MagicNum;
+ char ** rootdirlist;
+ /* key is plugin type, data is PILPluginType* */
+ GHashTable* PluginTypes;
+ struct PILInterfaceUniv_s*ifuniv; /* Universe of interfaces */
+ PILPluginImports* imports;
+};
+
+# endif /* ENABLE_PIL_DEFS_PRIVATE */
+#endif /*PILS_PLUGIN_H */
diff --git a/include/replace_uuid.h b/include/replace_uuid.h
new file mode 100644
index 0000000..d6bca89
--- /dev/null
+++ b/include/replace_uuid.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
+ */
+
+/*
+ * uuid: wrapper declarations.
+ *
+ * heartbeat originally used "uuid" functionality by calling directly,
+ * and only, onto the "e2fsprogs" implementation.
+ *
+ * The run-time usages in the code have since been abstracted, funnelled
+ * through a thin, common interface layer: a Good Thing.
+ *
+ * Similarly, the compile-time usages of "include <uuid/uuid.h>" are
+ * replaced, being funnelled through a reference to this header file.
+ *
+ * This header file interfaces onto the actual underlying implementation.
+ * In the case of the "e2fsprogs" implementation, it is simply a stepping
+ * stone onto "<uuid/uuid.h>". As other implementations are accommodated,
+ * so their header requirements can be accommodated here.
+ *
+ * Copyright (C) 2004 David Lee <t.d.lee@durham.ac.uk>
+ */
+
+#ifndef REPLACE_UUID_H
+#define REPLACE_UUID_H
+
+typedef unsigned char uuid_t[16];
+void uuid_clear(uuid_t uu);
+int uuid_compare(const uuid_t uu1, const uuid_t uu2);
+void uuid_copy(uuid_t dst, const uuid_t src);
+void uuid_generate(uuid_t out);
+void uuid_generate_random(uuid_t out);
+int uuid_is_null(const uuid_t uu);
+int uuid_parse(const char *in, uuid_t uu);
+void uuid_unparse(const uuid_t uu, char *out);
+
+#endif /* REPLACE_UUID_H */
diff --git a/include/stonith/Makefile.am b/include/stonith/Makefile.am
new file mode 100644
index 0000000..9e67a2a
--- /dev/null
+++ b/include/stonith/Makefile.am
@@ -0,0 +1,25 @@
+#
+# linux-ha: Linux-HA heartbeat code
+#
+# Copyright (C) 2001 Michael Moerz
+# This instance created by Horms
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+MAINTAINERCLEANFILES = Makefile.in
+
+idir=$(includedir)/stonith
+
+i_HEADERS = expect.h stonith.h stonith_plugin.h st_ttylock.h
diff --git a/include/stonith/expect.h b/include/stonith/expect.h
new file mode 100644
index 0000000..6084ef1
--- /dev/null
+++ b/include/stonith/expect.h
@@ -0,0 +1,61 @@
+/*
+ * Expect simple tokens. Simple expect infrastructure for STONITH API
+ *
+ * Copyright (c) 2000 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 __EXPECT_H
+# define __EXPECT_H
+/*
+ * If we find any of the given tokens in the input stream,
+ * we return it's "toktype", so we can tell which one was
+ * found.
+ *
+ */
+
+struct Etoken {
+ const char * string; /* The token to look for */
+ int toktype; /* The type to return on match */
+ int matchto; /* Modified during matches */
+};
+
+int ExpectToken(int fd
+, struct Etoken * toklist /* List of tokens to match against */
+ /* Final token has NULL string */
+, int to_secs /* Timeout value in seconds */
+, char * buf /* If non-NULL, then all the text
+ * matched/skipped over by this match */
+, int maxline,
+, int debug); /* debug level */
+
+
+/*
+ * A handy little routine. It runs the given process
+ * with it's standard output redirected into our *readfd, and
+ * its standard input redirected from our *writefd
+ *
+ * Doing this with all the pipes, etc. required for doing this
+ * is harder than it sounds :-)
+ */
+
+int StartProcess(const char * cmd, int* readfd, int* writefd);
+
+#ifndef EOS
+# define EOS '\0'
+#endif
+#endif /*__EXPECT_H*/
diff --git a/include/stonith/st_ttylock.h b/include/stonith/st_ttylock.h
new file mode 100644
index 0000000..5b5c7fd
--- /dev/null
+++ b/include/stonith/st_ttylock.h
@@ -0,0 +1,21 @@
+/*
+ * 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 __STONITH_ST_TTYLOCK_H
+# define __STONITH_ST_TTYLOCK_H
+int st_ttylock(const char *serial_device);
+int st_ttyunlock(const char *serial_device);
+#endif /*__STONITH_ST_TTYLOCK_H*/
diff --git a/include/stonith/stonith.h b/include/stonith/stonith.h
new file mode 100644
index 0000000..93fbaac
--- /dev/null
+++ b/include/stonith/stonith.h
@@ -0,0 +1,187 @@
+/*
+ * S hoot
+ * T he
+ * O ther
+ * N ode
+ * I n
+ * T he
+ * H ead
+ *
+ * Cause the other machine to reboot or die - now.
+ *
+ * We guarantee that when we report that the machine has been
+ * rebooted, then it has been (barring misconfiguration or hardware
+ * errors)
+ *
+ * A machine which we have STONITHed won't do anything more to its
+ * peripherials etc. until it goes through the reboot cycle.
+ */
+
+/*
+ *
+ * Copyright (c) 2000 Alan Robertson <alanr@unix.sh>
+ * Copyright (c) 2004 International Business Machines, Inc.
+ *
+ * Author: Alan Robertson
+ *
+ * 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 __STONITH_H
+# define __STONITH_H
+#include <glib.h>
+#include <ctype.h>
+
+#include <pils/plugin.h>
+#define STONITH_VERS 2
+
+/*
+ * Return codes from "Stonith" operations
+ */
+
+#define S_OK 0 /* Machine correctly reset */
+#define S_BADCONFIG 1 /* Bad config info given */
+#define S_ACCESS 2 /* Can't access STONITH device */
+ /* (login/passwd problem?) */
+#define S_INVAL 3 /* Bad/illegal argument */
+#define S_BADHOST 4 /* Bad/illegal host/node name */
+#define S_RESETFAIL 5 /* Reset failed */
+#define S_TIMEOUT 6 /* Timed out in the dialogues */
+#define S_ISOFF 7 /* Can't reboot: Outlet is off */
+#define S_OOPS 8 /* Something strange happened */
+
+typedef struct stonith {
+ char * stype;
+}Stonith;
+
+/* An array of StonithNVpairs is terminated by a NULL s_name */
+typedef struct {
+ char * s_name;
+ char * s_value;
+}StonithNVpair;
+
+/*
+ * Operation requested by reset_req()
+ */
+#define ST_GENERIC_RESET 1 /* Reset the machine any way you can */
+#define ST_POWERON 2 /* Power the node on */
+#define ST_POWEROFF 3 /* Power the node off */
+/*
+ * Type of information requested by the get_info() call
+ */
+#define ST_CONF_XML 1 /* XML config info */
+#define ST_DEVICEID 2 /* Device Type Identification */
+#define ST_DEVICENAME 3 /* Unique Individual Device Identification */
+ /* (only after stonith_set_config() call) */
+#define ST_DEVICEDESCR 4 /* Device Description text */
+#define ST_DEVICEURL 5 /* Manufacturer/Device URL */
+
+extern PILPluginUniv *StonithPIsys;
+
+char ** stonith_types(void); /* NULL-terminated list */
+ /* valid until next call of stonith_types() */
+Stonith*stonith_new(const char * type);
+void stonith_delete(Stonith *);
+
+const char * const * stonith_get_confignames (Stonith* s);
+ /* static/global return */
+ /* Return number and list of valid s_names */
+
+const char* /* static/global return - lots of things! */
+ stonith_get_info (Stonith* s, int infotype);
+
+void stonith_set_debug (Stonith* s, int debuglevel);
+void stonith_set_log (Stonith* s
+ , PILLogFun);
+
+int stonith_set_config (Stonith* s, StonithNVpair* list);
+int stonith_set_config_file(Stonith* s, const char * configname);
+ /* uses get_confignames to determine which
+ * names to look for in file configname, which
+ * is passed in by the -F option */
+int stonith_set_config_info(Stonith* s, const char * info);
+ /* uses get_confignames to determine which
+ * names to look for in string info, which
+ * is passed in by the -p option */
+ /*
+ * Must call stonith_set_config() before calling functions below...
+ */
+char** stonith_get_hostlist (Stonith* s);
+void stonith_free_hostlist (char** hostlist);
+int stonith_get_status (Stonith* s);
+int stonith_req_reset (Stonith* s, int operation, const char* node);
+
+StonithNVpair* stonith_env_to_NVpair(Stonith* s);
+
+/* Stonith 1 compatibility: Convert string to an NVpair set */
+StonithNVpair*
+ stonith1_compat_string_to_NVpair(Stonith* s, const char * str);
+StonithNVpair*
+ stonith_ghash_to_NVpair(GHashTable* stringtable);
+void free_NVpair(StonithNVpair*); /* Free result from above 2 functions */
+void strdown(char *str); /* simple replacement for g_strdown */
+
+/*
+ * The ST_DEVICEID info call is intended to return the type of the Stonith
+ * device. Note that it may return a different result once it has attempted
+ * to talk to the device (like after a status() call). This is because
+ * a given STONITH module may be able to talk to more than one kind of
+ * model of STONITH device, and can't tell which type is out there
+ * to until it talks to it. For example, Baytech 3, Baytech 5 and
+ * Baytech 5a are all supported by one module, and this module actually
+ * captures the particular model number after it talks to it.
+ *
+ * The ST_DEVICEDESCR info call is intended to return information identifying
+ * the type of STONITH device supported by this STONITH object. This is so
+ * users can tell if they have this kind of device or not.
+ *
+ * SHOULD THIS BE IN THE XML SO IT CAN BE SUPPLIED IN SEVERAL LANGUAGES??
+ * But, this would mean the STONITH command would have to parse XML.
+ * Sigh... I'd rather not... Or maybe it can be supplied duplicately
+ * in the XML if that is thought to be desirable...
+ *
+ * The ST_DEVICEURL info call is intended to return the URL of a web site
+ * related to the device in question. This might be the manufacturer,
+ * a pointer to the product line, or the individual product itself.
+ *
+ * A good way for a GUI to work which configures STONITH devices would be to
+ * use the result of the stonith_types() call in a pulldown menu.
+ *
+ * Once the type is selected, create a Stonith object of the selected type.
+ * One can then create a dialog box to create the configuration info for the
+ * device using return from the ST_CONF_XML info call to direct the
+ * GUI in what information to ask for to fill up the StonithNVpair
+ * argument to the stonith_set_config() call. This information would then
+ * be prompted for according to the XML information, and then put into
+ * a NULL-terminated array of StonithNVpair objects.
+ *
+ * Once this has been done, it can be tested for syntactic
+ * validity with stonith_set_config().
+ *
+ * If it passes set_config(), it can be further validated using status()
+ * which will then actually try and talk to the STONITH device. If status()
+ * returns S_OK, then communication with the device was successfully
+ * established.
+ *
+ * Normally that would mean that logins, passwords, device names, and IP
+ * addresses, etc. have been validated as required by the particular device.
+ *
+ * At this point, you can ask the device which machines it knows how to reset
+ * using the stonith_get_hostlist() function.
+ *
+ */
+
+#endif /*__STONITH_H*/
diff --git a/include/stonith/stonith_plugin.h b/include/stonith/stonith_plugin.h
new file mode 100644
index 0000000..9091a6e
--- /dev/null
+++ b/include/stonith/stonith_plugin.h
@@ -0,0 +1,125 @@
+/*
+ * S hoot
+ * T he
+ * O ther
+ * N ode
+ * I n
+ * T he
+ * H ead
+ *
+ * Cause the other machine to reboot or die - now.
+ *
+ * We guarantee that when we report that the machine has been
+ * rebooted, then it has been (barring misconfiguration or hardware errors)
+ *
+ * A machine which we have STONITHed won't do anything more to its
+ * peripherials etc. until it goes through the reboot cycle.
+ */
+
+/*
+ *
+ * Copyright (c) 2004 International Business Machines, Inc.
+ *
+ * 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 __STONITH_PLUGIN_H
+# define __STONITH_PLUGIN_H
+
+#include <stonith/stonith.h>
+#include <glib.h>
+
+typedef struct stonith_plugin StonithPlugin;
+
+#define NUM_STONITH_FNS 7
+
+struct stonith_ops {
+ StonithPlugin * (*new) (const char*); /* mini-Constructor */
+ void (*destroy) (StonithPlugin*); /*(full) Destructor */
+
+ const char* (*get_info) (StonithPlugin*, int infotype);
+ const char * const * (*get_confignames) (StonithPlugin*);
+ int (*set_config) (StonithPlugin*, StonithNVpair* list);
+ /* Finishes construction */
+ /*
+ * Must call set_config before calling any of
+ * the member functions below...
+ */
+
+ int (*get_status) (StonithPlugin*s);
+ int (*req_reset) (StonithPlugin*, int op, const char* node);
+
+
+ char** (*get_hostlist) (StonithPlugin*);
+ /* Returns list of hosts it supports */
+};
+
+struct stonith_plugin {
+ Stonith s;
+ struct stonith_ops* s_ops;
+ gboolean isconfigured;
+};
+
+#define STONITH_TYPE stonith2
+#define STONITH_TYPE_S "stonith2"
+typedef struct StonithImports_s StonithImports;
+
+struct Etoken {
+ const char * string; /* The token to look for */
+ int toktype; /* The type to return on match */
+ int matchto; /* Modified during matches */
+};
+
+/* An array of StonithNamesToGet is terminated by a NULL s_name */
+typedef struct {
+ const char * s_name;
+ char * s_value;
+}StonithNamesToGet;
+
+#define TELNET_PORT 23
+#define TELNET_SERVICE "telnet"
+
+struct StonithImports_s {
+ int (*ExpectToken)(int fd, struct Etoken * toklist, int to_secs
+ , char * buf, int maxline, int debug);
+ int (*StartProcess)(const char * cmd, int * readfd, int * writefd);
+ int (*OpenStreamSocket) (const char * host, int port
+ , const char * service);
+ /* Service can be NULL, port can be <= 0, but not both... */
+ const char* (*GetValue)(StonithNVpair*, const char * name);
+ int (*CopyAllValues) (StonithNamesToGet* out, StonithNVpair* in);
+ char **(*StringToHostList)(const char * hlstring);
+ char **(*CopyHostList)(const char * const * hlstring);
+ void (*FreeHostList)(char** hostlist);
+ int (*TtyLock)(const char* tty);
+ int (*TtyUnlock)(const char* tty);
+};
+
+
+/*
+ * A few standardized parameter names
+ */
+
+#define ST_HOSTLIST "hostlist"
+#define ST_IPADDR "ipaddr"
+#define ST_LOGIN "login"
+#define ST_PASSWD "password"
+#define ST_COMMUNITY "community" /* SNMP community */
+#define ST_TTYDEV "ttydev" /* TTY device name */
+
+#endif /*__STONITH__PLUGIN_H*/