瀏覽代碼

Add files missing from build but in dev repo.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1610 fd59a12c-fef9-0310-b244-a6a79926bd2f
Steven Dake 17 年之前
父節點
當前提交
13b48d09d4
共有 5 個文件被更改,包括 1407 次插入0 次删除
  1. 112 0
      openais/lib/Makefile
  2. 788 0
      openais/lib/util.c
  3. 151 0
      openais/lib/util.h
  4. 294 0
      openais/services/openaisparser.c
  5. 62 0
      openais/test/Makefile

+ 112 - 0
openais/lib/Makefile

@@ -0,0 +1,112 @@
+# Copyright (c) 2002-2005 MontaVista Software, Inc.
+# Copyright (c) 2006-2008 Red Hat, Inc.
+# 
+# All rights reserved.
+# 
+# This software licensed under BSD license, the text of which follows:
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 
+# - Redistributions of source code must retain the above copyright notice,
+#   this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+#   contributors may be used to endorse or promote products derived from this
+#   software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+# Include configuration
+#
+srcdir ?= $(CURDIR)/../
+
+include $(srcdir)Makefile.inc
+
+
+override CFLAGS += -I$(srcdir)include
+override LDFLAGS += -L./
+
+all: libSaClm.a libSaClm.so.2.0.0 \
+	libSaCkpt.a libSaCkpt.so.2.0.0 \
+	libSaEvt.a libSaEvt.so.2.0.0 \
+	libSaMsg.a libSaMsg.so.2.0.0  \
+	libSaLck.a libSaLck.so.2.0.0 
+
+libcoroutil.a: util.o
+	$(AR) -rc libcoroutil.a util.o
+
+ifeq (${OPENAIS_COMPAT}, DARWIN)
+
+DARWIN_OPTS=-dynamiclib -bind_at_load -current_version 2.0.0 -compatibility_version 2.0.0
+
+libSaClm.so.2.0.0: util.o clm.o
+	$(CC) $(DARWIN_OPTS) util.o clm.o -o $@
+
+libSaCkpt.so.2.0.0: util.o ckpt.o
+	$(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o ckpt.o -o $@
+
+libSaEvt.so.2.0.0: util.o evt.o sa-evt.o
+	$(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o evt.o
+
+libSaMsg.so.2.0.0: util.o clm.o
+	$(CC) $(DARWIN_OPTS) util.o msg.o -o $@
+
+libSaLck.so.2.0.0: util.o clm.o
+	$(CC) $(DARWIN_OPTS) util.o lck.o -o $@
+
+else
+
+libSaClm.so.2.0.0: util.o clm.o
+	$(CC) -shared -Wl,-soname,libclm.so.2,-version-script=libSaClm.versions util.o clm.o -o $@
+
+libSaCkpt.so.2.0.0: util.o ckpt.o
+	$(CC) $(LDFLAGS) -shared -Wl,-soname,libSaCkpt.so.2,-version-script=libSaCkpt.versions util.o ckpt.o -o $@
+
+libSaEvt.so.2.0.0: util.o evt.o
+	$(CC) $(LDFLAGS) -shared -Wl,-soname,libSaEvt.so.2,-version-script=libSaEvt.versions util.o evt.o
+
+libSaMsg.so.2.0.0: util.o msg.o
+	$(CC) -shared -Wl,-soname,libmsg.so.2,-version-script=libSaMsg.versions util.o msg.o -o $@
+
+libSaLck.so.2.0.0: util.o lck.o
+	$(CC) -shared -Wl,-soname,libSaLck.so.2,-version-script=libSaLck.versions util.o lck.o -o $@
+
+endif
+
+libSaCkpt.a: util.o ckpt.o
+	$(AR) -rc libSaCkpt.a util.o ckpt.o
+
+libSaClm.a: util.o clm.o
+	$(AR) -rc libSaClm.a util.o clm.o
+
+libSaEvt.a: util.o evt.o
+	$(AR) -rc libSaEvt.a util.o evt.o
+
+libSaMsg.a: util.o msg.o
+	$(AR) -rc libSaMsg.a util.o evt.o
+
+libSaLck.a: util.o msg.o
+	$(AR) -rc libSaLck.a util.o msg.o
+
+clean:
+	rm -f *.o libSa*.so.* libSa*.a *.da *.bb *.bbg
+ 
+# -fPIC rules required for all libraries
+%.o: %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $@ $<
+
+depend:
+	makedepend -Y -- $(CFLAGS) $(CPPFLAGS) $(LIBAIS_SRC) > /dev/null 2>&1

+ 788 - 0
openais/lib/util.c

@@ -0,0 +1,788 @@
+/*
+ * vi: set autoindent tabstop=4 shiftwidth=4 :
+ *
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <assert.h>
+
+#include <saAis.h>
+#include <corosync/ipc_gen.h>
+#include "util.h"
+
+enum SA_HANDLE_STATE {
+	SA_HANDLE_STATE_EMPTY,
+	SA_HANDLE_STATE_PENDINGREMOVAL,
+	SA_HANDLE_STATE_ACTIVE
+};
+
+struct saHandle {
+	int state;
+	void *instance;
+	int refCount;
+	uint32_t check;
+};
+
+#ifdef OPENAIS_SOLARIS
+#define MSG_NOSIGNAL 0
+#endif
+
+#if defined(OPENAIS_LINUX) || defined(OPENAIS_SOLARIS)
+/* SUN_LEN is broken for abstract namespace 
+ */
+#define AIS_SUN_LEN(a) sizeof(*(a))
+#else
+#define AIS_SUN_LEN(a) SUN_LEN(a)
+#endif
+
+#ifdef OPENAIS_LINUX
+static char *socketname = "libcorosync.socket";
+#else
+static char *socketname = "/var/run/libcorosync.socket";
+#endif
+
+#ifdef SO_NOSIGPIPE
+void socket_nosigpipe(int s)
+{
+	int on = 1;
+	setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, sizeof(on));
+}
+#endif 
+
+SaAisErrorT
+saServiceConnect (
+	int *responseOut,
+	int *callbackOut,
+	enum service_types service)
+{
+	int responseFD;
+	int callbackFD;
+	int result;
+	struct sockaddr_un address;
+	mar_req_lib_response_init_t req_lib_response_init;
+	mar_res_lib_response_init_t res_lib_response_init;
+	mar_req_lib_dispatch_init_t req_lib_dispatch_init;
+	mar_res_lib_dispatch_init_t res_lib_dispatch_init;
+	SaAisErrorT error;
+	gid_t egid;
+
+	/*
+	 * Allow set group id binaries to be authenticated
+	 */
+	egid = getegid();
+	setregid (egid, -1);
+
+	memset (&address, 0, sizeof (struct sockaddr_un));
+#if defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
+	address.sun_len = sizeof(struct sockaddr_un);
+#endif
+	address.sun_family = PF_UNIX;
+#if defined(OPENAIS_LINUX)
+	strcpy (address.sun_path + 1, socketname);
+#else
+	strcpy (address.sun_path, socketname);
+#endif
+	responseFD = socket (PF_UNIX, SOCK_STREAM, 0);
+	if (responseFD == -1) {
+		return (SA_AIS_ERR_NO_RESOURCES);
+	}
+
+	socket_nosigpipe (responseFD);
+
+	result = connect (responseFD, (struct sockaddr *)&address, AIS_SUN_LEN(&address));
+	if (result == -1) {
+		close (responseFD);
+		return (SA_AIS_ERR_TRY_AGAIN);
+	}
+
+	req_lib_response_init.resdis_header.size = sizeof (req_lib_response_init);
+	req_lib_response_init.resdis_header.id = MESSAGE_REQ_RESPONSE_INIT;
+	req_lib_response_init.resdis_header.service = service;
+
+	error = saSendRetry (responseFD, &req_lib_response_init,
+		sizeof (mar_req_lib_response_init_t));
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+	error = saRecvRetry (responseFD, &res_lib_response_init,
+		sizeof (mar_res_lib_response_init_t));
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+
+	/*
+	 * Check for security errors
+	 */
+	if (res_lib_response_init.header.error != SA_AIS_OK) {
+		error = res_lib_response_init.header.error;
+		goto error_exit;
+	}
+
+	*responseOut = responseFD;
+
+/* if I comment out the 4 lines below the executive crashes */
+	callbackFD = socket (PF_UNIX, SOCK_STREAM, 0);
+	if (callbackFD == -1) {
+		close (responseFD);
+		return (SA_AIS_ERR_NO_RESOURCES);
+	}
+
+	socket_nosigpipe (callbackFD);
+
+	result = connect (callbackFD, (struct sockaddr *)&address, AIS_SUN_LEN(&address));
+	if (result == -1) {
+		close (callbackFD);
+		close (responseFD);
+		return (SA_AIS_ERR_TRY_AGAIN);
+	}
+
+	req_lib_dispatch_init.resdis_header.size = sizeof (req_lib_dispatch_init);
+	req_lib_dispatch_init.resdis_header.id = MESSAGE_REQ_DISPATCH_INIT;
+	req_lib_dispatch_init.resdis_header.service = service;
+
+	req_lib_dispatch_init.conn_info = res_lib_response_init.conn_info;
+
+	error = saSendRetry (callbackFD, &req_lib_dispatch_init,
+		sizeof (mar_req_lib_dispatch_init_t));
+	if (error != SA_AIS_OK) {
+		goto error_exit_two;
+	}
+	error = saRecvRetry (callbackFD, &res_lib_dispatch_init,
+		sizeof (mar_res_lib_dispatch_init_t));
+	if (error != SA_AIS_OK) {
+		goto error_exit_two;
+	}
+
+	/*
+	 * Check for security errors
+	 */
+	if (res_lib_dispatch_init.header.error != SA_AIS_OK) {
+		error = res_lib_dispatch_init.header.error;
+		goto error_exit;
+	}
+
+	*callbackOut = callbackFD;
+	return (SA_AIS_OK);
+
+error_exit_two:
+	close (callbackFD);
+error_exit:
+	close (responseFD);
+	return (error);
+}
+
+SaAisErrorT
+saRecvRetry (
+	int s,
+	void *msg,
+	size_t len)
+{
+	SaAisErrorT error = SA_AIS_OK;
+	int result;
+	struct msghdr msg_recv;
+	struct iovec iov_recv;
+	char *rbuf = (char *)msg;
+	int processed = 0;
+
+	msg_recv.msg_iov = &iov_recv;
+	msg_recv.msg_iovlen = 1;
+	msg_recv.msg_name = 0;
+	msg_recv.msg_namelen = 0;
+#ifndef OPENAIS_SOLARIS
+	msg_recv.msg_control = 0;
+	msg_recv.msg_controllen = 0;
+	msg_recv.msg_flags = 0;
+#else
+	msg_recv.msg_accrights = NULL;
+	msg_recv.msg_accrightslen = 0;
+#endif
+
+retry_recv:
+	iov_recv.iov_base = (void *)&rbuf[processed];
+	iov_recv.iov_len = len - processed;
+
+	result = recvmsg (s, &msg_recv, MSG_NOSIGNAL);
+	if (result == -1 && errno == EINTR) {
+		goto retry_recv;
+	}
+	if (result == -1 && errno == EAGAIN) {
+		goto retry_recv;
+	}
+#if defined(OPENAIS_SOLARIS) || defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
+	/* On many OS poll never return POLLHUP or POLLERR.
+	 * EOF is detected when recvmsg return 0.
+	 */
+	if (result == 0) {
+		error = SA_AIS_ERR_LIBRARY;
+		goto error_exit;
+	}
+#endif
+	if (result == -1 || result == 0) {
+		error = SA_AIS_ERR_LIBRARY;
+		goto error_exit;
+	}
+	processed += result;
+	if (processed != len) {
+		goto retry_recv;
+	}
+	assert (processed == len);
+error_exit:
+	return (error);
+}
+
+SaAisErrorT
+saSendRetry (
+	int s,
+	const void *msg,
+	size_t len)
+{
+	SaAisErrorT error = SA_AIS_OK;
+	int result;
+	struct msghdr msg_send;
+	struct iovec iov_send;
+	char *rbuf = (char *)msg;
+	int processed = 0;
+
+	msg_send.msg_iov = &iov_send;
+	msg_send.msg_iovlen = 1;
+	msg_send.msg_name = 0;
+	msg_send.msg_namelen = 0;
+#ifndef OPENAIS_SOLARIS
+	msg_send.msg_control = 0;
+	msg_send.msg_controllen = 0;
+	msg_send.msg_flags = 0;
+#else
+	msg_send.msg_accrights = NULL;
+	msg_send.msg_accrightslen = 0;
+#endif
+
+retry_send:
+	iov_send.iov_base = (void *)&rbuf[processed];
+	iov_send.iov_len = len - processed;
+
+	result = sendmsg (s, &msg_send, MSG_NOSIGNAL);
+
+	/*
+	 * return immediately on any kind of syscall error that maps to
+	 * SA_AIS_ERR if no part of message has been sent
+	 */
+	if (result == -1 && processed == 0) {
+		if (errno == EINTR) {
+			error = SA_AIS_ERR_TRY_AGAIN;
+			goto error_exit;
+		}
+		if (errno == EAGAIN) {
+			error = SA_AIS_ERR_TRY_AGAIN;
+			goto error_exit;
+		}
+		if (errno == EFAULT) {
+			error = SA_AIS_ERR_INVALID_PARAM;
+			goto error_exit;
+		}
+	}
+
+	/*
+	 * retry read operations that are already started except
+	 * for fault in that case, return ERR_LIBRARY
+	 */
+	if (result == -1 && processed > 0) {
+		if (errno == EINTR) {
+			goto retry_send;
+		}
+		if (errno == EAGAIN) {
+			goto retry_send;
+		}
+		if (errno == EFAULT) {
+			error = SA_AIS_ERR_LIBRARY;
+			goto error_exit;
+		}
+	}
+
+	/*
+	 * return ERR_LIBRARY on any other syscall error
+	 */
+	if (result == -1) {
+		error = SA_AIS_ERR_LIBRARY;
+		goto error_exit;
+	}
+
+	processed += result;
+	if (processed != len) {
+		goto retry_send;
+	}
+
+error_exit:
+	return (error);
+}
+
+SaAisErrorT saSendMsgRetry (
+        int s,
+        struct iovec *iov,
+        int iov_len)
+{
+	SaAisErrorT error = SA_AIS_OK;
+	int result;
+	int total_size = 0;
+	int i;
+	int csize;
+	int csize_cntr;
+	int total_sent = 0;
+	int iov_len_sendmsg = iov_len;
+	struct iovec *iov_sendmsg = iov;
+	struct iovec iovec_save;
+	int iovec_saved_position = -1;
+
+	struct msghdr msg_send;
+
+	for (i = 0; i < iov_len; i++) {
+		total_size += iov[i].iov_len;
+	}
+	msg_send.msg_iov = iov_sendmsg;
+	msg_send.msg_iovlen = iov_len_sendmsg;
+	msg_send.msg_name = 0;
+	msg_send.msg_namelen = 0;
+#ifndef OPENAIS_SOLARIS
+	msg_send.msg_control = 0;
+	msg_send.msg_controllen = 0;
+	msg_send.msg_flags = 0;
+#else
+	msg_send.msg_accrights = NULL;
+	msg_send.msg_accrightslen = 0;
+#endif
+
+retry_sendmsg:
+	result = sendmsg (s, &msg_send, MSG_NOSIGNAL);
+	/*
+	 * Can't send now, and message not committed, so don't retry send
+	 */
+	if (result == -1 && iovec_saved_position == -1) {
+		if (errno == EINTR) {
+			error = SA_AIS_ERR_TRY_AGAIN;
+			goto error_exit;
+		}
+		if (errno == EAGAIN) {
+			error = SA_AIS_ERR_TRY_AGAIN;
+			goto error_exit;
+		}
+		if (errno == EFAULT) {
+			error = SA_AIS_ERR_INVALID_PARAM;
+			goto error_exit;
+		}
+	}
+
+	/*
+	 * Retry (and block) if portion of message has already been written
+	 */
+	if (result == -1 && iovec_saved_position != -1) {
+		if (errno == EINTR) {
+			goto retry_sendmsg;
+		}
+		if (errno == EAGAIN) {
+			goto retry_sendmsg;
+		}
+		if (errno == EFAULT) {
+			error = SA_AIS_ERR_LIBRARY;
+			goto error_exit;
+		}
+	}
+	
+	/*
+	 * ERR_LIBRARY for any other syscall error
+	 */
+	if (result == -1) {
+		error = SA_AIS_ERR_LIBRARY;
+		goto error_exit;
+	}
+
+	if (iovec_saved_position != -1) {
+			memcpy (&iov[iovec_saved_position], &iovec_save, sizeof (struct iovec));
+	}
+
+	total_sent += result;
+	if (total_sent != total_size) {
+		for (i = 0, csize = 0, csize_cntr = 0; i < iov_len; i++) {
+			csize += iov[i].iov_len;
+			if (csize > total_sent) {
+				break;
+			}
+
+			csize_cntr += iov[i].iov_len;
+		}
+		memcpy (&iovec_save, &iov[i], sizeof (struct iovec));
+		iovec_saved_position = i;
+		iov[i].iov_base = ((char *)(iov[i].iov_base)) +
+			(total_sent - csize_cntr);
+		iov[i].iov_len = total_size - total_sent;
+		msg_send.msg_iov = &iov[i];
+		msg_send.msg_iovlen = iov_len - i;
+
+		goto retry_sendmsg;
+	}
+
+error_exit:
+	return (error);
+}
+
+SaAisErrorT saSendMsgReceiveReply (
+        int s,
+        struct iovec *iov,
+        int iov_len,
+        void *responseMessage,
+        int responseLen)
+{
+	SaAisErrorT error = SA_AIS_OK;
+
+	error = saSendMsgRetry (s, iov, iov_len);
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+	
+	error = saRecvRetry (s, responseMessage, responseLen);
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+
+error_exit:
+	return (error);
+}
+
+SaAisErrorT saSendReceiveReply (
+        int s,
+        void *requestMessage,
+        int requestLen,
+        void *responseMessage,
+        int responseLen)
+{
+	SaAisErrorT error = SA_AIS_OK;
+
+	error = saSendRetry (s, requestMessage, requestLen);
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+	
+	error = saRecvRetry (s, responseMessage, responseLen);
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+
+error_exit:
+	return (error);
+}
+
+SaAisErrorT
+saPollRetry (
+        struct pollfd *ufds,
+        unsigned int nfds,
+        int timeout) 
+{
+	SaAisErrorT error = SA_AIS_OK;
+	int result;
+
+retry_poll:
+	result = poll (ufds, nfds, timeout);
+	if (result == -1 && errno == EINTR) {
+		goto retry_poll;
+	}
+	if (result == -1) {
+		error = SA_AIS_ERR_LIBRARY;
+	}
+
+	return (error);
+}
+
+
+SaAisErrorT
+saHandleCreate (
+	struct saHandleDatabase *handleDatabase,
+	int instanceSize,
+	SaUint64T *handleOut)
+{
+	uint32_t handle;
+	uint32_t check;
+	void *newHandles = NULL;
+	int found = 0;
+	void *instance;
+	int i;
+
+	pthread_mutex_lock (&handleDatabase->mutex);
+
+	for (handle = 0; handle < handleDatabase->handleCount; handle++) {
+		if (handleDatabase->handles[handle].state == SA_HANDLE_STATE_EMPTY) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found == 0) {
+		handleDatabase->handleCount += 1;
+		newHandles = (struct saHandle *)realloc (handleDatabase->handles,
+			sizeof (struct saHandle) * handleDatabase->handleCount);
+		if (newHandles == NULL) {
+			pthread_mutex_unlock (&handleDatabase->mutex);
+			return (SA_AIS_ERR_NO_MEMORY);
+		}
+		handleDatabase->handles = newHandles;
+	}
+
+	instance = malloc (instanceSize);
+	if (instance == 0) {
+		free (newHandles);
+		pthread_mutex_unlock (&handleDatabase->mutex);
+		return (SA_AIS_ERR_NO_MEMORY);
+	}
+
+
+	/*
+	 * This code makes sure the random number isn't zero
+	 * We use 0 to specify an invalid handle out of the 1^64 address space
+	 * If we get 0 200 times in a row, the RNG may be broken
+	 */
+	for (i = 0; i < 200; i++) {
+		check = random();
+		if (check != 0) {
+			break;
+		}
+	}
+
+	memset (instance, 0, instanceSize);
+
+	handleDatabase->handles[handle].state = SA_HANDLE_STATE_ACTIVE;
+
+	handleDatabase->handles[handle].instance = instance;
+
+	handleDatabase->handles[handle].refCount = 1;
+
+	handleDatabase->handles[handle].check = check;
+
+	*handleOut = (SaUint64T)((uint64_t)check << 32 | handle);
+
+	pthread_mutex_unlock (&handleDatabase->mutex);
+
+	return (SA_AIS_OK);
+}
+
+
+SaAisErrorT
+saHandleDestroy (
+	struct saHandleDatabase *handleDatabase,
+	SaUint64T inHandle)
+{
+	SaAisErrorT error = SA_AIS_OK;
+	uint32_t check = inHandle >> 32;
+	uint32_t handle = inHandle & 0xffffffff;
+
+	pthread_mutex_lock (&handleDatabase->mutex);
+
+	if (check != handleDatabase->handles[handle].check) {
+		pthread_mutex_unlock (&handleDatabase->mutex);
+		error = SA_AIS_ERR_BAD_HANDLE;
+		return (error);
+	}
+
+	handleDatabase->handles[handle].state = SA_HANDLE_STATE_PENDINGREMOVAL;
+
+	pthread_mutex_unlock (&handleDatabase->mutex);
+
+	saHandleInstancePut (handleDatabase, inHandle);
+
+	return (error);
+}
+
+
+SaAisErrorT
+saHandleInstanceGet (
+	struct saHandleDatabase *handleDatabase,
+	SaUint64T inHandle,
+	void **instance)
+{ 
+	uint32_t check = inHandle >> 32;
+	uint32_t handle = inHandle & 0xffffffff;
+
+	SaAisErrorT error = SA_AIS_OK;
+	pthread_mutex_lock (&handleDatabase->mutex);
+
+	if (handle >= (SaUint64T)handleDatabase->handleCount) {
+		error = SA_AIS_ERR_BAD_HANDLE;
+		goto error_exit;
+	}
+	if (handleDatabase->handles[handle].state != SA_HANDLE_STATE_ACTIVE) {
+		error = SA_AIS_ERR_BAD_HANDLE;
+		goto error_exit;
+	}
+	if (check != handleDatabase->handles[handle].check) {
+		error = SA_AIS_ERR_BAD_HANDLE;
+		goto error_exit;
+	}
+
+
+	*instance = handleDatabase->handles[handle].instance;
+
+	handleDatabase->handles[handle].refCount += 1;
+
+error_exit:
+	pthread_mutex_unlock (&handleDatabase->mutex);
+
+	return (error);
+}
+
+
+SaAisErrorT
+saHandleInstancePut (
+	struct saHandleDatabase *handleDatabase,
+	SaUint64T inHandle)
+{
+	void *instance;
+	SaAisErrorT error = SA_AIS_OK;
+	uint32_t check = inHandle >> 32;
+	uint32_t handle = inHandle & 0xffffffff;
+
+	pthread_mutex_lock (&handleDatabase->mutex);
+
+	if (check != handleDatabase->handles[handle].check) {
+		error = SA_AIS_ERR_BAD_HANDLE;
+		goto error_exit;
+	}
+
+	handleDatabase->handles[handle].refCount -= 1;
+	assert (handleDatabase->handles[handle].refCount >= 0);
+
+	if (handleDatabase->handles[handle].refCount == 0) {
+		instance = (handleDatabase->handles[handle].instance);
+		handleDatabase->handleInstanceDestructor (instance);
+		free (instance);
+		memset (&handleDatabase->handles[handle], 0, sizeof (struct saHandle));
+	}
+
+error_exit:
+	pthread_mutex_unlock (&handleDatabase->mutex);
+
+	return (error);
+}
+
+
+SaAisErrorT
+saVersionVerify (
+    struct saVersionDatabase *versionDatabase,
+	SaVersionT *version)
+{
+	int i;
+	SaAisErrorT error = SA_AIS_ERR_VERSION;
+
+	if (version == 0) {
+		return (SA_AIS_ERR_INVALID_PARAM);
+	}
+
+	/*
+	 * Look for a release code that we support.  If we find it then
+	 * make sure that the supported major version is >= to the required one.
+	 * In any case we return what we support in the version structure.
+	 */
+	for (i = 0; i < versionDatabase->versionCount; i++) {
+
+		/*
+		 * Check if the caller requires and old release code that we don't support.
+		 */
+		if (version->releaseCode < versionDatabase->versionsSupported[i].releaseCode) {
+				break;
+		}
+
+		/*
+		 * Check if we can support this release code.
+		 */
+		if (version->releaseCode == versionDatabase->versionsSupported[i].releaseCode) {
+
+			/*
+			 * Check if we can support the major version requested.
+			 */
+			if (versionDatabase->versionsSupported[i].majorVersion >= version->majorVersion) {
+				error = SA_AIS_OK;
+				break;
+			} 
+
+			/*
+			 * We support the release code, but not the major version.
+			 */
+			break;
+		}
+	}
+
+	/*
+	 * If we fall out of the if loop, the caller requires a release code
+	 * beyond what we support.
+	 */
+	if (i == versionDatabase->versionCount) {
+		i = versionDatabase->versionCount - 1;
+	}
+
+	/*
+	 * Tell the caller what we support
+	 */
+	memcpy(version, &versionDatabase->versionsSupported[i], sizeof(*version));
+	return (error);
+}
+
+/*
+ * Get the time of day and convert to nanoseconds
+ */
+SaTimeT clustTimeNow(void)
+{
+	struct timeval tv;
+	SaTimeT time_now;
+
+	if (gettimeofday(&tv, 0)) {
+		return 0ULL;
+	}
+
+	time_now = (SaTimeT)(tv.tv_sec) * 1000000000ULL;
+	time_now += (SaTimeT)(tv.tv_usec) * 1000ULL;
+
+	return time_now;
+}
+

+ 151 - 0
openais/lib/util.h

@@ -0,0 +1,151 @@
+
+/*
+ * Copyright (c) 2002-2003 MontaVista Software, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AIS_UTIL_H_DEFINED
+#define AIS_UTIL_H_DEFINED
+
+#include <pthread.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+
+#include <corosync/ipc_gen.h>
+
+/* Debug macro
+ */
+#ifdef DEBUG
+	#define DPRINT(s) printf s
+#else
+	#define DPRINT(s)
+#endif
+		
+#ifdef SO_NOSIGPIPE
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+void socket_nosigpipe(int s);
+#else
+#define socket_nosigpipe(s)
+#endif
+
+struct saHandleDatabase {
+	unsigned int handleCount;
+	struct saHandle *handles;
+	pthread_mutex_t mutex;
+	void (*handleInstanceDestructor) (void *);
+};
+
+
+struct saVersionDatabase {
+	int versionCount;
+	SaVersionT *versionsSupported;
+};
+
+SaAisErrorT
+saServiceConnect (
+        int *responseOut,
+        int *callbackOut,
+        enum service_types service);
+
+SaAisErrorT
+saRecvRetry (
+	int s,
+	void *msg,
+	size_t len);
+
+SaAisErrorT
+saSendRetry (
+	int s,
+	const void *msg,
+	size_t len);
+
+SaAisErrorT saSendMsgRetry (
+	int s,
+	struct iovec *iov,
+	int iov_len);
+
+SaAisErrorT saSendMsgReceiveReply (
+	int s,
+	struct iovec *iov,
+	int iov_len,
+	void *responseMessage,
+	int responseLen);
+
+SaAisErrorT saSendReceiveReply (
+	int s,
+	void *requestMessage,
+	int requestLen,
+	void *responseMessage,
+	int responseLen);
+
+SaAisErrorT
+saPollRetry (
+	struct pollfd *ufds,
+	unsigned int nfds,
+	int timeout);
+
+SaAisErrorT
+saHandleCreate (
+	struct saHandleDatabase *handleDatabase,
+	int instanceSize,
+	SaUint64T *handleOut);
+
+SaAisErrorT
+saHandleDestroy (
+	struct saHandleDatabase *handleDatabase,
+	SaUint64T handle);
+
+SaAisErrorT
+saHandleInstanceGet (
+	struct saHandleDatabase *handleDatabase,
+	SaUint64T handle,
+	void **instance);
+
+SaAisErrorT
+saHandleInstancePut (
+	struct saHandleDatabase *handleDatabase,
+	SaUint64T handle);
+
+SaAisErrorT
+saVersionVerify (
+	struct saVersionDatabase *versionDatabase,
+	SaVersionT *version);
+
+#define offset_of(type,member) (int)(&(((type *)0)->member))
+
+SaTimeT
+clustTimeNow(void);
+
+#endif /* AIS_UTIL_H_DEFINED */
+

+ 294 - 0
openais/services/openaisparser.c

@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2006 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Patrick Caulfield (pcaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+#include <corosync/engine/config.h>
+#include <corosync/lcr/lcr_comp.h>
+#include <corosync/engine/objdb.h>
+
+static int read_config_file_into_objdb(
+	struct objdb_iface_ver0 *objdb,
+	char **error_string);
+static char error_string_response[512];
+
+static char *strstr_rs (const char *haystack, const char *needle)
+{
+	char *end_address;
+	char *new_needle;
+
+	new_needle = (char *)strdup (needle);
+	new_needle[strlen (new_needle) - 1] = '\0';
+
+	end_address = strstr (haystack, new_needle);
+	if (end_address) {
+		end_address += strlen (new_needle);
+		end_address = strstr (end_address, needle + strlen (new_needle));
+	}
+	if (end_address) {
+		end_address += 1; /* skip past { or = */
+		do {
+			if (*end_address == '\t' || *end_address == ' ') {
+				end_address++;
+			} else {
+				break;
+			}
+		} while (*end_address != '\0');
+	}
+
+	free (new_needle);
+	return (end_address);
+}
+
+static int aisparser_readconfig (struct objdb_iface_ver0 *objdb, char **error_string)
+{
+	if (read_config_file_into_objdb(objdb, error_string)) {
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static char *remove_whitespace(char *string)
+{
+	char *start = string+strspn(string, " \t");
+	char *end = start+(strlen(start))-1;
+
+	while ((*end == ' ' || *end == '\t' || *end == ':' || *end == '{') && end > start)
+		end--;
+	if (end != start)
+		*(end+1) = '\0';
+
+	return start;
+}
+
+static int parse_section(FILE *fp,
+			 struct objdb_iface_ver0 *objdb,
+			 unsigned int parent_handle,
+			 char **error_string)
+{
+	char line[512];
+	int i;
+	char *loc;
+
+	while (fgets (line, 255, fp)) {
+		line[strlen(line) - 1] = '\0';
+		/*
+		 * Clear out white space and tabs
+		 */
+		for (i = strlen (line) - 1; i > -1; i--) {
+			if (line[i] == '\t' || line[i] == ' ') {
+				line[i] = '\0';
+			} else {
+				break;
+			}
+		}
+		/*
+		 * Clear out comments and empty lines
+		 */
+		if (line[0] == '#' || line[0] == '\0') {
+			continue;
+		}
+
+		/* New section ? */
+		if ((loc = strstr_rs (line, "{"))) {
+			unsigned int new_parent;
+			char *section = remove_whitespace(line);
+
+			loc--;
+			*loc = '\0';
+			objdb->object_create (parent_handle, &new_parent,
+					      section, strlen (section));
+			if (parse_section(fp, objdb, new_parent, error_string))
+				return -1;
+		}
+
+		/* New key/value */
+		if ((loc = strstr_rs (line, ":"))) {
+			char *key;
+			char *value;
+
+			*(loc-1) = '\0';
+			key = remove_whitespace(line);
+			value = remove_whitespace(loc);
+			objdb->object_key_create (parent_handle, key,
+				strlen (key),
+				value, strlen (value) + 1);
+		}
+
+		if ((loc = strstr_rs (line, "}"))) {
+			return 0;
+		}
+	}
+
+	if (parent_handle != OBJECT_PARENT_HANDLE) {
+		*error_string = "Missing closing brace";
+		return -1;
+	}
+
+	return 0;
+}
+
+
+
+/* Read config file and load into objdb */
+static int read_config_file_into_objdb(
+	struct objdb_iface_ver0 *objdb,
+	char **error_string)
+{
+	FILE *fp;
+	char *filename = "/etc/ais/openais.conf";
+	char *error_reason = error_string_response;
+	int res;
+	unsigned int object_handle;
+
+	fp = fopen (filename, "r");
+	if (fp == 0) {
+		sprintf (error_reason, "Can't read file %s reason = (%s)\n",
+			 filename, strerror (errno));
+		*error_string = error_reason;
+		return -1;
+	}
+
+	res = parse_section(fp, objdb, OBJECT_PARENT_HANDLE, error_string);
+
+	fclose(fp);
+
+	/*
+	 * Load clm module
+	 */
+        objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+		"service", strlen("service"));
+	objdb->object_key_create(object_handle, "name", strlen("name"),
+		"openais_clm", strlen("openais_clm") + 1);
+	objdb->object_key_create(object_handle, "ver", strlen("ver"),
+		"0", 2);
+
+	/*
+	 * Load ckpt module
+	 */
+        objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+		"service", strlen("service"));
+	objdb->object_key_create(object_handle, "name", strlen("name"),
+		"openais_ckpt", strlen("openais_ckpt") + 1);
+	objdb->object_key_create(object_handle, "ver", strlen("ver"),
+		"0", 2);
+
+	/*
+	 * Load evt module
+	 */
+        objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+		"service", strlen("service"));
+	objdb->object_key_create(object_handle, "name", strlen("name"),
+		"openais_evt", strlen("openais_evt") + 1);
+	objdb->object_key_create(object_handle, "ver", strlen("ver"),
+		"0", 2);
+
+#ifdef OUTAA
+	/*
+	 * Load msg module
+	 */
+        objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+		"service", strlen("service"));
+	objdb->object_key_create(object_handle, "name", strlen("name"),
+		"openais_msg", strlen("openais_msg") + 1);
+	objdb->object_key_create(object_handle, "ver", strlen("ver"),
+		"0", 2);
+
+	/*
+	 * Load lck module
+	 */
+        objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+		"service", strlen("service"));
+	objdb->object_key_create(object_handle, "name", strlen("name"),
+		"openais_lck", strlen("openais_lck") + 1);
+	objdb->object_key_create(object_handle, "ver", strlen("ver"),
+		"0", 2);
+#endif
+
+	sprintf (error_reason, "Successfully read main configuration file '%s'.\n", filename);
+	*error_string = error_reason;
+
+	return res;
+}
+
+/*
+ * Dynamic Loader definition
+ */
+
+struct config_iface_ver0 aisparser_iface_ver0 = {
+	.config_readconfig        = aisparser_readconfig,
+	.config_writeconfig = NULL
+};
+
+struct lcr_iface openais_aisparser_ver0[1] = {
+	{
+		.name				= "openaisparser",
+		.version			= 0,
+		.versions_replace		= 0,
+		.versions_replace_count		= 0,
+		.dependencies			= 0,
+		.dependency_count		= 0,
+		.constructor			= NULL,
+		.destructor			= NULL,
+		.interfaces			= NULL,
+	}
+};
+
+struct openais_service_handler *aisparser_get_handler_ver0 (void);
+
+struct lcr_comp aisparser_comp_ver0 = {
+	.iface_count				= 1,
+	.ifaces					= openais_aisparser_ver0
+};
+
+
+__attribute__ ((constructor)) static void aisparser_comp_register (void) {
+        lcr_interfaces_set (&openais_aisparser_ver0[0], &aisparser_iface_ver0);
+	lcr_component_register (&aisparser_comp_ver0);
+}
+
+

