/***********************************************************************
 * 
 *  Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
 *
 *  This library 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; version 2.1
 *  of the License.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 ***********************************************************************/

// NOTE TODO:  We need to check for null pointers on all callbacks.

#include "ad_gk.h"

// START FOR DYNAMIC LINKING
#include <micasa_types.h>
#include <dlfcn.h> 

// handle to gnome-keyring library
static void *gnomeIDK = NULL;
static char *GNOME_KEYRING_NDK = "libgnome-keyring.so.0";

// function typedefs
SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_UNLOCK_T)
					(const char                                  *keyring,
				      const char                                  *password,
				      GnomeKeyringOperationDoneCallback            callback,
				      gpointer                                     data,
				      GDestroyNotify                               destroy_data);

SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_ITEM_CREATE_T)
					(const char                                 *keyring,
				      GnomeKeyringItemType                        type,
				      const char                                 *display_name,
				      GnomeKeyringAttributeList                  *attributes,
				      const char                                 *secret,
				      gboolean                                    update_if_exists,
				      GnomeKeyringOperationGetIntCallback         callback,
				      gpointer                                    data,
				      GDestroyNotify                              destroy_data);

SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_CREATE_T)
					(const char                                  *keyring_name,
				      const char                                  *password,
				      GnomeKeyringOperationDoneCallback            callback,
				      gpointer                                     data,
				      GDestroyNotify                               destroy_data);

SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_LIST_KEYRING_NAMES_T)
					(GnomeKeyringOperationGetListCallback    callback,
					 gpointer                                data,
					 GDestroyNotify                          destroy_data);

SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_GET_INFO_T)
					(const char                                  *keyring,
				      GnomeKeyringOperationGetKeyringInfoCallback  callback,
				      gpointer                                     data,
				      GDestroyNotify						destroy_data);
SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_SET_INFO_T)
					(const char                                  *keyring,
				      GnomeKeyringInfo                            *info,
				      GnomeKeyringOperationDoneCallback            callback,
				      gpointer                                     data,
				      GDestroyNotify                               destroy_data);

 SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_LIST_ITEM_IDS_T)
					(const char                                  *keyring,
				      GnomeKeyringOperationGetListCallback         callback,
				      gpointer                                     data,
				      GDestroyNotify                               destroy_data);
 SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_ITEM_GET_INFO_T)
					(const char                                 *keyring,
				      guint32                                     id,
				      GnomeKeyringOperationGetItemInfoCallback    callback,
				      gpointer                                    data,
				      GDestroyNotify                              destroy_data);
 SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_ITEM_SET_INFO_T)
					(const char                                 *keyring,
				      guint32                                     id,
				      GnomeKeyringItemInfo                       *info,
				      GnomeKeyringOperationDoneCallback           callback,
				      gpointer                                    data,
				      GDestroyNotify                              destroy_data);
 SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_ITEM_GET_ATTRIBUTES_T)
					(const char                                 *keyring,
				      guint32                                     id,
				      GnomeKeyringOperationGetAttributesCallback  callback,
				      gpointer                                    data,
				      GDestroyNotify                              destroy_data);
 SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_ITEM_SET_ATTRIBUTES_T)
					(const char                                 *keyring,
				      guint32                                     id,
				      GnomeKeyringAttributeList                  *attributes,
				      GnomeKeyringOperationDoneCallback           callback,
				      gpointer                                    data,
				      GDestroyNotify                              destroy_data);
SSCS_TYPEDEF_LIBCALL(gpointer, GNOME_KEYRING_ITEM_DELETE_T)
					(const char                                 *keyring,
				      guint32                                     id,
				      GnomeKeyringOperationDoneCallback           callback,
				      gpointer                                    data,
				      GDestroyNotify                              destroy_data);

SSCS_TYPEDEF_LIBCALL_PTR(GnomeKeyringItemInfo, GNOME_KEYRING_ITEM_INFO_NEW_T)
					();

// check this
SSCS_TYPEDEF_LIBCALL(void, GNOME_KEYRING_ITEM_INFO_SET_SECRET_T)
					(GnomeKeyringItemInfo *item_info,
						const char           *value);

SSCS_TYPEDEF_LIBCALL_PTR(char, GNOME_KEYRING_ITEM_INFO_GET_SECRET_T)
					(GnomeKeyringItemInfo *item_info);

SSCS_TYPEDEF_LIBCALL(void, GNOME_KEYRING_ITEM_INFO_FREE_T)
					(GnomeKeyringItemInfo *item_info);

SSCS_TYPEDEF_LIBCALL(void, GNOME_KEYRING_ATTRIBUTE_LIST_FREE_T)
					(GnomeKeyringAttributeList *attributes);

SSCS_TYPEDEF_LIBCALL(time_t, GNOME_KEYRING_INFO_GET_MTIME_T)
					(GnomeKeyringInfo *keyring_info);

SSCS_TYPEDEF_LIBCALL(time_t, GNOME_KEYRING_INFO_GET_CTIME_T)
					(GnomeKeyringInfo *keyring_info);

