Exemplo n.º 1
0
void pidgin_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account) {
	struct log_viewer_hash_t *ht;
	PidginLogViewer *lv = NULL;
	const char *name = screenname;
	char *title;
	GdkPixbuf *prpl_icon;

	g_return_if_fail(account != NULL);
	g_return_if_fail(screenname != NULL);

	ht = g_new0(struct log_viewer_hash_t, 1);

	ht->type = type;
	ht->screenname = g_strdup(screenname);
	ht->account = account;

	if (log_viewers == NULL) {
		log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal);
	} else if ((lv = g_hash_table_lookup(log_viewers, ht))) {
		gtk_window_present(GTK_WINDOW(lv->window));
		g_free(ht->screenname);
		g_free(ht);
		return;
	}

	if (type == PURPLE_LOG_CHAT) {
		PurpleChat *chat;

		chat = purple_blist_find_chat(account, screenname);
		if (chat != NULL)
			name = purple_chat_get_name(chat);

		title = g_strdup_printf(_("Conversations in %s"), name);
	} else {
		PurpleBuddy *buddy;

		buddy = purple_find_buddy(account, screenname);
		if (buddy != NULL)
			name = purple_buddy_get_contact_alias(buddy);

		title = g_strdup_printf(_("Conversations with %s"), name);
	}

	prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);

	display_log_viewer(ht, purple_log_get_logs(type, screenname, account),
			title, gtk_image_new_from_pixbuf(prpl_icon),
			purple_log_get_total_size(type, screenname, account));

	if (prpl_icon)
		g_object_unref(prpl_icon);
	g_free(title);
}
Exemplo n.º 2
0
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = purple_conversation_get_account(c);
	const char *name = purple_conversation_get_name(c);
	PurpleConversationType convtype;
	GList *logs = NULL;
	const char *alias = name;
	PurpleLogReadFlags flags;
	char *history;
	char *header;
	PurpleMessageFlags mflag;

	convtype = purple_conversation_get_type(c);
	if (convtype == PURPLE_CONV_TYPE_IM) {
		GSList *buddies;
		GSList *cur;
		FinchConv *fc = FINCH_CONV(c);
		if (fc->list && fc->list->next) /* We were already in the middle of a conversation. */
			return;

		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_ims"))
			return;

		/* Find buddies for this conversation. */
		buddies = purple_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data);

		for (cur = buddies; cur != NULL; cur = cur->next) {
			PurpleBlistNode *node = cur->data;
			if ((node != NULL) &&
					((purple_blist_node_get_sibling_prev(node) != NULL) ||
						(purple_blist_node_get_sibling_next(node) != NULL))) {
				PurpleBlistNode *node2;

				alias = purple_buddy_get_contact_alias((PurpleBuddy *)node);

				/* We've found a buddy that matches this conversation.  It's part of a
				 * PurpleContact with more than one PurpleBuddy.  Loop through the PurpleBuddies
				 * in the contact and get all the logs. */
				for (node2 = purple_blist_node_get_first_child(purple_blist_node_get_parent(node));
						node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2)) {
					logs = g_list_concat(
							purple_log_get_logs(PURPLE_LOG_IM,
								purple_buddy_get_name((PurpleBuddy *)node2),
								purple_buddy_get_account((PurpleBuddy *)node2)),
							logs);
				}
				break;
			}
		}
		g_slist_free(buddies);

		if (logs == NULL)
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
		else
			logs = g_list_sort(logs, purple_log_compare);
	} else if (convtype == PURPLE_CONV_TYPE_CHAT) {
		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_chats"))
			return;

		logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account);
	}

	if (logs == NULL)
		return;

	mflag = PURPLE_MESSAGE_NO_LOG | PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_DELAYED;
	history = purple_log_read((PurpleLog*)logs->data, &flags);

	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), alias,
			purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time)));
	purple_conversation_write(c, "", header, mflag, time(NULL));
	g_free(header);

	if (flags & PURPLE_LOG_READ_NO_NEWLINE)
		purple_str_strip_char(history, '\n');
	purple_conversation_write(c, "", history, mflag, time(NULL));
	g_free(history);

	purple_conversation_write(c, "", "<hr>", mflag, time(NULL));

	g_list_foreach(logs, (GFunc)purple_log_free, NULL);
	g_list_free(logs);
}
Exemplo n.º 3
0
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = NULL;
	PurpleConversationType convtype;
	PidginConversation *gtkconv = NULL;
	GtkTextIter start;
	GtkIMHtmlOptions options;
	GList *logs = NULL, *logs_head = NULL;
	struct tm *log_tm = NULL, *local_tm = NULL;
	time_t t, log_time;
	double limit_time = 0.0;
	const char *name = NULL, *alias = NULL, *LOG_MODE = NULL;
	char *header = NULL, *protocol = NULL, *history = NULL;
	int conv_counter = 0;
	int limit_offset = 0;
	int byte_counter = 0;
	int check_time = 0;
	int log_size, overshoot;

	account = purple_conversation_get_account(c);
	name = purple_conversation_get_name(c);
	alias = name;
	LOG_MODE = purple_prefs_get_string("/purple/logging/format");

	/* If logging isn't enabled, don't show any history */
	if(!purple_prefs_get_bool("/purple/logging/log_ims") &&
			!purple_prefs_get_bool("/purple/logging/log_chats"))
		return;
	
	/* If the user wants to show 0 logs, stop now */
	if(PREF_NUMBER_VAL == 0) {
		return;
	}
	
	/* If the logging mode is html, set the output options to include no newline.
	 * Otherwise, it's normal text, so we don't need extra lines */
	if(strcasecmp(LOG_MODE, "html")==0) {
		options = GTK_IMHTML_NO_NEWLINE;
	} else {
		options = GTK_IMHTML_NO_COLOURS;
	}
	
	/* Determine whether this is an IM or a chat. In either case, if the user has that
	 * particular log type disabled, the logs file doesnt not get specified */
	convtype = purple_conversation_get_type(c);
	if (convtype == PURPLE_CONV_TYPE_IM && PREF_IM_VAL) {
		GSList *cur;
		GSList *buddies = NULL;

		/* Find buddies for this conversation. */
		buddies = purple_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data);

		for(cur = buddies; cur; cur = cur->next) {
			PurpleBlistNode *node = cur->data;

			if(node && (node->prev || node->next)) {
				PurpleBlistNode *node2;

				for(node2 = node->parent->child; node2; node2 = node2->next) {
					logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM,
								purple_buddy_get_name((PurpleBuddy *)node2),
								purple_buddy_get_account((PurpleBuddy *)node2)), logs);
				}

				break;
			}
		}

		g_slist_free(buddies);

		if (logs)
			logs = g_list_sort(logs, purple_log_compare);
		else
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
	} else if (convtype == PURPLE_CONV_TYPE_CHAT && PREF_CHAT_VAL) {
		logs = purple_log_get_logs(PURPLE_LOG_CHAT,
			purple_conversation_get_name(c), purple_conversation_get_account(c));
	}

	gtkconv = PIDGIN_CONVERSATION(c);

	/* The logs are non-existant or the user has disabled this type for log displaying. */
	if (!logs) {
		return;
	}

	/* Keep a pointer to the head of the logs for freeing later */
	logs_head = logs;

	/* If all time prefs are not 0, prepare to check times */
	if (!(PREF_MINS_VAL == 0 && PREF_HOURS_VAL == 0 && PREF_DAYS_VAL == 0)) {
		check_time = 1;

		/* Grab current time and normalize it to UTC */
		t = time(NULL);
		local_tm = gmtime(&t);
		t = mktime(local_tm);

		limit_time = (PREF_MINS_VAL * 60.0) + (PREF_HOURS_VAL * 60.0 * 60.0) +
				(PREF_DAYS_VAL * 60.0 * 60.0 * 24.0);
	}

	/* The protocol will need to be adjusted for each log for correct display,
	   so save the current imhtml protocol_name to restore it later */
	protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));

	/* Calculate time for the first log */
	log_tm = gmtime(&((PurpleLog*)logs->data)->time);
	log_time = mktime(log_tm);

	/* Continue to add older logs until they run out or the conditions are no
	   longer met */
	while (logs && conv_counter < PREF_NUMBER_VAL
			&& byte_counter < PREF_BYTES_VAL
			&& (!check_time || difftime(t, log_time) < limit_time)) {
		guint flags;

		/* Get the current log's contents as a char* */
		history = purple_log_read((PurpleLog*)logs->data, &flags);
		log_size = strlen(history);

		if (flags & PURPLE_LOG_READ_NO_NEWLINE)
			options |= GTK_IMHTML_NO_NEWLINE;
		else
			options &= ~GTK_IMHTML_NO_NEWLINE;

		/* Update the overall byte count and determine if this log exceeds the limit */
		byte_counter += log_size;
		overshoot = byte_counter - PREF_BYTES_VAL;
		if (overshoot > 0) {
			/* Start looking at the maximum log size for a newline to break at */
			limit_offset = overshoot;
			/* Find the next \n, or stop if the end of the log is reached */
			while (history[limit_offset] && history[limit_offset] != '\n') {
				limit_offset++;
			}
			/* If we're at or very close to the end of the log, forget this log */
			if (!history[limit_offset] || (log_size - limit_offset < 3)) {
				limit_offset = -1;
			}
			else {
				/* Start at the first character after the newline */
				limit_offset++;
			}
		}

		conv_counter++;

		/* If this log won't fit at all, don't display it in the conversation */
		if (limit_offset != -1) {
			/* Set the correct protocol_name for this log */
			gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
					purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));

			/* Prepend the contents of the log starting at the calculated offset */
			gtk_text_buffer_get_iter_at_offset(GTK_IMHTML(gtkconv->imhtml)->text_buffer,
					&start, 0);
			gtk_imhtml_insert_html_at_iter(GTK_IMHTML(gtkconv->imhtml),
						history + limit_offset, options, &start);

			/* Prepend the conversation header */
			if (PREF_DATES_VAL) {
				header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), alias,
					purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time)));
				gtk_text_buffer_get_iter_at_offset(GTK_IMHTML(gtkconv->imhtml)->text_buffer,
						&start, 0);
				gtk_imhtml_insert_html_at_iter(GTK_IMHTML(gtkconv->imhtml),
						header, options, &start);
				g_free(header);
			}
		}

		g_free(history);

		if (limit_offset > 0) {
			/* This log had to be chopped to fit, so stop after this one */
			break;
		}

		logs = logs->next;

		/* Recalculate log time if we haven't run out of logs */
		if (logs) {
			log_tm = gmtime(&((PurpleLog*)logs->data)->time);
			log_time = mktime(log_tm);
		}
	}

	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<hr>", options);

	/* Restore the original protocol_name */
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
	g_free(protocol);
	
	g_object_ref(G_OBJECT(gtkconv->imhtml));
	g_idle_add(_scroll_imhtml_to_end, gtkconv->imhtml);
	
	/* Clear the allocated memory that the logs are using */
	g_list_foreach(logs_head, (GFunc)purple_log_free, NULL);
	g_list_free(logs_head);
	
}
Exemplo n.º 4
0
void pidgin_log_show_contact(PurpleContact *contact) {
	struct log_viewer_hash_t *ht;
	PurpleBlistNode *child;
	PidginLogViewer *lv = NULL;
	GList *logs = NULL;
	GdkPixbuf *pixbuf;
	GtkWidget *image;
	const char *name = NULL;
	char *title;
	int total_log_size = 0;

	g_return_if_fail(contact != NULL);

	ht = g_new0(struct log_viewer_hash_t, 1);
	ht->type = PURPLE_LOG_IM;
	ht->contact = contact;

	if (log_viewers == NULL) {
		log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal);
	} else if ((lv = g_hash_table_lookup(log_viewers, ht))) {
		gtk_window_present(GTK_WINDOW(lv->window));
		g_free(ht);
		return;
	}

	for (child = contact->node.child ; child ; child = child->next) {
		if (!PURPLE_BLIST_NODE_IS_BUDDY(child))
			continue;

		logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, ((PurpleBuddy *)child)->name,
						((PurpleBuddy *)child)->account), logs);
		total_log_size += purple_log_get_total_size(PURPLE_LOG_IM, ((PurpleBuddy *)child)->name, ((PurpleBuddy *)child)->account);
	}
	logs = g_list_sort(logs, purple_log_compare);

	image = gtk_image_new();
	pixbuf = gtk_widget_render_icon(image, PIDGIN_STOCK_STATUS_PERSON,
					gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow");
	if (pixbuf) {
		gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
		g_object_unref(pixbuf);
	} else {
		gtk_widget_destroy(image);
		image = NULL;
	}

	if (contact->alias != NULL)
		name = contact->alias;
	else if (contact->priority != NULL)
		name = purple_buddy_get_contact_alias(contact->priority);

	/* This will happen if the contact doesn't have an alias,
	 * and none of the contact's buddies are online.
	 * There is probably a better way to deal with this. */
	if (name == NULL) {
		if (contact->node.child != NULL && PURPLE_BLIST_NODE_IS_BUDDY(contact->node.child))
			name = purple_buddy_get_contact_alias((PurpleBuddy *) contact->node.child);
		if (name == NULL)
			name = "";
	}

	title = g_strdup_printf(_("Conversations with %s"), name);
	display_log_viewer(ht, logs, title, image, total_log_size);
	g_free(title);
}
Exemplo n.º 5
0
static int try_to_append(PurpleBuddy *buddy, const char *message)
{
	int retval = 0;

	/* Log file to write to */
	PurpleLog *log = NULL;

	GList *list;
	list = purple_log_get_logs(PURPLE_LOG_IM, buddy->name, buddy->account);
	if (!list)
		return 0;

	log = g_list_first(list)->data;
	
	if (!log) {
		if (DEBUG)
			printf(INTRO "Unable to append, log list empty\n");
		goto cleanup;	
	}
	
	if (!log->logger) {
		if (DEBUG)
			printf(INTRO "Unable to append logger is NULL\n");
		goto cleanup;	
	}

	if (!log->logger_data) {
		if (DEBUG)
			printf(INTRO "Unable to append NULL logger_data\n");
		goto cleanup;	
	}

	/* We must reopen log file 
	 * This should work with txt logger and html logger.
	 * No idea about others. This is kind of hack.
	 *
	 * We don't know real type of logger_data.
	 */
	PurpleLogCommonLoggerData *data = log->logger_data;

	if (data->file) {
		/* Right. This should be NULL really, type might be wrong. */
		if (DEBUG) 
			printf(INTRO "WARNING incompatible logger or logging system updated!\n");
		goto cleanup;	
	} 

	data->file = fopen(data->path, "a");
	if (!data->file) {
		if (DEBUG) 
			printf(INTRO "Unable to append to existing log!\n");
		goto cleanup;	
	}

	const char *alias = purple_buddy_get_alias(buddy);
	purple_log_write(log, PURPLE_MESSAGE_SYSTEM, alias, time(NULL), message);

	fclose(data->file);
	data->file = NULL;

	/* All fine */
	retval = 1;
cleanup:
        g_list_foreach(list, (GFunc)purple_log_free, NULL);
	g_list_free(list);
	return retval;
}
Exemplo n.º 6
0
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = purple_conversation_get_account(c);
	const char *name = purple_conversation_get_name(c);
	GList *logs = NULL;
	const char *alias = name;
	guint flags;
	char *history;
	PidginConversation *gtkconv;
