示例#1
0
文件: acltools.cpp 项目: Firstyear/ds
NSAPI_PUBLIC void
ACL_ListDestroy(NSErr_t *errp, ACLListHandle_t *acl_list )
{
    ACLWrapper_t    *wrapper;
    ACLWrapper_t    *tmp_wrapper;
    ACLHandle_t     *tmp_acl;


    if ( acl_list == NULL )
        return;

    if ( acl_list->acl_sym_table ) {
        /* Destroy each entry in the symbol table */
        symTableEnumerate(acl_list->acl_sym_table, 0, acl_hash_entry_destroy);
        /* Destory the hash table itself */
        symTableDestroy(acl_list->acl_sym_table, 0);
    }

    ACL_EvalDestroyContext( (ACLListCache_t *)acl_list->cache );

    wrapper = acl_list->acl_list_head;
    
    while ( wrapper ) {
        tmp_acl = wrapper->acl;
        tmp_wrapper = wrapper;
        wrapper = wrapper->wrap_next;
        PERM_FREE( tmp_wrapper );
        ACL_AclDestroy(errp, tmp_acl );
    }

    PERM_FREE( acl_list );

    return;
}
/** **************************************************************************
 * Callback used from handle_purge_timeout(). Called for each element in
 * hashtable. Checks whether the element is too old since last use compared
 * to the purge_timeout.   See also
 * http://www.mozilla.org/projects/nspr/reference/html/plhash.html#35195
 *
 * Params:
 *   he: See 
 *       http://www.mozilla.org/projects/nspr/reference/html/plhash.html#35106
 *   index: Index of this element. Not used.
 *   arg: Used by handle_purge_timeout() to pass in a time_t of current time.
 *
 * Returns:
 *   HT_ENUMERATE_REMOVE: If element too old, free the key and value and 
 *        return this value which causes the hashtable to remove the 
 *        entry itself.
 *   HT_ENUMERATE_NEXT: If not too old, do nothing and return this.
 *
 */
