view include/waaad/waaad.h @ 400:22f29007b931

Detect when extensions are loaded several times (not allowed)
author Sebastien Decugis <sdecugis@nict.go.jp>
date Tue, 02 Jun 2009 14:49:37 +0900
parents e86dba02630a
children
line wrap: on
line source

/*********************************************************************************************************
* Software License Agreement (BSD License)                                                               *
* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
*													 *
* Copyright (c) 2009, WIDE Project and NICT								 *
* All rights reserved.											 *
* 													 *
* Redistribution and use of this software 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 WIDE Project or NICT nor the 						 *
*   names of its contributors may be used to endorse or 						 *
*   promote products derived from this software without 						 *
*   specific prior written permission of WIDE Project and 						 *
*   NICT.												 *
* 													 *
* 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.								 *
*********************************************************************************************************/

/*
 * This file contains the full definition of the API to be used between waaad daemon and its extensions. 
 *
 * The extensions are loaded by the function ext_load in the extension.c file in the daemon.
 *
 * If you are writing a new extension, you can find some models in the extensions directory.
 
 * INSTRUCTIONS FOR EXTENSIONS:
 *
 *  - Include this file as #include <waaad/waaad.h>, after defining IN_EXTENSION symbol.
 *
 *  - One (and only one) of your extension file must also define the DECLARE_API_POINTERS 
 *   symbol before including this file.
 *
 *  - The extension must have a function called waaad_ext_init with the following prototype:
 *  int waaad_ext_init(waaad_api_t * api, char * conffile);
 *    This function will be called by waaad daemon when the extension is loaded.
 *    See the content of the macro EXTENSION_API_INIT for example of such function (see bellow).
 *
 *  - The following macro may be used in your extension to define the waaad_ext_init function to standard behavior:
 *		EXTENSION_API_INIT(flags, function, name)
 *	flags    = combination of flags to tell what modules are needed by the extension.
 *	function = function to call once API is registered. prototype is: int function(char * conffile);
 *			where conffile is the name of a configuration file for this extension to parse.
 *	name     = name of the extension
 *     If you use this macro, you need to #include <stdio.h> and <errno.h>
 *
 *  - The extension may also provide a function called waaad_ext_fini with this prototype:
 *  void waaad_ext_fini (void);
 *    This function, if present, will be called when the daemon terminate cleanly.
 */

#ifndef _WAAAD_API_H
#define _WAAAD_API_H

/* Include all the modules API definitions */
#include <waaad/log-api.h>
#include <waaad/dictionary-api.h>
#include <waaad/conf-api.h>
#include <waaad/peer-api.h>
#include <waaad/message-api.h>
#include <waaad/routing-api.h>
#include <waaad/session-api.h>
#include <waaad/dispatch-api.h>
#include <waaad/security-api.h>



/* ********************************** */

/* The version of this API format. Increment each time you change the structure waaad_api_t */
#define WAAAD_API_VER	1

/* Now define the structure type that will be passed to the extension initializer */
typedef struct {
	int		version;	/* The global version of this API. Must be WAAAD_API_VER */
	api_log_t	log;
	api_dict_t	dictionary;	
	api_conf_t	conf;	
	api_peer_t	peer;
	api_msg_t	msg;
	api_rt_t	rt;
	api_sess_t	session;
	api_disp_t	dispatch;
	api_sec_t	security;
} waaad_api_t;

/* ********************************** */

/* The code bellow this line is only used to load the API in an extension and check the API number version. */
#ifdef IN_EXTENSION

#include <stdio.h>
#include <errno.h>

typedef struct {
	size_t		length;
	int		version;
} sub_api_header_t;


#define API_MODULE_ALL		0xffffffff	/* Load the complete API in the extension, safest setting */
#define API_MODULE_LOG		0x00000001	/* Load the log API in the extension */
#define API_MODULE_DICTIONARY	0x00000002	/* Load the dictionary API in the extension */
#define API_MODULE_CONF		0x00000004	/* Load the configuration API in the extension */
#define API_MODULE_PEER		0x00000008	/* Load the peer API in the extension */
#define API_MODULE_MSG		0x00000010	/* Load the message API in the extension */
#define API_MODULE_RT		0x00000020	/* Load the routing API in the extension */
#define API_MODULE_SESSION	0x00000040	/* Load the session API in the extension */
#define API_MODULE_DISPATCH	0x00000080	/* Load the dispatch API in the extension */
#define API_MODULE_SECURITY	0x00000100	/* Load the security API in the extension */