#if 0
	/* FIXME: WebView has no options */
	GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS;
#endif
	char *header;
#if 0
	/* FIXME: WebView has no protocol setting */
	char *protocol;
#endif
	char *escaped_alias;
	const char *header_date;

	gtkconv = PIDGIN_CONVERSATION(c);
	g_return_if_fail(gtkconv != NULL);

	/* An IM which is the first active conversation. */
	g_return_if_fail(gtkconv->convs != NULL);
	if (PURPLE_IS_IM_CONVERSATION(c) && !gtkconv->convs->next)
	{
		GSList *buddies;
		GSList *cur;

		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_ims"))
			return;

		/* Find buddies for this conversation. */
		buddies = purple_blist_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(buddies->data));

		for (cur = buddies; cur != NULL; cur = cur->next)
		{
			PurpleBlistNode *node = cur->data;
			PurpleBlistNode *prev = purple_blist_node_get_sibling_prev(node);
			PurpleBlistNode *next = purple_blist_node_get_sibling_next(node);
			if ((node != NULL) && ((prev != NULL) || (next != NULL)))
			{
				PurpleBlistNode *node2;
				PurpleBlistNode *parent = purple_blist_node_get_parent(node);
				PurpleBlistNode *child = purple_blist_node_get_first_child(parent);

				alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(node));

				/* We've found a buddy that matches this conversation.  It's part of a
				 * PurpleContact with more than one PurpleBuddy.  Loop through the PurpleBuddies
				 * in the contact and get all the logs. */
				for (node2 = child ; node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2))
				{
					logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM,
							purple_buddy_get_name(PURPLE_BUDDY(node2)),
							purple_buddy_get_account(PURPLE_BUDDY(node2))),
							logs);
				}
				break;
			}
		}
		g_slist_free(buddies);

		if (logs == NULL)
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
		else
			logs = g_list_sort(logs, purple_log_compare);
	}
	else if (PURPLE_IS_CHAT_CONVERSATION(c))
	{
		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_chats"))
			return;

		logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account);
	}

	if (logs == NULL)
		return;

	history = purple_log_read((PurpleLog*)logs->data, &flags);
	gtkconv = PIDGIN_CONVERSATION(c);