static PRIntn cleaner_enum(PLHashEntry *he, PRIntn index, void *arg)
{
    assert(he != NULL);
    assert(arg != NULL);

    ht_entries++;

    int conc = ((bucket_info *)(he->value))->conc;
    if (conc > 0) {
        // Don't purge buckets where conc>0 because that means a request
        // is still ongoing and has a reference to this bucket. (This
        // shouldn't really happen unless a request is very slow or the
        // purge timeout is far too low, but it could.)
        return HT_ENUMERATE_NEXT;
    }

    time_t age = *((time_t *)arg) - ((bucket_info *)(he->value))->time;

    if (age > purge_timeout) {
        ereport(LOG_VERBOSE, 
                "check-request-limits: Removing expired entry for [%s]", 
                (char *)(he->key));
        PERM_FREE(he->value);
        PERM_FREE((void *)(he->key));
        ht_expired++;
        return HT_ENUMERATE_REMOVE;
    }

    return HT_ENUMERATE_NEXT;
}
示例#3
0
文件: acltools.cpp 项目: Firstyear/ds
NSAPI_PUBLIC int
ACL_ExprSetDenyWith( NSErr_t *errp, ACLExprHandle_t *expr, char *deny_type, char *deny_response)
{
int rv;

    if ( expr->expr_argc == 0 ) {
       if ( (rv = ACL_ExprAddArg(errp, expr, deny_type)) < 0 ) 
           return(rv);
       if ( (rv = ACL_ExprAddArg(errp, expr, deny_response)) < 0 ) 
           return(rv);
    } else if ( expr->expr_argc == 2 ) {
       if ( deny_type ) {
           if ( expr->expr_argv[0] ) 
               PERM_FREE(expr->expr_argv[0]);
           expr->expr_argv[0] = PERM_STRDUP(deny_type);
           if ( expr->expr_argv[0] == NULL )
               return(ACLERRNOMEM);
       }
       if ( deny_response ) {
           if ( expr->expr_argv[1] ) 
               PERM_FREE(expr->expr_argv[1]);
           expr->expr_argv[1] = PERM_STRDUP(deny_response);
           if ( expr->expr_argv[0] == NULL )
               return(ACLERRNOMEM);
       }
    } else {
        return(ACLERRINTERNAL);
    }
    return(0);
}
示例#4
0
文件: acltools.cpp 项目: Firstyear/ds
NSAPI_PUBLIC void
ACL_AclDestroy(NSErr_t *errp, ACLHandle_t *acl )
{
ACLExprHandle_t    *handle;
ACLExprHandle_t    *tmp;

    if ( acl == NULL )
        return;

    acl->ref_count--;

    if ( acl->ref_count )
        return;

    if ( acl->tag )
        PERM_FREE( acl->tag );

    if ( acl->las_name )
        PERM_FREE( acl->las_name );

    if ( acl->attr_name )
        PERM_FREE( acl->attr_name );

    handle = acl->expr_list_head;
    while ( handle ) {
        tmp = handle;
        handle = handle->expr_next;
        ACL_ExprDestroy( tmp );
    }

    PERM_FREE(acl);

    return;
}
NSAPI_PUBLIC void 
cache_destroy(void *cache_ptr)
{
	cache_t *cache = (cache_t *)cache_ptr;
	cache_t *search, *last;
	cache_entry_t *ptr;
SOLARIS_PROBE(cache_destroy_start, "cache");

#ifdef IRIX
        NS_ASSERT(!cache->fast_mode);
#endif

	NS_ASSERT(cache_crit);
	NS_ASSERT(cache_ptr);
#ifdef CACHE_DEBUG
	NS_ASSERT(cache->magic == CACHE_MAGIC);
#endif

	crit_enter(cache_crit);
	crit_enter(cache->lock);

	ptr = cache->lru_head;
	while(ptr) {
		/* Caller MUST bump the access_count before calling delete
		 * We can do this since we hold the cache lock.  
		 */
		cache_use_increment(cache, ptr);
		cache_delete(cache, ptr, 0);
		ptr = cache->lru_head;
	}

	PERM_FREE(cache->table);

	cache->max_size = 0;
	cache->hash_size = 0;

	for ( last = NULL, search = cache_list; search; last = search,
		search = search->next)
		if (search == cache)
			break;

	if (search) {
		if (last) 
			last->next = search->next;
		else
			cache_list = search->next;
	}
	else {
		ereport(LOG_WARN, XP_GetAdminStr(DBT_cacheDestroyCacheTablesAppearCor_));
	}
	crit_exit(cache_crit);
	crit_exit(cache->lock);

	crit_terminate(cache->lock);

	PERM_FREE(cache);
SOLARIS_PROBE(cache_destroy_end, "cache");
}
NSAPI_PUBLIC int
ACL_ListPostParseForAuth(NSErr_t *errp, ACLListHandle_t *acl_list ) 
{
    ACLHandle_t *acl;
    ACLWrapper_t *wrap;
    ACLExprHandle_t *expr;
    char *method;
    char *database;
    int rv;
    ACLDbType_t *dbtype;
    ACLMethod_t *methodtype;

    if ( acl_list == NULL )
        return(0);

    // for all ACLs
    for ( wrap = acl_list->acl_list_head; wrap; wrap = wrap->wrap_next ) {

        acl = wrap->acl;
        if ( acl == NULL )
            continue;

        // for all expressions with the ACL
        for ( expr = acl->expr_list_head; expr; expr = expr->expr_next ) {

            if ( expr->expr_type != ACL_EXPR_TYPE_AUTH || expr->expr_auth == NULL) 
                continue;

            // get method attribute - this is a name now
            rv = PListGetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX, (void **) &method, NULL);
            if ( rv >= 0 ) {
		methodtype = (ACLMethod_t *)PERM_MALLOC(sizeof(ACLMethod_t));
		rv = ACL_MethodFind(errp, method, methodtype);
		if (rv < 0) {
		    nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
				  3, acl->tag, "method", method);
		    PERM_FREE(methodtype);
		    return(ACLERRUNDEF);
		}

                // replace it with a method type
	        rv = PListSetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX, methodtype, NULL);
		if ( rv < 0 ) {
		    nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program, 0);
		    return(ACLERRNOMEM);
		}
		PERM_FREE(method);
	    }
        }
    }
    return(0);
}
示例#7
0
文件: acltools.cpp 项目: Firstyear/ds
NSAPI_PUBLIC int
ACL_NameListDestroy(NSErr_t *errp, char **name_list)
{
    int			list_index;

    if ( name_list == NULL )
        return(ACLERRUNDEF);

    for ( list_index = 0; name_list[list_index]; list_index++ ) {
        PERM_FREE(name_list[list_index]);
    }
    PERM_FREE(name_list);
    return(0);
}
NSAPI_PUBLIC void session_free(Session *sn)
{
    NSAPISession *nsn = (NSAPISession *) sn;

    // If this session was cloned,
    // Remove any filters that were installed during this session
    if (nsn->session_clone && sn->csd && sn->csd_open)
        filter_finish_response(sn);

    INTsession_cleanup(sn);
    if (sn->inbuf)
      netbuf_close(sn->inbuf);

    if (nsn->session_clone) {
        if (sn->csd && sn->csd_open)
            PR_Close(sn->csd);
        sn->csd = NULL;
        sn->csd_open = 0;

        pool_free(sn->pool, sn);
    } else {
        systhread_setdata(getThreadMallocKey(), NULL);
        pool_destroy(sn->pool);

        PERM_FREE(sn);
    }
}
NSAPI_PUBLIC cache_entry_t *
cache_insert(cache_t *cache, void *key, void *data, cache_entry_functions_t *fn)
{
	cache_entry_t *newentry;

SOLARIS_PROBE(cache_insert_start, "cache");
	NS_ASSERT(cache_crit);
	NS_ASSERT(cache);
#ifdef CACHE_DEBUG
	NS_ASSERT(cache->magic == CACHE_MAGIC);
#endif

	if ( (newentry = cache_create_entry()) == NULL) {
		ereport(LOG_FAILURE, XP_GetAdminStr(DBT_cacheInsertUnableToCreateCacheEn_));
SOLARIS_PROBE(cache_insert_end, "cache");
		return NULL;
	}

	if ( cache_insert_p(cache, newentry, key, data, fn) < 0) {
		PERM_FREE(newentry);
SOLARIS_PROBE(cache_insert_end, "cache");
		return NULL;
	}


SOLARIS_PROBE(cache_insert_end, "cache");
	return newentry;
}
NSAPI_PUBLIC int INTnet_buffer_input(SYS_NETFD sd, int sz)
{
    NetLayer *nl = _netlayer_find(sd);
    if (nl) {
        if (sz > nl->maxsize) {
            void *inbuf = PERM_REALLOC(nl->inbuf, sz);
            if (!inbuf)
                return -1;

            nl->inbuf = (char *) inbuf;
        }

        nl->maxsize = sz;

        return 0;
    }

    nl = (NetLayer *) PERM_MALLOC(sizeof(NetLayer));
    if (!nl)
        return -1;

    nl->pos = 0;
    nl->cursize = 0;
    nl->maxsize = sz;
    nl->inbuf = (char *) PERM_MALLOC(sz);
    if (!nl->inbuf) {
        PERM_FREE(nl);
        return -1;
    }

    PRFileDesc *layer = PR_CreateIOLayerStub(_netlayer_identity, &_netlayer_methods);
    if (!layer) {
        PERM_FREE(nl->inbuf);
        PERM_FREE(nl);
        return -1;
    }

    layer->secret = (PRFilePrivate *) nl;

    PRStatus rv = PR_PushIOLayer(sd, PR_NSPR_IO_LAYER, layer);
    if (rv != PR_SUCCESS) {
        PR_Close(layer);
        return -1;
    }

    return 0;
}
NSAPI_PUBLIC dns_cache_entry_t *
dns_cache_insert(char *host, unsigned int ip, unsigned int verified)
{
	dns_cache_entry_t *newentry;

	if ( !dns_cache || !ip)  {
		return NULL;
    }

	if ( (newentry = (dns_cache_entry_t *)PERM_MALLOC(sizeof(dns_cache_entry_t))) == NULL) {
		ereport(LOG_FAILURE, XP_GetAdminStr(DBT_dnsCacheInsertErrorAllocatingEnt_));
		goto error;
	}

	if (host) {
		if ( (newentry->host = PERM_STRDUP(host)) == NULL) {
			ereport(LOG_FAILURE, XP_GetAdminStr(DBT_dnsCacheInsertMallocFailure_));
			goto error;
		}
	} else
		newentry->host = NULL;

#ifdef CACHE_DEBUG
	newentry->cache.magic = CACHE_ENTRY_MAGIC;
#endif

	newentry->ip = ip;
	newentry->verified = verified;

	newentry->last_access = ft_time();

	if ( cache_insert_p(dns_cache, &(newentry->cache), (void *)&(newentry->ip), 
		(void *)newentry, &dns_cache_entry_functions) < 0) {
		/* Not a bad error; it just means the cache is full */
		goto error;
	}

	return newentry;

error:
	if (newentry) {
		if (newentry->host)
			PERM_FREE(newentry->host);
		PERM_FREE(newentry);
	}
	return NULL;
}
PRStatus _netlayer_method_close(PRFileDesc *fd)
{
    NetLayer *nl = (NetLayer *) fd->secret;
    fd->secret = NULL;

    PRStatus rv = _netlayer_default_close_method(fd);

    /*
     * Because an uncancelled IO might have been pending on a Win32 IO
     * completion port, we can't free nl->inbuf until after the socket has
     * been closed
     */
    PERM_FREE(nl->inbuf);
    PERM_FREE(nl);

    return rv;
}
示例#13
0
文件: fsmutex.cpp 项目: Firstyear/ds
static void 
_fsmutex_delete(fsmutex_s *fsm)
{
    if(fsm->flags & FSMUTEX_VISIBLE)
        unlink(fsm->id);
    PERM_FREE(fsm->id);
    PR_Close(fsm->mutex);
}
示例#14
0
文件: acltools.cpp 项目: Firstyear/ds
static
int acl_hash_entry_destroy(Symbol_t * sym, void * argp)
{
    if (sym != 0) {

        /* Free the acl name string if any */
        if (sym->sym_name != 0) {
            PERM_FREE(sym->sym_name);
        }

        /* Free the Symbol_t structure */
        PERM_FREE(sym);
    }

    /* Indicate that the symbol table entry should be removed */
    return SYMENUMREMOVE;
}
/* cache_free_entry()
 * free a cache entry created by cache_create_entry()
 * which has not been added to the cache. if the entry
 * already been added to the cache, do not use this function
 * (use cache_delete() instead). this function is added here
 * to help free a newly created cache entry which for some
 * reason is not going to be added to the cache.
 */