SSCS_TYPEDEF_LIBCALL(gboolean, GNOME_KEYRING_INFO_GET_IS_LOCKED_T)
					(GnomeKeyringInfo *keyring_info);

SSCS_TYPEDEF_LIBCALL(guint32, GNOME_KEYRING_INFO_GET_LOCK_TIMEOUT_T)
					(GnomeKeyringInfo *keyring_info);

SSCS_TYPEDEF_LIBCALL(gboolean, GNOME_KEYRING_INFO_GET_LOCK_ON_IDLE_T)
					(GnomeKeyringInfo *keyring_info);

SSCS_TYPEDEF_LIBCALL(time_t, GNOME_KEYRING_ITEM_INFO_GET_MTIME_T)
					(GnomeKeyringItemInfo *item_info);

SSCS_TYPEDEF_LIBCALL(time_t, GNOME_KEYRING_ITEM_INFO_GET_CTIME_T)
					(GnomeKeyringItemInfo *item_info);

SSCS_TYPEDEF_LIBCALL_PTR(char, GNOME_KEYRING_ITEM_INFO_GET_DISPLAY_NAME_T)
					(GnomeKeyringItemInfo *item_info);

SSCS_TYPEDEF_LIBCALL(GnomeKeyringItemType, GNOME_KEYRING_ITEM_INFO_GET_TYPE_T)					 
					(GnomeKeyringItemInfo *item_info);

static GNOME_KEYRING_UNLOCK_T					p_gnome_keyring_unlock				= NULL;
static GNOME_KEYRING_ITEM_CREATE_T				p_gnome_keyring_item_create			= NULL;
static GNOME_KEYRING_CREATE_T					p_gnome_keyring_create				= NULL;
static GNOME_KEYRING_LIST_KEYRING_NAMES_T		p_gnome_keyring_list_keyring_names	= NULL;
static GNOME_KEYRING_GET_INFO_T					p_gnome_keyring_get_info			= NULL;
static GNOME_KEYRING_SET_INFO_T					p_gnome_keyring_set_info			= NULL;
static GNOME_KEYRING_LIST_ITEM_IDS_T			p_gnome_keyring_list_item_ids		= NULL;
static GNOME_KEYRING_ITEM_GET_INFO_T			p_gnome_keyring_item_get_info		= NULL;
static GNOME_KEYRING_ITEM_SET_INFO_T			p_gnome_keyring_item_set_info		= NULL;
static GNOME_KEYRING_ITEM_GET_ATTRIBUTES_T		p_gnome_keyring_item_get_attributes	= NULL;
static GNOME_KEYRING_ITEM_SET_ATTRIBUTES_T		p_gnome_keyring_item_set_attributes	= NULL;
static GNOME_KEYRING_ITEM_DELETE_T				p_gnome_keyring_item_delete			= NULL;
static GNOME_KEYRING_ITEM_INFO_NEW_T			p_gnome_keyring_item_info_new		= NULL;
static GNOME_KEYRING_ITEM_INFO_SET_SECRET_T		p_gnome_keyring_item_info_set_secret	= NULL;
static GNOME_KEYRING_ITEM_INFO_GET_SECRET_T		p_gnome_keyring_item_info_get_secret	= NULL;
static GNOME_KEYRING_ITEM_INFO_FREE_T			p_gnome_keyring_item_info_free			= NULL;
static GNOME_KEYRING_ATTRIBUTE_LIST_FREE_T		p_gnome_keyring_attribute_list_free		= NULL;
static GNOME_KEYRING_INFO_GET_MTIME_T			p_gnome_keyring_info_get_mtime			= NULL;
static GNOME_KEYRING_INFO_GET_CTIME_T			p_gnome_keyring_info_get_ctime			= NULL;
static GNOME_KEYRING_INFO_GET_IS_LOCKED_T		p_gnome_keyring_info_get_is_locked		= NULL;
static GNOME_KEYRING_INFO_GET_LOCK_TIMEOUT_T	p_gnome_keyring_info_get_lock_timeout	= NULL;
static GNOME_KEYRING_INFO_GET_LOCK_ON_IDLE_T	p_gnome_keyring_info_get_lock_on_idle	= NULL;
static GNOME_KEYRING_ITEM_INFO_GET_MTIME_T		p_gnome_keyring_item_info_get_mtime		= NULL;
static GNOME_KEYRING_ITEM_INFO_GET_CTIME_T		p_gnome_keyring_item_info_get_ctime		= NULL;
static GNOME_KEYRING_ITEM_INFO_GET_DISPLAY_NAME_T	p_gnome_keyring_item_info_get_display_name	= NULL;
static GNOME_KEYRING_ITEM_INFO_GET_TYPE_T			p_gnome_keyring_item_info_get_type	= NULL;



// functions
//***********************************************************************************************
gpointer casa_gnome_keyring_list_keyring_names(
									GnomeKeyringOperationGetListCallback    callback,
									gpointer data,
									GDestroyNotify destroy_data)
{
	if ((!gnomeIDK) 
		|| ((p_gnome_keyring_list_keyring_names = (GNOME_KEYRING_LIST_KEYRING_NAMES_T)dlsym(gnomeIDK, "gnome_keyring_list_keyring_names")) == NULL))
			return NULL;
	else			
		return(p_gnome_keyring_list_keyring_names (callback, data, destroy_data));
}

