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 f

⟦563fc7a2b⟧ TextFile

    Length: 11396 (0x2c84)
    Types: TextFile
    Names: »find_entry.c«

Derivation

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

TextFile

/* 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);

}