void
cache_free_entry(cache_entry_t * entry)
{
        NS_ASSERT(entry);
#ifdef CACHE_DEBUG
	NS_ASSERT(entry->magic == CACHE_ENTRY_MAGIC);
#endif
        PERM_FREE(entry);
    
}
/*    LASIpFlush
 *    Deallocates any memory previously allocated by the LAS
 */
void
LASIpFlush(void **las_cookie)
{
    if (*las_cookie    == NULL)
        return;

    LASIpTreeDealloc(((LASIpContext_t *)*las_cookie)->treetop);
    PERM_FREE(*las_cookie);
    *las_cookie = NULL;
    return;
}
示例#17
0
文件: fsmutex.cpp 项目: Firstyear/ds
NSAPI_PUBLIC void
fsmutex_terminate(FSMUTEX id)
{
    fsmutex_s *fsm = (fsmutex_s *) id;

    _fsmutex_delete(fsm);
#ifdef THREAD_ANY
    if(fsm->flags & FSMUTEX_NEEDCRIT)
        crit_terminate(fsm->crit);
#endif
    PERM_FREE(fsm);
}
// free up poll manager resources
void 
PollManager::Freeup()
{
    if (this->threads_)
    {
        for (PRUint32 i = 0; i < this->numThreads_; i++)
            delete threads_[i];
        PERM_FREE(this->threads_);
        this->threads_ = NULL;
        this->numThreads_ = 0;
    }
}
示例#19
0
文件: lasdns.cpp 项目: Firstyear/ds
/*  LASDnsFlush
 *  Given the address of a las_cookie for a DNS expression entry, frees up
 *  all allocated memory for it.  This includes the hash table, plus the
 *  context structure.
 */
