|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 7826 (0x1e92)
Types: TextFile
Names: »cache.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/quipu/cache.c«
/* 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;
}
}