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; }
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)); }
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); }
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; }
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; }
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; }