//***********************************************************************************************
gpointer casa_gnome_keyring_unlock
					(const char                                  *keyring,
				      const char                                  *password,
				      GnomeKeyringOperationDoneCallback            callback,
				      gpointer                                     data,
				      GDestroyNotify                               destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_unlock = (GNOME_KEYRING_UNLOCK_T)dlsym(gnomeIDK, "gnome_keyring_unlock")) == NULL))
			return NULL;
	else	
		return(p_gnome_keyring_unlock (keyring, password, callback, data, destroy_data));
}

//***********************************************************************************************
gpointer casa_gnome_keyring_item_create(
							const char                                 *keyring,
						      GnomeKeyringItemType                        type,
						      const char                                 *display_name,
						      GnomeKeyringAttributeList                  *attributes,
						      const char                                 *secret,
						      gboolean                                    update_if_exists,
						      GnomeKeyringOperationGetIntCallback         callback,
						      gpointer                                    data,
						      GDestroyNotify                              destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_create = (GNOME_KEYRING_ITEM_CREATE_T)dlsym(gnomeIDK, "gnome_keyring_item_create")) == NULL))
			return NULL;
	else
		return(p_gnome_keyring_item_create (keyring, type, display_name, attributes, secret, update_if_exists, callback, data, destroy_data));

}

//***********************************************************************************************
gpointer casa_gnome_keyring_create(
					  const char                                *keyring_name,
				      const char                               *password,
				      GnomeKeyringOperationDoneCallback         callback,
				      gpointer                                  data,
				      GDestroyNotify							destroyData)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_create = (GNOME_KEYRING_CREATE_T)dlsym(gnomeIDK, "gnome_keyring_create")) == NULL))
			return NULL;
	else
		return(p_gnome_keyring_create (keyring_name, password, callback, data, destroyData));
}

//***********************************************************************************************
gpointer casa_gnome_keyring_get_info(
					const char                                  *keyring,
				      GnomeKeyringOperationGetKeyringInfoCallback  callback,
				      gpointer                                     data,
				      GDestroyNotify						destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_get_info = (GNOME_KEYRING_GET_INFO_T)dlsym(gnomeIDK, "gnome_keyring_get_info")) == NULL))
			return NULL;
	else
		return(p_gnome_keyring_get_info (keyring, callback, data, destroy_data));
}

//***********************************************************************************************
gpointer casa_gnome_keyring_set_info(
					const char                                  *keyring,
				      GnomeKeyringInfo                            *info,
				      GnomeKeyringOperationDoneCallback            callback,
				      gpointer                                     data,
				      GDestroyNotify                               destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_set_info = (GNOME_KEYRING_SET_INFO_T)dlsym(gnomeIDK, "gnome_keyring_set_info")) == NULL))
			return NULL;
	else		
		return(p_gnome_keyring_set_info (keyring, info, callback, data, destroy_data));
}

//***********************************************************************************************
gpointer casa_gnome_keyring_list_item_ids(
					const char                                  *keyring,
				      GnomeKeyringOperationGetListCallback         callback,
				      gpointer                                     data,
				      GDestroyNotify                               destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_list_item_ids = (GNOME_KEYRING_LIST_ITEM_IDS_T)dlsym(gnomeIDK, "gnome_keyring_list_item_ids")) == NULL))
			return NULL;
	else			
		return(p_gnome_keyring_list_item_ids (keyring, callback, data, destroy_data));
}

//***********************************************************************************************
gpointer casa_gnome_keyring_item_get_info(
							const char                                 *keyring,
						      guint32                                     id,
						      GnomeKeyringOperationGetItemInfoCallback    callback,
						      gpointer                                    data,
						      GDestroyNotify                              destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_get_info = (GNOME_KEYRING_ITEM_GET_INFO_T)dlsym(gnomeIDK, "gnome_keyring_item_get_info")) == NULL))
			return NULL;
	else			
		return(p_gnome_keyring_item_get_info (keyring, id, callback, data, destroy_data));

}

//***********************************************************************************************
gpointer casa_gnome_keyring_item_set_info(
							const char                                 *keyring,
						      guint32                                     id,
						      GnomeKeyringItemInfo                       *info,
						      GnomeKeyringOperationDoneCallback           callback,
						      gpointer                                    data,
						      GDestroyNotify                              destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_set_info = (GNOME_KEYRING_ITEM_SET_INFO_T)dlsym(gnomeIDK, "gnome_keyring_item_set_info")) == NULL))
			return NULL;
	else			
		return(p_gnome_keyring_item_set_info (keyring, id, info, callback, data, destroy_data));

}

