DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦9d72a6efb⟧ TextFile

    Length: 7826 (0x1e92)
    Types: TextFile
    Names: »cache.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/quipu/cache.c« 

TextFile

/* cache.c - */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/cache.c,v 6.0 89/03/18 23:41:05 mrose Rel $";
#endif

/* 
 * $Header: /f/osi/quipu/RCS/cache.c,v 6.0 89/03/18 23:41:05 mrose Rel $
 *
 *
 * $Log:	cache.c,v $
 * Revision 6.0  89/03/18  23:41:05  mrose
 * Release 5.0
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


#include "quipu/util.h"
#include "quipu/dua.h"
#include "quipu/list.h"
#include "quipu/entry.h"
#include "quipu/connection.h"

struct list_cache *list_top = NULLCACHE;
Entry  current_entry = NULLENTRY;
DN     current_dn = NULLDN;

struct subordinate * subord_cpy (x)
struct subordinate * x;
{
struct subordinate * sub;
struct subordinate * y;
struct subordinate * top;

	if (x == NULLSUBORD)
		return (x);
	
	top = (struct subordinate *) smalloc (sizeof(struct subordinate));
	top->sub_copy =  x->sub_copy;
	top->sub_rdn = rdn_cpy(x->sub_rdn);
	top->sub_aliasentry = x->sub_aliasentry;
	top->sub_next = NULLSUBORD;
	y = top;

	for (x=x->sub_next; x != NULLSUBORD; x=x->sub_next) {
		sub = (struct subordinate *) smalloc (sizeof(struct subordinate));
		sub->sub_copy =  x->sub_copy;
		sub->sub_rdn = rdn_cpy(x->sub_rdn);
		sub->sub_aliasentry = x->sub_aliasentry;
		sub->sub_next = NULLSUBORD;
		y->sub_next = sub;
		y = sub;
	}

	return (top);	
}

/* ARGSUSED */
cache_list (ptr, prob,dn,sizelimit)
struct subordinate *ptr;
int             prob;
DN 		dn;
int 		sizelimit;
{
	struct list_cache *cache;
	struct subordinate *sub;
	register int i;

/*
 * If called by the DSA we need to store some ACL info.
 * This will come in the next version (hopefully)
 */

	if ((cache = find_list_cache (dn,0)) == NULLCACHE) {
		cache = (struct list_cache *) smalloc (sizeof (struct list_cache));
		cache->list_dn = dn_cpy (dn);
		cache->list_subs = subord_cpy (ptr);
		cache->list_sub_top = cache->list_subs;
		cache->list_next = list_top;
		cache->list_problem = prob;
		list_top = cache;
	} else {
		subords_free (cache->list_sub_top);
		cache->list_subs = subord_cpy (ptr);
			cache->list_sub_top = cache->list_subs;
		cache->list_problem = prob;
	}

	for (i=0, sub=cache->list_subs; 
		sub != NULLSUBORD; 
		i++, sub = sub->sub_next);
	cache->list_count = i;

}

struct list_cache *find_list_cache (dn,sizelimit)
DN dn;
int sizelimit;
{
	struct list_cache *ptr;
	int i;
	for (ptr = list_top; ptr != NULLCACHE; ptr = ptr->list_next)
		if (dn_cmp (ptr->list_dn, dn) == 0)
			if ((ptr->list_problem == LSR_NOLIMITPROBLEM) 
				|| ((ptr->list_count >= sizelimit) && (sizelimit != -1)))
				{
				ptr->list_subs = ptr->list_sub_top;
				if (sizelimit == -1) 	
					return (ptr);
				/* only want sizelimit of them */
				for (i=ptr->list_count - sizelimit; i>0; i--)
					ptr->list_subs = ptr->list_subs->sub_next;
				return (ptr);
				}

	return (NULLCACHE);
}



cache_entry (ptr, complete, vals)
EntryInfo      *ptr;
char            complete;
char            vals;
{
	Entry           make_path ();
	Entry           get_default_entry ();
	DN              dnptr;

	/* use e_lock to indicate if values are present */

	dn_free (current_dn);
	dn_decode (ptr->ent_dn);

	current_dn = dn_cpy (ptr->ent_dn);

	for (dnptr = current_dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent)
		;

	as_decode (ptr->ent_attr);

	if ((current_entry = local_find_entry (current_dn, FALSE)) != NULLENTRY) {
		if (vals && complete) {
			as_free (current_entry->e_attributes);
			current_entry->e_attributes = as_cpy(ptr->ent_attr);
			current_entry->e_lock = vals;
			current_entry->e_complete = complete;
		} else if (!current_entry->e_complete) {
			current_entry->e_complete = complete;
			current_entry->e_attributes = as_merge (current_entry->e_attributes, as_cpy(ptr->ent_attr));
			if (vals != current_entry->e_lock)
				current_entry->e_lock = FALSE;
		} else if ((!current_entry->e_lock) & vals) {
			current_entry->e_attributes = as_merge (current_entry->e_attributes, as_cpy(ptr->ent_attr));
		}
	} else {
		current_entry = make_path (current_dn);
		current_entry->e_name = rdn_cpy (dnptr->dn_rdn);
		current_entry->e_complete = complete;
		current_entry->e_data = E_TYPE_CACHE_FROM_MASTER;
		current_entry->e_lock = vals;
		current_entry->e_attributes = as_cpy(ptr->ent_attr);
	}
}



