void silc_client_empty_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel) { SilcHashTableList htl; SilcChannelUser chu; silc_rwlock_wrlock(channel->internal.lock); silc_hash_table_list(channel->user_list, &htl); while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { silc_hash_table_del(chu->client->channels, chu->channel); silc_hash_table_del(chu->channel->user_list, chu->client); silc_client_unref_client(client, conn, chu->client); silc_client_unref_channel(client, conn, chu->channel); silc_free(chu); } silc_rwlock_unlock(channel->internal.lock); silc_hash_table_list_reset(&htl); }
void silc_client_remove_from_channels(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { SilcHashTableList htl; SilcChannelUser chu; if (!silc_hash_table_count(client_entry->channels)) return; SILC_LOG_DEBUG(("Remove client from all joined channels")); silc_rwlock_wrlock(client_entry->internal.lock); silc_hash_table_list(client_entry->channels, &htl); while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { silc_rwlock_wrlock(chu->channel->internal.lock); silc_hash_table_del(chu->client->channels, chu->channel); silc_hash_table_del(chu->channel->user_list, chu->client); /* If channel became empty, delete it */ if (!silc_hash_table_count(chu->channel->user_list)) silc_client_del_channel(client, conn, chu->channel); silc_rwlock_unlock(chu->channel->internal.lock); silc_client_unref_client(client, conn, chu->client); silc_client_unref_channel(client, conn, chu->channel); silc_free(chu); } silc_rwlock_unlock(client_entry->internal.lock); silc_hash_table_list_reset(&htl); }
static void silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components) { SilcPurple sg = gc->proto_data; const char *chname; char tmp[256], *tmp2; GString *s; SilcChannelEntry channel; SilcHashTableList htl; SilcChannelUser chu; if (!components) return; chname = g_hash_table_lookup(components, "channel"); if (!chname) return; channel = silc_client_get_channel(sg->client, sg->conn, (char *)chname); if (!channel) { silc_client_get_channel_resolve(sg->client, sg->conn, (char *)chname, silcpurple_chat_getinfo_res, components); return; } s = g_string_new(""); tmp2 = g_markup_escape_text(channel->channel_name, -1); g_string_append_printf(s, _("<b>Channel Name:</b> %s"), tmp2); g_free(tmp2); if (channel->user_list && silc_hash_table_count(channel->user_list)) g_string_append_printf(s, _("<br><b>User Count:</b> %d"), (int)silc_hash_table_count(channel->user_list)); silc_hash_table_list(channel->user_list, &htl); while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) { tmp2 = g_markup_escape_text(chu->client->nickname, -1); g_string_append_printf(s, _("<br><b>Channel Founder:</b> %s"), tmp2); g_free(tmp2); break; } } silc_hash_table_list_reset(&htl); if (channel->cipher) g_string_append_printf(s, _("<br><b>Channel Cipher:</b> %s"), channel->cipher); if (channel->hmac) /* Definition of HMAC: http://en.wikipedia.org/wiki/HMAC */ g_string_append_printf(s, _("<br><b>Channel HMAC:</b> %s"), channel->hmac); if (channel->topic) { tmp2 = g_markup_escape_text(channel->topic, -1); g_string_append_printf(s, _("<br><b>Channel Topic:</b><br>%s"), tmp2); g_free(tmp2); } if (channel->mode) { g_string_append_printf(s, _("<br><b>Channel Modes:</b> ")); silcpurple_get_chmode_string(channel->mode, tmp, sizeof(tmp)); g_string_append(s, tmp); } if (channel->founder_key) { char *fingerprint, *babbleprint; unsigned char *pk; SilcUInt32 pk_len; pk = silc_pkcs_public_key_encode(channel->founder_key, &pk_len); if (pk) { fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); g_string_append_printf(s, _("<br><b>Founder Key Fingerprint:</b><br>%s"), fingerprint); g_string_append_printf(s, _("<br><b>Founder Key Babbleprint:</b><br>%s"), babbleprint); silc_free(fingerprint); silc_free(babbleprint); silc_free(pk); } } purple_notify_formatted(gc, NULL, _("Channel Information"), NULL, s->str, NULL, NULL); g_string_free(s, TRUE); }
unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len) { SilcMime part; SilcHashTableList htl; SilcBufferStruct buf; SilcBuffer buffer; char *field, *value, tmp[1024], tmp2[4]; unsigned char *ret; int i; SILC_LOG_DEBUG(("Encoding MIME message")); if (!mime) return NULL; memset(&buf, 0, sizeof(buf)); /* Encode the headers. Order doesn't matter */ i = 0; silc_hash_table_list(mime->fields, &htl); while (silc_hash_table_get(&htl, (void *)&field, (void *)&value)) { memset(tmp, 0, sizeof(tmp)); SILC_LOG_DEBUG(("Header %s: %s", field, value)); silc_snprintf(tmp, sizeof(tmp) - 1, "%s: %s\r\n", field, value); silc_buffer_strformat(&buf, tmp, SILC_STRFMT_END); i++; } silc_hash_table_list_reset(&htl); if (i) silc_buffer_strformat(&buf, "\r\n", SILC_STRFMT_END); /* Assemble the whole buffer */ buffer = silc_buffer_alloc_size(mime->data_len + silc_buffer_len(&buf)); if (!buffer) return NULL; /* Add headers */ if (silc_buffer_len(&buf)) { silc_buffer_put(buffer, buf.head, silc_buffer_len(&buf)); silc_buffer_pull(buffer, silc_buffer_len(&buf)); silc_buffer_purge(&buf); } /* Add data */ if (mime->data) { SILC_LOG_DEBUG(("Data len %d", mime->data_len)); silc_buffer_put(buffer, mime->data, mime->data_len); } /* Add multiparts */ if (mime->multiparts) { SILC_LOG_DEBUG(("Encoding multiparts")); silc_dlist_start(mime->multiparts); i = 0; while ((part = silc_dlist_get(mime->multiparts)) != SILC_LIST_END) { unsigned char *pd; SilcUInt32 pd_len; /* Recursive encoding */ pd = silc_mime_encode(part, &pd_len); if (!pd) return NULL; memset(tmp, 0, sizeof(tmp)); memset(tmp2, 0, sizeof(tmp2)); /* If fields are not present, add extra CRLF */ if (!silc_hash_table_count(part->fields)) silc_snprintf(tmp2, sizeof(tmp2) - 1, "\r\n"); silc_snprintf(tmp, sizeof(tmp) - 1, "%s--%s\r\n%s", i != 0 ? "\r\n" : "", mime->boundary, tmp2); i = 1; buffer = silc_buffer_realloc(buffer, silc_buffer_truelen(buffer) + pd_len + strlen(tmp)); if (!buffer) return NULL; silc_buffer_put_tail(buffer, tmp, strlen(tmp)); silc_buffer_pull_tail(buffer, strlen(tmp)); silc_buffer_put_tail(buffer, pd, pd_len); silc_buffer_pull_tail(buffer, pd_len); silc_free(pd); } memset(tmp, 0, sizeof(tmp)); silc_snprintf(tmp, sizeof(tmp) - 1, "\r\n--%s--\r\n", mime->boundary); buffer = silc_buffer_realloc(buffer, silc_buffer_truelen(buffer) + strlen(tmp)); if (!buffer) return NULL; silc_buffer_put_tail(buffer, tmp, strlen(tmp)); silc_buffer_pull_tail(buffer, strlen(tmp)); } ret = silc_buffer_steal(buffer, encoded_len); silc_buffer_free(buffer); return ret; }
static void refresh_nicklist_resolved(SilcClient client, SilcClientConnection conn, SilcClientEntry *clients, SilcUInt32 clients_count, void *context) { SilcJoinResolve *r = context; SilcChannelEntry channel_entry = r->channel; SilcHashTableList htl; SilcChannelUser chu; struct presence *presence; struct channel_presence *chpres; struct i_silc_presence *silc_presence; struct i_silc_gateway_connection *silc_gwconn; struct i_silc_channel_connection *silc_chconn; int usercount = 0; char *userhost; silc_gwconn = (struct i_silc_gateway_connection *) i_silc_gateway_connection_lookup_conn(conn); i_assert(silc_gwconn != NULL); silc_chconn = i_silc_channel_connection_lookup_entry(silc_gwconn, channel_entry); i_assert(silc_chconn != NULL); if( !clients && r->retry < 1 ) { r->retry++; silc_client_get_clients_by_channel(client, conn, channel_entry, refresh_nicklist_resolved, context); return; } silc_hash_table_list(channel_entry->user_list, &htl); while( silc_hash_table_get(&htl, NULL, (void *)&chu) ) { if( !chu->client->nickname ) continue; usercount++; /* Do not init myself, as I'm already inited */ if( chu->client == silc_gwconn->conn->local_entry ) continue; userhost = i_silc_userhost(chu->client); presence = presence_lookup(&silc_gwconn->gwconn, chu->client->nickname); if( presence == NULL ) { presence = presence_init(&silc_gwconn->gwconn, chu->client->nickname); presence_set_address(presence, userhost); presence_set_real_name(presence, chu->client->realname); chpres = channel_connection_presence_init( &silc_chconn->chconn, presence); channel_connection_add_presence(&silc_chconn->chconn, chpres); presence_unref(presence); silc_presence = (struct i_silc_presence *)presence; silc_presence->client_entry = chu->client; } else { chpres = channel_connection_presence_init( &silc_chconn->chconn, presence); channel_connection_add_presence(&silc_chconn->chconn, chpres); } free(userhost); } silc_hash_table_list_reset(&htl); channel_connection_initial_presences_added(&silc_chconn->chconn); }