//***********************************************************************************************
gpointer casa_gnome_keyring_item_get_attributes(
							const char                                 *keyring,
						      guint32                                     id,
						      GnomeKeyringOperationGetAttributesCallback  callback,
						      gpointer                                    data,
						      GDestroyNotify                              destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_get_attributes = (GNOME_KEYRING_ITEM_GET_ATTRIBUTES_T)dlsym(gnomeIDK, "gnome_keyring_item_get_attributes")) == NULL))
			return NULL;
	else			
		return(p_gnome_keyring_item_get_attributes (keyring, id, callback, data, destroy_data));
}


//***********************************************************************************************
gpointer casa_gnome_keyring_item_set_attributes(
							const char                                 *keyring,
						      guint32                                     id,
						      GnomeKeyringAttributeList                  *attributes,
						      GnomeKeyringOperationDoneCallback           callback,
						      gpointer                                    data,
						      GDestroyNotify                              destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_set_attributes = (GNOME_KEYRING_ITEM_SET_ATTRIBUTES_T)dlsym(gnomeIDK, "gnome_keyring_item_set_attributes")) == NULL))
			return NULL;
	else			
		return(p_gnome_keyring_item_set_attributes (keyring, id, attributes, callback, data, destroy_data));
}

//***********************************************************************************************
gpointer casa_gnome_keyring_item_delete(
							const char                                 *keyring,
						      guint32                                     id,
						      GnomeKeyringOperationDoneCallback           callback,
						      gpointer                                    data,
						      GDestroyNotify                              destroy_data)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_delete = (GNOME_KEYRING_ITEM_DELETE_T)dlsym(gnomeIDK, "gnome_keyring_item_delete")) == NULL))
			return NULL;
	else
		return(p_gnome_keyring_item_delete (keyring, id, callback, data, destroy_data));
}


//***********************************************************************************************
GnomeKeyringItemInfo* casa_gnome_keyring_item_info_new()
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_new = (GNOME_KEYRING_ITEM_INFO_NEW_T)dlsym(gnomeIDK, "gnome_keyring_item_info_new")) == NULL))
			return NULL;
	else
		return(p_gnome_keyring_item_info_new ());
}

//***********************************************************************************************
void	casa_gnome_keyring_item_info_set_secret(GnomeKeyringItemInfo *item_info,
												const char           *value)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_set_secret = (GNOME_KEYRING_ITEM_INFO_SET_SECRET_T)dlsym(gnomeIDK, "gnome_keyring_item_info_set_secret")) == NULL))
			return;
	else			
		return(p_gnome_keyring_item_info_set_secret (item_info, value));
}
//***********************************************************************************************
char *	casa_gnome_keyring_item_info_get_secret(GnomeKeyringItemInfo *item_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_get_secret = (GNOME_KEYRING_ITEM_INFO_GET_SECRET_T)dlsym(gnomeIDK, "gnome_keyring_item_info_get_secret")) == NULL))
			return NULL;
	else
		return(p_gnome_keyring_item_info_get_secret (item_info));
}

//***********************************************************************************************
void	casa_gnome_keyring_item_info_free(GnomeKeyringItemInfo *item_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_free = (GNOME_KEYRING_ITEM_INFO_FREE_T)dlsym(gnomeIDK, "gnome_keyring_item_info_free")) == NULL))
			return;
	else			
		return(p_gnome_keyring_item_info_free (item_info));
}

//***********************************************************************************************
void	casa_gnome_keyring_attribute_list_free(GnomeKeyringAttributeList *attributes)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_attribute_list_free = (GNOME_KEYRING_ATTRIBUTE_LIST_FREE_T)dlsym(gnomeIDK, "gnome_keyring_attribute_list_free")) == NULL))
			return;
	else			
		return(p_gnome_keyring_attribute_list_free (attributes));
}

//***********************************************************************************************
time_t casa_gnome_keyring_info_get_mtime(GnomeKeyringInfo *keyring_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_info_get_mtime = (GNOME_KEYRING_INFO_GET_MTIME_T)dlsym(gnomeIDK, "gnome_keyring_info_get_mtime")) == NULL))
		return 0;
	else			
		return(p_gnome_keyring_info_get_mtime (keyring_info));
}

//***********************************************************************************************
time_t casa_gnome_keyring_info_get_ctime(GnomeKeyringInfo *keyring_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_info_get_ctime = (GNOME_KEYRING_INFO_GET_CTIME_T)dlsym(gnomeIDK, "gnome_keyring_info_get_ctime")) == NULL))
			return 0;
	else			
		return(p_gnome_keyring_info_get_ctime (keyring_info));
}
//***********************************************************************************************
gboolean casa_gnome_keyring_info_get_is_locked(GnomeKeyringInfo *keyring_info)
{	
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_info_get_is_locked = (GNOME_KEYRING_INFO_GET_IS_LOCKED_T)dlsym(gnomeIDK, "gnome_keyring_info_get_is_locked")) == NULL))
			return TRUE;
	else			
		return(p_gnome_keyring_info_get_is_locked (keyring_info));
}
//***********************************************************************************************
guint32	casa_gnome_keyring_info_get_lock_timeout(GnomeKeyringInfo *keyring_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_info_get_lock_timeout = (GNOME_KEYRING_INFO_GET_LOCK_TIMEOUT_T)dlsym(gnomeIDK, "gnome_keyring_info_get_lock_timeout")) == NULL))
			return TRUE;
	else			
		return(p_gnome_keyring_info_get_lock_timeout (keyring_info));
}
//***********************************************************************************************
gboolean casa_gnome_keyring_info_get_lock_on_idle(GnomeKeyringInfo *keyring_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_info_get_lock_on_idle = (GNOME_KEYRING_INFO_GET_LOCK_ON_IDLE_T)dlsym(gnomeIDK, "gnome_keyring_info_get_lock_on_idle")) == NULL))
			return FALSE;
	else			
		return(p_gnome_keyring_info_get_lock_on_idle (keyring_info));
}

