|
|
1.1 root 1: /* entry_load.c - load bits of the database */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/quipu/RCS/entry_load.c,v 7.3 90/07/09 14:46:10 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/quipu/RCS/entry_load.c,v 7.3 90/07/09 14:46:10 mrose Exp $
9: *
10: *
11: * $Log: entry_load.c,v $
12: * Revision 7.3 90/07/09 14:46:10 mrose
13: * sync
14: *
15: * Revision 7.2 90/04/18 08:49:54 mrose
16: * 6.2
17: *
18: * Revision 7.1 89/12/19 16:20:34 mrose
19: * sync
20: *
21: * Revision 7.0 89/11/23 22:17:39 mrose
22: * Release 6.0
23: *
24: */
25:
26: /*
27: * NOTICE
28: *
29: * Acquisition, use, and distribution of this module and related
30: * materials are subject to the restrictions of a license agreement.
31: * Consult the Preface in the User's Manual for the full terms of
32: * this agreement.
33: *
34: */
35:
36: #include "config.h"
37: #include "quipu/util.h"
38: #include "quipu/entry.h"
39: #include "quipu/ds_error.h"
40: #include "tailor.h"
41: #include <sys/stat.h>
42: #include <errno.h>
43:
44: extern char * treedir;
45: extern LLog * log_dsap;
46: extern int errno;
47: struct acl_info * acl_dflt ();
48:
49: static char filename [LINESIZE];
50: static PS ps;
51:
52: #define EDBLEN 3 /* length of string "EDB" */
53:
54: fileexists (fname)
55: char * fname;
56: {
57: struct stat buf;
58:
59: if (stat (fname,&buf) != 0) {
60: if (errno != ENOENT)
61: DLOG (log_dsap,LLOG_DEBUG,("File %s will not stat - %d",fname,errno));
62: return FALSE;
63: }
64: return TRUE;
65: }
66:
67: static read_mapped_rdn (aps,name,file)
68: PS aps;
69: char * name;
70: char * file;
71: {
72: FILE * mapfp;
73: char *ptr, *newname, *tmp, *getline();
74: extern int parse_line;
75: register int i;
76:
77: if ((mapfp = fopen (file,"r")) == (FILE *)NULL) {
78: LLOG(log_dsap,LLOG_EXCEPTIONS,("Can read \"%s\" (%d)",file,errno));
79: return FALSE;
80: }
81:
82: parse_line = 0;
83: while ( (ptr = getline(mapfp)) != NULLCP) {
84: if ((newname = rindex(ptr,'#')) == NULLCP) {
85: LLOG(log_dsap,LLOG_EXCEPTIONS,("Seperator missing in map file \"%s\", line %d",file,parse_line));
86: (void) fclose (mapfp);
87: return FALSE;
88: }
89: tmp = newname;
90: *newname++ = 0;
91: while (isspace(*--tmp))
92: *tmp = 0;
93:
94: if (lexequ (name,ptr) == 0) {
95: /* got it - replace in ps*/
96: i = strlen (name);
97: aps->ps_ptr -= i;
98: aps->ps_cnt += i;
99: ps_print (aps,SkipSpace(newname));
100: (void) fclose (mapfp);
101: return TRUE;
102: }
103: }
104:
105: DLOG (log_dsap, LLOG_DEBUG,("%s not found in map file %s",name,file));
106: (void) fclose (mapfp);
107: return FALSE;
108: }
109:
110: static write_mapped_rdn (aps,name,file)
111: PS aps;
112: char * name;
113: char * file;
114: {
115: FILE * mapfp;
116: char mapname[LINESIZE];
117: char sname[LINESIZE];
118: char *mptr, *nptr;
119: register int i;
120:
121: if (strlen(name) < MAXFILENAMELEN)
122: return FALSE;
123:
124: /* Make unique name for it */
125: mptr = mapname;
126: if ((nptr = index (name,'=')) == NULLCP)
127: return FALSE;
128:
129: for (i=0 ; (*nptr!=0) && (i < MAXFILENAMELEN-6) ; nptr++)
130: if (isalpha(*nptr))
131: *mptr++ = *nptr, i++;
132:
133: (void) strcpy (sname,name);
134: (void) strcpy (mptr,"XXXXXX");
135: i = strlen (name);
136: nptr = (aps->ps_ptr -= i);
137: aps->ps_cnt += i;
138: ps_print (aps,mapname);
139: *aps->ps_ptr = 0;
140:
141: if ((aps->ps_base = mktemp (aps->ps_base)) == NULLCP)
142: return FALSE;
143:
144: DLOG(log_dsap,LLOG_DEBUG,("mapped name %s",aps->ps_base));
145:
146: if (mkdir (aps->ps_base,0700) != 0) {
147: LLOG (log_dsap,LLOG_EXCEPTIONS,("map rdn mkdir failure \"%s\" (%d)",aps->ps_base,errno));
148: return FALSE;
149: }
150:
151: /* write it to map file */
152: if (fileexists(file))
153: mapfp = fopen (file,"a");
154: else {
155: int um;
156: um = umask (0177);
157: mapfp = fopen (file,"w");
158: (void) umask (um);
159: }
160:
161: if (mapfp == (FILE *)NULL) {
162: LLOG(log_dsap,LLOG_EXCEPTIONS,("Can't write to \"%s\" (%d)",file,errno));
163: return FALSE;
164: }
165:
166: if (fprintf (mapfp,"%s#%s\n",sname,nptr) == EOF) {
167: LLOG(log_dsap,LLOG_EXCEPTIONS,("Can't write to \"%s\" (%d)",file,errno));
168: return FALSE;
169: }
170:
171: if (fclose (mapfp) != 0) {
172: LLOG(log_dsap,LLOG_EXCEPTIONS,("Can't close \"%s\" (%d)",file,errno));
173: return FALSE;
174: }
175:
176: return TRUE;
177: }
178:
179: static rdn2filename (aps,rdn,make)
180: PS aps;
181: RDN rdn;
182: char make;
183: {
184: char *start = aps->ps_ptr;
185: char mapbuf [LINESIZE];
186:
187: /* look for EDB.map file */
188: *aps->ps_ptr = 0;
189: (void) sprintf (mapbuf, "%sEDB.map",aps->ps_base);
190:
191: rdn_print (aps,rdn,DIROUT);
192: *aps->ps_ptr = 0;
193:
194: if ((fileexists (mapbuf)) && (read_mapped_rdn (aps,start,mapbuf)))
195: return OK;
196: #ifdef SYS5
197: else if ( strlen(start) > MAXFILENAMELEN )
198: LLOG (log_dsap,LLOG_EXCEPTIONS,("Potential problem with \"%s\" (name too long)",start));
199: #endif
200:
201: if (fileexists(aps->ps_base))
202: return OK;
203:
204: if (make) {
205: if (write_mapped_rdn (aps,start,mapbuf))
206: return OK;
207: if (mkdir (aps->ps_base,0700) != 0) {
208: LLOG (log_dsap,LLOG_EXCEPTIONS,("dn2file mkdir failure \"%s\" (%d)",aps->ps_base,errno));
209: return NOTOK;
210: }
211: return OK;
212: }
213:
214: return NOTOK;
215: }
216:
217: static dn2filename (aps,dn,make)
218: PS aps;
219: DN dn;
220: char make;
221: {
222: if (treedir != NULLCP) {
223: ps_print (aps,isodefile(treedir,0));
224: if (make) {
225: *aps->ps_ptr = 0;
226: if ((! fileexists (aps->ps_base)) &&
227: (mkdir (aps->ps_base,0700) != 0)) {
228: LLOG (log_dsap,LLOG_EXCEPTIONS,("dn2file mkdir failure \"%s\" (%d)",aps->ps_base,errno));
229: return NOTOK;
230: }
231: }
232: if (*(aps->ps_ptr - 1) != '/')
233: ps_print (aps,"/");
234: } else
235: ps_print (aps,"./");
236:
237: if (dn != NULLDN) {
238: if (rdn2filename (aps,dn->dn_rdn,make) == NOTOK)
239: return NOTOK;
240: if (dn->dn_parent != NULLDN) {
241: DN eptr;
242: for (eptr = dn->dn_parent; eptr != NULLDN; eptr = eptr->dn_parent) {
243: ps_print (aps,"/");
244: if (rdn2filename (aps,eptr->dn_rdn,make) == NOTOK)
245: return NOTOK;
246: }
247: }
248: }
249:
250: return OK;
251:
252: }
253:
254: char * dn2edbfile (dn)
255: DN dn;
256: {
257: PS aps;
258: static char result [LINESIZE];
259:
260: if ((aps = ps_alloc (str_open)) == NULLPS) {
261: LLOG (log_dsap, LLOG_EXCEPTIONS, ("dn2dir ps_alloc failed"));
262: return NULLCP;
263: }
264: if (str_setup (aps,result,LINESIZE,1) == NOTOK) {
265: LLOG (log_dsap, LLOG_EXCEPTIONS, ("dn2dir ps_alloc failed"));
266: return NULLCP;
267: }
268:
269: if (dn2filename (aps,dn,TRUE) != OK)
270: return NULLCP;
271:
272: if (*(aps->ps_ptr - 1) != '/')
273: ps_print (aps,"/EDB");
274: else
275: ps_print (aps,"EDB");
276: *aps->ps_ptr = 0;
277:
278: ps_free (aps);
279:
280: return result;
281: }
282:
283: static file_check (offset,entryptr)
284: register int offset;
285: register Entry entryptr;
286: {
287: ps->ps_ptr = filename + offset;
288: ps->ps_cnt = LINESIZE - offset;
289:
290: if (rdn2filename (ps,entryptr->e_name,FALSE) == OK) {
291: if (*(ps->ps_ptr - 1) != '/')
292: ps_print (ps,"/EDB");
293: else
294: ps_print (ps,"EDB");
295: *ps->ps_ptr = 0;
296: return (OK);
297: }
298: return (NOTOK);
299: }
300:
301: static entry_load_kids (entryptr,offset)
302: register Entry entryptr;
303: register int offset;
304: {
305: register Entry ptr;
306:
307: ps->ps_ptr = filename + offset;
308: ps->ps_cnt = LINESIZE - offset;
309: *ps->ps_ptr = 0;
310:
311: for ( ptr = entryptr; ptr != NULLENTRY; ptr = ptr->e_sibling) {
312: if ((ptr->e_master == NULLAV) && (ptr->e_slave == NULLAV)) {
313: ptr->e_leaf = TRUE;
314: continue;
315: }
316:
317: if (file_check (offset,ptr) == OK) {
318: if ((ptr->e_child = getentry_block (ptr,filename)) == NULLENTRY)
319: return (NOTOK);
320:
321: ptr->e_leaf = FALSE;
322: if (entry_load_kids (ptr->e_child,strlen(filename) - EDBLEN) == NOTOK)
323: return (NOTOK);
324: } else
325: LLOG (log_dsap,LLOG_TRACE,("Sibling file %s/EDB NOT found", filename));
326: }
327: return (OK);
328:
329: }
330:
331:
332: Entry subtree_load (parent,dn)
333: Entry parent;
334: DN dn;
335: {
336: Entry treetop, temp, old_entry, sibl, find_sibling();
337:
338: if ((parent != NULLENTRY) && (parent->e_child != NULLENTRY))
339: if (parent->e_child->e_data != E_TYPE_CONSTRUCTOR)
340: return (parent->e_child);
341:
342: if ((ps = ps_alloc (str_open)) == NULLPS) {
343: LLOG (log_dsap, LLOG_EXCEPTIONS, ("file open ps_alloc failed"));
344: return (NULLENTRY);
345: }
346: if (str_setup (ps,filename,LINESIZE,1) == NOTOK) {
347: LLOG (log_dsap, LLOG_EXCEPTIONS, ("file open ps_alloc failed"));
348: return (NULLENTRY);
349: }
350:
351: (void) dn2filename (ps,dn,FALSE);
352: if (*(ps->ps_ptr - 1) != '/')
353: ps_print (ps,"/EDB");
354: else
355: ps_print (ps,"EDB");
356: *ps->ps_ptr = 0;
357:
358: if ((parent != NULLENTRY) && (parent->e_child != NULLENTRY)) {
359: /* yuk - already got an edb lower in the DIT ... */
360: treetop = getentry_block (parent,filename);
361:
362: for (temp = treetop; temp != NULLENTRY; temp=temp->e_sibling) {
363: temp->e_parent = parent;
364:
365: if ((old_entry = find_sibling (temp->e_name,parent->e_child)) != NULLENTRY) {
366: temp->e_leaf = FALSE;
367: temp->e_allchildrenpresent = old_entry->e_allchildrenpresent;
368: temp->e_child = old_entry->e_child;
369: for (sibl = temp->e_child; sibl != NULLENTRY; sibl=sibl->e_sibling)
370: sibl->e_parent = temp;
371: if (old_entry->e_edbversion != NULLCP)
372: temp->e_edbversion = strdup (old_entry->e_edbversion);
373: }
374:
375: }
376: for (temp = parent->e_child; temp != NULLENTRY; temp=old_entry) {
377: old_entry = temp->e_sibling;
378: entry_free (temp);
379: }
380:
381: parent->e_child = treetop;
382:
383: ps_free (ps);
384: return (treetop);
385: }
386:
387: if (dn == NULLDN) {
388: parent = get_default_entry (NULLENTRY);
389: parent->e_leaf = FALSE;
390: parent->e_acl = acl_alloc();
391: parent->e_acl->ac_child = acl_dflt ();
392: parent->e_acl->ac_entry = acl_dflt ();
393: parent->e_acl->ac_default = acl_dflt ();
394: if ((treetop = getentry_block (parent,filename)) == NULLENTRY)
395: return (NULLENTRY);
396: } else
397: treetop = getentry_block (parent,filename);
398:
399: parent->e_child = treetop;
400:
401: if (entry_load_kids (treetop,strlen (filename) - EDBLEN) == NOTOK)
402: return (NULLENTRY);
403:
404: ps_free (ps);
405:
406: if (dn == NULLDN)
407: return (parent); /* be wary of this when calling subtree load... */
408: /* if DN == NULL - you may want the child !!! */
409: else
410: return (treetop);
411: }
412:
413: refresh_from_disk(dn)
414: DN dn;
415: {
416: Entry parent;
417: Entry child;
418: Entry tmp;
419: extern Entry database_root;
420:
421: if ((parent = local_find_entry (dn,FALSE)) == NULLENTRY)
422: return (NOTOK);
423:
424: if (parent->e_data != E_DATA_MASTER) {
425: LLOG (log_dsap,LLOG_NOTICE, ("Can only refresh MASTER EDB files"));
426: return (NOTOK);
427: }
428:
429: child = parent->e_child;
430: parent->e_child = NULLENTRY;
431:
432: if ((tmp = subtree_load (parent,dn)) == NULLENTRY)
433: return (NOTOK);
434:
435: if (dn == NULLDN) {
436: database_root = tmp;
437: entry_free (parent);
438: }
439: directory_free (child);
440:
441: return (OK);
442: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.