Exemple #1
0
/*
 * Copy the attributes of stanza src into stanza dst. Return -1 on error.
 */
static int _stanza_copy_attributes(xmpp_stanza_t * dst,
                                   const xmpp_stanza_t * const src)
{
    hash_iterator_t *iter;
    const char *key;
    const char *val;
    int rc = XMPP_EOK;

    iter = hash_iter_new(src->attributes);
    if (!iter) rc = XMPP_EMEM;

    while (rc == XMPP_EOK && (key = hash_iter_next(iter))) {
        val = hash_get(src->attributes, key);
        if (!val) rc = XMPP_EINT;
        if (rc == XMPP_EOK)
            rc = xmpp_stanza_set_attribute(dst, key, val);
    }
    hash_iter_release(iter);

    if (rc != XMPP_EOK && dst->attributes) {
        hash_release(dst->attributes);
        dst->attributes = NULL;
    }
    return rc;
}
Exemple #2
0
/*
 * Copy the attributes of stanza src into stanza dst. Return -1 on error.
 */
static int _stanza_copy_attributes(xmpp_stanza_t * dst,
                                   const xmpp_stanza_t * const src)
{
    hash_iterator_t *iter = NULL;
    const char *key;
    void *val;

    dst->attributes = hash_new(src->ctx, 8, xmpp_free);
    if (!dst->attributes)
        return -1;
    iter = hash_iter_new(src->attributes);
    if (!iter)
        goto error;
    while ((key = hash_iter_next(iter))) {
        val = xmpp_strdup(src->ctx,
                          (char *)hash_get(src->attributes, key));
        if (!val)
            goto error;

        if (hash_add(dst->attributes, key, val)) {
            xmpp_free(src->ctx, val);
            goto error;
        }
    }
    hash_iter_release(iter);
    return 0;

error:
    if (iter != NULL)
        hash_iter_release(iter);
    hash_release(dst->attributes);
    return -1;
}
Exemple #3
0
/** Get all attributes for a stanza object.
 *  This function populates the array with attributes from the stanza.  The
 *  attr array will be in the format:  attr[i] = attribute name, 
 *  attr[i+1] = attribute value.
 *
 *  @param stanza a Strophe stanza object
 *  @param attr the string array to populate
 *  @param attrlen the size of the array
 *
 *  @return the number of slots used in the array, which will be 2 times the 
 *      number of attributes in the stanza
 *
 *  @ingroup Stanza
 */