//***********************************************************************************************
time_t casa_gnome_keyring_item_info_get_mtime(GnomeKeyringItemInfo *item_info)

{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_get_mtime = (GNOME_KEYRING_ITEM_INFO_GET_MTIME_T)dlsym(gnomeIDK, "gnome_keyring_item_info_get_mtime")) == NULL))
			return 0;
	else			
		return(p_gnome_keyring_item_info_get_mtime (item_info));
}
//***********************************************************************************************

time_t casa_gnome_keyring_item_info_get_ctime(GnomeKeyringItemInfo *item_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_get_ctime = (GNOME_KEYRING_ITEM_INFO_GET_CTIME_T)dlsym(gnomeIDK, "gnome_keyring_item_info_get_ctime")) == NULL))
			return 0;
	else			
		return(p_gnome_keyring_item_info_get_ctime (item_info));
}
//***********************************************************************************************

char * casa_gnome_keyring_item_info_get_display_name (GnomeKeyringItemInfo *item_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_get_display_name = (GNOME_KEYRING_ITEM_INFO_GET_DISPLAY_NAME_T)dlsym(gnomeIDK, "gnome_keyring_item_info_get_display_name")) == NULL))
			return NULL;
	else			
		return(p_gnome_keyring_item_info_get_display_name (item_info));
}

//***********************************************************************************************


GnomeKeyringItemType casa_gnome_keyring_item_info_get_type (GnomeKeyringItemInfo *item_info)
{
	if ((!gnomeIDK)
		|| ((p_gnome_keyring_item_info_get_type = (GNOME_KEYRING_ITEM_INFO_GET_TYPE_T)dlsym(gnomeIDK, "gnome_keyring_item_info_get_type")) == NULL))
			return(GNOME_KEYRING_ITEM_NO_TYPE);
	else			
		return(p_gnome_keyring_item_info_get_type (item_info));
}

//***********************************************************************************************

#define gnome_keyring_unlock						casa_gnome_keyring_unlock
#define gnome_keyring_item_create					casa_gnome_keyring_item_create
#define gnome_keyring_create						casa_gnome_keyring_create
#define gnome_keyring_list_keyring_names			casa_gnome_keyring_list_keyring_names
#define gnome_keyring_get_info						casa_gnome_keyring_get_info
#define gnome_keyring_set_info						casa_gnome_keyring_set_info
#define gnome_keyring_list_item_ids					casa_gnome_keyring_list_item_ids
#define gnome_keyring_item_get_info					casa_gnome_keyring_item_get_info
#define gnome_keyring_item_set_info					casa_gnome_keyring_item_set_info
#define gnome_keyring_item_get_attributes			casa_gnome_keyring_item_get_attributes
#define gnome_keyring_item_set_attributes			casa_gnome_keyring_item_set_attributes
#define gnome_keyring_item_delete					casa_gnome_keyring_item_delete
#define gnome_keyring_item_info_new					casa_gnome_keyring_item_info_new
#define gnome_keyring_info_get_mtime				casa_gnome_keyring_info_get_mtime
#define gnome_keyring_info_get_ctime				casa_gnome_keyring_info_get_ctime
#define gnome_keyring_info_get_is_locked			casa_gnome_keyring_info_get_is_locked
#define gnome_keyring_info_get_lock_timeout			casa_gnome_keyring_info_get_lock_timeout
#define gnome_keyring_info_get_lock_on_idle			casa_gnome_keyring_info_get_lock_on_idle
#define gnome_keyring_item_info_get_secret			casa_gnome_keyring_item_info_get_secret
#define gnome_keyring_item_info_set_secret			casa_gnome_keyring_item_info_set_secret
#define gnome_keyring_item_info_free				casa_gnome_keyring_item_info_free
#define gnome_keyring_item_info_get_mtime			casa_gnome_keyring_item_info_get_mtime
#define gnome_keyring_item_info_get_ctime			casa_gnome_keyring_item_info_get_ctime
#define gnome_keyring_item_info_get_display_name	casa_gnome_keyring_item_info_get_display_name
#define gnome_keyring_item_info_get_type			casa_gnome_keyring_item_info_get_type
#define gnome_keyring_attribute_list_free			casa_gnome_keyring_attribute_list_free