void
LASDnsFlush(void **las_cookie)
{
    if (*las_cookie == NULL)
        return;

    pool_destroy(((LASDnsContext_t *)*las_cookie)->pool);
    PR_HashTableDestroy(((LASDnsContext_t *)*las_cookie)->Table);
    PERM_FREE(*las_cookie);
    *las_cookie = NULL;
    return;
}
/*
 * Destroys an ACL List
 *
 * Input:
 *    acl_list		target list
 */
NSAPI_PUBLIC void
ACL_ListDestroy(NSErr_t *errp, ACLListHandle_t *acl_list )
{
    ACLWrapper_t    *wrapper;
    ACLWrapper_t    *tmp_wrapper;
    ACLHandle_t     *tmp_acl;

    // nothing to do?
    if ( acl_list == NULL )
        // nothing to do.
        return;

    if (acl_list->ref_count != 0) {
        NS_ASSERT(acl_list->ref_count == 0);
    }

    if ( acl_list->acl_sym_table ) {
        /* Destroy each entry in the symbol table */
        symTableEnumerate(acl_list->acl_sym_table, 0, acl_hash_entry_destroy);
        /* Destory the hash table itself */
        symTableDestroy(acl_list->acl_sym_table, 0);
    }

    // destroy evaluation cache (if there)
    ACL_EvalDestroyContext( (ACLListCache_t *)acl_list->cache );

    wrapper = acl_list->acl_list_head;
    
    while ( wrapper ) {
        tmp_acl = wrapper->acl;
        tmp_wrapper = wrapper;
        wrapper = wrapper->wrap_next;
        PERM_FREE( tmp_wrapper );
        ACL_AclDestroy(errp, tmp_acl );
    }

    PERM_FREE( acl_list );

    return;
}
示例#21
0
文件: acltools.cpp 项目: Firstyear/ds
NSAPI_PUBLIC void
ACL_ExprDestroy( ACLExprHandle_t *expr )
{
int    ii;

    if ( expr == NULL )
        return;

    if ( expr->expr_tag )
        PERM_FREE( expr->expr_tag );

    if ( expr->expr_argv ) {
        for ( ii = 0; ii < expr->expr_argc; ii++ )
            if ( expr->expr_argv[ii] )
                PERM_FREE( expr->expr_argv[ii] );
        PERM_FREE( expr->expr_argv );
    }

    for ( ii = 0; ii < expr->expr_term_index; ii++ )
        ACL_ExprEntryDestroy( &expr->expr_arry[ii] );

    if ( expr->expr_auth ) {
	PListEnumerate(expr->expr_auth, acl_expr_auth_destroy, NULL);
        PListDestroy(expr->expr_auth);
    }

    PERM_FREE( expr->expr_arry );
    PERM_FREE( expr->expr_raw );

    PERM_FREE( expr );

    return;
}
示例#22
0
文件: acltools.cpp 项目: Firstyear/ds
static void
ACL_ExprEntryDestroy( ACLExprEntry_t *entry )
{
    LASFlushFunc_t flushp;
    
    if ( entry == NULL )
        return;
    
    if ( entry->las_cookie )
/*	freeLAS(NULL, entry->attr_name, &entry->las_cookie);		*/
    {
	ACL_LasFindFlush( NULL, entry->attr_name, &flushp );
	if ( flushp )
	    ( *flushp )( &entry->las_cookie );
    }

    if ( entry->attr_name )
        PERM_FREE( entry->attr_name );

    if ( entry->attr_pattern )
        PERM_FREE( entry->attr_pattern );

    return;
}
示例#23
0
文件: acltools.cpp 项目: Firstyear/ds
NSAPI_PUBLIC ACLHandle_t *
ACL_AclNew(NSErr_t *errp, char *tag )
{
ACLHandle_t *handle;

    handle = ( ACLHandle_t * ) PERM_CALLOC ( 1 * sizeof (ACLHandle_t) );
    if ( handle && tag ) {
        handle->tag = PERM_STRDUP( tag );    
        if ( handle->tag == NULL ) {
            PERM_FREE(handle);
            return(NULL);
        }
    }
    return(handle);
}
示例#24
0
文件: fsmutex.cpp 项目: Firstyear/ds
NSAPI_PUBLIC FSMUTEX
fsmutex_init(char *name, int number, int flags)
{
    fsmutex_s *ret = (fsmutex_s *) PERM_MALLOC(sizeof(fsmutex_s));

    ret->flags = flags;
    if(_fsmutex_create(ret, name, number) == -1) {
        PERM_FREE(ret);
        return NULL;
    }
#ifdef THREAD_ANY
    if(flags & FSMUTEX_NEEDCRIT)
        ret->crit = crit_init();
#endif
    return (FSMUTEX) ret;
}
static int 
dns_cache_cleanup(void *voiddata)
{
	dns_cache_entry_t *data = (dns_cache_entry_t *)voiddata;

	if (!dns_cache || !data)
		return -1;

	if (data->host)
		PERM_FREE(data->host);

	/* It is imperative that we do not FREE the dns_cache_entry_t (data)
     * structure here.  cache_delete() will do that for us.
     */

	return 0;
}
NSAPI_PUBLIC void
cache_collect_garbage(cache_t *cache)
{
  unsigned int now;
  cache_entry_t	*ptr, *last;

  NS_ASSERT(cache_crit);
  NS_ASSERT(cache);
#ifdef CACHE_DEBUG
  NS_ASSERT(cache->magic == CACHE_MAGIC);
#endif

  if(!cache->fast_mode)
    return;

  now = ft_time();
  if(now - cache->gc_time < GC_INTERVAL)
    return;

  crit_enter(cache->lock);

  last = NULL;
  ptr = cache->garbage_list_head;
  while(ptr) {
    NS_ASSERT(ptr->delete_pending);
    if((ptr->delete_time + SAFE_INTERVAL < now) && (ptr->access_count == 0)) {
      if(last)
	last->next_deleted = ptr->next_deleted;
      else
	cache->garbage_list_head = ptr->next_deleted;

      ptr->fn_list->cleanup_fn(ptr->data);
      PERM_FREE(ptr);

      ptr = (last) ? (last->next_deleted) : (cache->garbage_list_head);

    } else {
      last = ptr;
      ptr = ptr->next_deleted;
    }
  }

  crit_exit(cache->lock);
  cache->gc_time = now;
}
示例#27
0
文件: acltools.cpp 项目: Firstyear/ds
static Symbol_t *
acl_sym_new(ACLHandle_t *acl)
{
    Symbol_t *sym;
    /* It's not there, so add it */
    sym = (Symbol_t *) PERM_MALLOC(sizeof(Symbol_t));
    if ( sym == NULL ) 
        return(NULL);

    sym->sym_name = PERM_STRDUP(acl->tag);
    if ( sym->sym_name == NULL ) {
        PERM_FREE(sym);
        return(NULL);
    }

    sym->sym_type = ACLSYMACL;
    sym->sym_data = (void *) acl;
    return(sym);

}
/*    LASIpTreeDealloc
 *    Deallocates a Tree starting from a given node down.
 *    INPUT
 *    startnode    Starting node to remove.  Could be a constant in 
 *            which case, just return success.
 *    OUTPUT
 *    N/A
 */
