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