示例#1
0
static int
blockstore_set_chain_links(struct blockstore *bs,
                           struct blockentry *be)
{
   struct blockentry *prev;
   char hashStr[80];
   uint256 hash;
   bool s;

   hash256_calc(&be->header, sizeof be->header, &hash);
   uint256_snprintf_reverse(hashStr, sizeof hashStr, &hash);

   if (be->height >= 0) {
      struct blockentry *li;
      /*
       * We've reached the junction with the current/old best chain. All the
       * entries from now on need to be made orphans.
       */

      Log(LGPFX" Reached block %s\n", hashStr);

      li = be->next;
      while (li) {
         hash256_calc(&li->header, sizeof li->header, &hash);
         uint256_snprintf_reverse(hashStr, sizeof hashStr, &hash);
         Log(LGPFX" moving #%d %s from blk -> orphan\n", li->height, hashStr);
         s = hashtable_remove(bs->hash_blk, &hash, sizeof hash);
         ASSERT(s);
         li->height = -1;
         s = hashtable_insert(bs->hash_orphans, &hash, sizeof hash, li);
         ASSERT(s);
         li = li->next;
      }

      return be->height;
   }

   ASSERT(be->height == -1); // orphan

   prev = blockstore_lookup(bs, &be->header.prevBlock);
   ASSERT(prev);

   be->height = 1 + blockstore_set_chain_links(bs, prev);

   Log(LGPFX" moving #%d %s from orphan -> blk\n", be->height, hashStr);

   prev->next = be;
   be->prev = prev;

   s = hashtable_remove(bs->hash_orphans, &hash, sizeof hash);
   ASSERT(s);
   s = hashtable_insert(bs->hash_blk, &hash, sizeof hash, be);
   ASSERT(s);

   return be->height;
}
示例#2
0
void *
cache_fetch(cache_t *c, char *prefix, char *key, int timeout)
{



	char *k = gen_key(prefix, key);
	cache_value_t *v;
	time_t now;

	pthread_mutex_lock(&c->c_lock);

	v = hashtable_search(c->c_data, k);
	if (v == NULL) {
		goto nomatch;
	}

	now = time(NULL);
	if (now - v->mtime > timeout) {
		v = hashtable_remove(c->c_data, k);
		c->c_freevalue(v->p);
		free(v);
		printf("cache_fetch: removed timouted key %s\n",k);
		goto nomatch;
	}
	v->atime = time(NULL);
	pthread_mutex_unlock(&c->c_lock);
	free(k);
	return v->p;
 nomatch:
	pthread_mutex_unlock(&c->c_lock);
	free(k);
	return NULL;
}
示例#3
0
static int tcp_client_remove(int cid) { 
	tcp_client* c;
	c = hashtable_remove(clients, &cid);
	if (c == NULL) return 0;
	tcp_client_free(c);
	return 1;
}
示例#4
0
/* userlist_remove:
 *	removes specified user from userlist
 * params:
 *	@explicit_part - non-0 if the user left explicitly (he notified us of that)
 */
