209 lines
5.1 KiB
C
209 lines
5.1 KiB
C
/*
|
|
* Copyright (C) 2000 Carsten Haitzler, Geoff Harrison and various contributors
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
* and software packages that this Software was used.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#include "E.h"
|
|
|
|
/* Added by Marty Riedling for HPUX 10 support */
|
|
#ifdef HPUX10
|
|
#include <dl.h>
|
|
#define dlopen(p, f) (shl_load((p), BIND_IMMEDIATE|BIND_VERBOSE|BIND_NOSTART, 0L))
|
|
#define dlclose(h) (shl_unload((shl_t) (h)))
|
|
#else
|
|
#include <dlfcn.h>
|
|
#endif
|
|
|
|
/* modules.c - generic module loader / unloader */
|
|
|
|
/* This is the Modules List that we maintain */
|
|
typedef struct _ModuleMember
|
|
{
|
|
|
|
char *ModuleName;
|
|
void *handle;
|
|
|
|
}
|
|
ModuleMember;
|
|
|
|
int ListLength = 0;
|
|
ModuleMember *ModuleList;
|
|
|
|
/* This is a few of our return code DEFINES */
|
|
|
|
#define MODULE_ALREADY_LOADED 1
|
|
#define MODULE_LOAD_FAIL 2
|
|
#define MODULE_UNLOAD_FAIL 3
|
|
#define MODULE_NOT_LOADED 4
|
|
#define MODULE_EXEC_FAIL 5
|
|
|
|
int
|
|
LoadModule(char *module_name)
|
|
{
|
|
|
|
void *handle = NULL;
|
|
|
|
/* Well, we don't want to load twice now, do we? */
|
|
if (IsLoadedModule(module_name))
|
|
return (MODULE_ALREADY_LOADED);
|
|
|
|
/* We'll attempt to load the module first */
|
|
{
|
|
|
|
char pathoffiletoload[FILEPATH_LEN_MAX];
|
|
|
|
Esnprintf(pathoffiletoload, sizeof(pathoffiletoload), "%s/%s",
|
|
FindModulePath(module_name), module_name);
|
|
handle = dlopen(pathoffiletoload, RTLD_LAZY);
|
|
|
|
if (!handle)
|
|
return (MODULE_LOAD_FAIL);
|
|
}
|
|
|
|
/* create or append to ModuleList? */
|
|
if (ModuleList)
|
|
{
|
|
ModuleList = Erealloc(ModuleList, ++ListLength * sizeof(ModuleMember));
|
|
}
|
|
else
|
|
{
|
|
ModuleList = Emalloc(sizeof(ModuleMember));
|
|
ListLength = 1;
|
|
}
|
|
|
|
/* Now we'll chunk everything useful into the ModuleList */
|
|
ModuleList[ListLength - 1].ModuleName = duplicate(module_name);
|
|
ModuleList[ListLength - 1].handle = handle;
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
int
|
|
UnloadModule(char *module_name)
|
|
{
|
|
|
|
int ModuleID;
|
|
int i;
|
|
|
|
if (!(ModuleID = IsLoadedModule(module_name)))
|
|
return (MODULE_NOT_LOADED);
|
|
|
|
/* fix the ModuleID */
|
|
ModuleID--;
|
|
|
|
if (dlclose(ModuleList[ModuleID].handle))
|
|
return (MODULE_UNLOAD_FAIL);
|
|
|
|
if (ModuleList[ModuleID].ModuleName)
|
|
Efree(ModuleList[ModuleID].ModuleName);
|
|
|
|
for (i = ModuleID; i < ListLength; i++)
|
|
{
|
|
ModuleList[i].ModuleName = ModuleList[i + 1].ModuleName;
|
|
ModuleList[i].handle = ModuleList[i + 1].handle;
|
|
}
|
|
|
|
ModuleList = Erealloc(ModuleList, --ListLength * sizeof(ModuleMember));
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
char *
|
|
ModuleErrorCodeToString(int error_code)
|
|
{
|
|
|
|
switch (error_code)
|
|
{
|
|
|
|
case MODULE_ALREADY_LOADED:
|
|
return (_("Module is Already Loaded.\n"));
|
|
case MODULE_LOAD_FAIL:
|
|
return (_("Module Failed During Load.\n"));
|
|
case MODULE_UNLOAD_FAIL:
|
|
return (_("Module Unload Failed.\n"));
|
|
case MODULE_NOT_LOADED:
|
|
return (_("Module is not Loaded.\n"));
|
|
default:
|
|
return (_("Unknown Module Error.\n"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
char *
|
|
ModuleListAsString(void)
|
|
{
|
|
|
|
int i;
|
|
|
|
char returnList[FILEPATH_LEN_MAX];
|
|
|
|
returnList[0] = 0;
|
|
|
|
strcat(returnList, "");
|
|
for (i = 0; i < ListLength; i++)
|
|
{
|
|
strcat(returnList, ModuleList[i].ModuleName);
|
|
strcat(returnList, "\n");
|
|
|
|
}
|
|
|
|
return (duplicate(returnList));
|
|
|
|
}
|
|
|
|
int
|
|
IsLoadedModule(char *module_name)
|
|
{
|
|
|
|
/* unfortunately this must return the module id + 1, since
|
|
* a 0 is the "not loaded" response, and the index can be 0
|
|
* (note to anyone wondering what the hell this was about)
|
|
* --Mandrake
|
|
*/
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ListLength; i++)
|
|
{
|
|
if (!strcmp(ModuleList[i].ModuleName, module_name))
|
|
{
|
|
return (i + 1);
|
|
}
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
char *
|
|
FindModulePath(char *module_name)
|
|
{
|
|
|
|
/* yeah yeah so it's hard-coded for now. BITE ME */
|
|
/* *** FIXME *** */
|
|
module_name = module_name; /* suppress warning until we actually use the module name for something */
|
|
|
|
return (ENLIGHTENMENT_ROOT "/modules");
|
|
|
|
}
|