|
|
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 u
Length: 20746 (0x510a)
Types: TextFile
Names: »update.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/quipu/update.c«
/* update.c - write EDB back to disk after modify */
#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/update.c,v 7.1 89/12/19 16:20:54 mrose Exp $";
#endif
/*
* $Header: /f/osi/quipu/RCS/update.c,v 7.1 89/12/19 16:20:54 mrose Exp $
*
*
* $Log: update.c,v $
* Revision 7.1 89/12/19 16:20:54 mrose
* sync
*
* Revision 7.0 89/11/23 22:18:18 mrose
* Release 6.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 "tailor.h"
#include "quipu/read.h"
#include "quipu/dua.h"
#include "quipu/connection.h"
#ifndef NO_STATS
extern LLog * log_stat;
#endif
extern int dn_print ();
extern LLog * log_dsap;
extern char remote_lookup;
extern int local_slave_size;
extern int slave_edbs;
struct oper_act * oper_alloc();
struct oper_act * make_get_edb_op();
/* routine name is historic - not significant */
journal (myentry)
Entry myentry;
{
char * filename, *dn2edbfile();
char savefile [LINESIZE], newfile[LINESIZE];
DN dn;
extern char * treedir;
extern char * parse_file;
Entry liststart;
extern int errno;
if (myentry == NULLENTRY) {
LLOG (log_dsap,LLOG_FATAL,("update edb problem"));
return NOTOK;
}
if ((myentry->e_parent != NULLENTRY) && (myentry->e_parent->e_leaf)) {
liststart = myentry;
dn = get_copy_dn (liststart->e_parent);
if ((filename = dn2edbfile (dn)) == NULLCP) {
dn_free (dn);
return NOTOK;
}
myentry->e_parent->e_leaf = FALSE; /* not a leaf now !! */
if ( write_edb(liststart,filename) != OK)
return NOTOK;
} else {
if (myentry->e_parent == NULLENTRY) {
liststart = myentry;
dn = NULLDN;
} else {
liststart = myentry->e_parent->e_child;
dn = get_copy_dn (liststart->e_parent);
}
if ((filename = dn2edbfile (dn)) == NULLCP) {
dn_free (dn);
return NOTOK;
}
(void) strcpy (newfile,filename);
(void) strcat (newfile,".new");
if ( write_edb(liststart,newfile) != OK) {
(void) unlink (newfile);
return NOTOK;
}
(void) strcpy (savefile,filename);
(void) strcat (savefile,".bak");
(void) unlink (savefile);
if (link (filename, savefile) == NOTOK)
SLOG (log_dsap, LLOG_EXCEPTIONS, savefile,
("unable to link %s to", filename));
if (rename (newfile, filename) == NOTOK) {
SLOG (log_dsap, LLOG_EXCEPTIONS, filename,
("unable to rename %s to", newfile));
if (link (savefile, filename) == NOTOK
&& !fileexists (filename))
LLOG (log_dsap, LLOG_EXCEPTIONS,
("and couldn't get old file back - PANIC!!!"));
return NOTOK;
}
}
return OK;
}
modify_attr (eptr,who)
Entry eptr;
DN who;
{
AttributeType at;
AttributeValue av;
AV_Sequence avs;
Attr_Sequence as, old;
extern int no_last_mod;
extern char *new_version ();
if (no_last_mod)
return;
if ((at = AttrT_new (LAST_MOD_OID)) == NULLAttrT) {
LLOG (log_dsap, LLOG_EXCEPTIONS, ("last mod oid missing"));
return;
}
av = AttrV_alloc ();
av->av_syntax = str2syntax ("UTCTime");
av->av_struct = (caddr_t) new_version();
avs = avs_comp_new(av);
if ((old = as_find_type (eptr->e_attributes,at)) == NULLATTR) {
as = as_comp_new (at,avs,NULLACL_INFO);
eptr->e_attributes = as_merge (eptr->e_attributes,as);
} else {
avs_free (old->attr_value);
old->attr_value = avs;
AttrT_free (at);
}
if ((at = AttrT_new (MOD_BY_OID)) == NULLAttrT) {
LLOG (log_dsap, LLOG_EXCEPTIONS, ("last mod by oid missing"));
return;
}
av = AttrV_alloc ();
av->av_syntax = str2syntax ("DN");
av->av_struct = (caddr_t) dn_cpy (who);
avs = avs_comp_new(av);
if ((old = as_find_type (eptr->e_attributes,at)) == NULLATTR) {
as = as_comp_new (at,avs,NULLACL_INFO);
eptr->e_attributes = as_merge (eptr->e_attributes,as);
} else {
avs_free (old->attr_value);
old->attr_value = avs;
AttrT_free (at);
}
}
do_get_edb (arg,error,result,binddn)
struct getedb_arg *arg;
struct DSError *error;
struct getedb_result *result;
DN binddn;
{
Entry eptr;
extern DN mydsadn;
Entry my_entry;
AV_Sequence avs;
struct edb_info * dsainfo;
char proceed = FALSE;
struct dn_seq * dnseq;
struct di_block * di;
(void) dn_decode (arg->ga_entry);
DLOG (log_dsap,LLOG_DEBUG,("getedb '%s'",arg->ga_version));
switch(really_find_entry (arg->ga_entry,FALSE,NULLDNSEQ,FALSE,&(eptr),error,&(di)))
{
case DS_OK:
/*
* Entry has been found and returned via eptr.
* Go through and process this entry.
*/
break;
case DS_CONTINUE:
/*
* Get edb operations should never generate referrals.
* Free the di_blocks generated and return an error.
*/
error->dse_type = DSE_SERVICEERROR;
error->ERR_SERVICE.DSE_sv_problem = DSE_SV_CHAININGREQUIRED;
return (DS_X500_ERROR);
case DS_X500_ERROR:
/* something wrong with the request - error should be filled out */
return(DS_X500_ERROR);
default:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_get_edb() - really_find_entry() failed"));
error->dse_type = DSE_SERVICEERROR;
error->ERR_SERVICE.DSE_sv_problem = DSE_SV_DITERROR;
return (DS_X500_ERROR);
}
if ((my_entry = local_find_entry (mydsadn,TRUE)) == NULLENTRY)
fatal (84,"my entry has gone - no getedb");
/* Check we will send to this DSA */
for (avs = my_entry->e_dsainfo->dsa_attr ; avs != NULLAV; avs=avs->avseq_next) {
if (avs->avseq_av.av_struct == NULL)
continue;
dsainfo = (struct edb_info *) avs->avseq_av.av_struct;
if (dn_cmp(dsainfo->edb_name,arg->ga_entry) == 0) {
for (dnseq=dsainfo->edb_allowed; dnseq!=NULLDNSEQ; dnseq=dnseq->dns_next) {
if (dn_cmp(dnseq->dns_dn,binddn) == 0) {
proceed = TRUE;
break;
}
}
}
if (proceed)
break;
}
if (!proceed) {
error->dse_type = DSE_SECURITYERROR;
error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
return (DS_ERROR_REMOTE);
}
if ((eptr->e_child == NULLENTRY)
|| ((eptr->e_child->e_data != E_DATA_MASTER)
&& (eptr->e_child->e_data != E_TYPE_SLAVE))) {
error->dse_type = DSE_SERVICEERROR;
error->ERR_SERVICE.DSE_sv_problem = DSE_SV_DITERROR;
return (DS_X500_ERROR);
}
if (eptr->e_edbversion != NULLCP) {
DLOG(log_dsap, LLOG_DEBUG, ("edb_ver = %s", eptr->e_edbversion));
if (lexequ (arg->ga_version,eptr->e_edbversion) == 0) {
result->gr_version = eptr->e_edbversion;
result->gr_edb = NULLENTRY;
result->gr_next = NULL_GETRESULT;
return (DS_OK);
}
} else
eptr->e_edbversion = new_version();
result->gr_version = eptr->e_edbversion;
result->gr_edb = eptr->e_child;
result->gr_next = NULL_GETRESULT;
return (DS_OK);
}
slave_update ()
{
extern time_t lastedb_update, time();
(void) update_aux (NULLDN, 0);
lastedb_update = time((time_t *)0);
}
update_aux (dn, isroot)
DN dn;
int isroot;
{
Entry my_entry, make_path();
Entry find_sibling();
extern DN mydsadn;
struct edb_info * dsainfo;
Entry eptr;
static char *version = NULLCP;
AV_Sequence avs;
AV_Sequence avs_head;
int success;
DLOG (log_dsap,LLOG_TRACE,("slave update"));
if ((my_entry = local_find_entry (mydsadn,TRUE)) == NULLENTRY)
fatal (82,"Can't update slaves - my entry has gone");
avs_head = avs_cpy(my_entry->e_dsainfo->dsa_attr);
#ifdef REMOVE_FOR_6_0
{
int loop;
for (loop=0 ; loop <2 ; loop++) {
#endif
for (avs = avs_head ; avs != NULLAV; avs=avs->avseq_next)
{
if (avs->avseq_av.av_struct == NULL)
continue;
dsainfo = (struct edb_info *) avs->avseq_av.av_struct;
if (dsainfo->edb_getfrom == NULLDN)
continue; /* not an EDB to update */
if ((dn || isroot) && dn_cmp (dn, dsainfo -> edb_name) != OK)
continue; /* not an EDB this time */
if ((eptr = local_find_entry (dsainfo->edb_name,FALSE)) == NULLENTRY) {
version = "0000000000Z";
eptr = make_path (dsainfo->edb_name);
}
else
{
if((version = eptr->e_edbversion) == NULLCP)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("update_aux: edbversion was NULLCP"));
version = "0000000000Z";
}
}
#ifdef REMOVE_FOR_6_0
success = send_get_edb(version, dsainfo->edb_name, dsainfo->edb_getfrom,loop);
#else
success = send_get_edb(version, dsainfo->edb_name, dsainfo->edb_getfrom);
#endif
if(dn || isroot)
break;
dsa_wait (0); /* accept any results of previous ops */
}
#ifdef REMOVE_FOR_6_0
}
}
#endif
avs_free (avs_head);
return((dn || isroot) ? success : OK);
}
#ifdef REMOVE_FOR_6_0
int send_get_edb (version,dn,from,loop)
char * version;
DN dn,from;
int loop;
#else
int send_get_edb (version,dn,from)
char * version;
DN dn,from;
#endif
{
struct di_block * di;
struct DSError error;
struct oper_act * on;
char buffer[BUFSIZ];
PS ps;
#ifdef REMOVE_FOR_6_0
Entry ptr;
if ((ptr = local_find_entry (from,FALSE)) != NULLENTRY)
if (quipu_ctx_supported (ptr) == 1) {
/* probably 5.0 based - send SYNC DAP call */
if (loop == 0)
do_sync_getedb (dn,ptr);
return OK;
}
if (loop == 0)
return OK;
#endif
switch(get_dsa_info(from, NULLDNSEQ, &(error), &(di)))
{
case DS_OK:
/*
* di is a completed dsa info block
* Make a get_edb operation from it, attempt to send the operation
* and link the operation onto the global list of get_edb
* operations.
*/
if (ps = ps_alloc (str_open)) {
if (str_setup (ps, buffer, sizeof buffer, 1) != NOTOK) {
ps_printf (ps, "contact ");
dn_print (ps, from, EDBOUT);
ps_printf (ps, " for ");
if (dn)
dn_print (ps, dn, EDBOUT);
*ps -> ps_ptr = NULL;
LLOG (log_dsap, LLOG_NOTICE, ("%s", buffer));
}
(void) ps_free (ps);
}
#ifdef DEBUG
DLOG(log_dsap, LLOG_DEBUG, ("send_get_edb - get_dsa_info OK:"));
di_list_log(di);
#endif
if((on = make_get_edb_op(dn, version, di)) == NULLOPER)
{
/* Flake out screaming */
LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_edb_op failed for send_get_edb"));
return(NOTOK);
}
if(oper_chain(on) != OK)
{
LLOG(log_dsap, LLOG_NOTICE, ("Could not chain a getEDB operation"));
return(NOTOK);
}
on->on_next_task = get_edb_ops;
get_edb_ops = on;
return(OK);
case DS_CONTINUE:
/*
* di is a deferred dsa info block
* make the operation and suspend waiting for the di_block to be
* woken up.
*/
#ifdef DEBUG
DLOG(log_dsap, LLOG_DEBUG, ("send_get_edb - get_dsa_info CONT:"));
di_list_log(di);
#endif
if((on = make_get_edb_op(dn, version, di)) == NULLOPER)
{
/* Flake out screaming */
LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_edb_op failed for send_get_edb"));
return(NOTOK);
}
on->on_state = ON_DEFERRED;
on->on_next_task = get_edb_ops;
get_edb_ops = on;
if (ps = ps_alloc (str_open)) {
if (str_setup (ps, buffer, sizeof buffer, 1) != NOTOK) {
ps_printf (ps, "contact ");
dn_print (ps, from, EDBOUT);
ps_printf (ps, " for ");
if (dn)
dn_print (ps, dn, EDBOUT);
*ps -> ps_ptr = NULL;
LLOG (log_dsap, LLOG_NOTICE, ("%s", buffer));
}
(void) ps_free (ps);
}
return(OK);
case DS_X500_ERROR:
/* Error encountered generating di_block */
LLOG(log_dsap, LLOG_NOTICE, ("send_get_edb - get_dsa_info returned X500 ERROR"));
log_ds_error (&error);
ds_error_free (&error);
return(NOTOK);
default:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("send_get_edb - get_dsa_info unexpected return"));
return(NOTOK);
}
/* NOTREACHED */
}
process_edb(on)
struct oper_act * on;
{
extern DN mydsadn;
Entry make_path(), find_sibling();
Entry new_entry, old_entry, temp, sibl, next;
Entry eptr;
/* up 'n' down to make sure first child !!! */
struct DSError error;
struct getedb_result * result = &(on->on_resp.resp_res.dcr_dsres.res_ge);
int entry_cnt = 0;
if ((eptr = local_find_entry (on->on_req.dca_dsarg.arg_ge.ga_entry,FALSE)) == NULLENTRY) {
LLOG (log_dsap, LLOG_EXCEPTIONS, ("Updating something which does not exist !!!"));
return;
}
if ((new_entry = result->gr_edb) == NULLENTRY) {
DLOG (log_dsap, LLOG_NOTICE,(" EDBs are the same (%d): %s",on->on_id,on->on_getedb_ver));
return;
} else {
DLOG (log_dsap, LLOG_NOTICE,(" EDB updated from (%d): %s to: %s", on->on_id,on->on_getedb_ver, result->gr_version));
;
}
if (eptr->e_edbversion)
free (eptr->e_edbversion);
if (result->gr_version == NULLCP) {
eptr->e_edbversion = "Unknown";
LLOG(log_dsap, LLOG_EXCEPTIONS, ("EDBRES: NULL version"));
} else
eptr->e_edbversion = strdup (result->gr_version);
for (temp = new_entry; temp != NULLENTRY; temp=temp->e_sibling) {
temp->e_parent = eptr;
if (unravel_attribute (temp,&error,TRUE) != OK) {
LLOG (log_dsap,LLOG_EXCEPTIONS, ("Error in new EDB - continuing with old"));
log_ds_error (&error);
return;
}
}
for (temp = new_entry; temp != NULLENTRY; temp=temp->e_sibling) {
entry_cnt++;
if ((old_entry = find_sibling (temp->e_name,eptr->e_child)) != NULLENTRY) {
temp->e_leaf = FALSE;
temp->e_allchildrenpresent = old_entry->e_allchildrenpresent;
temp->e_child = old_entry->e_child;
for (sibl = temp->e_child; sibl != NULLENTRY; sibl=sibl->e_sibling)
sibl->e_parent = temp;
if (old_entry->e_edbversion != NULLCP)
temp->e_edbversion = strdup (old_entry->e_edbversion);
}
}
if (eptr->e_child == NULLENTRY)
slave_edbs++;
for (temp = eptr->e_child; temp != NULLENTRY; temp=next) {
next = temp->e_sibling;
local_slave_size--;
entry_free (temp);
}
local_slave_size += entry_cnt;
eptr->e_child = new_entry;
#ifndef NO_STATS
{
DN tmp_dn;
tmp_dn = get_copy_dn (eptr);
pslog (log_stat,LLOG_NOTICE,"Slave update",dn_print,(caddr_t)tmp_dn);
dn_free (tmp_dn);
}
#endif
if (journal (new_entry) != OK)
fatal (-79,"Lost old EDB, can't write new one !!!");
if (local_find_entry (mydsadn,TRUE) == NULLENTRY)
fatal (-80,"My entry has disappeared from the DIT !!!");
}
/*
* get_edb_fail_wakeup suffices for both fail and error conditions
* arising on a get edb operation.
*/
get_edb_fail_wakeup(on)
struct oper_act * on;
{
struct oper_act * on_tmp;
struct oper_act **on_p;
DLOG(log_dsap, LLOG_TRACE, ("get_edb_fail_wakeup"));
/* Should do extra logging here */
on_p = &(get_edb_ops);
for(on_tmp = get_edb_ops; on_tmp != NULLOPER; on_tmp = on_tmp->on_next_task)
{
if(on_tmp == on)
break;
on_p = &(on_tmp->on_next_task);
}
if(on_tmp != NULLOPER)
{
(*on_p) = on_tmp->on_next_task;
}
else
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("get_edb_fail_wakeup - op escaped from get_edb_ops (the global list)"));
}
oper_conn_extract(on);
oper_free(on);
}
struct oper_act * make_get_edb_op(dn, version, di)
DN dn;
char * version;
struct di_block * di;
{
struct di_block * di_tmp;
struct oper_act * on_tmp;
struct getedb_arg * arg;
DLOG(log_dsap, LLOG_TRACE, ("make_get_edb_op"));
if((on_tmp = oper_alloc()) == NULLOPER)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_edb_op - out of memory"));
return(NULLOPER);
}
on_tmp->on_type = ON_TYPE_GET_EDB;
on_tmp->on_arg = &(on_tmp->on_req);
on_tmp->on_req.dca_dsarg.arg_type = OP_GETEDB;
on_tmp->on_getedb_ver = version;
arg = &(on_tmp->on_req.dca_dsarg.arg_ge);
arg->ga_entry = dn_cpy(dn);
arg->ga_version = strdup(version);
DLOG(log_dsap, LLOG_NOTICE, ("EDBARG: ver = %s", arg->ga_version));
on_tmp->on_dsas = di;
for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
{
#ifdef DEBUG
DLOG(log_dsap, LLOG_DEBUG, ("Linking a di_block to this op"));
di_log(di_tmp);
#endif
di_tmp->di_type = DI_OPERATION;
di_tmp->di_oper = on_tmp;
}
return(on_tmp);
}
get_edb_extract(on)
struct oper_act * on;
{
struct oper_act * on_tmp;
struct oper_act **next_on;
next_on = &(get_edb_ops);
for(on_tmp=get_edb_ops; on_tmp!=NULLOPER; on_tmp=on_tmp->on_next_task)
{
if(on_tmp == on)
break;
next_on = &(on_tmp->on_next_task);
}
if(on_tmp != NULLOPER)
{
(*next_on) = on_tmp->on_next_task;
}
else
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Not on get_edb list"));
}
}
#ifdef REMOVE_FOR_6_0
Entry read_edb (version,dn,addr)
char ** version;
DN dn;
struct PSAPaddr * addr;
{
struct DSError error;
static struct ds_bind_arg bindarg;
static struct ds_bind_arg bindresult;
static struct ds_bind_error binderr;
int ad;
struct getedb_arg arg;
struct getedb_result result;
Entry my_entry;
extern DN mydsdn;
char * passwd, *get_entry_passwd();
/* read from of remote DSA */
/* Do synchronus read for now */
/* Async read eventually */
{
char buffer[BUFSIZ];
PS ps;
if (ps = ps_alloc (str_open)) {
if (str_setup (ps, buffer, sizeof buffer, 1) != NOTOK) {
ps_printf (ps, "SYNC update of @");
if (dn)
dn_print (ps, dn, EDBOUT);
*ps -> ps_ptr = NULL;
/* XXX: should be NOTICE, but since we are synchronous... */
LLOG (log_dsap, LLOG_EXCEPTIONS, ("%s", buffer));
}
(void) ps_free (ps);
}
}
bindarg.dba_version = DBA_VERSION_V1988;
bindarg.dba_auth_type = DBA_AUTH_SIMPLE;
bindarg.dba_time1 = NULLCP;
bindarg.dba_time2 = NULLCP;
if ((my_entry = local_find_entry (mydsadn ,TRUE)) == NULLENTRY) {
bindarg.dba_dn = NULLDN;
bindarg.dba_auth_type = DBA_AUTH_NONE;
bindarg.dba_passwd[0] = 0;
bindarg.dba_passwd_len = 0;
} else {
bindarg.dba_dn = dn_cpy(mydsadn);
if ( (passwd = get_entry_passwd(my_entry->e_attributes)) != NULLCP) {
(void) strncpy (bindarg.dba_passwd,passwd,DBA_MAX_PASSWD_LEN);
bindarg.dba_passwd_len = strlen (passwd);
} else {
bindarg.dba_auth_type = DBA_AUTH_NONE;
bindarg.dba_passwd[0] = 0;
bindarg.dba_passwd_len = 0;
}
}
if (dap_bind (&ad, &bindarg, &binderr, &bindresult,addr) != OK) {
LLOG (log_dsap,LLOG_EXCEPTIONS,("getedb bind failed"));
bind_arg_free (&bindarg);
return (NULLENTRY);
}
bind_arg_free (&bindarg);
bind_arg_free (&bindresult);
arg.ga_entry = dn;
arg.ga_version = *version;
DLOG(log_dsap, LLOG_NOTICE, ("EDBARG: ver = %s", arg.ga_version));
if (getedb (&arg,&error,&result,ad) != OK) {
LLOG (log_dsap,LLOG_EXCEPTIONS,("getedb remote operation failed"));
log_ds_error (&error);
ds_error_free (&error);
(void) dap_unbind (ad);
return (NULLENTRY);
}
(void) dap_unbind (ad);
*version = result.gr_version;
if (result.gr_version == NULLCP)
LLOG(log_dsap, LLOG_NOTICE, ("EDBRES: NULL version"));
else
DLOG(log_dsap, LLOG_NOTICE, ("EDBRES: ver = %s", result.gr_version));
/* XXX: should be NOTICE, but since we are synchronous... */
if (result.gr_edb == NULLENTRY)
LLOG (log_dsap, LLOG_EXCEPTIONS,
(" EDBs are the same: %s", *version));
else
LLOG (log_dsap, LLOG_EXCEPTIONS,
(" EDB updated: %s", *version));
return (result.gr_edb);
}
do_sync_getedb (dn, dsa)
DN dn;
Entry dsa;
{
Entry make_path();
Entry find_sibling();
extern DN mydsadn;
Entry new_entry, eptr, old_entry, temp, sibl, next;
struct DSError error;
static char *version = NULLCP;
int entry_cnt = 0;
DLOG (log_dsap,LLOG_TRACE,("slave update"));
if ((eptr = local_find_entry (dn,FALSE)) == NULLENTRY) {
version = "0000000000Z";
eptr = make_path (dn);
} else
version = eptr->e_edbversion;
if ((new_entry = read_edb (&version,dn,dsa->e_dsainfo->dsa_addr)) == NULLENTRY)
return;
if (version == NULLCP)
eptr->e_edbversion = "Unknown";
else
eptr->e_edbversion = strdup (version);
for (temp = new_entry; temp != NULLENTRY; temp=temp->e_sibling) {
temp->e_parent = eptr;
entry_cnt++;
if (unravel_attribute (temp,&error,TRUE) != OK) {
LLOG (log_dsap,LLOG_EXCEPTIONS, ("Error in new EDB - continuing with old"));
log_ds_error (&error);
return;
}
if ((old_entry = find_sibling (temp->e_name,eptr->e_child)) != NULLENTRY) {
temp->e_leaf = FALSE;
temp->e_allchildrenpresent = old_entry->e_allchildrenpresent;
temp->e_child = old_entry->e_child;
for (sibl = temp->e_child; sibl != NULLENTRY; sibl=sibl->e_sibling)
sibl->e_parent = temp;
if (old_entry->e_edbversion != NULLCP)
temp->e_edbversion = strdup (old_entry->e_edbversion);
}
}
for (temp = eptr->e_child; temp != NULLENTRY; temp=next) {
next = temp->e_sibling;
local_slave_size--;
entry_free (temp);
}
local_slave_size += entry_cnt;
eptr->e_child = new_entry;
if (journal (new_entry) != OK)
fatal (-45,"Lost old EDB, can't write new one !!!");
#ifndef NO_STATS
else
pslog (log_stat,LLOG_NOTICE,"slave update",dn_print,(caddr_t)dn);
#endif
if (local_find_entry (mydsadn,TRUE) == NULLENTRY)
fatal (-80,"My entry has disappeared form the DIT !!!");
}
#endif