Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}