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

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.9 $   $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"





#include "s_me.h"

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


static SHAREDLIB * shared_lib_lists_INIT[] = {
    &use_shared_base,
    &use_shared_connect,
};

static SHAREDLIB ** shared_lib_lists = shared_lib_lists_INIT;
static int shared_lib_lists_count = sizeof (shared_lib_lists_INIT) /
                     sizeof (shared_lib_lists_INIT[0]);

void register_list(Z)
     SHAREDLIB *Z;
{
    if (shared_lib_lists == shared_lib_lists_INIT) {
	int i;
	shared_lib_lists = safe_malloc((shared_lib_lists_count+1) *
				       sizeof (shared_lib_lists_INIT[0]));

	for (i = 0; i < shared_lib_lists_count; i++)
	    shared_lib_lists[i] = shared_lib_lists_INIT[i];
    } else
	shared_lib_lists = safe_realloc(shared_lib_lists,
					(shared_lib_lists_count+1) *
					sizeof (shared_lib_lists_INIT[0]));

    shared_lib_lists[shared_lib_lists_count] = Z;
    shared_lib_lists_count++;
}

S_(sl_reg_functions sl_reg_all)
static int sl_reg_all P_((struct ImpInfo *i,
			  int reg_idx));
static int sl_reg_all(i,reg_idx)
     struct ImpInfo *i;
     int reg_idx;
{
    int j;
    int found = 0;

    /* WARNING: give_rnum adds new items
                to i->regs[] array therefore
		we can not take pointer to it
		bacause array is reallocated
    */

    if (&use_shared_all != i->regs[reg_idx].var)
	panic("SHARED PANIC",__FILE__,__LINE__,
	      "sl_reg_all",
	      "Wrong variable",0);
   
    DPRINT(Debug,10,(&Debug,
		     "sl_reg_all: Trying move %s out of use-library [var %p]\n",
		     i->tag,i->regs[reg_idx].var));

    for (j = 0; j < shared_lib_lists_count; j++) {
	int k = give_rnum(i,shared_lib_lists[j]);

	/* First assume validity ... */
	i->regs[k].valid = 1;

	if (reg_code1(i,k)) {
	    i->regs[reg_idx].valid = 0; /* remove form use-library */
	    mark_local_changed((void *)shared_lib_lists[j]);
	    mark_local_changed((void *)&use_shared_all);

	    shared_lib_lists[j]->libraries_loaded = 0;

	    found++;
	} else {
	    i->regs[k].valid = 0;
	}    
    }

    if (!found) {
	DPRINT(Debug,1,(&Debug, 
			"Not found variable for library %s !!\n",
			i->tag));
    }

    if (! i->regs[reg_idx].valid) {
	DPRINT(Debug,7,(&Debug, 
			"Library %s marked as invalid for var use-library [var %p]\n",
			i->tag,i->regs[reg_idx].var));
    }

    DPRINT(Debug,10,(&Debug,
		     "sl_reg_all: %s ... found = %d  valid [var %p] = %d\n",
		     i->tag,found,
		     i->regs[reg_idx].var,
		     i->regs[reg_idx].valid));

    return 1;  /* OK */
}

S_(sl_zero_reg_list sl_zero_all)
static void sl_zero_all P_((struct dt_shared_info *var,
			      struct reg_list *r));
static void sl_zero_all(var,r)
     struct dt_shared_info *var;
     struct reg_list *r;
{
    r->var     = var;
    r->r.dummy = NULL;
}

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

}


static struct shared_loader all_loader = {
    SHARED_LOADER_magic,
    sl_reg_all,
    sl_zero_all,
    sl_unreg_all
};


SHAREDLIB use_shared_all = {
    &all_loader            /* loader */,
    0,                       
    NULL, 0,

    NULL
};

/* For elmlibregister.c  -- if argv is NULL only check current list */
void test_and_set_shared (argv, will_write)
     char **argv;
     int will_write;
{
    int i;

    /* 1) Load current libraries */

    load_shared_libs();

    /* load generic ... */
    load_shared_libs1(&use_shared_all);

    if (argv) {

	/* 2) Test explicity argument list ....
	 */

	int j;

	for (j = 0; argv[j]; j++) {
	    struct ImpInfo * I;

	    if (!tag_ok(argv[j])) {
		lib_error(CATGETS(elm_msg_cat, MeSet,
				  MeInvalidUseXLib,
				  "%s: %s: Invalid name"),
			  "use-*-library", argv[j]);
		continue;
	    }

	    I = give_impinfo(argv[j]);

	    /* Assume valid */
	    I->valid = 1;
	    load_code0(I);       /* Test validity */

	    if (I->valid) {
		int found = 0;
		int k;

		for (k = 0; k < shared_lib_lists_count; k++) {
		    int m = give_rnum(I,shared_lib_lists[k]);
		    
		    /* First assume validity ... */
		    I->regs[m].valid = 1;

		    if (reg_code1(I,m)) {
			found++;
			mark_local_changed((void *)shared_lib_lists[k]);

			shared_lib_lists[k]->libraries_loaded = 0;
		    } else {
			I->regs[m].valid = 0;

		    }
		}

		if (!found) {
		    DPRINT(Debug,1,(&Debug, 
				    "Not found variable for library %s !!\n",
				    argv[j]));
		}

		if (will_write && found)
		    lib_error(CATGETS(elm_msg_cat, MeSet,
				      MeLibraryRegistered,
				      "Library %s registered"),
			      argv[j]);
		else
		    lib_error(CATGETS(elm_msg_cat, MeSet,
				      MeLibraryAvailable,
				      "Library %s is available"),
			      argv[j]);
	    }
	}
    }
    
    for (i = 0; i < library_list_count; i++) {
	    if (!library_list[i]->valid) {
		if (will_write)
		    lib_error(CATGETS(elm_msg_cat, MeSet,
				      MeLibraryUnRegistered,
				      "Library %s unregistered"),
			      library_list[i]->tag);
		else
		    lib_error(CATGETS(elm_msg_cat, MeSet,
				      MeLibraryUnavailable,
				      "Library %s is unavailable"),
			      library_list[i]->tag);
		

	    }
    }
}


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



syntax highlighted by Code2HTML, v. 0.9.1