#define EXTENSION_API_INIT_INTERN( flags, name, api ) {								\
	sub_api_header_t * hdr;											\
	char * buffer = (char *)api;										\
	int index = 0;												\
														\
	if (api->version != WAAAD_API_VER) {									\
		/* Unable to parse this API, do not continue */							\
		fprintf(stderr, 										\
			"[%s] Incompatible API version, please recompile the extension.\n", (name));		\
		return EINVAL;											\
	}													\
														\
	index += sizeof(int);											\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_LOG ) {									\
		g_api_log = (api_log_t *)hdr;									\
		if (g_api_log->version != WAAAD_API_LOG_VER) {							\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible log API version, please recompile the extension.\n", 	\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_DICTIONARY ) {								\
		g_api_dict = (api_dict_t *)hdr;									\
		if (g_api_dict->version != WAAAD_API_DICT_VER) {						\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible dictionary API version, please recompile the extension.\n", 	\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_CONF ) {									\
		g_api_conf = (api_conf_t *)hdr;									\
		if (g_api_conf->version != WAAAD_API_CONF_VER) {						\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible conf API version, please recompile the extension.\n", 	\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_PEER ) {									\
		g_api_peer = (api_peer_t *)hdr;									\
		if (g_api_peer->version != WAAAD_API_PEER_VER) {						\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible peer API version, please recompile the extension"		\
				" or update the initialization in extensions.c.\n",				\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_MSG ) {									\
		g_api_msg = (api_msg_t *)hdr;									\
		if (g_api_msg->version != WAAAD_API_MSG_VER) {							\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible message API version, please recompile the extension"		\
				" or update the initialization in extensions.c.\n",				\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_RT ) {									\
		g_api_rt = (api_rt_t *)hdr;									\
		if (g_api_rt->version != WAAAD_API_RT_VER) {							\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible routing API version, please recompile the extension"		\
				" or update the initialization in extensions.c.\n",				\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_SESSION ) {									\
		g_api_session = (api_sess_t *)hdr;								\
		if (g_api_session->version != WAAAD_API_SESSION_VER) {						\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible session API version, please recompile the extension"		\
				" or update the initialization in extensions.c.\n",				\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_DISPATCH ) {									\
		g_api_disp = (api_disp_t *)hdr;									\
		if (g_api_disp->version != WAAAD_API_DISP_VER) {						\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible dispatch API version, please recompile the extension"	\
				" or update the initialization in extensions.c.\n",				\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	if ( (flags) & API_MODULE_SECURITY ) {									\
		g_api_sec = (api_sec_t *)hdr;									\
		if (g_api_sec->version != WAAAD_API_SEC_VER) {							\
			/* Unable to parse this API, do not continue */						\
			fprintf(stderr, 									\
				"[%s] Incompatible security API version, please recompile the extension"	\
				" or update the initialization in extensions.c.\n",				\
				(name));									\
			return EINVAL;										\
		}												\
	}													\
														\
	hdr = (sub_api_header_t *) &buffer[index];								\
	index += hdr->length;											\
														\
	/* next module... */											\
														\
}


#define EXTENSION_API_INIT(flags, function, name, no_double)			\
static int extension_loaded = 0;						\
int waaad_ext_init(waaad_api_t * api, char * conffile) {			\
	EXTENSION_API_INIT_INTERN( flags, name, api );				\
	if (extension_loaded && no_double) {					\
		log_error("Extension %s cannot be loaded twice!\n", name);	\
		return ENOTSUP;							\
	}									\
	extension_loaded++;							\
	return (function)(conffile);						\
}														
		

#endif /* IN_EXTENSION */
#endif /* ! _WAAAD_API_H */
"Welcome to our mercurial repository"