//***********************************************************************************************
int 
LoadGnomeKeyringLibrary()
{
	if (!gnomeIDK)
	{
		g_set_application_name("CASAManager");	
		if ((gnomeIDK = dlopen(GNOME_KEYRING_NDK, RTLD_LAZY)) == NULL)
			return FAILURE;
	}	
	return SUCCESS;
}

int 
ReleaseGnomeKeyringLibrary()
{
	if (!gnomeIDK)
	{
		dlclose(GNOME_KEYRING_NDK);
		gnomeIDK = NULL;
	}
	return SUCCESS;
}

// END DYNAMIC LINKING


//***********************************************************************************************
GMainLoop *loop = NULL;

static void
OperationCompletedCb  (GnomeKeyringResult result,
        gpointer           data)
{
        OperationCompleted *cbData = (OperationCompleted *)data;
        //g_print ("ad_gk.c : Operation %s Completed %d\n", cbData->OperationName, result);
        cbData->result = result;
        g_main_loop_quit (loop);
}

static void
CreateItemCb  (GnomeKeyringResult result,
                guint32            id,
                gpointer           data)
{
        OperationCompleted *cbData = (OperationCompleted *)data;
        //g_print ("ad_gk.c : CreateItemCb : created item: res: %d id: %d\n", result, id);
    	if (result != GNOME_KEYRING_RESULT_OK)
    	{
        //g_print ("ad_gk.c : CreateItemCb : Unable to create item : %d\n", result);
	}
        cbData->result = result;
        g_main_loop_quit (loop);
}

int
UnlockRing(char *keyring,
        char *password)
{

        // unlock the named keyring
        OperationCompleted cbData;
        cbData.OperationName = "Unlock Ring";

        loop = g_main_loop_new (NULL, FALSE);
        gnome_keyring_unlock(keyring, password, OperationCompletedCb, &cbData, NULL);

        g_main_loop_run (loop);
	return cbData.result;
}

static int
CreateItemInKeyring(char *keyring, int32_t itemType, char *display_name, char *secret, Attribute **attrs, int attrcnt)
{
        GnomeKeyringAttributeList *attributes;
        GnomeKeyringAttribute attribute;
        OperationCompleted cbData;

        int i;
        //printf("ad.gk.c : CreateItemInKeyring : Keyring %s, itemType %d displayname %s, secret %s \n",keyring,itemType, display_name,secret);
        cbData.OperationName = "Create Item";
        loop = g_main_loop_new (NULL, FALSE);
                                                                                
        attributes = gnome_keyring_attribute_list_new ();
        for (i=0; i< attrcnt; i++)
        {
                //printf("as.gk.c : CreateItemInKeyring : In key %s \n", attrs[i]->key);
                attribute.name = g_strdup (attrs[i]->key);
		if( !strcmp(attrs[i]->key, "port"))
		{
			attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32;
			attribute.value.integer = atoi(attrs[i]->value);
		}
		else
		{
			attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
			attribute.value.string = g_strdup(attrs[i]->value);
		}
                g_array_append_val (attributes, attribute);
        }
        
        gnome_keyring_item_create(NULL,itemType,display_name,attributes,secret,FALSE,CreateItemCb,&cbData,NULL);
        gnome_keyring_attribute_list_free (attributes);
        g_main_loop_run (loop);
        return cbData.result;
}

static int 
CreateKeyring(char *keyring)
{

        OperationCompleted cbData;

        cbData.OperationName = "Create Keyring";
        loop = g_main_loop_new (NULL, FALSE);
	gnome_keyring_create(keyring,NULL,OperationCompletedCb,&cbData,NULL);
        g_main_loop_run(loop);
        return cbData.result;
}


void ListKeyringsCb (GnomeKeyringResult result,
                       GList *keyrings,
                       gpointer data)
{
    GList *l = NULL;
    char *name = NULL;
    GList **retList = data;

    GetKeyringsCbData *cbData = data;
    GMainLoop *loop = cbData->loop;
    retList = cbData->keyringList;
    *retList = NULL;

    if (result != GNOME_KEYRING_RESULT_OK) 
    {
        //g_print ("Unable to get keyring list -  %d\n", result);
    } 
    else 
    {
        for (l = keyrings; l != NULL; l = l->next)
        {
            name = l->data;
            *retList = g_list_append (*retList, g_strdup (name));
        }
    }
    g_main_loop_quit (loop);
}

void KeyringGetInfoCb(GnomeKeyringResult result,
                      GnomeKeyringInfo *info,
                      gpointer data)
{
    GetKeyringInfoCbData *cbData = data;
    KeyringInfo *retInfo = cbData->info;
    if (result != GNOME_KEYRING_RESULT_OK) 
    {
        //g_print ("Unable to get keyring info %d\n", result);
    }
    else
    {
        retInfo->lockOnIdle = gnome_keyring_info_get_lock_on_idle(info);
        retInfo->lockTimeout = gnome_keyring_info_get_lock_timeout(info);
        retInfo->mTime = gnome_keyring_info_get_mtime(info);
        retInfo->cTime = gnome_keyring_info_get_ctime(info);
        retInfo->isLocked = gnome_keyring_info_get_is_locked(info);
    }
    g_main_loop_quit (cbData->loop);
}

