static char rcsid[] = "@(#)$Id: shared_mailer.c,v 1.5 2006/06/29 17:26:41 hurtta Exp $";

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

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

#include "def_mailer.h"

DEBUG_VAR(Debug,__FILE__,"dl");

#include "shared_imp.h"
#include "mailer_imp.h"

#include "rc_imp.h"
#include "save_opts.h"


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

#define SHARED_MAILER_magic	0xF904

struct sl_mailer_data {
  uint16            magic;      

};


S_(sl_reg_functions sl_reg_mailer)
static int sl_reg_mailer P_((struct ImpInfo *i,
			      int reg_idx));
static int sl_reg_mailer(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 F14 {
	void *                       ptr;
	provides_shared_MCF_f      * f14;
    } f14;

    f14.ptr = dlsym(i->handle, "provides_shared_MCF");

    if (!f14.f14) {
	DPRINT(Debug,7,(&Debug, " ... NO provides_shared_MCF\n"));
    }

    if (f14.f14) {
      int count;
      size_t  s_res14, s_opt_size;

      struct mailer_config *res14 = f14.f14(&count,&s_res14,
					    &s_opt_size);
      
      if (s_res14 != sizeof (*res14)) {
	DPRINT(Debug,1,(&Debug,
				"...  struct mailer_config mismatch: %d should be %d\n",
			s_res14,sizeof (*res14)));
      } else if (s_opt_size != sizeof (struct mailer_option_list)) {
	DPRINT(Debug,1,(&Debug,
			"...  struct mailer_option_list mismatch: %d should be %d\n",
			s_opt_size,sizeof (struct mailer_option_list)));
      } else {		
	int x;
	
	shared_MCF_types = 
	  safe_realloc(shared_MCF_types,
		       sizeof (shared_MCF_types[0]) *
		       (shared_MCF_type_count + count));
	
	DPRINT(Debug,7,(&Debug," ... provides_shared_MCF:  (shared_MCF_types) count %d\n",
			count));
	res = 1;
	
	for (x = 0; x < count; x++) {
	  shared_MCF_types[shared_MCF_type_count+x].T = &(res14[x]);
	  shared_MCF_types[shared_MCF_type_count+x].imp_idx = i;
	}
	shared_MCF_type_count += count;
      }
    }
    
    i->regs[reg_idx].valid   = res;

    DPRINT(Debug,7,(&Debug, 
		    "sl_reg_mailer:  [%p]->regs[%d].valid = %d\n",
		    i,reg_idx,res));

    
    return res;
}

S_(sl_zero_reg_list sl_zero_mailer)
static void sl_zero_mailer P_((struct dt_shared_info *var,
				struct reg_list *r));
static void sl_zero_mailer(var,r)
     struct dt_shared_info *var;
     struct reg_list *r;
{
    r->var     = var;
    r->valid   = 0;
    r->r.mailer  = safe_malloc(sizeof (*r->r.mailer));   /* never freed ... */
    r->r.mailer->magic = SHARED_MAILER_magic;
}

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

}

static struct shared_loader mailer_loader = {
    SHARED_LOADER_magic,
    sl_reg_mailer,
    sl_zero_mailer,
    sl_unreg_mailer
};

SHAREDLIB use_shared_mailer = {
    &mailer_loader            /* loader */,
    0,                       
    NULL, 0,

    NULL
};

struct mailer_config  * loc_mailer_type(f)
     char *f;
{
    int x;
    
    /* We must load all mailer libraries */
    load_shared_libs1(&use_shared_mailer); 

 
   for (x = 0; x < shared_MCF_type_count; x++)
	if (0 == strcmp(shared_MCF_types[x].T->mailer_type,f)) {
	    return shared_MCF_types[x].T;
	}
    return NULL;
}


syntax highlighted by Code2HTML, v. 0.9.1