static void
LASIpTreeDealloc(LASIpTree_t *startnode)
{
    int    i;

    if (startnode == NULL)
        return;

    /* If this is just a constant then we're done             */
    if (LAS_IP_IS_CONSTANT(startnode))
        return;

    /* Else recursively call ourself for each branch down        */
    for (i=0; i<2; i++) {
        if (!(LAS_IP_IS_CONSTANT(startnode->action[i])))
            LASIpTreeDealloc(startnode->action[i]);
    }

    /* Now deallocate the local node                */
    PERM_FREE(startnode);
}
/*
 * Caller can pass dec_hits as 1 or 0:
 * If dec_hits is non-zero, the cache_hits will be decremented on return.
 * Caller should only specify non-zero dec_hits when the caller has 
 * incremented the cache_hits while the entry handle is obtained (eg. by 
 * doing lookup). Only use non-zero dec_hits when caller found the entry
 * data become invalid and cannot count as a cache hit
 */
NSAPI_PUBLIC int
cache_delete(cache_t *cache, cache_entry_t *entry, int dec_hits)
{
	int bucket;
	cache_entry_t *ptr, *last;

SOLARIS_PROBE(cache_delete_try_start, "cache");
	NS_ASSERT(cache);
	NS_ASSERT(entry);
#ifdef CACHE_DEBUG
	NS_ASSERT(cache->magic == CACHE_MAGIC);
	NS_ASSERT(entry->magic == CACHE_ENTRY_MAGIC);
#endif
	NS_ASSERT(cache_crit);

	/* the caller is supposed to bump access count to before calling us.  
	 * If the count is less than 1, something is wrong...
	 */
	NS_ASSERT(entry->access_count >= 1);

	crit_enter(cache->lock);

	entry->delete_pending = 1;
        if (dec_hits) {
            NS_ASSERT(cache->cache_hits > 0);
            cache->cache_hits--;
        }

	/* Check the access_count now that we have the lock.  If
	 * we got context switched just after we checked, it is possible
	 * that someone else is now using the entry.
	 */
	if (entry->access_count > 1) {
		crit_exit(cache->lock);
SOLARIS_PROBE(cache_delete_try_end, "cache");
		return -1;
	}

SOLARIS_PROBE(cache_delete_start, "cache");
	/* Delete from the hash table */
	bucket = cache->virtual_fn->hash_fn(cache->hash_size, entry->key);
	for (last = NULL, ptr = cache->table[bucket]; ptr; 
		last = ptr, ptr= ptr->next)
		if (entry == ptr)
			break;
	NS_ASSERT(ptr);
	if (ptr) {
		if (last)
			last->next = ptr->next;
		else
			cache->table[bucket] = ptr->next;
	}
	cache->cache_size--;

	/* don't need to remove from the MRU/LRU list because
	 * the access count is > 0 in order to call delete 
	 */

	/* Technically, someone else could kill the whole cache
	 * right now, and we would be left with a bum pointer.   XXXMB
	 */
	entry->fn_list->cleanup_fn(entry->data);

    cache->deletes++;
	crit_exit(cache->lock);

	PERM_FREE(entry);

SOLARIS_PROBE(cache_delete_end, "cache");
	return 0;
}
示例#30
0
文件: lasdns.cpp 项目: Firstyear/ds
/*  LASDNSBuild
 *  Builds a hash table of all the hostnames provided (plus their aliases
 *  if aliasflg is true).  Wildcards are only permitted in the leftmost
 *  field.  They're represented in the hash table by a leading period.
 *  E.g. ".mcom.com".
 *
 *  RETURNS	Zero on success, else LAS_EVAL_INVALID
 */
