static char rcsid[] = "@(#)$Id: shared_base.c,v 1.5 2006/04/09 07:37:08 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.5 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
 *****************************************************************************/

/*
 * This file is compiled only if dlopen() is available, so
 * that file does not need to be guarded with #ifdef 
 */

#include "headers.h"

DEBUG_VAR(Debug,__FILE__,"dl");

#include "shared_imp.h"
#include "rc_imp.h"
#include "save_opts.h"
#include "cs_imp.h"

#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif


S_(CS_auto_charset_f no_cs_auto_charset)
static int no_cs_auto_charset(name,type,map)
     CONST char *name;
     struct  charset_type **type;
     struct  map_info **map;
{
    *type = NULL;
    *map = NULL;

    return 0;  /* No auto defination */
}



#define SHARED_BASE_magic	0xF902

struct sl_base_data {
    uint16            magic;      
    CS_auto_charset_f       * cs_auto_charset;

    struct  charset_type    * cs_first_type;
};

S_(sl_reg_functions sl_reg_base)
static int sl_reg_base P_((struct ImpInfo *i,
			   int reg_idx));
static int sl_reg_base(i,reg_idx)
     struct ImpInfo *i;
     int reg_idx;
{
    /* union hack to avoid warnings about casting
     * between pointer-to-object and pointer-to-function
     */
    
    int res = 0;
    
        
    union F13 {
	void *                       ptr;
	CS_auto_charset_f          * f13;
    } f13;
    
    struct reg_list *r = & (i->regs[reg_idx] );

    if (&use_shared_base != r->var)
	panic("SHARED PANIC",__FILE__,__LINE__,
	      "sl_reg_base",
	      "Wrong variable",0);

    f13.ptr = dlsym(i->handle, "CS_auto_charset");

        
    if (!f13.f13) {
	DPRINT(Debug,7,(&Debug, " ... NO CS_auto_charset\n"));
    }
    
    if (r->r.base->magic != SHARED_BASE_magic)
	panic("SHARED PANIC",__FILE__,__LINE__,
	      "sl_reg_base",
	      "Bad magic bumber",0);
    
           
    if (f13.f13) {
	r->r.base->cs_auto_charset = f13.f13;
	
	res = 1;
	
	DPRINT(Debug,7,(&Debug," ... CS_auto_charset\n"));		
    }
    
    r->valid   = res;

    return res;
}

S_(sl_zero_reg_list sl_zero_base)
static void sl_zero_base P_((struct dt_shared_info *var,
			      struct reg_list *r));
static void sl_zero_base(var,r)
     struct dt_shared_info *var;
     struct reg_list *r;
{
    r->var     = var;
    r->r.base  = safe_malloc(sizeof (*r->r.base));   /* never freed ... */
    r->r.base->magic = SHARED_BASE_magic;
    r->r.base->cs_auto_charset = no_cs_auto_charset;
    r->r.base->cs_first_type   = NULL;
}

S_(sl_unreg_functions sl_unreg_base)
static void sl_unreg_base P_((struct ImpInfo *i, int reg_idx));
static void sl_unreg_base(i,reg_idx)
     struct ImpInfo *i; 
     int reg_idx;
{
    struct reg_list *r = & (i->regs[reg_idx] );

}


static struct shared_loader base_loader = {
    SHARED_LOADER_magic,
    sl_reg_base,
    sl_zero_base,
    sl_unreg_base
};


SHAREDLIB use_shared_base = {
    &base_loader            /* loader */,
    0,                       
    NULL, 0
};

/* ------------------------------------------------------------------------- */


struct  charset_type * find_shared_CS_type(val)
     CONST char *val;
{
    int i;

    /* We must load all base libraries */
    load_shared_libs1(&use_shared_base);  


    for (i = 0; i < use_shared_base.shared_list_len; i++) {
	if (use_shared_base.shared_list[i]->handle) {
	    int r = give_rnum(use_shared_base.shared_list[i],&use_shared_base);

	    struct sl_base_data    * base = 
		use_shared_base.shared_list[i]->regs[r].r.base;

	    if (base ->magic != SHARED_BASE_magic)
		panic("SHARED PANIC",__FILE__,__LINE__,
		      "find_shared_CS_type",
		      "Bad magic bumber",0);


	    if (use_shared_base.shared_list[i]->regs[r].valid &&
		base->cs_first_type) {
		struct  charset_type * walk;

		for (walk = base->cs_first_type;
		     walk; 
		     walk = walk -> next_type)
		    if (0 == strcmp(val,walk->type_name))
			break;
		if (walk) {
		    DPRINT(Debug,8,(&Debug,
				    "library [%d] %s provides charset type=%s\n",
				    i,use_shared_base.shared_list[i]->shname,
				    walk->type_name));
		    return walk;
		}
	    }
	}
    }
    
    return NULL;
}

int cs_auto_charset(name,type,map)
     CONST char *name;
     struct  charset_type **type;
     struct  map_info **map;
{
    int i;

    /* We must load all base libraries */
    load_shared_libs1(&use_shared_base); 

    *type = NULL;
    *map  = NULL;
    
    for (i = 0; i < use_shared_base.shared_list_len; i++) {
	if (use_shared_base.shared_list[i]->handle) {
	    int r = give_rnum(use_shared_base.shared_list[i],&use_shared_base);
	    
	    struct sl_base_data    * base = 
		use_shared_base.shared_list[i]->regs[r].r.base;
	    
	    if (base ->magic != SHARED_BASE_magic)
		panic("SHARED PANIC",__FILE__,__LINE__,
		      "find_shared_CS_type",
		      "Bad magic bumber",0);
	    
	    if (use_shared_base.shared_list[i]->regs[r].valid &&
		base->cs_auto_charset(name,type,map)) {
		DPRINT(Debug,8,(&Debug,
				"library [%d] %s auto-defines charset %s (type=%s)\n",
				i,use_shared_base.shared_list[i][i].shname,
				name,
				(*type) && (*type)->type_name ?
				(*type)->type_name :
				"<no type or type name>"
				));
		return 1;
	    }
	}
    }
    return 0;
}



/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 * End:
 */



syntax highlighted by Code2HTML, v. 0.9.1