+ 62 - 0
openais/test/Makefile

@@ -0,0 +1,62 @@
+# Copyright (c) 2002-2004 MontaVista Software, Inc.
+# Copyright (c) 2006-2008 Red Hat, Inc.
+# 
+# All rights reserved.
+# 
+# This software licensed under BSD license, the text of which follows:
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 
+# - Redistributions of source code must retain the above copyright notice,
+#   this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+#   contributors may be used to endorse or promote products derived from this
+#   software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+# Include configuration
+#
+include ../Makefile.inc
+
+ifeq (${OPENAIS_COMPAT}, SOLARIS)
+	override LDFLAGS += -lnsl -lsocket -lrt
+endif
+
+LIBRARIES= ../lib/libSaCkpt.a sa_error.o
+LIBS = $(LIBRARIES) 
+BINARIES= testckpt
+
+override CFLAGS += -I../include
+override LDFLAGS += -L../lib
+
+EXTRA_CFLAGS = -I$(srcdir)include
+TEST_SRC = testckpt.c
+
+all: $(BINARIES)
+
+testckpt: testckpt.o $(LIBRARIES)
+	$(CC) $(LDFLAGS) -o testckpt testckpt.o $(LIBS)
+
+clean:
+	rm -f *.o $(LIBRARIES) $(BINARIES)
+
+%.o: %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+
+depend:
+	makedepend -Y -- $(CFLAGS) $(CPPFLAGS) $(TEST_SRC) > /dev/null 2>&1