void userlist_remove(const char * user_name, int explicit_remove)
{
	struct userlist_entry * entry;

	ASSERT_RETURNIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash));

	entry = userlist_entry_by_name(user_name);
	if(entry) {
		const char * enum_cb_data[2];
		
		/* notify DB that the user has become offline
		 * (if the user is in db list)
		 */
		HANDLE hContact = contacts_find_contact(user_name);
		if(hContact)
			contacts_set_contact_status(hContact, ID_STATUS_OFFLINE);

		/* update user's chatroom:
		 * leave every channel the user is in */
		enum_cb_data[0] = user_name;
		enum_cb_data[1] = (const char *)explicit_remove;
		chanlist_enum(
			entry->chanlist,
			userlist_remove_channel_part_enum, (void*)enum_cb_data);
		
		/* remove user entry from the hash and free it */
		hashtable_remove(s_userlistHash, (void*)user_name, 1);
	}
}
示例#5
0
void *hasher_thread(void *v) {
    struct args *args = (struct args *)v;
    
    fprintf(stderr,"Thread %p running\n", (void*)pthread_self());
    int start_value = random() % args->num_words;
    int values_to_add = args->max_values;

    int i = 0;
    for (i = 0; i < values_to_add; i++) {
        hashtable_add(args->hash, args->words[(start_value + i) % args->num_words]);
    }
    
    pthread_mutex_lock(&args->done_adding_mutex);
    // add one to done_adding as a signal to main thread that we're done
    // adding to hashtable.
    args->done_adding += 1;
    // wait for main thread to signal to workers to start removing from table
    while (args->done_adding != -1) {
        pthread_cond_wait(&args->done_adding_condv, &args->done_adding_mutex);
    }
    pthread_mutex_unlock(&args->done_adding_mutex);
    
    for (i = 0; i < values_to_add; i++) {
        hashtable_remove(args->hash, args->words[(start_value + i) % args->num_words]);
    }
    return NULL;
}
示例#6
0
文件: drfuzz.c 项目: pb2bee/drmemory
DR_EXPORT drmf_status_t
drfuzz_fuzz_target(generic_func_t func_pc, uint arg_count, uint flags, uint wrap_flags,
                   void (*pre_fuzz_cb)(void *fuzzcxt, generic_func_t target_pc,
                                       dr_mcontext_t *mc),
                   bool (*post_fuzz_cb)(void *fuzzcxt, generic_func_t target_pc))
{
    fuzz_target_t *target;

    if (func_pc == NULL)
        return DRMF_ERROR_INVALID_PARAMETER;

    target = global_alloc(sizeof(fuzz_target_t), HEAPSTAT_MISC);
    memset(target, 0, sizeof(fuzz_target_t));
    target->func_pc = (app_pc) func_pc;
    target->arg_count = arg_count;
    target->flags = flags;
    target->pre_fuzz_cb = pre_fuzz_cb;
    target->post_fuzz_cb = post_fuzz_cb;
    if (!hashtable_add(&fuzz_target_htable, func_pc, target)) {
        free_fuzz_target(target);
        return DRMF_ERROR_INVALID_PARAMETER; /* entry already exists */
    }

    /* wrap after adding to hashtable: avoids racing on presence of hashtable entry */
    if (drwrap_wrap_ex((app_pc) func_pc, pre_fuzz_handler, post_fuzz_handler,
                       NULL, wrap_flags)) {
        return DRMF_SUCCESS;
    } else {
        hashtable_remove(&fuzz_target_htable, func_pc); /* ignore result: error already */
        return DRMF_ERROR;
    }
}
示例#7
0
hashtable_rc_t hashtable_resize(hash_table_t * const hashtblP, const hash_size_t sizeP)
{
    hash_table_t       newtbl;
    hash_size_t        n;
    hash_node_t       *node,*next;

    if (hashtblP == NULL) {
        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
    }

    newtbl.size     = sizeP;
    newtbl.hashfunc = hashtblP->hashfunc;

    if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t*)))) return -1;

    for(n=0; n<hashtblP->size; ++n) {
        for(node=hashtblP->nodes[n]; node; node=next) {
            next = node->next;
            hashtable_insert(&newtbl, node->key, node->data);
            // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
            hashtable_remove(hashtblP, node->key);

        }
    }

    free(hashtblP->nodes);
    hashtblP->size=newtbl.size;
    hashtblP->nodes=newtbl.nodes;

    return HASH_TABLE_OK;
}
示例#8
0
static void add_to_set(struct hashtable* h, key* k, val* v) {
	int rv;
	key* new_key;
	flat_key_val* new_value;
	
	new_value = hashtable_search(h, k);
	if (new_value == NULL) {
		new_key = key_new(k->data, k->size);
		new_value = malloc(sizeof(flat_key_val) + k->size + v->size);
		assert(new_value != NULL);
		rv = hashtable_insert(h, new_key, new_value);
		assert(rv != 0);
	} else {
		if ((k->size + v->size) != (new_value->ksize + new_value->vsize)) {
			new_key = key_new(k->data, k->size);
			new_value = hashtable_remove(h, k);
			free(new_value);
			new_value = malloc(sizeof(flat_key_val) + k->size + v->size);
			assert(new_value != NULL);
			rv = hashtable_insert(h, new_key, new_value);
			assert(rv != 0);
		}
	}
	
	new_value->ksize = k->size;
	new_value->vsize = v->size;
	memcpy(new_value->data, k->data, k->size);
	memcpy(&new_value->data[k->size], v->data, v->size);
}
示例#9
0
文件: kernel.cpp 项目: whunmr/circa
void Map__remove(caStack* stack)
{
    caValue* out = circa_output(stack, 0);
    copy(circa_input(stack, 0), out);

    hashtable_remove(out, circa_input(stack, 1));
}
/**
 * override_attributes - override inode attributes.
 * @st: struct stat object to containing the attributes to override
 * @ph_elt: path hash table element object
 * @nh_elt: name hash table element object containing the new values
 *
 * The device table file may override attributes like UID of files. For
 * example, the device table may contain a "/dev" entry, and the UBIFS FS on
 * the host may contain "/dev" directory. In this case the attributes of the
 * "/dev" directory inode has to be as the device table specifies.
 *
 * Note, the hash element is removed by this function as well.
 */