cache_dsp_entry (ptr)
EntryInfo      *ptr;
{
	/* assumes entry passed is complete */

	Entry           make_path ();
	Entry           get_default_entry ();
	Entry		eptr;

	Attr_Sequence   asptr;
	extern oid_table_attr * tab_acl;

	struct DSError  error;
	DN              dnptr;
	char		aclfound = FALSE;

	dn_decode (ptr->ent_dn);

	for (asptr = ptr->ent_attr; asptr != NULLATTR; asptr = asptr->attr_link) {
		AttrT_decode (asptr->attr_type);
		if (asptr->attr_type->at_table == tab_acl) {
			aclfound = TRUE;
			break; 
		}
	}

	if (!aclfound)
		return;		/* don't cache if not acl */

	for (dnptr = ptr->ent_dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent)
		;

	if ((eptr = local_find_entry (ptr->ent_dn, FALSE)) != NULLENTRY) {
		if ((eptr->e_data == E_TYPE_CACHE_FROM_MASTER) ||
		    (eptr->e_data == E_TYPE_CONSTRUCTOR)) {	
			as_free (eptr->e_attributes);
			eptr->e_attributes = as_cpy(ptr->ent_attr);
			eptr->e_complete = TRUE;
			eptr->e_data = E_TYPE_CACHE_FROM_MASTER;
		    }
	} else {
		eptr = make_path (ptr->ent_dn);
		eptr->e_name = rdn_cpy (dnptr->dn_rdn);
		eptr->e_complete = TRUE;
		eptr->e_data = E_TYPE_CACHE_FROM_MASTER;
		eptr->e_attributes = as_cpy(ptr->ent_attr);
	}

	if (unravel_attribute (eptr,&error,TRUE) == NOTOK) {
		/* Keep name, but throw away attributes */
		eptr->e_data = E_TYPE_CONSTRUCTOR;
		eptr->e_complete = FALSE;
		as_free (eptr->e_attributes);
		eptr->e_attributes = NULLATTR;
	}
}



delete_cache (adn)
DN              adn;
{
	Entry           ptr;
	struct DSError  error;
	extern	char	remote_lookup;

	remote_lookup = FALSE;
	/* need to use "really", as we want the sorting */
	if ((ptr = really_find_entry (adn, &error, FALSE)) != NULLENTRY) {
		if (ptr->e_data == E_TYPE_CACHE_FROM_MASTER) {
			if (ptr->e_child != NULLENTRY) {
				ptr->e_data = E_TYPE_CONSTRUCTOR;
				ptr->e_complete = FALSE;	
				as_free (ptr->e_attributes);
				ptr->e_attributes = NULLATTR;
			} else {		
				ptr->e_parent->e_child = ptr->e_sibling;
				entry_free (ptr);
			}
		}
	}
	remote_lookup = TRUE;
}


dsp_cache (arg,res)
struct DSArgument *arg;
struct DSResult   *res;
{
/* cache results of remote operations using DSP */

    switch(arg->arg_type) {    
	/* only cache read and search if all attributes asked for */
    case OP_READ:
	if ((arg->arg_rd.rda_eis.eis_allattributes == TRUE) && 
	    (arg->arg_rd.rda_eis.eis_infotypes == EIS_ATTRIBUTESANDVALUES))
		cache_dsp_entry (&(res->res_rd.rdr_entry));
	break;
    case OP_SEARCH:
 	if ((arg->arg_sr.sra_eis.eis_allattributes == TRUE) &&
 	    (arg->arg_sr.sra_eis.eis_infotypes == EIS_ATTRIBUTESANDVALUES)) {
 		EntryInfo *ptr;
 		for (ptr = res->res_sr.CSR_entries; ptr != NULLENTRYINFO; ptr = ptr->ent_next) 
 			cache_dsp_entry (ptr);
 	}
    	break;
    case OP_LIST:
	cache_list (res->res_ls.lsr_subordinates,
		    res->res_ls.lsr_limitproblem,
		    arg->arg_ls.lsa_object,
		    arg->arg_ls.lsa_common.ca_servicecontrol.svc_sizelimit);
    	break;

    /* the following change an entry - the easiest thing is to
       deleted the cached entry and start again */
    case OP_ADDENTRY:
	delete_cache (arg->arg_ad.ada_object);
	break;
    case OP_REMOVEENTRY:
	delete_cache (arg->arg_rm.rma_object);
    	break;
    case OP_MODIFYENTRY:
	delete_cache (arg->arg_me.mea_object);
	break;
    case OP_MODIFYRDN:
	delete_cache (arg->arg_mr.mra_object);
	break;
    default:    break;
    }


}