[dovecot-cvs] dovecot/src/lib module-dir.c,NONE,1.1 module-dir.h,NONE,1.1

cras at procontrol.fi cras at procontrol.fi
Wed May 14 22:23:42 EEST 2003


Update of /home/cvs/dovecot/src/lib
In directory danu:/tmp/cvs-serv23344

Added Files:
	module-dir.c module-dir.h 
Log Message:
missing



--- NEW FILE: module-dir.c ---
/* Copyright (C) 2003 Timo Sirainen */

#include "lib.h"
#include "module-dir.h"

#ifdef HAVE_MODULES

#include <unistd.h>
#include <dirent.h>
#include <dlfcn.h>

static void *get_symbol(const char *path, void *handle, const char *symbol)
{
	const char *error;
	void *ret;

	/* get our init func */
	ret = dlsym(handle, symbol);

	error = dlerror();
	if (error != NULL) {
		i_error("module %s: dlsym(%s) failed: %s", path, symbol, error);
		ret = NULL;
	}

	return ret;
}

static struct module *module_load(const char *path, const char *name)
{
	void *handle;
	void (*init)(void);
	void (*deinit)(void);
	struct module *module;

	handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW);
	if (handle == NULL) {
		i_error("dlopen(%s) failed: %s", path, dlerror());
		return NULL;
	}

	/* get our init func */
	init = get_symbol(path, handle, t_strconcat(name, "_init", NULL));
	deinit = init == NULL ? NULL :
		get_symbol(path, handle, t_strconcat(name, "_deinit", NULL));

	if (init == NULL || deinit == NULL) {
		(void)dlclose(handle);
		return NULL;
	}

	init();

	module = i_new(struct module, 1);
	module->handle = handle;
	module->deinit = deinit;
	return module;
}

struct module *module_dir_load(const char *dir)
{
	DIR *dirp;
	struct dirent *d;
	const char *name, *path, *p;
	struct module *modules, *module;

	dirp = opendir(dir);
	if (dirp == NULL) {
		i_error("opendir(%s) failed: %m", dir);
		return NULL;
	}

	modules = NULL;
	while ((d = readdir(dirp)) != NULL) {
		name = d->d_name;

		if (name[0] == '.')
			continue;

		p = strstr(name, ".so");
		if (p == NULL || strlen(p) != 3)
			continue;

		if (strncmp(name, "lib", 3) == 0)
			name += 3;

		t_push();
		name = t_strdup_until(d->d_name, p);
		path = t_strconcat(dir, "/", d->d_name, NULL);
		module = module_load(path, name);
		t_pop();

		if (module != NULL) {
			module->next = modules;
			modules = module;
		}
	}

	if (closedir(dirp) < 0)
		i_error("closedir(%s) failed: %m", dir);

	return modules;
}

void module_dir_unload(struct module *modules)
{
	struct module *next;

	while (modules != NULL) {
		next = modules->next;
		modules->deinit();
		if (dlclose(modules->handle) != 0)
			i_error("dlclose() failed: %m");
		i_free(modules);
		modules = next;
	}
}

#else

struct module *module_dir_load(const char *dir __attr_unused__)
{
	i_error("Dynamically loadable module support not built in");
	return NULL;
}

void module_dir_unload(struct module *modules __attr_unused__)
{
}

#endif

--- NEW FILE: module-dir.h ---
#ifndef __MODULE_DIR_H
#define __MODULE_DIR_H

struct module {
	void *handle;
	void (*deinit)(void);

        struct module *next;
};

/* Load all modules in given directory. */
struct module *module_dir_load(const char *dir);
/* Unload all modules */
void module_dir_unload(struct module *modules);

#endif



More information about the dovecot-cvs mailing list