int xmpp_stanza_get_attributes(xmpp_stanza_t * const stanza,
                               const char **attr, int attrlen)
{
    hash_iterator_t *iter;
    const char *key;
    int num = 0;

    if (stanza->attributes == NULL) {
        return 0;
    }

    iter = hash_iter_new(stanza->attributes);
    while ((key = hash_iter_next(iter)) != NULL && attrlen) {
        attr[num++] = key;
        attrlen--;
        if (attrlen == 0) {
            hash_iter_release(iter);
            return num;
        }
        attr[num++] = hash_get(stanza->attributes, key);
        attrlen--;
        if (attrlen == 0) {
            hash_iter_release(iter);
            return num;
        }
    }

    hash_iter_release(iter);
    return num;
}
Exemple #4
0
static int test_hash_iter_after_del(const struct test *t)
{
	struct hash *h = hash_new(8, NULL);
	struct hash *h2 = hash_new(8, NULL);
	const char *k1 = "k1", *k2 = "k2", *k3 = "k3";
	const char *v1 = "v1", *v2 = "v2", *v3 = "v3";
	struct hash_iter iter;
	const char *k, *v;

	hash_add(h, k1, v1);
	hash_add(h2, k1, v1);
	hash_add(h, k2, v2);
	hash_add(h2, k2, v2);
	hash_add(h, k3, v3);
	hash_add(h2, k3, v3);

	hash_del(h, k1);

	for (hash_iter_init(h, &iter);
	     hash_iter_next(&iter, &k, (const void **) &v);) {
		v2 = hash_find(h2, k);
		assert_return(v2 != NULL, EXIT_FAILURE);
		hash_del(h2, k);
	}

	assert_return(hash_get_count(h) == 2, EXIT_FAILURE);
	assert_return(hash_get_count(h2) == 1, EXIT_FAILURE);

	hash_free(h);
	hash_free(h2);
	return 0;
}
Exemple #5
0
int hash_iter_init(hash_iter_t *iter, hash_t *ht) {
    iter->pos = 0;
    iter->depth = 0;
    iter->ht = ht;
    iter->key = NULL;
    iter->value = NULL;
    return hash_iter_next(iter);
}
Exemple #6
0
/** Copy a stanza and its children.
 *  This function copies a stanza along with all its children and returns
 *  the new stanza and children with a reference count of 1.  The returned
 *  stanza will have no parent and no siblings.  This function is useful
 *  for extracting a child stanza for inclusion in another tree.
 *
 *  @param stanza a Strophe stanza object
 *
 *  @return a new Strophe stanza object
 *
 *  @ingroup Stanza
 */
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t * const stanza)
{
    xmpp_stanza_t *copy, *child, *copychild, *tail;
    hash_iterator_t *iter;
    const char *key;
    void *val;

    copy = xmpp_stanza_new(stanza->ctx);
    if (!copy) goto copy_error;

    copy->type = stanza->type;

    if (stanza->data) {
        copy->data = xmpp_strdup(stanza->ctx, stanza->data);
        if (!copy->data) goto copy_error;
    }

    if (stanza->attributes) {
        copy->attributes = hash_new(stanza->ctx, 8, xmpp_free);
        if (!copy->attributes) goto copy_error;
        iter = hash_iter_new(stanza->attributes);
        if (!iter) {
            printf("DEBUG HERE\n");
            goto copy_error;
        }
        while ((key = hash_iter_next(iter))) {
            val = xmpp_strdup(stanza->ctx,
                              (char *)hash_get(stanza->attributes, key));
            if (!val) goto copy_error;

            if (hash_add(copy->attributes, key, val))
                goto copy_error;
        }
        hash_iter_release(iter);
    }

    tail = copy->children;
    for (child = stanza->children; child; child = child->next) {
        copychild = xmpp_stanza_copy(child);
        if (!copychild) goto copy_error;
        copychild->parent = copy;

        if (tail) {
            copychild->prev = tail;
            tail->next = copychild;
        } else
            copy->children = copychild;
        tail = copychild;
    }

    return copy;

copy_error:
    /* release all the hitherto allocated memory */
    if (copy) xmpp_stanza_release(copy);
    return NULL;
}
static void dump_macro_set(MACRO_SET & set, MyString & str, const char * prefix) {
	str.clear();
	HASHITER it = hash_iter_begin(set, HASHITER_NO_DEFAULTS | HASHITER_SHOW_DUPS);
	while( ! hash_iter_done(it)) {
		const char *name = hash_iter_key(it);
		const char *val = hash_iter_value(it);
		//const MACRO_META *met = hash_iter_meta(it);
		if (prefix) str += prefix;
		str += name;
		str += "=";
		str += val ? val : "";
		str += "\n";
		hash_iter_next(it);
	}
	hash_iter_delete(&it);
}
Exemple #8
0
void write_sizes(const char * to_file) {
  FILE *f = fopen(to_file, "wt");
  fputs(VFILESIZE_FILE_TYPE /**/ "\n", f);
  fputs(VFILESIZE_FILE_VERSION /**/ "\n", f);
  hash_iter_t it;
  it = vfilesize_hash_iter(SIZE_HASH);
  while (!hash_iter_end(it)) {
    vfile_size_t *e = vfilesize_hash_get(SIZE_HASH, hash_iter_key(it) );
    if (e != NULL) {
      fprintf(f, "%s\n%lu\n%lu\n", hash_iter_key(it),
                  (unsigned long) e->size, (unsigned long) e->mtime );
    } else {
      log_debug("Unexpected!");
    }
    it = hash_iter_next(it);
  }
  fclose(f);
}
Exemple #9
0
static void
check_buffer(EFLOWDESC *ex, void *mdl)
{
    /* 
     * lookup for a item in the hash table with sequence number = ex->next_seq.
     * if found, repeat until not found
     */
    block_t * block;
    hash_iter_t iterator;
    
    block = (block_t *)hash_lookup_ulong(ex->htable, ex->next_seq);
    
    while (block != NULL) {
        if (block->seq == ex->next_seq) {   /* must ALWAYS be true :) */
            add_block(ex, block, mdl);
            unbuffer_block(ex, block->seq, block->len);
        }
        block = (block_t *)hash_lookup_ulong(ex->htable, ex->next_seq);
    }
    
    /* 
     * in case there are overlapped packets, iterate on the hash table to look 
     * for sequence numbers < ex->next_seq
     */
    hash_iter_init(ex->htable, &iterator);
    
    while (hash_iter_next (&iterator)) {
        block = (block_t *)hash_iter_get_value(&iterator);
        
        if (block->seq <= ex->next_seq) {
            add_block(ex, block, mdl);
            
            /*
             * remove from hash with current key value, because the sequence 
             * number could have changed (in case of overlap with valid data), 
             * so no longer would coincide with the hash key
             */
            unbuffer_block(ex, hash_iter_get_ulong_key(&iterator), block->len);
            
            /* start again */
            hash_iter_init(ex->htable, &iterator);
        }
    }
}
Exemple #10
0
static void debug_print_hash_elements(lref_t obj, lref_t port, bool machine_readable)
{
     assert(HASHP(obj));

     fixnum_t count = 0;

     lref_t key, val;

     hash_iter_t ii;
     hash_iter_begin(obj, &ii);
     while (hash_iter_next(obj, &ii, &key, &val))
     {
          count++;

          write_char(port, _T(' '));

          debug_print_object(key, port, machine_readable);
          write_char(port, _T(' '));
          debug_print_object(val, port, machine_readable);
     }
}
Exemple #11
0
int main(int argc, char *argv[]) {
    char buf[32];
    char buf2[32];
    int i;
    int len;
    hash_t *ht, *htcpy;
    hash_iter_t *iter;

    srand(time(NULL));
    ht = hash_create(16);
    HASH_SET_KEYCPY(ht, _demo_dup);
    HASH_SET_VALCPY(ht, _demo_dup);
    HASH_SET_FREE_KEY(ht, _demo_destructor);
    HASH_SET_FREE_VAL(ht, _demo_destructor);
    HASH_SET_KEYCMP(ht, _demo_cmp);

    for (i = 0; i < 100000; ++i) {
        len = randstring(buf, 1, sizeof(buf) - 1);
        buf[len] = '\0';
        len = randstring(buf2, 1, sizeof(buf2) - 1);
        buf2[len] = '\0';
        hash_insert(ht, buf, buf2);
    }

    hash_dump(ht);
    htcpy = hash_dup(ht);
    hash_free(ht);
    printf("================================\n\n\n");
    iter = hash_iter_new(htcpy);
    assert(iter);

    do {
        printf("%s=>%s\n", (char *)iter->key, (char *)iter->value);
    } while (hash_iter_next(iter) == 0);

    hash_free(htcpy);
    exit(0);
}
Exemple #12
0
static void 
sort_buffer(EFLOWDESC *ex, void *mdl)
{
    /* 
     * this only happens when FIN / RST arrives for a flow that was already 
     * established when sniffing started. so SYN was not captured (initial
     * sequence number). in this case, just sort what we have captured.
     */
    hash_iter_t iterator;
    block_t * block, * min_block;
    
    min_block = NULL;
    hash_iter_init(ex->htable, &iterator);
    
    while (hash_iter_next(&iterator)) {
        block = (block_t *)hash_iter_get_value (&iterator);
        
        if (min_block == NULL || block->seq < min_block->seq)
            min_block = block;
    }
    
    /* 
     * min_block is now the 'first' block of all. so set it as the first block,
     * then call check_buffer to put everything in place.
     */
    if (min_block != NULL) {
        ex->base_seq = min_block->seq;
        ex->next_seq = min_block->seq;
        
        add_block(ex, min_block, mdl);
        unbuffer_block(ex, min_block->seq, min_block->len);
        
        check_buffer(ex, mdl);
    }
    
    /* now all possible blocks to be ordered (if any) should be in order */
}
Exemple #13
0
/* always returns number of bytes written or that would have been
 * written if the buffer was large enough
 * return values < 0 indicate some error occurred,
 * and return values > buflen indicate buffer was not large enough
 */
