示例#1
0
SilcBool silc_client_add_to_channel(SilcClient client,
				    SilcClientConnection conn,
				    SilcChannelEntry channel,
				    SilcClientEntry client_entry,
				    SilcUInt32 cumode)
{
  SilcChannelUser chu;

  if (silc_client_on_channel(channel, client_entry))
    return TRUE;

  SILC_LOG_DEBUG(("Add client %s to channel", client_entry->nickname));

  chu = silc_calloc(1, sizeof(*chu));
  if (!chu)
    return FALSE;

  chu->client = client_entry;
  chu->channel = channel;
  chu->mode = cumode;

  silc_client_ref_client(client, conn, client_entry);
  silc_client_ref_channel(client, conn, channel);

  silc_hash_table_add(channel->user_list, client_entry, chu);
  silc_hash_table_add(client_entry->channels, channel, chu);

  return TRUE;
}
示例#2
0
void silc_mime_add_field(SilcMime mime, const char *field, const char *value)
{
    if (!mime || !field || !value)
        return;

    silc_hash_table_add(mime->fields, strdup(field), strdup(value));
}
示例#3
0
void silc_hash_table_rehash(SilcHashTable ht, SilcUInt32 new_size)
{
  int i;
  SilcHashTableEntry *table, e, tmp;
  SilcUInt32 table_size, size_index;
  SilcBool auto_rehash;

  SILC_HT_DEBUG(("Start"));

  if (new_size)
    silc_hash_table_primesize(new_size, &size_index);
  else
    silc_hash_table_primesize(ht->entry_count, &size_index);

  if (size_index == ht->table_size)
    return;

  SILC_HT_DEBUG(("Rehashing"));

  /* Take old hash table */
  table = ht->table;
  table_size = ht->table_size;
  auto_rehash = ht->auto_rehash;
  ht->auto_rehash = FALSE;

  /* Allocate new table */
  ht->table = silc_calloc(primesize[size_index], sizeof(*ht->table));
  if (!ht->table)
    return;
  ht->table_size = size_index;
  ht->entry_count = 0;

  /* Rehash */
  for (i = 0; i < primesize[table_size]; i++) {
    e = table[i];
    while (e) {
      silc_hash_table_add(ht, e->key, e->context);
      tmp = e;
      e = e->next;

      /* Remove old entry */
      silc_free(tmp);
    }
  }

  ht->auto_rehash = auto_rehash;

  /* Remove old table */
  silc_free(table);
}
示例#4
0
SilcAttributePayload silc_client_attribute_add(SilcClient client,
					       SilcClientConnection conn,
					       SilcAttribute attribute,
					       void *object,
					       SilcUInt32 object_size)
{
  SilcAttributePayload attr;

  attr = silc_attribute_payload_alloc(attribute, SILC_ATTRIBUTE_FLAG_VALID,
				      object, object_size);
  if (!attr)
    return NULL;

  if (!conn->internal->attrs)
    conn->internal->attrs =
      silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
			    NULL, silc_client_attribute_destruct,
			    NULL, TRUE);
  silc_hash_table_add(conn->internal->attrs,
		      SILC_32_TO_PTR(attribute), attr);
  return attr;
}
示例#5
0
SilcServerPending silc_server_command_pending(SilcServerThread thread,
					      SilcUInt16 cmd_ident)
{
  SilcServerPending pending;

  silc_mutex_lock(thread->server->lock);

  /* Check if pending already */
  if (silc_hash_table_find(thread->server->pending_commands,
			   SILC_32_TO_PTR(cmd_ident), NULL,
			   (void **)&pending)) {
    pending->refcnt++;
    silc_mutex_unlock(thread->server->lock);
    return pending;
  }

  pending = silc_calloc(1, sizeof(*pending));
  if (!pending) {
    silc_mutex_unlock(thread->server->lock);
    return NULL;
  }

  silc_fsm_event_init(&pending->wait_reply, &thread->fsm, 0);
  pending->refcnt = 1;
  pending->cmd_ident = cmd_ident;

  /* Add to pending commands hash table */
  if (!silc_hash_table_add(thread->server->pending_commands,
			   SILC_32_TO_PTR(cmd_ident), pending)) {
    silc_mutex_unlock(thread->server->lock);
    silc_free(pending);
    return NULL;
  }

  silc_mutex_unlock(thread->server->lock);

  return pending;
}
示例#6
0
SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial)
{
    char *type, *id = NULL, *tmp;
    SilcHashTable f;
    SilcMime p, complete;
    int i, number, total = -1;
    const unsigned char *data;
    SilcUInt32 data_len;
    SilcBuffer compbuf = NULL;

    SILC_LOG_DEBUG(("Assembling MIME fragments"));

    if (!assembler || !partial)
        goto err;

    type = (char *)silc_mime_get_field(partial, "Content-Type");
    if (!type)
        goto err;

    /* Get ID */
    tmp = strstr(type, "id=");
    if (!tmp)
        goto err;
    if (strlen(tmp) <= 4)
        goto err;
    tmp += 3;
    if (*tmp == '"')
        tmp++;
    id = strdup(tmp);
    if (strchr(id, ';'))
        *strchr(id, ';') = '\0';
    if (strrchr(id, '"'))
        *strrchr(id, '"') = '\0';

    SILC_LOG_DEBUG(("Fragment ID %s", id));

    /* Get fragment number */
    tmp = strstr(type, "number=");
    if (!tmp)
        goto err;
    tmp = strchr(tmp, '=');
    if (strlen(tmp) < 2)
        goto err;
    tmp++;
    if (strchr(tmp, ';')) {
        tmp = strdup(tmp);
        *strchr(tmp, ';') = '\0';
        number = atoi(tmp);
        silc_free(tmp);
    } else {
        number = atoi(tmp);
    }

    SILC_LOG_DEBUG(("Fragment number %d", number));

    /* Find fragments with this ID. */
    if (!silc_hash_table_find(assembler->fragments, (void *)id,
                              NULL, (void *)&f)) {
        /* This is new fragment to new message.  Add to hash table and return. */
        f = silc_hash_table_alloc(0, silc_hash_uint, NULL, NULL, NULL,
                                  silc_mime_assemble_dest, NULL, TRUE);
        if (!f)
            goto err;
        silc_hash_table_add(f, SILC_32_TO_PTR(number), partial);
        silc_hash_table_add(assembler->fragments, id, f);
        return NULL;
    }

    /* Try to get total number */
    tmp = strstr(type, "total=");
    if (tmp) {
        tmp = strchr(tmp, '=');
        if (strlen(tmp) < 2)
            goto err;
        tmp++;
        if (strchr(tmp, ';')) {
            tmp = strdup(tmp);
            *strchr(tmp, ';') = '\0';
            total = atoi(tmp);
            silc_free(tmp);
        } else {
            total = atoi(tmp);
        }

        SILC_LOG_DEBUG(("Fragment total %d", total));
    }

    /* If more fragments to come, add to hash table */
    if (number != total) {
        silc_hash_table_add(f, SILC_32_TO_PTR(number), partial);
        return NULL;
    }

    silc_hash_table_add(f, SILC_32_TO_PTR(number), partial);

    /* Verify that we really have all the fragments */
    if (silc_hash_table_count(f) < total)
        return NULL;

    /* Assemble the complete MIME message now. We get them in order from
       the hash table. */
    for (i = 1; i <= total; i++) {
        if (!silc_hash_table_find(f, SILC_32_TO_PTR(i), NULL, (void *)&p))
            goto err;

        /* The fragment is in the data portion of the partial message */
        data = silc_mime_get_data(p, &data_len);
        if (!data)
            goto err;

        /* Assemble */
        if (!compbuf) {
            compbuf = silc_buffer_alloc_size(data_len);
            if (!compbuf)
                goto err;
            silc_buffer_put(compbuf, data, data_len);
        } else {
            compbuf = silc_buffer_realloc(compbuf, silc_buffer_truelen(compbuf) +
                                          data_len);
            if (!compbuf)
                goto err;
            silc_buffer_put_tail(compbuf, data, data_len);
            silc_buffer_pull_tail(compbuf, data_len);
        }
    }

    /* Now parse the complete MIME message and deliver it */
    complete = silc_mime_decode(NULL, (const unsigned char *)compbuf->head,
                                silc_buffer_truelen(compbuf));
    if (!complete)
        goto err;

    /* Delete the hash table entry. Destructors will free memory */
    silc_hash_table_del(assembler->fragments, (void *)id);
    silc_free(id);
    silc_buffer_free(compbuf);

    return complete;

err:
    silc_free(id);
    if (compbuf)
        silc_buffer_free(compbuf);
    silc_mime_free(partial);
    return NULL;
}