On Tue, Jun 17, 2003 at 05:52:43PM -0400, Brad Chapman wrote:
> (sorry about the long URL). 

There really should be a universal clipboard system that non-X programs
could use too, but in the meanwhile: http://tinyurl.com/

> The short of it is that they are
> working on the update, but it's not there yet because it is a big
> job due to all the other software which depends on it.

I don't see a single problem in providing 1.4 (perhaps with a different
name if that would break the package system) in some non-default path.
Even cygwin provides both 1.4.3 and 1.5. (But unfortunately uses some
autoconf-dependant wrapper kludge to detect which to use.)

> Is this a case where I am stuck until FreeBSD gets up to date, or is
> using 1.3.4 an easy task? 

I have attached modules.c from 20030601, it should work by just
copying it over the current one and should not use the iteration
functions. You still need CF_LTDL_ANCIENT for lt_dlinsertsearchdir in
readconfig.c, though. (Apparently the flag is useless after all as I 
changed the rest of the code to refer to 1.4 functions so I don't 
have to duplicate code.)

-- 
Tuomo
/*
 * ion/ioncore/modules.c
 *
 * Copyright (c) Tuomo Valkonen 1999-2003. 
 *
 * Ion is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 */

#include <ltdl.h>
#include <string.h>
#include <ctype.h>

#include "common.h"
#include "modules.h"
#include "readconfig.h"
#include "../version.h"


INTRSTRUCT(Module);
        
DECLSTRUCT(Module){
        lt_dlhandle handle;
        char *name;
        Module *next, *prev;
};

static Module *modules=NULL;



/*{{{ Loading and initialization code */


static bool check_version(lt_dlhandle handle, char *name)
{
        char *p=scat(name, "_module_ion_version");
        char *versionstr;

        if(p==NULL){
                warn_err();
                return FALSE;
        }
        
        versionstr=(char*)lt_dlsym(handle, p);
        
        free(p);
        
        if(versionstr==NULL)
                return FALSE;
        
        return (strcmp(versionstr, ION_VERSION)==0);
}


static bool call_init(lt_dlhandle handle, char *name)
{
        char *p=scat(name, "_module_init");
        bool (*initfn)(void);

        if(p==NULL){
                warn_err();
                return FALSE;
        }
        
        initfn=(bool (*)())lt_dlsym(handle, p);
        
        free(p);
        
        if(initfn==NULL)
                return TRUE;
        
        return initfn();
}


bool init_module_support()
{
#ifdef CF_PRELOAD_MODULES
        LTDL_SET_PRELOADED_SYMBOLS();
#endif
        if(lt_dlinit()!=0){
                warn("lt_dlinit: %s", lt_dlerror());
                return FALSE;
        }
        return TRUE;
}


/*EXTL_DOC
 * Attempt to load module \var{modname}. Ion will use libltdl to search
 * library path (the default setting is \file{\~{}/.ion-devel/libs} and
 * \file{\$PREFIX/lib/ion-devel}) and also try diffent extensions so only
 * the module name should usually be necessary to give here.
 */
EXTL_EXPORT
bool load_module(const char *modname)
{
        lt_dlhandle handle=NULL;
        Module *m;
        const char *p;
        char *n;
        size_t l;
        
        if(modname==NULL)
                return FALSE;
        
        handle=lt_dlopenext(modname);
        
        if(handle==NULL){
                warn("Failed to load module %s: %s", modname, lt_dlerror());
                return FALSE;
        }
        
        for(m=modules; m!=NULL; m=m->next){
                if(m->handle==handle)
                        return TRUE;
        }

        /* Get the module name without directory or extension */
        
        p=strrchr(modname, '/');
        
        if(p!=NULL)
                modname=p+1;
        
        for(p=modname; *p!='\0'; p++){
                if(!isalnum(*p) && *p!='_')
                        break;
        }
        
        n=ALLOC_N(char, p-modname+1);
        
        if(n==NULL){
                warn_err();
                goto err1;
        }
         
        memcpy(n, modname, p-modname);
        n[p-modname]='\0';
        
        /* Allocate space for module info */
        
        m=ALLOC(Module);
        
        if(m==NULL){
                warn_err();
                goto err2;
        }
        
        m->name=n;
        m->handle=handle;
        m->next=NULL;
        
        /* initialize */
        if(!check_version(handle, n)){
                warn_obj(modname, "Module version information not found or version "
                                 "mismatch. Refusing to use.");
                goto err3;
        }
        
        if(!call_init(handle, n))
                goto err3;

        LINK_ITEM(modules, m, next, prev);
        
        return TRUE;
        
err3:
        free(m);
err2:
        free(n);
err1:
        lt_dlclose(handle);
        return FALSE;
}


/*EXTL_EXPORT
bool load_module(const char *name)
{
        char *name2=NULL;
        bool ret=FALSE;
        
        if(strchr(name, '/')!=NULL)
                return do_load_module(name);

        if(strchr(name, '.')==NULL){
                name2=scat(name, ".la");
                if(name2==NULL){
                        warn_err();
                        return FALSE;
                }
                ret=load_module(name2);
                free(name2);
                return ret;
        }

        name2=find_module(name);
        
        if(name2!=NULL){
                ret=do_load_module(name2);
                free(name2);
        }
        
        return ret;
}*/


/*}}}*/


/*{{{ Deinit */


static void call_deinit(lt_dlhandle handle, char *name)
{
        char *p=scat(name, "_module_deinit");
        void (*deinitfn)(void);

        if(p==NULL){
                warn_err();
                return;
        }
        
        deinitfn=(void (*)())lt_dlsym(handle, p);
        
        free(p);
        
        if(deinitfn!=NULL)
                deinitfn();
}


static void do_unload_module(Module *m)
{
        call_deinit(m->handle, m->name);

        lt_dlclose(m->handle);
        if(m->name!=NULL)
                free(m->name);
        free(m);
}


void unload_modules()
{
        Module *m;
        
        while(modules!=NULL){
                m=modules->prev;
                UNLINK_ITEM(modules, m, next, prev);
                do_unload_module(m);
        }
}


/*}}}*/


Reply via email to