static int _render_stanza_recursive(xmpp_stanza_t *stanza,
                             char * const buf, size_t const buflen)
{
    char *ptr = buf;
    size_t left = buflen;
    int ret, written;
    xmpp_stanza_t *child;
    hash_iterator_t *iter;
    const char *key;
    char *tmp;

    written = 0;

    if (stanza->type == XMPP_STANZA_UNKNOWN) return XMPP_EINVOP;

    if (stanza->type == XMPP_STANZA_TEXT) {
        if (!stanza->data) return XMPP_EINVOP;

        tmp = _escape_xml(stanza->ctx, stanza->data);
        if (tmp == NULL) return XMPP_EMEM;
        ret = xmpp_snprintf(ptr, left, "%s", tmp);
        xmpp_free(stanza->ctx, tmp);
        if (ret < 0) return XMPP_EMEM;
        _render_update(&written, buflen, ret, &left, &ptr);
    } else { /* stanza->type == XMPP_STANZA_TAG */
        if (!stanza->data) return XMPP_EINVOP;

        /* write beginning of tag and attributes */
        ret = xmpp_snprintf(ptr, left, "<%s", stanza->data);
        if (ret < 0) return XMPP_EMEM;
        _render_update(&written, buflen, ret, &left, &ptr);

        if (stanza->attributes && hash_num_keys(stanza->attributes) > 0) {
            iter = hash_iter_new(stanza->attributes);
            while ((key = hash_iter_next(iter))) {
                if (!strcmp(key, "xmlns")) {
                    /* don't output namespace if parent stanza is the same */
                    if (stanza->parent &&
                        stanza->parent->attributes &&
                        hash_get(stanza->parent->attributes, key) &&
                        !strcmp((char*)hash_get(stanza->attributes, key),
                            (char*)hash_get(stanza->parent->attributes, key)))
                        continue;
                    /* or if this is the stream namespace */
                    if (!stanza->parent &&
                        !strcmp((char*)hash_get(stanza->attributes, key),
                            XMPP_NS_CLIENT))
                        continue;
                }
                tmp = _escape_xml(stanza->ctx,
                    (char *)hash_get(stanza->attributes, key));
                if (tmp == NULL) return XMPP_EMEM;
                ret = xmpp_snprintf(ptr, left, " %s=\"%s\"", key, tmp);
                xmpp_free(stanza->ctx, tmp);
                if (ret < 0) return XMPP_EMEM;
                _render_update(&written, buflen, ret, &left, &ptr);
            }
            hash_iter_release(iter);
        }

        if (!stanza->children) {
            /* write end if singleton tag */
            ret = xmpp_snprintf(ptr, left, "/>");
            if (ret < 0) return XMPP_EMEM;
            _render_update(&written, buflen, ret, &left, &ptr);
        } else {
            /* this stanza has child stanzas */

            /* write end of start tag */
            ret = xmpp_snprintf(ptr, left, ">");
            if (ret < 0) return XMPP_EMEM;
            _render_update(&written, buflen, ret, &left, &ptr);

            /* iterate and recurse over child stanzas */
            child = stanza->children;
            while (child) {
                ret = _render_stanza_recursive(child, ptr, left);
                if (ret < 0) return ret;

                _render_update(&written, buflen, ret, &left, &ptr);

                child = child->next;
            }

            /* write end tag */
            ret = xmpp_snprintf(ptr, left, "</%s>", stanza->data);
            if (ret < 0) return XMPP_EMEM;

            _render_update(&written, buflen, ret, &left, &ptr);
        }
    }

    return written;
}
Exemple #14
0
/* always returns number of bytes written or that would have been
 * written if the buffer was large enough
 * return values < 0 indicate some error occured,
 * and return values > buflen indicate buffer was not large enough
 */
