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 d

⟦3b768c98c⟧ TextFile

    Length: 6759 (0x1a67)
    Types: TextFile
    Names: »ds_add.c«

Derivation

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

TextFile

/* ds_add.c - */

#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_add.c,v 6.0 89/03/18 23:41:14 mrose Rel $";
#endif

/*
 * $Header: /f/osi/quipu/RCS/ds_add.c,v 6.0 89/03/18 23:41:14 mrose Rel $
 *
 *
 * $Log:	ds_add.c,v $
 * Revision 6.0  89/03/18  23:41:14  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/entry.h"
#include "quipu/add.h"

extern Entry database_root;
extern LLog * log_dsap;

#ifndef NO_STATS
extern LLog * log_stat;
extern int dn_print ();
#endif


do_ds_addentry (arg, error, binddn,target)
    struct ds_addentry_arg      *arg;
    struct DSError              *error;
    DN                          binddn;
    DN                          target;
{
Entry  entryptr,ptr;
register DN  dntop, dn = NULLDN;
DN  trail = NULLDN;
extern Entry database_root;
ContinuationRef cont_ref_parent ();
char * new_version ();

	DLOG (log_dsap,LLOG_TRACE,("ds_add"));

	if (target == NULLDN)
		target = arg->ada_object;

#ifndef NO_STATS
	dn_decode (target);
	pslog (log_stat,LLOG_NOTICE,"add",dn_print,(caddr_t)target);
#endif

	error ->dse_type = DSE_NOERROR;
	/* first of all see if entry exists */
	if ((entryptr = find_entry (target,&arg->ada_common,error,binddn)) != NULLENTRY) {
		error->dse_type = DSE_UPDATEERROR;
		error->ERR_UPDATE.DSE_up_problem = DSE_UP_ALREADYEXISTS;
		return(DS_ERROR_REMOTE);
	}

	if ((error->dse_type != DSE_NAMEERROR) || (error->ERR_NAME.DSE_na_problem != DSE_NA_NOSUCHOBJECT)) 
		return (DS_ERROR_REMOTE);

	ds_error_free (error);  /* not interested - know it does not exist */
	/* object does not exist, so create it */

	DLOG (log_dsap,LLOG_TRACE,("add - find parent"));
	/* find parent */

	if ((dntop = dn_cpy(target)) != NULLDN)
		for (dn=dntop; dn->dn_parent != NULLDN; dn=dn->dn_parent)
			trail = dn;

	if (trail == NULLDN) {
		dntop = NULLDN;
		entryptr = database_root;
		if (entryptr->e_data != E_DATA_MASTER) {
			error->dse_type = DSE_REFERRAL;
        		error->ERR_REFERRAL.DSE_ref_prefix = NULLDN;
			if ((error->ERR_REFERRAL.DSE_ref_candidates = cont_ref_parent (NULLDN)) == NULLCONTINUATIONREF) {
				error->dse_type = DSE_SERVICEERROR;
				error->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
			}
			return (DS_ERROR_CONNECT);
		}
	} else {
		trail->dn_parent = NULLDN;
		entryptr = find_master_entry (dntop,&arg->ada_common,error,binddn);
	}

	if (entryptr != NULLENTRY) {
		if ((entryptr->e_parent != NULLENTRY) && (entryptr->e_parent->e_lock)) {
			error->dse_type = DSE_SERVICEERROR;
			error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
			dn_free (dn);
			return (DS_ERROR_REMOTE);
		}

		DLOG (log_dsap,LLOG_TRACE,("add - acl"));
		if (check_acl (binddn,ACL_ADD,entryptr->e_acl->ac_child,dntop) == NOTOK) {
			error->dse_type = DSE_SECURITYERROR;
			error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
			dn_free (dn);
			return (DS_ERROR_REMOTE);
		}

		DLOG (log_dsap,LLOG_TRACE,("add - default"));
		ptr = get_default_entry (entryptr);
		ptr->e_name = rdn_cpy (dn->dn_rdn);
		ptr->e_attributes = as_cpy (arg->ada_entry);

		DLOG (log_dsap,LLOG_TRACE,("add - unravel"));
		if (unravel_attribute (ptr,error,TRUE) != OK) {
			free (dn);
			entry_free (ptr);
			return (DS_ERROR_REMOTE);
		}

		DLOG (log_dsap,LLOG_TRACE,("add - schema"));
		if (check_schema (ptr,NULLATTR,error,TRUE) != OK) {
			free (dn);
			entry_free (ptr);
			return (DS_ERROR_REMOTE);
		}

		free (dn);
		
		if ( entryptr->e_leaf) {
			Attr_Sequence newas;
			AttributeType newat;

			entryptr->e_child = ptr;
			/* add master and slave attributes */

			if ((entryptr->e_parent->e_slave == NULLAV) && (entryptr->e_parent->e_master == NULLAV)) {
				extern char * mydsaname;
				newat = AttrT_new (MASTERDSA_OID);
				entryptr->e_master = str2avs (mydsaname,newat);
				newas = as_comp_new (newat,entryptr->e_master,NULLACL_INFO);
				entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
			} else {
	 			if ((entryptr->e_master = avs_cpy(entryptr->e_parent->e_master)) != NULLAV) {
					newat = AttrT_new (MASTERDSA_OID);
					newas = as_comp_new (newat,entryptr->e_master,NULLACL_INFO);
					entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
				}
				if ((entryptr->e_slave = avs_cpy (entryptr->e_parent->e_slave)) != NULLAV) {
					newat = AttrT_new (SLAVEDSA_OID);
					newas = as_comp_new (newat,entryptr->e_slave,NULLACL_INFO);
					entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
				}
			}
			/* add new QuipuNonLeaf objectclass */
			newat = AttrT_new (OBJECTCLASS_OID);
			newas = as_comp_new (newat,str2avs(NONLEAFOBJECT,newat),NULLACL_INFO);
			entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);

			if (entryptr->e_parent != NULLENTRY)
				entryptr->e_parent->e_edbversion = new_version();
			entryptr->e_edbversion = new_version();
			ptr->e_edbversion = new_version();
			entryptr->e_allchildrenpresent = TRUE;

			if (journal (ptr) == NOTOK)
				fatal (-32,"add journal (2) failure - check database");
			entryptr->e_leaf = FALSE;
			/* rewrite the parent as well */
			if (journal (entryptr) != OK)
				fatal (-31,"add parent journal failed - check database");
			return (OK);

		} else if (entryptr->e_child == NULLENTRY) {

/* 
   A user can not be allowed to add a node here.
   The consequencies are quite large, and need *LOTS* of code
   cope with.  This will be added at a later date, but the exact
   algorithm needs sorting first.
   The problem is one of DSA configuration 
   hence will need masterDSA attributes, also the
   DSA responsible for the node must update its edbinfo attribute.
*/
			error->dse_type = DSE_UPDATEERROR;
			error->ERR_UPDATE.DSE_up_problem = DSE_UP_AFFECTSMULTIPLEDSAS;
 			free (dn);
			entry_free (ptr);
			return (DS_ERROR_REMOTE);

		} else {
			ptr->e_sibling = entryptr->e_child;
			entryptr->e_child = ptr;
		}

		if (ptr->e_parent != NULLENTRY)
			ptr->e_parent->e_edbversion = new_version();
		if (journal (ptr) == NOTOK)
			fatal (-32,"add journal failure - check database");

		return (DS_OK);

	} else {
		if (error->dse_type == DSE_REFERRAL) {
			/* Change name to target (currently parent) !!! */
			if (error->ERR_REFERRAL.DSE_ref_candidates == NULLCONTINUATIONREF)
				return (DS_ERROR_REMOTE);
			if (error->ERR_REFERRAL.DSE_ref_candidates->cr_name != NULLDN )
				dn_free(error->ERR_REFERRAL.DSE_ref_candidates->cr_name);
			error->ERR_REFERRAL.DSE_ref_candidates->cr_name = dn_cpy (target);
		}
		
		return (DS_ERROR_REMOTE);
	}

}