|
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; } }