void ListItemCb( GnomeKeyringResult result,
                   GList *list,
                   gpointer data)
{
    GList **retList;
    GetItemsCbData *cbData = data;
    retList = cbData->itemList;
    *retList = NULL;

    if (result != GNOME_KEYRING_RESULT_OK)
    {
        //g_print ("Unable to get list of items : %d\n", result);
    }
    else
    {
        *retList = g_list_copy (list);
    }

    g_main_loop_quit (cbData->loop);    
}

void ItemGetInfoCb( GnomeKeyringResult result,
                    GnomeKeyringItemInfo *info,
                    gpointer data)
{
    GetItemInfoCbData *cbData = data;
    ItemInfo *itemInfo = cbData->info;
    char *item;
    size_t itemlen = 0, maxlen = 0;
    if (result != GNOME_KEYRING_RESULT_OK) 
    {
        //g_print ("Unable to get Item info: %d\n", result);
    } 
    else 
    {
	/* maxlen = 512. This should be one less than the size of 
	Novell.CASA.DataEngines.GK.NativeItemInfo.displayName */
	maxlen = 512; 
	item = gnome_keyring_item_info_get_display_name(info);
	itemlen = strlen (item);
	if (itemlen > maxlen) {
		itemInfo->displayName = NULL;
	} else {
		strncpy(itemInfo->displayName, item, itemlen);
		itemInfo->displayName[itemlen] = '\0';
	}

	/* maxlen = 512. This should be one less than the size of 
	Novell.CASA.DataEngines.GK.NativeItemInfo.secret */
	maxlen = 512; 
	item = gnome_keyring_item_info_get_secret(info);
	itemlen = strlen (item);
	if (itemlen > maxlen) {
		itemInfo->secret = NULL;
	} else {
		strncpy(itemInfo->secret, item, itemlen);
		itemInfo->secret[itemlen] = '\0';
	}

        itemInfo->mTime = gnome_keyring_item_info_get_mtime(info);
        itemInfo->cTime = gnome_keyring_item_info_get_ctime(info);
           
    }
    g_main_loop_quit (cbData->loop);    
}

