/* entry_load.c - load bits of the database */
static char *rcsid
= "$Header: /f/osi/quipu/RCS/entry_load.c,v 7.6 91/03/09 11:56:52 mrose Exp $";
* $Header: /f/osi/quipu/RCS/entry_load.c,v 7.6 91/03/09 11:56:52 mrose Exp $
* Revision 7.6 91/03/09 11:56:52 mrose
* Revision 7.5 91/02/22 09:39:20 mrose
* Revision 7.4 90/10/17 11:54:17 mrose
* Revision 7.3 90/07/09 14:46:10 mrose
* Revision 7.2 90/04/18 08:49:54 mrose
* Revision 7.1 89/12/19 16:20:34 mrose
* Revision 7.0 89/11/23 22:17:39 mrose
* 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
#include "quipu/ds_error.h"
struct acl_info
* acl_dflt ();
extern AttributeType
*turbo_index_types
;
static char filename
[LINESIZE
];
#define EDBLEN 3 /* length of string "EDB" */
if (stat (fname
,&buf
) != 0) {
DLOG (log_dsap
,LLOG_DEBUG
,("File %s will not stat - %d",fname
,errno
));
static read_mapped_rdn (aps
,name
,file
)
char *ptr
, *newname
, *tmp
, *getline();
if ((mapfp
= fopen (file
,"r")) == (FILE *)NULL
) {
LLOG(log_dsap
,LLOG_EXCEPTIONS
,("Can read \"%s\" (%d)",file
,errno
));
while ( (ptr
= getline(mapfp
)) != NULLCP
) {
if ((newname
= rindex(ptr
,'#')) == NULLCP
) {
LLOG(log_dsap
,LLOG_EXCEPTIONS
,("Seperator missing in map file \"%s\", line %d",file
,parse_line
));
if (lexequ (name
,ptr
) == 0) {
/* got it - replace in ps*/
ps_print (aps
,SkipSpace(newname
));
DLOG (log_dsap
, LLOG_DEBUG
,("%s not found in map file %s",name
,file
));
static write_mapped_rdn (aps
,name
,file
)
if (strlen(name
) < MAXFILENAMELEN
)
/* Make unique name for it */
if ((nptr
= index (name
,'=')) == NULLCP
)
for (i
=0 ; (*nptr
!=0) && (i
< MAXFILENAMELEN
-6) ; nptr
++)
(void) strcpy (sname
,name
);
(void) strcpy (mptr
,"XXXXXX");
nptr
= (aps
->ps_ptr
-= i
);
if ((aps
->ps_base
= mktemp (aps
->ps_base
)) == NULLCP
)
DLOG(log_dsap
,LLOG_DEBUG
,("mapped name %s",aps
->ps_base
));
if (mkdir (aps
->ps_base
,0700) != 0) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("map rdn mkdir failure \"%s\" (%d)",aps
->ps_base
,errno
));
/* write it to map file */
mapfp
= fopen (file
,"a");
mapfp
= fopen (file
,"w");
if (mapfp
== (FILE *)NULL
) {
LLOG(log_dsap
,LLOG_EXCEPTIONS
,("Can't write to \"%s\" (%d)",file
,errno
));
if (fprintf (mapfp
,"%s#%s\n",sname
,nptr
) == EOF
) {
LLOG(log_dsap
,LLOG_EXCEPTIONS
,("Can't write to \"%s\" (%d)",file
,errno
));
if (fclose (mapfp
) != 0) {
LLOG(log_dsap
,LLOG_EXCEPTIONS
,("Can't close \"%s\" (%d)",file
,errno
));
static rdn2filename (aps
,rdn
,make
)
char *start
= aps
->ps_ptr
;
/* look for EDB.map file */
(void) sprintf (mapbuf
, "%sEDB.map",aps
->ps_base
);
rdn_print (aps
,rdn
,DIROUT
);
if (fileexists (mapbuf
) && read_mapped_rdn (aps
,start
,mapbuf
)) {
if (fileexists(aps
->ps_base
))
if (mkdir (aps
->ps_base
,0700) != 0) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("dn2file mkdir (mapped) failure \"%s\" (%d)",aps
->ps_base
,errno
));
LLOG (log_dsap
,LLOG_NOTICE
,("WARNING: Needed to make mapped directory \"%s\"",aps
->ps_base
));
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("mapped file missing \"%s\"",aps
->ps_base
));
else if ( strlen(start
) > MAXFILENAMELEN
)
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("Potential problem with \"%s\" (name too long)",start
));
if (fileexists(aps
->ps_base
))
if (write_mapped_rdn (aps
,start
,mapbuf
))
if (mkdir (aps
->ps_base
,0700) != 0) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("dn2file mkdir failure \"%s\" (%d)",aps
->ps_base
,errno
));
static dn2filename (aps
,dn
,make
)
ps_print (aps
,isodefile(treedir
,0));
if ((! fileexists (aps
->ps_base
)) &&
(mkdir (aps
->ps_base
,0700) != 0)) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("dn2file mkdir failure \"%s\" (%d)",aps
->ps_base
,errno
));
if (*(aps
->ps_ptr
- 1) != '/')
if (rdn2filename (aps
,dn
->dn_rdn
,make
) == NOTOK
)
if (dn
->dn_parent
!= NULLDN
) {
for (eptr
= dn
->dn_parent
; eptr
!= NULLDN
; eptr
= eptr
->dn_parent
) {
if (rdn2filename (aps
,eptr
->dn_rdn
,make
) == NOTOK
)
static char result
[LINESIZE
];
if ((aps
= ps_alloc (str_open
)) == NULLPS
) {
LLOG (log_dsap
, LLOG_EXCEPTIONS
, ("dn2dir ps_alloc failed"));
if (str_setup (aps
,result
,LINESIZE
,1) == NOTOK
) {
LLOG (log_dsap
, LLOG_EXCEPTIONS
, ("dn2dir ps_alloc failed"));
if (dn2filename (aps
,dn
,TRUE
) != OK
)
if (*(aps
->ps_ptr
- 1) != '/')
static file_check (offset
,entryptr
)
ps
->ps_ptr
= filename
+ offset
;
ps
->ps_cnt
= LINESIZE
- offset
;
if (rdn2filename (ps
,entryptr
->e_name
,FALSE
) == OK
) {
if (*(ps
->ps_ptr
- 1) != '/')
static char got_all
= TRUE
;
static load_a_kid(e
, offset
)
static int entry_load_kids();
(e
->e_master
== NULLAV
) &&
(e
->e_slave
== NULLAV
)) {
e
->e_allchildrenpresent
= 2;
if (file_check(offset
, e
) == OK
) {
if ((e
->e_children
= getentry_block(e
, filename
)) == NULLAVL
) {
if (e
->e_allchildrenpresent
!= FALSE
&&
if (entry_load_kids(e
->e_children
, strlen( filename
) - EDBLEN
)
if (e
->e_allchildrenpresent
!= 2)
LLOG (log_dsap
, LLOG_TRACE
, ("Sibling file %s/EDB NOT found", filename
));
e
->e_allchildrenpresent
= FALSE
;
static entry_load_kids (entryptr
,offset
)
Avlnode
*entryptr
; /* in this case, entryptr is really a tree of kids */
ps
->ps_ptr
= filename
+ offset
;
ps
->ps_cnt
= LINESIZE
- offset
;
if (avl_apply(entryptr
, load_a_kid
, (caddr_t
) offset
, NOTOK
, AVL_PREORDER
)
akid
= (Entry
) avl_getone(entryptr
);
if (akid
&& (parent
= akid
->e_parent
)) {
if (parent
->e_allchildrenpresent
== 1)
parent
->e_allchildrenpresent
= 2;
} else if (parent
->e_allchildrenpresent
== 2)
parent
->e_allchildrenpresent
= 1;
if (entryptr
== NULLENTRY
)
for ( ptr
= entryptr
; ptr
!= NULLENTRY
; ptr
= ptr
->e_sibling
) {
if ((!ptr
->e_external
) &&
(ptr
->e_master
== NULLAV
) &&
(ptr
->e_slave
== NULLAV
)) {
ptr
->e_allchildrenpresent
= 2;
if (file_check (offset
,ptr
) == OK
) {
if ((ptr
->e_child
= getentry_block (ptr
,filename
)) == NULLENTRY
)
if (ptr
->e_allchildrenpresent
!= FALSE
&&
if (entry_load_kids (ptr
->e_child
,strlen(filename
) - EDBLEN
) == NOTOK
)
if (ptr
->e_allchildrenpresent
!= 2)
LLOG (log_dsap
,LLOG_TRACE
,("WARNING, sibling file %s/EDB NOT found", filename
));
ptr
->e_allchildrenpresent
= FALSE
;
if (entryptr
->e_parent
) {
if (entryptr
->e_parent
->e_allchildrenpresent
== 1)
entryptr
->e_parent
->e_allchildrenpresent
= 2;
} else if (entryptr
->e_parent
->e_allchildrenpresent
== 2)
entryptr
->e_parent
->e_allchildrenpresent
= 1;
static check_entry_free (e
)
if (e
->e_allchildrenpresent
< 2)
static merge_entry(newentry
, oldtree
)
newentry
->e_parent
= ((Entry
) avl_getone(oldtree
))->e_parent
;
if ((p
= (Entry
) avl_find(oldtree
, (caddr_t
) newentry
, entry_cmp
))
newentry
->e_leaf
= FALSE
;
newentry
->e_allchildrenpresent
= p
->e_allchildrenpresent
;
newentry
->e_children
= p
->e_children
;
(void) avl_apply(newentry
->e_children
, parent_link
, (caddr_t
) newentry
,
if (p
->e_edbversion
!= NULLCP
)
newentry
->e_edbversion
= strdup(p
->e_edbversion
);
newentry
->e_allchildrenpresent
= FALSE
;
Entry
subtree_load (parent
,dn
)
Entry treetop
, sibl
, find_sibling();
if ((parent
!= NULLENTRY
) && (parent
->e_children
!= NULLAVL
)) {
akid
= (Entry
) avl_getone(parent
->e_children
);
if (akid
->e_data
!= E_TYPE_CONSTRUCTOR
)
if ((parent
!= NULLENTRY
) && (parent
->e_child
!= NULLENTRY
))
if (parent
->e_child
->e_data
!= E_TYPE_CONSTRUCTOR
)
return (parent
->e_child
);
if ((ps
= ps_alloc (str_open
)) == NULLPS
) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("file open ps_alloc failed"));
if (str_setup (ps
,filename
,LINESIZE
,1) == NOTOK
) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("file open ps_alloc failed"));
(void) dn2filename (ps
,dn
,FALSE
);
if (*(ps
->ps_ptr
- 1) != '/')
if (parent
!= NULLENTRY
&& parent
->e_children
!= NULLAVL
) {
if ((parent
!= NULLENTRY
) && (parent
->e_child
!= NULLENTRY
)) {
/* yuk - already got an edb lower in the DIT ... */
treetop
= getentry_block (parent
,filename
);
* go through the tree we just loaded, merging it with the
* tree previously loaded.
(void) avl_apply(treetop
, merge_entry
, (caddr_t
) parent
->e_children
,
if (got_subtree
&& (parent
->e_allchildrenpresent
== 1))
parent
->e_allchildrenpresent
= 2;
/* free the old tree and set got_subtree */
(void) avl_free(parent
->e_children
, check_entry_free
);
if (got_subtree
&& (parent
->e_allchildrenpresent
== 1))
parent
->e_allchildrenpresent
= 2;
parent
->e_children
= treetop
;
for (temp
= treetop
; temp
!= NULLENTRY
; temp
=temp
->e_sibling
) {
if ((old_entry
= find_sibling (temp
->e_name
,parent
->e_child
)) != NULLENTRY
) {
if ((temp
->e_allchildrenpresent
= old_entry
->e_allchildrenpresent
) < 2 )
temp
->e_child
= old_entry
->e_child
;
for (sibl
= temp
->e_child
; sibl
!= NULLENTRY
; sibl
=sibl
->e_sibling
) {
if (old_entry
->e_edbversion
!= NULLCP
)
temp
->e_edbversion
= strdup (old_entry
->e_edbversion
);
} else if ( ! temp
->e_leaf
) {
temp
->e_allchildrenpresent
= FALSE
;
if (got_subtree
&& (treetop
->e_allchildrenpresent
== 1))
treetop
->e_allchildrenpresent
= 2;
for (temp
= parent
->e_child
; temp
!= NULLENTRY
; temp
=old_entry
) {
old_entry
= temp
->e_sibling
;
if (temp
->e_allchildrenpresent
< 2)
if (got_subtree
&& (parent
->e_allchildrenpresent
== 1))
parent
->e_allchildrenpresent
= 2;
/* do we need to ripple e_allchildrenpresent higher ? */
parent
->e_children
= treetop
;
parent
->e_child
= treetop
;
parent
= get_default_entry (NULLENTRY
);
parent
->e_acl
= acl_alloc();
parent
->e_acl
->ac_child
= acl_dflt ();
parent
->e_acl
->ac_entry
= acl_dflt ();
parent
->e_acl
->ac_default
= acl_dflt ();
if ((treetop
= getentry_block (parent
,filename
)) == NULLAVL
)
if ((treetop
= getentry_block (parent
,filename
)) == NULLENTRY
)
treetop
= getentry_block (parent
,filename
);
parent
->e_children
= treetop
;
parent
->e_child
= treetop
;
if (entry_load_kids (treetop
,strlen (filename
) - EDBLEN
) == NOTOK
) {
return (parent
); /* be wary of this when calling subtree load... */
/* if DN == NULL - you may want the child !!! */
extern Entry database_root
;
if ((parent
= local_find_entry (dn
,FALSE
)) == NULLENTRY
)
if (parent
->e_data
!= E_DATA_MASTER
)
LLOG (log_dsap
,LLOG_EXCEPTIONS
, ("WARNING: refreshing SLAVE EDB file -- should not be needed"));
child
= (Entry
) entry_cpy(parent
);
child
->e_parent
= parent
->e_parent
;
child
->e_children
= parent
->e_children
;
parent
->e_children
= NULLAVL
;
parent
->e_child
= NULLENTRY
;
tmp
= subtree_load (NULLENTRY
,NULLDN
);
tmp
= subtree_load (parent
,dn
);