int override_attributes(struct stat *st, struct path_htbl_element *ph_elt,
			struct name_htbl_element *nh_elt)
{
	if (!path_htbl)
		return 0;

	if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode) ||
	    S_ISFIFO(st->st_mode))
		return err_msg("%s/%s both exists at UBIFS root at host, "
			       "and is referred from the device table",
			       strcmp(ph_elt->path, "/") ? ph_elt->path : "",
			       nh_elt->name);

	if ((st->st_mode & S_IFMT) != (nh_elt->mode & S_IFMT))
		return err_msg("%s/%s is referred from the device table also exists in "
			       "the UBIFS root directory at host, but the file type is "
			       "different", strcmp(ph_elt->path, "/") ? ph_elt->path : "",
			       nh_elt->name);

	dbg_msg(3, "set UID %d, GID %d, mode %o for %s/%s as device table says",
		nh_elt->uid, nh_elt->gid, nh_elt->mode, ph_elt->path, nh_elt->name);

	st->st_uid = nh_elt->uid;
	st->st_gid = nh_elt->gid;
	st->st_mode = nh_elt->mode;

	hashtable_remove(ph_elt->name_htbl, (void *)nh_elt->name);
	return 0;
}
示例#11
0
文件: drfuzz.c 项目: pb2bee/drmemory
DR_EXPORT drmf_status_t
drfuzz_unfuzz_target(generic_func_t func_pc)
{
    drmf_status_t res = DRMF_SUCCESS;
    fuzz_pass_context_t *fp = drfuzz_get_fuzzcxt();
    pass_target_t *live_target = lookup_live_target(fp, (app_pc) func_pc);
    fuzz_target_t *target = hashtable_lookup(&fuzz_target_htable, func_pc);

    if (target == NULL)
        return DRMF_ERROR_INVALID_PARAMETER;
    if (live_target != NULL) {
        /* XXX i#1734: ideally we would check all threads, or flag the target as live */
        DRFUZZ_ERROR("Attempt to unfuzz a live fuzz target\n");
        return DRMF_ERROR; /* cannot unfuzz the target in this state */
    }
    if (!hashtable_remove(&fuzz_target_htable, func_pc)) {
        DRFUZZ_ERROR("failed to remove "PIFX" from the fuzz target hashtable\n", func_pc);
        res = DRMF_ERROR;         /* Missing entry does not prevent unfuzzing, */
        free_fuzz_target(target); /* but at least free it.                     */
    }
    if (!drwrap_unwrap((app_pc) func_pc, pre_fuzz_handler, post_fuzz_handler)) {
        DRFUZZ_ERROR("failed to unwrap the fuzz target "PIFX" via drwrap_unwrap\n",
                     func_pc);
        res = DRMF_ERROR;
    }
    return res;
}
示例#12
0
/**
 * Replace one node with another
 * @param ht the hashtable to do it in
 * @param u the node to replace it with
 * @return 1 if it worked
 */
