|
|
1.1 ! root 1: /* cache.c - */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/dsap/common/RCS/cache.c,v 7.1 90/07/09 14:34:09 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/dsap/common/RCS/cache.c,v 7.1 90/07/09 14:34:09 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: cache.c,v $ ! 12: * Revision 7.1 90/07/09 14:34:09 mrose ! 13: * sync ! 14: * ! 15: * Revision 7.0 89/11/23 22:16:40 mrose ! 16: * Release 6.0 ! 17: * ! 18: */ ! 19: ! 20: /* ! 21: * NOTICE ! 22: * ! 23: * Acquisition, use, and distribution of this module and related ! 24: * materials are subject to the restrictions of a license agreement. ! 25: * Consult the Preface in the User's Manual for the full terms of ! 26: * this agreement. ! 27: * ! 28: */ ! 29: ! 30: ! 31: #include "quipu/util.h" ! 32: #include "quipu/dua.h" ! 33: #include "quipu/list.h" ! 34: #include "quipu/entry.h" ! 35: ! 36: extern LLog * log_dsap; ! 37: extern Entry database_root; ! 38: extern time_t time(); ! 39: extern int local_cache_size; ! 40: ! 41: struct list_cache *list_top = NULLCACHE; ! 42: Entry current_entry = NULLENTRY; ! 43: DN current_dn = NULLDN; ! 44: extern time_t cache_timeout; ! 45: ! 46: struct subordinate * subord_cpy (x) ! 47: struct subordinate * x; ! 48: { ! 49: struct subordinate * sub; ! 50: struct subordinate * y; ! 51: struct subordinate * top; ! 52: ! 53: if (x == NULLSUBORD) ! 54: return (x); ! 55: ! 56: top = (struct subordinate *) smalloc (sizeof(struct subordinate)); ! 57: top->sub_copy = x->sub_copy; ! 58: top->sub_rdn = rdn_cpy(x->sub_rdn); ! 59: top->sub_aliasentry = x->sub_aliasentry; ! 60: top->sub_next = NULLSUBORD; ! 61: y = top; ! 62: ! 63: for (x=x->sub_next; x != NULLSUBORD; x=x->sub_next) { ! 64: sub = (struct subordinate *) smalloc (sizeof(struct subordinate)); ! 65: sub->sub_copy = x->sub_copy; ! 66: sub->sub_rdn = rdn_cpy(x->sub_rdn); ! 67: sub->sub_aliasentry = x->sub_aliasentry; ! 68: sub->sub_next = NULLSUBORD; ! 69: y->sub_next = sub; ! 70: y = sub; ! 71: } ! 72: ! 73: return (top); ! 74: } ! 75: ! 76: /* ARGSUSED */ ! 77: cache_list (ptr, prob,dn,sizelimit) ! 78: struct subordinate *ptr; ! 79: int prob; ! 80: DN dn; ! 81: int sizelimit; ! 82: { ! 83: struct list_cache *cache; ! 84: struct subordinate *sub; ! 85: register int i; ! 86: ! 87: if ((cache = find_list_cache (dn,0)) == NULLCACHE) { ! 88: cache = (struct list_cache *) smalloc (sizeof (struct list_cache)); ! 89: cache->list_dn = dn_cpy (dn); ! 90: cache->list_subs = subord_cpy (ptr); ! 91: cache->list_sub_top = cache->list_subs; ! 92: cache->list_next = list_top; ! 93: cache->list_problem = prob; ! 94: list_top = cache; ! 95: } else { ! 96: subords_free (cache->list_sub_top); ! 97: cache->list_subs = subord_cpy (ptr); ! 98: cache->list_sub_top = cache->list_subs; ! 99: cache->list_problem = prob; ! 100: } ! 101: ! 102: for (i=0, sub=cache->list_subs; ! 103: sub != NULLSUBORD; ! 104: i++, sub = sub->sub_next); ! 105: cache->list_count = i; ! 106: ! 107: } ! 108: ! 109: delete_list_cache (adn) ! 110: DN adn; ! 111: { ! 112: DN dntop, trail = NULLDN; ! 113: struct list_cache *ptr, *lt = NULLCACHE; ! 114: ! 115: if (adn == NULLDN) ! 116: return; ! 117: ! 118: dntop = adn; ! 119: ! 120: for (; adn->dn_parent != NULLDN; adn=adn->dn_parent) ! 121: trail = adn; ! 122: ! 123: if (trail == NULLDN) ! 124: dntop = NULLDN; ! 125: else ! 126: trail->dn_parent = NULLDN; ! 127: ! 128: for (ptr = list_top; ptr != NULLCACHE; ptr = ptr->list_next) { ! 129: if (dn_cmp (ptr->list_dn, dntop) == 0) { ! 130: if (lt == NULLCACHE) ! 131: list_top = ptr->list_next; ! 132: else ! 133: lt->list_next = ptr->list_next; ! 134: subords_free(ptr->list_sub_top); ! 135: free ((char *)ptr); ! 136: if (trail != NULLDN) ! 137: trail->dn_parent = adn; ! 138: return; ! 139: } ! 140: lt = ptr; ! 141: } ! 142: if (trail != NULLDN) ! 143: trail->dn_parent = adn; ! 144: } ! 145: ! 146: struct list_cache *find_list_cache (dn,sizelimit) ! 147: DN dn; ! 148: int sizelimit; ! 149: { ! 150: struct list_cache *ptr; ! 151: int i; ! 152: for (ptr = list_top; ptr != NULLCACHE; ptr = ptr->list_next) ! 153: if (dn_cmp (ptr->list_dn, dn) == 0) ! 154: if ((ptr->list_problem == LSR_NOLIMITPROBLEM) ! 155: || ((ptr->list_count >= sizelimit) && (sizelimit != -1))) ! 156: { ! 157: ptr->list_subs = ptr->list_sub_top; ! 158: if (sizelimit == -1) ! 159: return (ptr); ! 160: /* only want sizelimit of them */ ! 161: for (i=ptr->list_count - sizelimit; i>0; i--) ! 162: ptr->list_subs = ptr->list_subs->sub_next; ! 163: return (ptr); ! 164: } ! 165: ! 166: return (NULLCACHE); ! 167: } ! 168: ! 169: ! 170: ! 171: cache_entry (ptr, complete, vals) ! 172: EntryInfo *ptr; ! 173: char complete; ! 174: char vals; ! 175: { ! 176: Entry make_path (); ! 177: DN dnptr; ! 178: extern oid_table_attr * tab_alias; ! 179: Attr_Sequence as, as_merge_aux(); ! 180: ! 181: /* use e_lock to indicate if values are present */ ! 182: ! 183: if (ptr->ent_dn == NULLDN) ! 184: return; ! 185: ! 186: dn_free (current_dn); ! 187: ! 188: current_dn = dn_cpy (ptr->ent_dn); ! 189: ! 190: for (dnptr = current_dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) ! 191: ; ! 192: ! 193: if ((current_entry = local_find_entry (current_dn, FALSE)) != NULLENTRY) { ! 194: current_entry->e_age = time((time_t *)0); ! 195: if (vals && complete) { ! 196: as_free (current_entry->e_attributes); ! 197: current_entry->e_attributes = as_cpy(ptr->ent_attr); ! 198: current_entry->e_lock = vals; ! 199: current_entry->e_complete = complete; ! 200: } else if (!current_entry->e_complete) { ! 201: current_entry->e_complete = complete; ! 202: current_entry->e_attributes = as_merge_aux (current_entry->e_attributes, as_cpy(ptr->ent_attr)); ! 203: if (vals != current_entry->e_lock) ! 204: current_entry->e_lock = FALSE; ! 205: } else if ((!current_entry->e_lock) & vals) { ! 206: current_entry->e_attributes = as_merge_aux (current_entry->e_attributes, as_cpy(ptr->ent_attr)); ! 207: } ! 208: } else { ! 209: current_entry = make_path (current_dn); ! 210: /* ! 211: current_entry->e_name = rdn_cpy (dnptr->dn_rdn); ! 212: */ ! 213: current_entry->e_complete = complete; ! 214: current_entry->e_data = E_TYPE_CACHE_FROM_MASTER; ! 215: current_entry->e_age = time((time_t *)0); ! 216: current_entry->e_lock = vals; ! 217: current_entry->e_attributes = as_cpy(ptr->ent_attr); ! 218: local_cache_size++; ! 219: } ! 220: ! 221: /* insert alias pointers */ ! 222: for ( as = current_entry->e_attributes; as != NULLATTR; as = as->attr_link) { ! 223: if (as->attr_type == tab_alias) ! 224: if (as->attr_value) ! 225: current_entry->e_alias = (DN) as->attr_value->avseq_av.av_struct; ! 226: } ! 227: } ! 228: ! 229: ! 230: delete_cache (adn) ! 231: DN adn; ! 232: { ! 233: Entry ptr; ! 234: ! 235: delete_list_cache (adn); ! 236: ! 237: if ((ptr = local_find_entry (adn, FALSE)) != NULLENTRY) { ! 238: if (ptr->e_data == E_TYPE_CACHE_FROM_MASTER) { ! 239: local_cache_size--; ! 240: if (ptr->e_child != NULLENTRY) { ! 241: ptr->e_data = E_TYPE_CONSTRUCTOR; ! 242: ptr->e_complete = FALSE; ! 243: as_free (ptr->e_attributes); ! 244: ptr->e_attributes = NULLATTR; ! 245: } else if ( ptr->e_parent->e_child == ptr ) { ! 246: ptr->e_parent->e_child = ptr->e_sibling; ! 247: entry_free (ptr); ! 248: } else { ! 249: Entry tmp; ! 250: for (tmp=ptr->e_parent->e_child; tmp != NULLENTRY; tmp=tmp->e_sibling) { ! 251: if (tmp->e_sibling == ptr) ! 252: break; ! 253: } ! 254: tmp->e_sibling = ptr->e_sibling ; ! 255: entry_free (ptr); ! 256: } ! 257: } ! 258: } ! 259: } ! 260: ! 261: ! 262: Entry local_find_entry (object,deref) ! 263: DN object; ! 264: char deref; ! 265: { ! 266: Entry the_entry; ! 267: register RDN a_rdn, b_rdn; ! 268: DN dn; ! 269: ! 270: DLOG (log_dsap,LLOG_TRACE,("local find entry")); ! 271: ! 272: if (database_root == NULLENTRY) ! 273: return (NULLENTRY); ! 274: ! 275: if ((dn = object) == NULLDN) ! 276: return (database_root); ! 277: ! 278: b_rdn = dn->dn_rdn; ! 279: if ((the_entry = database_root->e_child) == NULLENTRY) ! 280: return (NULLENTRY); ! 281: ! 282: a_rdn = the_entry->e_name ; ! 283: ! 284: for(;;) { /* break or return out */ ! 285: while (rdn_cmp (a_rdn, b_rdn) != OK) { ! 286: the_entry = the_entry->e_sibling ; ! 287: if ( the_entry == NULLENTRY ) ! 288: return (NULLENTRY); ! 289: a_rdn = the_entry->e_name ; ! 290: } ! 291: ! 292: if ( the_entry->e_alias != NULLDN ) ! 293: /* got an alias entry */ ! 294: if (deref) { ! 295: Entry new_entry; ! 296: if (dn_cmp (the_entry->e_alias,object) == 0) ! 297: return (NULLENTRY); ! 298: new_entry = local_find_entry (the_entry->e_alias,deref); ! 299: if (new_entry == NULLENTRY ) ! 300: return (NULLENTRY); ! 301: the_entry = new_entry; ! 302: } else if ( dn->dn_parent == NULLDN) { ! 303: if ((the_entry->e_data == E_TYPE_CACHE_FROM_MASTER) ! 304: && (time((time_t *)0) - the_entry->e_age > cache_timeout)) ! 305: return (NULLENTRY); ! 306: else ! 307: return (the_entry); /* found it !!! */ ! 308: } else ! 309: return (NULLENTRY); ! 310: ! 311: if ( dn->dn_parent == NULLDN) { ! 312: if ((the_entry->e_data == E_TYPE_CACHE_FROM_MASTER) ! 313: && (time((time_t *)0) - the_entry->e_age > cache_timeout)) ! 314: return (NULLENTRY); ! 315: else ! 316: return (the_entry); /* found it !!! */ ! 317: } ! 318: ! 319: dn = dn->dn_parent; ! 320: b_rdn = dn->dn_rdn; ! 321: ! 322: if ( the_entry->e_child == NULLENTRY ) ! 323: return (NULLENTRY); ! 324: ! 325: the_entry = the_entry->e_child; ! 326: a_rdn = the_entry->e_name; ! 327: } ! 328: /* NOTREACHED */ ! 329: } ! 330: ! 331: ! 332: DN get_copy_dn (entryptr) ! 333: Entry entryptr; ! 334: { ! 335: DN dn; ! 336: DN dnptr; ! 337: Entry ptr; ! 338: ! 339: if ((entryptr == NULLENTRY) || (entryptr->e_parent == NULL)) ! 340: return NULLDN; ! 341: ! 342: dn = dn_comp_new (rdn_cpy (entryptr->e_name)); ! 343: for (ptr = entryptr->e_parent; ptr->e_parent != NULLENTRY; ptr = ptr->e_parent) { ! 344: dnptr = dn_comp_new (rdn_cpy (ptr->e_name)); ! 345: dnptr->dn_parent = dn; ! 346: dn = dnptr; ! 347: } ! 348: ! 349: return (dn); ! 350: } ! 351: ! 352: ! 353: IFP unrav_fn = NULLIFP; ! 354: IFP schema_fn = NULLIFP; ! 355: ! 356: unravel_attribute (eptr,error) ! 357: Entry eptr; ! 358: struct DSError * error; ! 359: { ! 360: if (unrav_fn == NULLIFP) ! 361: return (OK); ! 362: else ! 363: return ((*unrav_fn)(eptr,error)); ! 364: } ! 365: ! 366: check_schema (eptr,as,error) ! 367: Entry eptr; ! 368: Attr_Sequence as; ! 369: struct DSError * error; ! 370: { ! 371: if (schema_fn == NULLIFP) ! 372: return (OK); ! 373: else ! 374: return ((*schema_fn)(eptr,as,error)); ! 375: } ! 376: ! 377: ! 378: char * new_version () ! 379: { ! 380: long clock; ! 381: struct UTCtime ut; ! 382: extern time_t time(); ! 383: ! 384: (void) time (&clock); ! 385: tm2ut (gmtime (&clock),&ut); ! 386: return (strdup(utct2str(&ut))); ! 387: } ! 388:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.