static int _render_stanza_recursive(xmpp_stanza_t *stanza,
			     char * const buf, size_t const buflen)
{
    char *ptr = buf;
    size_t left = buflen;
    int ret, written;
    xmpp_stanza_t *child;
    hash_iterator_t *iter;
    const char *key;

    assert(stanza);

    written = 0;

    if (stanza->type == XMPP_STANZA_UNKNOWN) return XMPP_EINVOP;

    if (stanza->type == XMPP_STANZA_TEXT) {
	if (!stanza->data) return XMPP_EINVOP;

        assert(stanza->data);
	ret = xmpp_snprintf(ptr, left, "%s", stanza->data);
	if (ret < 0) return XMPP_EMEM;
	_render_update(&written, buflen, ret, &left, &ptr);
    } else { /* stanza->type == XMPP_STANZA_TAG */
	if (!stanza->data) return XMPP_EINVOP;

	/* write begining of tag and attributes */
        assert(stanza->data);
	ret = xmpp_snprintf(ptr, left, "<%s", stanza->data);
	if (ret < 0) return XMPP_EMEM;
	_render_update(&written, buflen, ret, &left, &ptr);

	if (stanza->attributes && hash_num_keys(stanza->attributes) > 0) {
	    iter = hash_iter_new(stanza->attributes);
	    while ((key = hash_iter_next(iter))) {
                assert(hash_get(stanza->attributes, key));
		ret = xmpp_snprintf(ptr, left, " %s=\"%s\"", key,
			       (char *)hash_get(stanza->attributes, key));
		if (ret < 0) return XMPP_EMEM;
		_render_update(&written, buflen, ret, &left, &ptr);
	    }
	    hash_iter_release(iter);
	}

	if (!stanza->children) {
	    /* write end if singleton tag */
	    ret = xmpp_snprintf(ptr, left, "/>");
	    if (ret < 0) return XMPP_EMEM;
	    _render_update(&written, buflen, ret, &left, &ptr);
	} else {
	    /* this stanza has child stanzas */

	    /* write end of start tag */
	    ret = xmpp_snprintf(ptr, left, ">");
	    if (ret < 0) return XMPP_EMEM;
	    _render_update(&written, buflen, ret, &left, &ptr);

	    /* iterate and recurse over child stanzas */
	    child = stanza->children;
	    while (child) {
		ret = _render_stanza_recursive(child, ptr, left);
		if (ret < 0) return ret;

		_render_update(&written, buflen, ret, &left, &ptr);

		child = child->next;
	    }

	    /* write end tag */
            assert(stanza->data);
	    ret = xmpp_snprintf(ptr, left, "</%s>", stanza->data);
	    if (ret < 0) return XMPP_EMEM;

	    _render_update(&written, buflen, ret, &left, &ptr);
	}
    }

    return written;
}
Exemple #15
0
int main(int argc, char **argv)
{
    xmpp_ctx_t *ctx;
    hash_t *table, *clone;
    hash_iterator_t *iter;
    unsigned int seed;
    const char *key;
    char *result;
    int err = 0;
    int i;

    /* initialize random numbers */
    if (argc > 2) {
	/* use a seed from the command line */
	seed = (unsigned int)atoi(argv[1]);
    } else {
	seed = (unsigned int)clock();
    }
    /* using random seed 'seed' */
    srand(seed);

    /* allocate a default context */
    ctx = xmpp_ctx_new(NULL, NULL);
    if (ctx == NULL) {
	/* ctx allocation failed! */
	return -1;
    }

    /* allocate a hash table */
    table = hash_new(ctx, TABLESIZE, NULL);
    if (table == NULL) {
	/* table allocation failed! */
	return 1;
    }

    /* test insertion */
    for (i = 0; i < nkeys; i++) {
	err = hash_add(table, keys[i], (void*)values[i]);
	if (err) return err;
    }

    /* test key count */
    if (hash_num_keys(table) != nkeys) {
	/* wrong number of keys in table! */
	return 1;
    }

    /* test cloning */
    clone = hash_clone(table);

    /* test lookup */
    for (i = 0; i < nkeys; i++) {
	result = hash_get(clone, keys[i]);
	if (result == NULL) {
	    /* lookup failed! */
	    return 1;
	}
	if (strcmp(values[i], result)) {
	    /* lookup returned incorrect value! */
	    return 1;
	}
    }

    /* test key iterator */
    iter = hash_iter_new(clone);
    if (iter == NULL) {
	/* iterator allocation failed! */
	return 1;
    }
    for (i = 0; i < nkeys; i++) {
	key = hash_iter_next(iter);
	printf("key: '%s'\n", key);
    }
    key = hash_iter_next(iter);
    if (key != NULL) {
	/* extra keys returned! */
	return 1;
    }
    key = hash_iter_next(iter);
    if (key != NULL) {
	/* extra keys returned! */
	return 1;
    }
    hash_iter_release(iter);

    /* release the hash table */
    hash_release(table);

    /* test drops */
    hash_drop(clone, keys[2]);
    if (hash_get(clone, keys[2]) != NULL) return 1;
    hash_drop(clone, keys[1]);
    hash_drop(clone, keys[4]);
    if (hash_get(clone, keys[4]) != NULL) return 1;
    if (hash_get(clone, keys[1]) != NULL) return 1;
    /* keys 0,3 should still be available */
    if (hash_get(clone, keys[0]) == NULL) return 1;
    if (hash_get(clone, keys[3]) == NULL) return 1;

    /* release our clone */
    hash_release(clone);

    /* release our library context */
    xmpp_ctx_free(ctx);

    return err;
}
Exemple #16
0
static void tea_thread_new(int tid, TEA_OBJECT *to, SNODE *command)
{
  THREAD_WORK *tw = NULL;
  TEA_OBJCFG *ocline;
  HASH_ITER hi;
  HASH_NODE *hn;
  int fatal = 0;

  DBG("[tea] Creating thread %d.", tid);
  if((tw = calloc(1, sizeof(THREAD_WORK))) == NULL)
    FAT("Cannot alloc THREAD_WORK struct for thread %d.", tid);

  tw->id         = tid;
  tw->pthread_id = 0;
  tw->to         = to;
  tw->options    = hash_copy(command->command.thc.to->options);

  /* check methods */
  if(tw->to->listener || tw->to->sender)
    tw->mqueue = mqueue_create();
  pthreadex_flag_init(&(tw->mwaiting), 0);
  pthreadex_flag_name(&(tw->mwaiting), "mwaiting");
  pthreadex_flag_init(&(tw->cleanup_do), 0);
  pthreadex_flag_name(&(tw->cleanup_do), "cleanup_do");
  pthreadex_flag_init(&(tw->cleanup_done), 0);
  pthreadex_flag_name(&(tw->cleanup_done), "cleanup_done");

  /* global thread initialization here */
  if(tw->to->global_init && !tw->to->initialized)
  {
    tw->to->initialized = -1;
    tw->to->global_init();
  }

  /* make space for thread data */
  if((tw->data = calloc(1, to->datasize)) == NULL)
    FAT("%d:%s: No memory for thread data.", command->line, to->name);

  /* check config params */
  if(to->cparams)
  {
    /* check only allowed params are defined */
    for(hn = hash_iter_first(&hi, command->command.thc.to->options);
        !hash_iter_finished(&hi);
        hn = hash_iter_next(&hi))
    {
      /* iterate all allowed params and stop if (1) declared  */
      /* parameter hn->key is found in allowed paramter list, */
      /* or (2) stop if there is not moar allowed params      */
      for(ocline = to->cparams;
          ocline->name && strcasecmp(hn->key, ocline->name);
          ocline++)
        ;
      if(!ocline->name)
        FAT("%d:%s: Parameter %s not allowed here.", command->line, to->name, hn->key);
    }

    /* set params (apply configuration) */
    for(ocline = to->cparams; ocline->name; ocline++)
    {
      SNODE *val;

      /* get configured value (or set default value if not specified) */
      val = tea_thread_param_value_get(tw->options, ocline->name);

      /* check if parameter is optional */
      if(!val && ocline->needed)
        FAT("%d:%s: Parameter %s is mandatory.", command->line, to->name, ocline->name);

      /* set value */
      if(tea_thread_param_value_set(tw, ocline, val))
        FAT("%d:%s: Cannot set parameter %s.", command->line, to->name, ocline->name);
    }
  } else {
    if(command->command.thc.to->options
    || command->command.thc.to->options->nentries > 0)
      FAT("%d:%s: Parameters not allowed for this type of thread.", command->line, to->name);
  }

  /* once configuration applied, launch thread configuration routine */
  if(tw->to->configure
  && tw->to->configure(tw, command, 1))
      FAT("%d:%s: Thread configuration failed.", command->line, to->name);

  /* add thread to the list */
  pthreadex_lock_get_exclusive_n(&ttable_lock, "install-thread");
  DBG("[tea] Installing thread %d.", tid);

  /* build threads */
  if(ttable[tid])
    FATAL_ERROR("Thread slot %d is used already.", tid);
  ttable[tid] = tw;

  /* launch thread */
  if(pthread_create(&(tw->pthread_id), NULL, tea_thread, tw) != 0)
  {
    ERR_ERRNO("Error creating thread %d", tid);
    FATAL_ERROR("Fatal error happened during thread creation.");
  }

termination:
  if(fatal && tw)
  {
    if(ttable[tid] == tw)
      ttable[tid] = NULL;
    if(tw->mqueue)
      mqueue_destroy(tw->mqueue);
    pthreadex_flag_destroy(&(tw->mwaiting));
    pthreadex_flag_destroy(&(tw->cleanup_do));
    pthreadex_flag_destroy(&(tw->cleanup_done));
    free(tw);
  }

  pthreadex_lock_release();
  
  if(!fatal)
    return;

  FAT("Aborting.");
}
Exemple #17
0
/** Release a Strophe connection object.
 *  Decrement the reference count by one for a connection, freeing the 
 *  connection object if the count reaches 0.
 *
 *  @param conn a Strophe connection object
 *
 *  @return TRUE if the connection object was freed and FALSE otherwise
 *
 *  @ingroup Connections
 */