int hashtable_replace( hashtable *ht, node *v, node *u )
{
    if ( hashtable_remove(ht,v,node_first_char(u)) )
        return hashtable_add(ht,u);
    else
        return 0;
}
示例#13
0
static void
removeInt (hashtable_t* hashtablePtr, long* data)
{
    printf("Removing: %li\n", *data);
    hashtable_remove(hashtablePtr, (void*)data);
    printHashtable(hashtablePtr);
    puts("");
}
示例#14
0
Vertex*
dirfibheap_extract_min( dirfibheap_t self )
{
  Vertex* best = (Vertex*)fibheap_extract_min( self->heap );
  if(best) 
    hashtable_remove(self->dir, best->label);
  return best;
}
示例#15
0
void commit_data(struct config *conf) {
  int dbid = 0, done = 0;
  setitimer(ITIMER_PROF, &global_itimer, NULL);


  pthread_mutex_lock(&shutdown_lock);
  while (!done) {
    struct timespec sleep_time;
    struct timeval tv;
    gettimeofday(&tv, NULL);
    sleep_time.tv_sec = tv.tv_sec + conf->commit_interval;
    sleep_time.tv_nsec = tv.tv_usec * 1e3;

    if (pthread_cond_timedwait(&shutdown_cond, &shutdown_lock, &sleep_time) == 0)
      done = 1;

    debug("commit: checking for new data\n");
    for (dbid = 0; dbid < MAX_SUBSTREAMS; dbid++) {
      unsigned long long *key = NULL;
      ReadingSet *val;

      while (1) {
        if (pthread_mutex_lock(&dbs[dbid].lock) != 0)
          break;
        key = NULL;
        val = hashtable_next(dbs[dbid].dirty_data, (void **)&key);
        if (val == NULL) {
          pthread_mutex_unlock(&dbs[dbid].lock);
          break;
        }
        val = hashtable_remove(dbs[dbid].dirty_data, key);
        pthread_mutex_unlock(&dbs[dbid].lock);
        assert(val != NULL);

        debug("adding dbid: %i streamid: %llu nrecs: %i\n",
              val->substream, val->streamid, val->n_data);
        
        if (add(conf, dbs[dbid].dbp, val) < 0) {
          warn("Transaction aborted in commit thread... retrying\n");
          sleep(rand() % 10 );
          if (add(conf, dbs[dbid].dbp, val) < 0) {
            warn("Transaction retry failed in commit thread... giving up\n");
            INCR_STAT(failed_adds);
          }
        }
        _rpc_free_rs(val);
      }

      debug("Syncing...\n");
      dbs[dbid].dbp->sync(dbs[dbid].dbp, 0);
      
      debug("Done!\n");
      continue;
    }
  }
  pthread_mutex_unlock(&shutdown_lock);
}
示例#16
0
void block_remove_property(Block* block, Symbol key)
{
    if (is_null(&block->properties))
        return;

    Value keyVal;
    set_symbol(&keyVal, key);
    hashtable_remove(&block->properties, &keyVal);
}
示例#17
0
int main()
{
	char key[9];
	int i;
	int pos = 0;

	init_key(key, ARRAY_SIZE(key));
	for (i = 0; i < HASHTABLE_SIZE; i++) {
		void *unchanged = NULL + 1234;
		void *actual = unchanged;
		void *value = NULL + i;
		assert(!find_next_collision(pos, key, strlen(key)));
		assert(hashtable_get(key, &actual) == 1);
		assert(actual == unchanged);
		assert(!hashtable_set(key, value));
		assert(hashtable_test_key_at_pos(key, pos + i % HASHTABLE_SIZE));
	}

	assert(!find_next_collision(pos, key, strlen(key)));
	/* table is full */
	assert(hashtable_set(key, NULL) == 1);

	init_key(key, ARRAY_SIZE(key));
	for (i = 0; i < HASHTABLE_SIZE; i++) {
		void *expect = NULL + i;
		void *actual;
		assert(!find_next_collision(pos, key, strlen(key)));
		assert(!hashtable_get(key, &actual));
		assert(actual == expect);
	}

	assert(hashtable_remove("asdf"));
	assert(hashtable_remove(""));
	init_key(key, ARRAY_SIZE(key));
	for (i = 0; i < HASHTABLE_SIZE; i++) {
		assert(!find_next_collision(pos, key, strlen(key)));
		assert(!hashtable_remove(key));
		assert(hashtable_remove(key));
	}
	init_key(key, ARRAY_SIZE(key));
	assert(hashtable_remove(key));

	return 0;
}
示例#18
0
int
secure_decrypt_data_not_decrypted (const char *passphrase)
{
    char **keys, *buffer, *decrypted;
    const char *value;
    int num_ok, num_keys, i, length_buffer, length_decrypted, rc;

    /* we need a passphrase to decrypt data! */
    if (!passphrase || !passphrase[0])
        return 0;

    num_ok = 0;

    keys = string_split (hashtable_get_string (secure_hashtable_data_encrypted,
                                               "keys"),
                         ",", 0, 0, &num_keys);
    if (keys)
    {
        for (i = 0; i < num_keys; i++)
        {
            value = hashtable_get (secure_hashtable_data_encrypted, keys[i]);
            if (value && value[0])
            {
                buffer = malloc (strlen (value) + 1);
                if (buffer)
                {
                    length_buffer = string_decode_base16 (value, buffer);
                    decrypted = NULL;
                    length_decrypted = 0;
                    rc = secure_decrypt_data (buffer,
                                              length_buffer,
                                              secure_hash_algo[CONFIG_INTEGER(secure_config_crypt_hash_algo)],
                                              secure_cipher[CONFIG_INTEGER(secure_config_crypt_cipher)],
                                              passphrase,
                                              &decrypted,
                                              &length_decrypted);
                    if ((rc == 0) && decrypted)
                    {
                        hashtable_set (secure_hashtable_data, keys[i],
                                       decrypted);
                        hashtable_remove (secure_hashtable_data_encrypted,
                                          keys[i]);
                        num_ok++;
                    }
                    if (decrypted)
                        free (decrypted);
                    free (buffer);
                }
            }
        }
        string_free_split (keys);
    }

    return num_ok;
}
示例#19
0
static void add_for_event(zk_hashtable *ht, char *path, watcher_object_list_t **list)
{
    watcher_object_list_t* wl;
    wl = (watcher_object_list_t*)hashtable_remove(ht->ht, path);
    if (wl) {
        copy_watchers(wl, *list, 0);
        // Since we move, not clone the watch_objects, we just need to free the
        // head pointer
        free(wl);
    }
}
示例#20
0
文件: lru.c 项目: HarryR/ZeroDB
char* lru_find(char* k)
{
	cache_t* item=(cache_t*)hashtable_get(_ht,k);
	if(item)
	{
		hashtable_remove(_ht,k);
		hashtable_set(_ht,k,item);
		return item->v;
	}

	return NULL;
}
示例#21
0
文件: dnscache.c 项目: huayl/rsyslog
findEntry(struct sockaddr_storage *const addr,
	prop_t **const fqdn, prop_t **const fqdnLowerCase,
	prop_t **const localName, prop_t **const ip)
{
	DEFiRet;

	pthread_rwlock_rdlock(&dnsCache.rwlock);
	dnscache_entry_t * etry = hashtable_search(dnsCache.ht, addr);
	DBGPRINTF("findEntry: 1st lookup found %p\n", etry);

	if(etry == NULL || (dnscacheEnableTTL && (etry->validUntil <= time(NULL)))) {
		pthread_rwlock_unlock(&dnsCache.rwlock);
		pthread_rwlock_wrlock(&dnsCache.rwlock);
		etry = hashtable_search(dnsCache.ht, addr); /* re-query, might have changed */
		DBGPRINTF("findEntry: 2nd lookup found %p\n", etry);
		if(etry == NULL || (dnscacheEnableTTL && (etry->validUntil <= time(NULL)))) {
			if(etry != NULL) {
				DBGPRINTF("hashtable: entry timed out, discarding it; "
					"valid until %lld, now %lld\n",
					(long long) etry->validUntil, (long long) time(NULL));
				dnscache_entry_t *const deleted = hashtable_remove(dnsCache.ht, addr);
				if(deleted != etry) {
					LogError(0, RS_RET_INTERNAL_ERROR, "dnscache %d: removed different "
						"hashtable entry than expected - please report issue; "
						"rsyslog version is %s", __LINE__, VERSION);
				}
				entryDestruct(etry);
			}
			/* now entry doesn't exist in any case, so let's (re)create it */
			CHKiRet(addEntry(addr, &etry));
		}
	}

	prop.AddRef(etry->ip);
	*ip = etry->ip;
	if(fqdn != NULL) {
		prop.AddRef(etry->fqdn);
		*fqdn = etry->fqdn;
	}
	if(fqdnLowerCase != NULL) {
		prop.AddRef(etry->fqdnLowerCase);
		*fqdnLowerCase = etry->fqdnLowerCase;
	}
	if(localName != NULL) {
		prop.AddRef(etry->localName);
		*localName = etry->localName;
	}

finalize_it:
	pthread_rwlock_unlock(&dnsCache.rwlock);
	RETiRet;
}
示例#22
0
static void grpobj_remove_membership(obj_t grp_obj,
				     struct grp_membership *membership)
{
	struct grp_desc *grp_desc;
	struct grp_membership *m;

