|
|
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 f
Length: 11396 (0x2c84)
Types: TextFile
Names: »find_entry.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/quipu/find_entry.c«
/* find_entry.c - */
#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/find_entry.c,v 6.0 89/03/18 23:41:36 mrose Rel $";
#endif
/*
* $Header: /f/osi/quipu/RCS/find_entry.c,v 6.0 89/03/18 23:41:36 mrose Rel $
*
*
* $Log: find_entry.c,v $
* Revision 6.0 89/03/18 23:41:36 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/commonarg.h"
#include "quipu/entry.h"
#include "quipu/ds_error.h"
#ifndef NO_STATS
extern LLog * log_stat;
extern int dn_print ();
#endif
extern Entry database_root;
extern DN super_user;
extern LLog * log_dsap;
ContinuationRef cont_ref_new () ;
ContinuationRef cont_ref_parent ();
Entry no_reply_child () ;
Entry no_reply_edb () ;
Entry find_entry (object,ca,err,acl_who)
DN object;
common_args *ca;
struct DSError *err;
DN acl_who;
{
register Entry the_entry;
char deref = FALSE;
DLOG (log_dsap,LLOG_TRACE,("find_entry"));
dn_decode (acl_who);
err->dse_type = DSE_NOERROR;
if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0)
deref = TRUE;
if ((the_entry = really_find_entry (object,err,deref)) == NULLENTRY)
return (NULLENTRY);
/* if the returned entry is a CONSTRUCTOR, return a referral */
if (the_entry->e_data == E_TYPE_CONSTRUCTOR) {
constructor_referral (the_entry,err,object) ;
return (NULLENTRY);
}
/* if the returned entry is a COPY, - check service controls */
if (the_entry->e_data != E_DATA_MASTER)
if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0) {
constructor_referral (the_entry,err,object) ;
return (NULLENTRY);
}
if (the_entry->e_parent == NULLENTRY)
return (the_entry); /* no acl for root entry */
if (check_acl (acl_who,ACL_DETECT, the_entry->e_parent->e_acl->ac_child, object) == NOTOK) {
err->dse_type = DSE_SECURITYERROR;
err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
return (NULLENTRY);
}
if (check_acl (acl_who,ACL_DETECT, the_entry->e_acl->ac_entry, object) == NOTOK) {
err->dse_type = DSE_SECURITYERROR;
err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
return (NULLENTRY);
}
return (the_entry);
}
Entry find_master_entry (object,ca,err,acl_who)
DN object;
common_args *ca;
struct DSError *err;
DN acl_who;
{
register Entry the_entry;
char deref = FALSE;
DLOG (log_dsap,LLOG_TRACE,("find_entry (master)"));
dn_decode (acl_who);
err->dse_type = DSE_NOERROR;
if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0)
deref = TRUE;
if ((the_entry = really_find_entry (object,err,deref)) == NULLENTRY)
return (NULLENTRY);
/* if the returned entry is not MASTER, return a referral */
if (the_entry->e_data != E_DATA_MASTER) {
constructor_referral (the_entry,err,object) ;
return (NULLENTRY);
}
if (the_entry->e_parent == NULLENTRY)
return (the_entry); /* no acl for root entry */
if (check_acl (acl_who,ACL_DETECT, the_entry->e_parent->e_acl->ac_child, object) == NOTOK) {
err->dse_type = DSE_SECURITYERROR;
err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
return (NULLENTRY);
}
if (check_acl (acl_who,ACL_DETECT, the_entry->e_acl->ac_entry, object) == NOTOK) {
err->dse_type = DSE_SECURITYERROR;
err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
return (NULLENTRY);
}
return (the_entry);
}
Entry really_find_entry (object,err,deref)
DN object;
struct DSError *err;
char deref;
{
Entry the_entry;
Entry trail;
register RDN a_rdn, b_rdn;
DN dn;
DLOG (log_dsap,LLOG_TRACE,("really find entry"));
dn_decode (object);
if (database_root == NULLENTRY) {
LLOG (log_dsap,LLOG_DEBUG,("null root !!!"));
err->dse_type = DSE_REFERRAL;
err->ERR_REFERRAL.DSE_ref_prefix = NULLDN;
if ((err->ERR_REFERRAL.DSE_ref_candidates = cont_ref_parent (object)) == NULLCONTINUATIONREF) {
err->dse_type = DSE_SERVICEERROR;
err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
}
return (NULLENTRY);
}
if ((dn = object) == NULLDN)
return (database_root);
b_rdn = dn->dn_rdn;
if ((the_entry = database_root->e_child) == NULLENTRY) {
return (no_reply_child (object,database_root,err));
}
a_rdn = the_entry->e_name ;
for(;;) { /* break or return out */
trail = NULLENTRY;
while (rdn_cmp (a_rdn, b_rdn) != OK) {
trail = the_entry;
the_entry = the_entry->e_sibling ;
if ( the_entry == NULLENTRY )
return (no_reply_edb (object,trail->e_parent,err));
a_rdn = the_entry->e_name ;
}
/* make found element first in list - optimistaion */
if (trail != NULLENTRY) { /* NOT already the first */
trail->e_sibling = the_entry->e_sibling;
the_entry->e_sibling = the_entry->e_parent->e_child;
the_entry->e_parent->e_child = the_entry;
}
if ( the_entry->e_alias != NULLDN )
/* got an alias entry */
if (deref) {
Entry new_entry;
/* err->dse_type = DSE_ALIASERROR; */
/* There has not been an error !!! */
/* this is just a way of letting the caller */
/* know an alias has been dereferenced */
new_entry = really_find_entry (the_entry->e_alias,err,deref);
if (new_entry == NULLENTRY ) {
if (err->dse_type == DSE_REFERRAL)
return (NULLENTRY);
else {
ds_error_free (err);
err->dse_type = DSE_NAMEERROR;
err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
err->ERR_NAME.DSE_na_matched = dn_cpy(the_entry->e_alias);
return (NULLENTRY);
}
}
the_entry = new_entry;
} else if ( dn->dn_parent == NULLDN)
return (the_entry); /* found it !!! */
else {
/* alias on route - error in this case */
err->dse_type = DSE_NAMEERROR;
err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
err->ERR_NAME.DSE_na_matched = dn_cpy(the_entry->e_alias);
return (NULLENTRY);
}
if ( dn->dn_parent == NULLDN)
return (the_entry);
dn = dn->dn_parent;
b_rdn = dn->dn_rdn;
if ( the_entry->e_child == NULLENTRY ) {
return (no_reply_child (object,the_entry,err));
}
the_entry = the_entry->e_child;
a_rdn = the_entry->e_name;
}
/* NOTREACHED */
}
Entry local_find_entry (object,deref)
DN object;
char deref;
{
Entry the_entry;
register RDN a_rdn, b_rdn;
DN dn;
DLOG (log_dsap,LLOG_TRACE,("local find entry"));
dn_decode (object);
if (database_root == NULLENTRY)
return (NULLENTRY);
if ((dn = object) == NULLDN)
return (database_root);
b_rdn = dn->dn_rdn;
if ((the_entry = database_root->e_child) == NULLENTRY)
return (NULLENTRY);
a_rdn = the_entry->e_name ;
for(;;) { /* break or return out */
while (rdn_cmp (a_rdn, b_rdn) != OK) {
the_entry = the_entry->e_sibling ;
if ( the_entry == NULLENTRY )
return (NULLENTRY);
a_rdn = the_entry->e_name ;
}
if ( the_entry->e_alias != NULLDN )
/* got an alias entry */
if (deref) {
Entry new_entry;
new_entry = local_find_entry (the_entry->e_alias,deref);
if (new_entry == NULLENTRY )
return (NULLENTRY);
the_entry = new_entry;
} else if ( dn->dn_parent == NULLDN)
return (the_entry); /* found it !!! */
else
return (NULLENTRY);
if ( dn->dn_parent == NULLDN)
return (the_entry);
dn = dn->dn_parent;
b_rdn = dn->dn_rdn;
if ( the_entry->e_child == NULLENTRY )
return (NULLENTRY);
the_entry = the_entry->e_child;
a_rdn = the_entry->e_name;
}
/* NOTREACHED */
}
DN get_copy_dn (entryptr)
Entry entryptr;
{
DN dn;
DN dnptr;
Entry ptr;
if (entryptr == NULLENTRY )
return (NULLDN);
if (entryptr->e_parent == NULL)
return (dn_comp_new (rdn_cpy (entryptr->e_name)));
dn = dn_comp_new (rdn_cpy (entryptr->e_name));
for (ptr = entryptr->e_parent; ptr->e_parent != NULLENTRY; ptr = ptr->e_parent) {
dnptr = dn_comp_new (rdn_cpy (ptr->e_name));
dnptr->dn_parent = dn;
dn = dnptr;
}
return (dn);
}
constructor_referral (ptr,err,object)
Entry ptr;
struct DSError * err;
DN object;
{
DLOG (log_dsap,LLOG_TRACE,("constructor ref"));
if (ptr != NULLENTRY)
ptr=ptr->e_parent;
constructor_referral_aux (ptr,err,object);
}
constructor_referral_aux (ptr,err,object)
Entry ptr;
struct DSError * err;
DN object;
{
DLOG (log_dsap,LLOG_TRACE,("construct ref aux"));
err->dse_type = DSE_REFERRAL;
err->ERR_REFERRAL.DSE_ref_prefix = NULLDN;
/* follow entry back, until something that is not a CONSTRUCTOR */
for (; ptr!= NULLENTRY; ptr=ptr->e_parent)
if ((ptr->e_data != E_TYPE_CONSTRUCTOR) && (ptr->e_data != E_TYPE_CACHE_FROM_MASTER)) {
if ( (ptr->e_master == NULLAV) && (ptr->e_slave == NULLAV))
continue ;
if ((err->ERR_REFERRAL.DSE_ref_candidates = cont_ref_new (object,ptr)) == NULLCONTINUATIONREF) {
err->dse_type = DSE_SERVICEERROR;
err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
}
return ;
}
if ((err->ERR_REFERRAL.DSE_ref_candidates = cont_ref_parent (object)) == NULLCONTINUATIONREF) {
err->dse_type = DSE_SERVICEERROR;
err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
}
}
Entry no_reply_child (object,entryptr,err)
DN object;
Entry entryptr;
struct DSError * err;
{
DLOG (log_dsap,LLOG_TRACE,("no reply child"));
if (entryptr->e_leaf) {
DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
err->dse_type = DSE_NAMEERROR;
err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
err->ERR_NAME.DSE_na_matched = dn_cpy (object);
}
else if ( (entryptr->e_master != NULLAV) || (entryptr->e_slave != NULLAV)) {
err->dse_type = DSE_REFERRAL;
err->ERR_REFERRAL.DSE_ref_prefix = NULLDN;
if ((err->ERR_REFERRAL.DSE_ref_candidates = cont_ref_new (object,entryptr)) == NULLCONTINUATIONREF) {
err->dse_type = DSE_SERVICEERROR;
err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
}
}
else if (entryptr->e_child == NULLENTRY) {
constructor_referral (entryptr,err,object);
}
else if ((entryptr->e_child->e_data == E_TYPE_SLAVE) || (entryptr->e_child->e_data == E_DATA_MASTER)) {
DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
err->dse_type = DSE_NAMEERROR;
err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
err->ERR_NAME.DSE_na_matched = dn_cpy (object);
} else {
/* build a referral */
constructor_referral (entryptr,err,object);
}
return (NULLENTRY);
}
Entry no_reply_edb (object,entryptr,err)
DN object;
Entry entryptr;
struct DSError * err;
{
DLOG (log_dsap,LLOG_TRACE,("no reply edb"));
if (entryptr->e_leaf) {
DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
err->dse_type = DSE_NAMEERROR;
err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
err->ERR_NAME.DSE_na_matched = dn_cpy (object);
}
else if (entryptr->e_child == NULLENTRY) {
constructor_referral (entryptr,err,object);
}
else if ((entryptr->e_child->e_data == E_TYPE_SLAVE) || (entryptr->e_child->e_data == E_DATA_MASTER)) {
DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
err->dse_type = DSE_NAMEERROR;
err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
err->ERR_NAME.DSE_na_matched = dn_cpy (object);
} else {
/* build a referral */
constructor_referral_aux (entryptr,err,object);
}
return (NULLENTRY);
}