int
LASDnsBuild(NSErr_t *errp, char *attr_pattern, LASDnsContext_t *context, int aliasflg)
{
    size_t delimiter; /* length of valid tokeni */
    char token[256];  /* max length dns name */
    int i;
    char **p;
    pool_handle_t *pool;
    PRStatus error=PR_SUCCESS;
    char	buffer[PR_NETDB_BUF_SIZE];
#ifdef	UTEST
    struct hostent *he, host;
#else
    PRHostEnt *he, host;
#endif
    char *end_attr_pattern;

    if (attr_pattern == NULL) {
        nserrGenerate(errp, ACLERRINVAL, ACLERR4770, ACL_Program, 1,
                      XP_GetAdminStr(DBT_lasdnsbuildInvalidAttributePattern_));
        return LAS_EVAL_INVALID;
    }

    context->Table = PR_NewHashTable(0,
                                     PR_HashCaseString,
                                     PR_CompareCaseStrings,
                                     PR_CompareValues,
                                     &ACLPermAllocOps,
                                     NULL);
    pool = pool_create();
    context->pool = pool;
    if ((!context->Table) || (!context->pool)) {
        nserrGenerate(errp, ACLERRNOMEM, ACLERR4700, ACL_Program, 1,
                      XP_GetAdminStr(DBT_lasdnsbuildUnableToAllocateHashT_));
        return LAS_EVAL_INVALID;
    }

    end_attr_pattern = attr_pattern + strlen(attr_pattern);
    do {
        size_t maxsize = sizeof(token);
        /*  Get a single hostname from the pattern string        */
        delimiter = strcspn(attr_pattern, ", \t");
        if (delimiter >= maxsize) {
            delimiter = maxsize-1;
        }
        PL_strncpyz(token, attr_pattern, delimiter + 1);
        token[delimiter] = '\0';

        /*  Skip any white space after the token                 */
        attr_pattern += delimiter;
        if (attr_pattern < end_attr_pattern) {
            attr_pattern += strspn(attr_pattern, ", \t");
        }

        /*  If there's a wildcard, strip it off but leave the "."
         *  Can't have aliases for a wildcard pattern.
         *  Treat "*" as a special case.  If so, go ahead and hash it.
         */
        if (token[0] == '*') {
            if (token[1] != '\0') {
                if (!PR_HashTableAdd(context->Table, pool_strdup(pool, &token[1]), (void *)-1)) {
                    nserrGenerate(errp, ACLERRFAIL, ACLERR4710, ACL_Program, 2,
                                  XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), token);
                    return LAS_EVAL_INVALID;
                }
            } else {
                if (!PR_HashTableAdd(context->Table, pool_strdup(pool, token), (void *)-1)) {
                    nserrGenerate(errp, ACLERRFAIL, ACLERR4720, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), token);
                    return LAS_EVAL_INVALID;
                }
            }
        } else  {
            /*  This is a single hostname add it to the hash table        */
            if (!PR_HashTableAdd(context->Table, pool_strdup(pool, &token[0]), (void *)-1)) {
                nserrGenerate(errp, ACLERRFAIL, ACLERR4730, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), token);
                return LAS_EVAL_INVALID;
            }

            if (aliasflg) {
                void *iter = NULL;
                int addrcnt = 0;
                PRNetAddr *netaddr = (PRNetAddr *)PERM_CALLOC(sizeof(PRNetAddr));
                PRAddrInfo *infop = PR_GetAddrInfoByName(token,
                                    PR_AF_UNSPEC, (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME));
                if (!netaddr) {
                    if (infop) {
                        PR_FreeAddrInfo(infop);
                    }
                    return LAS_EVAL_NEED_MORE_INFO; /* hostname not known to dns? */
                }
                if (!infop) {
                    if (netaddr) {
                        PERM_FREE(netaddr);
                    }
                    return LAS_EVAL_NEED_MORE_INFO; /* hostname not known to dns? */
                }
                /* need to count the address, first */
                while ((iter = PR_EnumerateAddrInfo(iter, infop, 0, netaddr))) {
                    addrcnt++;
                }
                if (0 == addrcnt) {
                    PERM_FREE(netaddr);
                    PR_FreeAddrInfo(infop);
                    return LAS_EVAL_NEED_MORE_INFO; /* hostname not known to dns? */
                }
                iter = NULL; /* from the beginning */
                memset(netaddr, 0, sizeof(PRNetAddr));
                for (i = 0; i < addrcnt; i++) {
                    iter = PR_EnumerateAddrInfo( iter, infop, 0, netaddr );
                    if (NULL == iter) {
                        break;
                    }
                    error = PR_GetHostByAddr(netaddr, buffer,
                                             PR_NETDB_BUF_SIZE, &host);
                    if (error == PR_SUCCESS) {
                        he = &host;
                    } else {
                        continue;
                    }
                    if (he->h_name) {
                        /* Add it to the hash table */
                        if (!PR_HashTableAdd(context->Table,
                                             pool_strdup(pool, he->h_name),
                                             (void *)-1)) {
                            nserrGenerate(errp, ACLERRFAIL, ACLERR4750,
                                          ACL_Program, 2,
                                          XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_),
                                          he->h_name);
                            PERM_FREE(netaddr);
                            PR_FreeAddrInfo(infop);
                            return LAS_EVAL_INVALID;
                        }
                    }

                    if (he->h_aliases && he->h_aliases[0]) {
                        for (p = he->h_aliases; *p; ++p) {
                            /* Add it to the hash table */
                            if (!PR_HashTableAdd(context->Table,
                                                 pool_strdup(pool, *p),
                                                 (void *)-1)) {
                                nserrGenerate(errp, ACLERRFAIL, ACLERR4760,
                                              ACL_Program, 2,
                                              XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_),
                                              *p);
                                PERM_FREE(netaddr);
                                PR_FreeAddrInfo(infop);
                                return LAS_EVAL_INVALID;
                            }
                        }
                    }
                } /* for (i = 0; i < addrcnt; i++) */
                PERM_FREE(netaddr);
                PR_FreeAddrInfo(infop);
            } /* if aliasflg */
        } /* else - single hostname */
    } while ((attr_pattern != NULL) &&
             (attr_pattern[0] != '\0') &&
             (delimiter != 0));

    return 0;
}