	ASSERT(membership != NULL);
	grp_desc = GRP_DESC(grp_obj);

	m = hashtable_remove(&grp_desc->members,
			     &OBJ_OID(membership->member_obj));
	ASSERT(m == membership);
}
示例#23
0
/* To keep the size of our hashtable down. */
static void
event_fragment_deleted(void *drcontext, void *tag)
{
    trace_head_entry_t *e;
    hashtable_lock(&head_table);
    e = hashtable_lookup(&head_table, tag);
    if (e != NULL) {
        e->refcount--;
        if (e->refcount == 0)
            hashtable_remove(&head_table, tag);
    }
    hashtable_unlock(&head_table);
}
示例#24
0
int
pos_hashtable_remove(char *name, void *_k)
{
	struct hashtable *h;
	unsigned long *k;
		
	if (name==NULL || _k==NULL)
		return -1;

	k = (unsigned long *)_k;
	h = (struct hashtable *)pos_get_prime_object(name);

	return hashtable_remove(name, h, k);
}
示例#25
0
void
hdata_free_all_plugin_map_cb (void *data, struct t_hashtable *hashtable,
                              const void *key, const void *value)
{
    struct t_hdata *ptr_hdata;

    ptr_hdata = (struct t_hdata *)value;

    if (ptr_hdata->plugin == (struct t_dogechat_plugin *)data)
    {
        hdata_free (ptr_hdata);
        hashtable_remove (hashtable, key);
    }
}
示例#26
0
void syscall_destroy(kobject_t * object)
{
	syscall_t * sys = (syscall_t *)object;
	hashtable_remove(&sys->global_entry);

	function_free(sys->ffi);
	free(sys->name);
	free(sys->signature);

	if (sys->description != NULL)
	{
		free(sys->description);
	}
}
示例#27
0
void
hdata_free_all_map_cb (void *data, struct t_hashtable *hashtable,
                       const void *key, const void *value)
{
    struct t_hdata *ptr_hdata;

    /* make C compiler happy */
    (void) data;

    ptr_hdata = (struct t_hdata *)value;

    hdata_free (ptr_hdata);
    hashtable_remove (hashtable, key);
}
示例#28
0
void remove_node(unsigned int set_type, OBJECT_PTR val)
{

#ifdef GC_USES_HASHTABLE

  if(set_type == WHITE)
    hashtable_remove(white, (void *)val);
  else if(set_type == GREY)
    hashtable_remove(grey, (void *)val);
  else if(set_type == BLACK)
    hashtable_remove(black, (void *)val);
  else
    assert(false);

#else

  rb_red_blk_tree *tree;

  if(set_type == WHITE)
    tree = white;
  else if(set_type == GREY)
    tree = grey;
  else if(set_type == BLACK)
    tree = black;
  else
    assert(false);

  if(!tree)
    return;

  rb_red_blk_node* newNode;
  if((newNode=RBExactQuery(tree,&val))) 
    RBDelete(tree,newNode);  

#endif
}
示例#29
0
int krgsyms_unregister(enum krgsyms_val v)
{
	void *p;

	if( (v < 0) || (v >= KRGSYMS_TABLE_SIZE) ){
		printk("krgsyms_unregister: Incorrect krgsym value (%d)\n", v);
		BUG();
		return -1;
	};

	p = krgsyms_table[v];
	krgsyms_table[v] = NULL;
	hashtable_remove(krgsyms_htable, (unsigned long)p);

	return 0;
};
示例#30
0
void set_mount_status(char *p,char *val) {

    if (util_starts_with(p,NETWORK_SHARE)) {
        p += strlen(NETWORK_SHARE);
    }

    char *current = hashtable_search(mount_points,p);
    if (current == NULL) {
        HTML_LOG(0,"Adding mount point [%s] = %s",p,val);
        hashtable_insert(mount_points,STRDUP(p),val);
    } else if ( STRCMP(current,val) != 0) {
        hashtable_remove(mount_points,p,1);
        HTML_LOG(0,"mount point [%s] status changed from [%s] to [%s]",p,current,val);
        hashtable_insert(mount_points,STRDUP(p),val);
    }
}