int xmpp_conn_release(xmpp_conn_t * const conn)
{
    xmpp_ctx_t *ctx;
    xmpp_connlist_t *item, *prev;
    xmpp_handlist_t *hlitem, *thli;
    hash_iterator_t *iter;
    const char *key;
    int released = 0;

    if (conn->ref > 1) 
	conn->ref--;
    else {
	ctx = conn->ctx;

	/* remove connection from context's connlist */
	if (ctx->connlist->conn == conn) {
	    item = ctx->connlist;
	    ctx->connlist = item->next;
	    xmpp_free(ctx, item);
	} else {
	    prev = NULL;
	    item = ctx->connlist;
	    while (item && item->conn != conn) {
		prev = item;
		item = item->next;
	    }

	    if (!item) {
		xmpp_error(ctx, "xmpp", "Connection not in context's list\n");
	    } else {
		prev->next = item->next;
		xmpp_free(ctx, item);
	    }
	}

	/* free handler stuff
	 * note that userdata is the responsibility of the client
	 * and the handler pointers don't need to be freed since they
	 * are pointers to functions */

	hlitem = conn->timed_handlers;
	while (hlitem) {
	    thli = hlitem;
	    hlitem = hlitem->next;

	    xmpp_free(ctx, thli);
	}

	/* id handlers
	 * we have to traverse the hash table freeing list elements 
	 * then release the hash table */
	iter = hash_iter_new(conn->id_handlers);
	while ((key = hash_iter_next(iter))) {
	    hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key);
	    while (hlitem) {
		thli = hlitem;
		hlitem = hlitem->next;
		xmpp_free(conn->ctx, thli->id);
		xmpp_free(conn->ctx, thli);
	    }
	}
	hash_iter_release(iter);
	hash_release(conn->id_handlers);

	hlitem = conn->handlers;
	while (hlitem) {
	    thli = hlitem;
	    hlitem = hlitem->next;

	    if (thli->ns) xmpp_free(ctx, thli->ns);
	    if (thli->name) xmpp_free(ctx, thli->name);
	    if (thli->type) xmpp_free(ctx, thli->type);
	    xmpp_free(ctx, thli);
	}

	if (conn->stream_error) {
	    xmpp_stanza_release(conn->stream_error->stanza);
	    if (conn->stream_error->text)
		xmpp_free(ctx, conn->stream_error->text);
	    xmpp_free(ctx, conn->stream_error);
	}

        parser_free(conn->parser);
	
	if (conn->domain) xmpp_free(ctx, conn->domain);
	if (conn->jid) xmpp_free(ctx, conn->jid);
    if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid);
	if (conn->pass) xmpp_free(ctx, conn->pass);
	if (conn->stream_id) xmpp_free(ctx, conn->stream_id);
	if (conn->lang) xmpp_free(ctx, conn->lang);
	xmpp_free(ctx, conn);
	released = 1;
    }

    return released;
}
Exemple #18
0
/** Release a Strophe connection object.
 *  Decrement the reference count by one for a connection, freeing the
 *  connection object if the count reaches 0.
 *
 *  @param conn a Strophe connection object
 *
 *  @return TRUE if the connection object was freed and FALSE otherwise
 *
 *  @ingroup Connections
 */
