"Fossies" - the Fresh Open Source Software archive 
Member "evlog-1.6.1/user/cmd/evlogd/backendmgr.c" of archive evlog-1.6.1.tar.gz:
/*
* Linux Event Logging for the Enterprise
* Copyright (c) International Business Machines Corp., 2001
*
*
* 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.
*
* Please send e-mail to lkessler@users.sourceforge.net if you have
* questions or comments.
*
* Project Website: http://evlog.sourceforge.net/
*
*/
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include "callback.h"
#include "config.h"
#define MAX_BACKENDS 10
#define BACKENDS_DIR EVLOG_PLUGIN_DIR
#define SMALL_BUF_SIZE 256
#ifdef DEBUG2
#define TRACE(fmt, args...) fprintf(stderr, fmt, ##args)
#else
#define TRACE(fmt, args...) /* fprintf(stderout, fmt, ##args) */
#endif
typedef struct backend {
void *plugin;
be_desc_t *desc;
int state;
} backend_t;
static int be_add(void *plugin, be_desc_t *desc);
static int be_release(backend_t *);
/* Backends table */
static backend_t be_table[MAX_BACKENDS];
static int be_cnt = 0;
/*
* dlopens the shared lib whose name is name. Returns the handle returned by
* dlopen().
*/
void * getPlugInHandle(char * name)
{
void *hdle;
char lib_path[256];
char *ext;
ext = (char *) strrchr(name, '.');
/* Skip . and .. */
if (!strcmp(name, ".") || !strcmp(name, ".."))
return (void *)NULL;
/* Skip if extension is not .so */
if (ext == NULL || strcmp(ext, ".so"))
return (void*)NULL;
sprintf(lib_path, BACKENDS_DIR "/%s", name);
/* Load plugin */
if (!(hdle = dlopen(lib_path, RTLD_LAZY))) {
fprintf(stderr, "%s\n", dlerror());
return (void *)NULL;
}
return hdle;
}
be_desc_t * getPlugInInterface(void * handle)
{
be_desc_t * d;
int status;
/* Get the back end interface functions for this plugin */
if (!(d = (be_desc_t *)dlsym(handle, "_evlPluginDesc"))) {
fprintf(stderr, "%s\n", dlerror());
return NULL;
}
/*
* Initialize the plugin. We give the
* callback inf so it can invoke some of
* evlogd functions.
*/
status = d->init(evl_callback);
if (status == -1) {
dlclose(handle);
return NULL;
}
return d;
}
/* Called during evlogd setup */
int
be_init()
{
struct dirent **plugins;
int n;
static void * handle;
n = scandir(BACKENDS_DIR, &plugins, 0, 0);
if (n < 0) {
//perror("scandir");
} else {
while(n--) {
be_desc_t *d;
handle = (void *)getPlugInHandle((char *)(plugins[n]->d_name));
free(plugins[n]);
if (!handle)
continue;
d = getPlugInInterface(handle);
if (!d)
continue;
be_add(handle, d);
}
free(plugins);
}
return be_cnt;
}
void
be_cleanup()
{
int i;
TRACE("be_cleanup invoked...\n");
for (i = 0; i < MAX_BACKENDS; i++) {
if (be_table[i].plugin != NULL) {
dlclose(be_table[i].plugin);
TRACE("be_cleanup plugin index #%d is set to NULL...\n", i);
be_table[i].plugin = NULL;
be_table[i].desc = NULL;
}
}
}
int
be_add(void *plugin, be_desc_t *d)
{
int i;
if (be_cnt >= MAX_BACKENDS) {
fprintf(stderr, "No more room for your plugin.\n");
return -1;
}
for (i = 0; i < MAX_BACKENDS; i++) {
if (be_table[i].desc == NULL) {
be_table[i].desc = d;
be_table[i].plugin = plugin;
be_cnt++;
break;
}
}
return 0;
}
static int
be_release(backend_t *be)
{
be->desc = NULL;
dlclose(be->plugin);
be->plugin = NULL;
be_cnt--;
return 0;
}
/*
* Execute all registered functions in the function table
* (also pass its arguments to those funtions).
*/
void
be_run(const char *data1, const char *data2, evl_callback_t callback)
{
int i;
int rc;
for (i = 0; i < MAX_BACKENDS; i++) {
if (be_table[i].desc != NULL) {
rc = be_table[i].desc->process(data1, data2, evl_callback);
if (rc != 0) {
/* release the backend */
be_release(&be_table[i]);
}
}
}
}
#if 0
int
main(char *argv[], int argc)
{
/* Initialize backends */
be_init();
/* Pass data to back end functions, and run them */
be_run("data1 is here", "data2 is also here", evl_callback);
printf("\nclean up...");
be_cleanup();
printf("done.\n");
return 0;
}
#endif