#if 0
	/* FIXME: WebView has no options */
	if (flags & PURPLE_LOG_READ_NO_NEWLINE)
		options |= GTK_IMHTML_NO_NEWLINE;
#endif

#if 0
	/* FIXME: WebView has no protocol setting */
	protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
			purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));
#endif

#if 0
	/* TODO WebKit: Do this properly... */
	if (!pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->webview)))
		pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<BR>");
#endif

	escaped_alias = g_markup_escape_text(alias, -1);

	if (((PurpleLog *)logs->data)->tm)
		header_date = purple_date_format_full(((PurpleLog *)logs->data)->tm);
	else
		header_date = purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time));

	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date);
	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), header);
	g_free(header);
	g_free(escaped_alias);

	g_strchomp(history);
	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), history);
	g_free(history);

	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<hr>");

#if 0
	/* FIXME: WebView has no protocol setting */
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
	g_free(protocol);
#endif

	g_object_ref(G_OBJECT(gtkconv->webview));
	g_idle_add(_scroll_webview_to_end, gtkconv->webview);

	g_list_foreach(logs, (GFunc)purple_log_free, NULL);
	g_list_free(logs);
}
Exemplo n.º 7
0
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = purple_conversation_get_account(c);
	const char *name = purple_conversation_get_name(c);
	PurpleConversationType convtype;
	GList *logs = NULL;
	const char *alias = name;
	guint flags;
	char *history;
	PidginConversation *gtkconv;
	GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS;
	char *header;
	char *protocol;
	char *escaped_alias;
	const char *header_date;

	convtype = purple_conversation_get_type(c);
	gtkconv = PIDGIN_CONVERSATION(c);
	g_return_if_fail(gtkconv != NULL);

	/* An IM which is the first active conversation. */
	g_return_if_fail(gtkconv->convs != NULL);
	if (convtype == PURPLE_CONV_TYPE_IM && !gtkconv->convs->next)
	{
		GSList *buddies;
		GSList *cur;

		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_ims"))
			return;

		/* Find buddies for this conversation. */
	        buddies = purple_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data);

	        for (cur = buddies; cur != NULL; cur = cur->next)
	        {
	                PurpleBlistNode *node = cur->data;
	                if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
	                {
				PurpleBlistNode *node2;

				alias = purple_buddy_get_contact_alias((PurpleBuddy *)node);

				/* We've found a buddy that matches this conversation.  It's part of a
				 * PurpleContact with more than one PurpleBuddy.  Loop through the PurpleBuddies
				 * in the contact and get all the logs. */
				for (node2 = node->parent->child ; node2 != NULL ; node2 = node2->next)
				{
					logs = g_list_concat(
						purple_log_get_logs(PURPLE_LOG_IM,
							purple_buddy_get_name((PurpleBuddy *)node2),
							purple_buddy_get_account((PurpleBuddy *)node2)),
						logs);
				}
				break;
	                }
	        }
	        g_slist_free(buddies);

		if (logs == NULL)
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
		else
			logs = g_list_sort(logs, purple_log_compare);
	}
	else if (convtype == PURPLE_CONV_TYPE_CHAT)
	{
		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_chats"))
			return;

		logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account);
	}

	if (logs == NULL)
		return;

	history = purple_log_read((PurpleLog*)logs->data, &flags);
	gtkconv = PIDGIN_CONVERSATION(c);
	if (flags & PURPLE_LOG_READ_NO_NEWLINE)
		options |= GTK_IMHTML_NO_NEWLINE;

	protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
							      purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));

	if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml))))
		gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", options);

	escaped_alias = g_markup_escape_text(alias, -1);

	if (((PurpleLog *)logs->data)->tm)
		header_date = purple_date_format_full(((PurpleLog *)logs->data)->tm);
	else
		header_date = purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time));

	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date);
	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), header, options);
	g_free(header);
	g_free(escaped_alias);

	g_strchomp(history);
	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), history, options);
	g_free(history);

	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<hr>", options);

	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
	g_free(protocol);

	g_object_ref(G_OBJECT(gtkconv->imhtml));
	g_idle_add(_scroll_imhtml_to_end, gtkconv->imhtml);

	g_list_foreach(logs, (GFunc)purple_log_free, NULL);
	g_list_free(logs);
}