int xmpp_conn_release(xmpp_conn_t * const conn)
{
	xmpp_ctx_t *ctx;
	list_t *item;
	xmpp_handler_t *temp;
	xmpp_handlist_t *hlitem, *thli;
	hash_iterator_t *iter;
	const char *key;

	if (conn->ref > 1) {
		conn->ref--;
		return 0;
	}

	ctx = conn->ctx;

	/* remove connection from context's connlist */
	item = list_pop_by_data(ctx->connlist, (void *)conn);
	if (item)
		xmpp_free(ctx, item);
	else
		xmpp_error(ctx, "xmpp", "Connection not in context's list\n");

	/* free handler stuff
	 * note that userdata is the responsibility of the client
	 * and the handler pointers don't need to be freed since they
	 * are pointers to functions */

	while ((item = list_shift(conn->timed_handlers))) {
		xmpp_free(ctx, item->data);
		xmpp_free(ctx, item);
	}
	list_destroy(conn->timed_handlers);

	/* id handlers
	 * we have to traverse the hash table freeing list elements
	 * then release the hash table */
	iter = hash_iter_new(conn->id_handlers);
	while ((key = hash_iter_next(iter))) {
		hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key);
		while (hlitem) {
			thli = hlitem;
			hlitem = hlitem->next;
			xmpp_free(ctx, thli->id);
			xmpp_free(ctx, thli);
		}
	}
	hash_iter_release(iter);
	hash_release(conn->id_handlers);

	while ((item = list_shift(conn->handlers))) {
		temp = (xmpp_handler_t *)item->data;

		if (temp->ns)
			xmpp_free(ctx, temp->ns);
		if (temp->name)
			xmpp_free(ctx, temp->name);
		if (temp->type)
			xmpp_free(ctx, temp->type);
		xmpp_free(ctx, temp);
		xmpp_free(ctx, item);
	}
	list_destroy(conn->handlers);

	if (conn->stream_error) {
		xmpp_stanza_release(conn->stream_error->stanza);
		if (conn->stream_error->text)
			xmpp_free(ctx, conn->stream_error->text);
		xmpp_free(ctx, conn->stream_error);
	}

	parser_free(conn->parser);

	/* free send_queue */
	list_destroy(conn->send_queue);

	if (conn->domain)
		xmpp_free(ctx, conn->domain);
	if (conn->jid)
		xmpp_free(ctx, conn->jid);
	if (conn->bound_jid)
		xmpp_free(ctx, conn->bound_jid);
	if (conn->pass)
		xmpp_free(ctx, conn->pass);
	if (conn->stream_id)
		xmpp_free(ctx, conn->stream_id);
	if (conn->lang)
		xmpp_free(ctx, conn->lang);
	if (conn->tls)
		tls_free(conn->tls);
	xmpp_free(ctx, conn);

	return 1;
}