void ItemGetAttributesCb(GnomeKeyringResult result,
                         GnomeKeyringAttributeList *attributes,
                         gpointer data)
{ 
    GnomeKeyringAttribute *attrList = NULL;
    int i = 0;
    GetAttributeListCbData *cbData = data;

    Attribute *attr = NULL;
    size_t attrlen = 0;
    GList **retList;

    retList = cbData->attrList;
    *retList = NULL;
    
    if( result != GNOME_KEYRING_RESULT_OK )
    {
        //g_print("Unable to get the attributes of item\n");
    }
    else
    {
        attrList = (GnomeKeyringAttribute*)(attributes->data); //GArray has len and data
        for(i = 0; i < attributes->len; i++ )
        {
            if(attrList[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING)
            {
                attr = (Attribute*)malloc(sizeof(Attribute));

                if( NULL != attr )
                {
                    memset(attr,0,sizeof(Attribute));
                    attr->type = 0;
                    attr->key = (char*)malloc(KEY_SIZE);
                    if(attr->key != NULL) {
			attrlen = strlen (attrList[i].name);
			if (attrlen > (KEY_SIZE - 1))
				attrlen = KEY_SIZE - 1;
                        strncpy(attr->key, attrList[i].name, attrlen);
			attr->key[attrlen] = '\0';
		    }
                    attr->value = (char*)malloc(VAL_SIZE);
                    if(attr->value != NULL) {
			attrlen = strlen (attrList[i].value.string);
			if (attrlen > (VAL_SIZE - 1))
				attrlen = VAL_SIZE - 1;
                        strncpy(attr->value, attrList[i].value.string, attrlen);
			attr->value[attrlen] = '\0';
		    }
                }
            }
            else if(attrList[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32)
            {
                attr = (Attribute*)malloc(sizeof(Attribute));
                if( NULL != attr )
                {
                    memset(attr,0,sizeof(Attribute));
                    attr->type = 0;
                    attr->key = (char*)malloc(KEY_SIZE);
                    if(attr->key != NULL) {
			attrlen = strlen (attrList[i].name);
			/* We simply truncate the name if it is greater than KEY_SIZE */
			if (attrlen > (KEY_SIZE - 1))
				attrlen = KEY_SIZE - 1;
                        strncpy(attr->key, attrList[i].name, attrlen);
			attr->key [attrlen] = '\0';
		    }
                    attr->value = (char*)malloc(VAL_SIZE);
                    if(attr->value != NULL)
                        sprintf(attr->value,"%d",attrList[i].value.integer);
                }
            }
            *retList = g_list_append (*retList, attr);
        }
    }
    g_main_loop_quit (cbData->loop);    
}

int GetKeyrings(GList **keyringList)
{    
    GetKeyringsCbData cbData;
    cbData.loop = g_main_loop_new (NULL, FALSE);
    cbData.keyringList = keyringList;

    gnome_keyring_list_keyring_names(ListKeyringsCb,&cbData,NULL);
    g_main_loop_run(cbData.loop);
    return SUCCESS;
}

int GetKeyringInfo(char *keyring,KeyringInfo *info)
{
    GetKeyringInfoCbData cbData;

    cbData.loop = g_main_loop_new (NULL, FALSE);
    cbData.info = info;
    
    gnome_keyring_get_info(keyring, KeyringGetInfoCb,&cbData, NULL);
    g_main_loop_run (cbData.loop);
    return SUCCESS;
}

int GetItems(char *keyring, GList **itemList)
{        
    GetItemsCbData cbData;
    cbData.loop = g_main_loop_new (NULL, FALSE);
    cbData.itemList = itemList;

    gnome_keyring_list_item_ids(keyring, ListItemCb, &cbData, NULL);
    g_main_loop_run (cbData.loop);
    return SUCCESS;
}
int GetItemInfo(char *keyring, int itemId, ItemInfo *info)
{
    GetItemInfoCbData cbData;
    cbData.loop = g_main_loop_new (NULL, FALSE);
    cbData.info = info;

    gnome_keyring_item_get_info (keyring,itemId, ItemGetInfoCb,
                                 &cbData, NULL);
    g_main_loop_run (cbData.loop);
    return SUCCESS;
}

int GetAttributeList(char *keyring, int itemId, GList **attrList)
{

    GetAttributeListCbData cbData;
    cbData.loop = g_main_loop_new (NULL, FALSE);
    cbData.attrList = attrList;

    gnome_keyring_item_get_attributes (keyring, itemId,
                                       ItemGetAttributesCb, &cbData,
                                       NULL);
    g_main_loop_run (cbData.loop);
    return SUCCESS;
}

int FreeAttributeList(GList *attrList)
{
    GList *l;
    Attribute *attr = NULL;
    for(l = attrList; l != NULL; l = l->next)
    {
        attr = (Attribute*)(l->data);
        if(attr->key)
        {
            free(attr->key);
        }
        if(attr->value)
        {
            free(attr->value);
        }
    }
    g_list_free(attrList);
    return SUCCESS;
}





int
SetItemAttributes (char *keyring, guint32 itemid, Attribute **attrs, int length)
{
        GnomeKeyringAttributeList *attributes;
        GnomeKeyringAttribute attribute;
        OperationCompleted cbData;
        int i;
        //printf("ad_gk.c : In SetItemAttributes\n");
        //printf("ad_gk.c : Keyring %s, itemid %d\n",keyring,itemid);
        cbData.OperationName = "Set Item Attributes";
        loop = g_main_loop_new (NULL, FALSE);

        attributes = gnome_keyring_attribute_list_new ();
	for (i=0; i< length; i++)
        {
                //printf("ad_gk.c : In key %s \n", attrs[i]->key);
        	attribute.name = g_strdup (attrs[i]->key);
		if( !strcmp(attrs[i]->key, "port"))
                {
                        attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32;
                        attribute.value.integer = atoi(attrs[i]->value);
                }
                else
                {
                        attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
                        attribute.value.string = g_strdup(attrs[i]->value);
                }
        	g_array_append_val (attributes, attribute);
        }
        gnome_keyring_item_set_attributes (keyring, itemid, attributes,
                                           OperationCompletedCb, &cbData, NULL);
        gnome_keyring_attribute_list_free (attributes);
        g_main_loop_run (loop);
        return cbData.result;
}


int
RemoveItem (char *keyring, guint32 itemid)
{
        OperationCompleted cbData;
        loop = g_main_loop_new (NULL, FALSE);
        cbData.OperationName = "Remove Item";
        gnome_keyring_item_delete (keyring, itemid,
                                   OperationCompletedCb,  &cbData, NULL);
        g_main_loop_run (loop);
        return cbData.result;
}


int 
SetPassword (char *keyring, guint32 itemid, char *secret)
{
        GnomeKeyringItemInfo *info;
        OperationCompleted cbData;
        loop = g_main_loop_new (NULL, FALSE);

        cbData.OperationName = "Set Item Secret";
        info = gnome_keyring_item_info_new();
        gnome_keyring_item_info_set_secret (info, secret);
        gnome_keyring_item_set_info (keyring, itemid, info,
                                     OperationCompletedCb,  &cbData, NULL);
        gnome_keyring_item_info_free (info);
        g_main_loop_run (loop);
        return cbData.result;
}


int
CreateItem(char *keyring, int32_t itemType, char *display_name, char *secret, Attribute **attrs, int attrcnt)
{
        int ret;
	ret = CreateItemInKeyring(keyring,itemType,display_name,secret,attrs,attrcnt);       
        if (ret == 4)
        {
		ret = CreateKeyring(keyring);
                if (ret != 0)
                {
		 	return GNOME_KEYRING_RESULT_CANNOT_CREATE_KEYRING ;
                }
		ret = CreateItemInKeyring(keyring,itemType,display_name ,secret,attrs,attrcnt);       
                return ret;
        }
        return ret;
}