aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/twitter/twitter.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/twitter/twitter.c')
-rw-r--r--protocols/twitter/twitter.c255
1 files changed, 153 insertions, 102 deletions
diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c
index eb30187f..f3dcde31 100644
--- a/protocols/twitter/twitter.c
+++ b/protocols/twitter/twitter.c
@@ -90,14 +90,15 @@ static struct twitter_filter *twitter_filter_get(struct groupchat *c,
{
struct twitter_data *td = c->ic->proto_data;
struct twitter_filter *tf = NULL;
- struct twitter_filter tfc = {type, (char*) text};
+ struct twitter_filter tfc = { type, (char *) text };
GSList *l;
for (l = td->filters; l; l = g_slist_next(l)) {
tf = l->data;
- if (twitter_filter_cmp(tf, &tfc) == 0)
+ if (twitter_filter_cmp(tf, &tfc) == 0) {
break;
+ }
tf = NULL;
}
@@ -109,15 +110,17 @@ static struct twitter_filter *twitter_filter_get(struct groupchat *c,
td->filters = g_slist_prepend(td->filters, tf);
}
- if (!g_slist_find(tf->groupchats, c))
+ if (!g_slist_find(tf->groupchats, c)) {
tf->groupchats = g_slist_prepend(tf->groupchats, c);
+ }
- if (td->filter_update_id > 0)
+ if (td->filter_update_id > 0) {
b_event_remove(td->filter_update_id);
+ }
/* Wait for other possible filter changes to avoid request spam */
td->filter_update_id = b_timeout_add(TWITTER_FILTER_UPDATE_WAIT,
- twitter_filter_update, c->ic);
+ twitter_filter_update, c->ic);
return tf;
}
@@ -148,12 +151,14 @@ static void twitter_filter_remove(struct groupchat *c)
}
}
- if (td->filter_update_id > 0)
+ if (td->filter_update_id > 0) {
b_event_remove(td->filter_update_id);
+ }
/* Wait for other possible filter changes to avoid request spam */
td->filter_update_id = b_timeout_add(TWITTER_FILTER_UPDATE_WAIT,
- twitter_filter_update, c->ic);}
+ twitter_filter_update, c->ic);
+}
static void twitter_filter_remove_all(struct im_connection *ic)
{
@@ -168,8 +173,9 @@ static void twitter_filter_remove_all(struct im_connection *ic)
/* Build up a list of groupchats to be freed */
for (p = tf->groupchats; p; p = g_slist_next(p)) {
- if (!g_slist_find(chats, p->data))
+ if (!g_slist_find(chats, p->data)) {
chats = g_slist_prepend(chats, p->data);
+ }
}
p = l;
@@ -216,8 +222,9 @@ static GSList *twitter_filter_parse(struct groupchat *c, const char *text)
};
for (f = fs; *f; f++) {
- if ((v = strchr(*f, ':')) == NULL)
+ if ((v = strchr(*f, ':')) == NULL) {
continue;
+ }
*(v++) = 0;
@@ -228,8 +235,9 @@ static GSList *twitter_filter_parse(struct groupchat *c, const char *text)
}
}
- if (t < 0 || strlen(v) == 0)
+ if (t < 0 || strlen(v) == 0) {
continue;
+ }
tf = twitter_filter_get(c, types[t], v);
ret = g_slist_prepend(ret, tf);
@@ -247,8 +255,9 @@ gboolean twitter_main_loop(gpointer data, gint fd, b_input_condition cond)
struct im_connection *ic = data;
// Check if we are still logged in...
- if (!g_slist_find(twitter_connections, ic))
+ if (!g_slist_find(twitter_connections, ic)) {
return FALSE;
+ }
// Do stuff..
return twitter_get_timeline(ic, -1) &&
@@ -260,24 +269,27 @@ static void twitter_main_loop_start(struct im_connection *ic)
struct twitter_data *td = ic->proto_data;
char *last_tweet = set_getstr(&ic->acc->set, "_last_tweet");
- if (last_tweet)
+
+ if (last_tweet) {
td->timeline_id = g_ascii_strtoull(last_tweet, NULL, 0);
+ }
/* Create the room now that we "logged in". */
- if (td->flags & TWITTER_MODE_CHAT)
+ if (td->flags & TWITTER_MODE_CHAT) {
twitter_groupchat_init(ic);
+ }
imcb_log(ic, "Getting initial statuses");
// Run this once. After this queue the main loop function (or open the
// stream if available).
twitter_main_loop(ic, -1, 0);
-
+
if (set_getbool(&ic->acc->set, "stream")) {
/* That fetch was just to get backlog, the stream will give
us the rest. \o/ */
twitter_open_stream(ic);
-
+
/* Stream sends keepalives (empty lines) or actual data at
least twice a minute. Disconnect if this stops. */
ic->flags |= OPT_PONGS;
@@ -285,8 +297,8 @@ static void twitter_main_loop_start(struct im_connection *ic)
/* Not using the streaming API, so keep polling the old-
fashioned way. :-( */
td->main_loop_id =
- b_timeout_add(set_getint(&ic->acc->set, "fetch_interval") * 1000,
- twitter_main_loop, ic);
+ b_timeout_add(set_getint(&ic->acc->set, "fetch_interval") * 1000,
+ twitter_main_loop, ic);
}
}
@@ -297,8 +309,9 @@ struct groupchat *twitter_groupchat_init(struct im_connection *ic)
struct twitter_data *td = ic->proto_data;
GSList *l;
- if (td->timeline_gc)
+ if (td->timeline_gc) {
return td->timeline_gc;
+ }
td->timeline_gc = gc = imcb_chat_new(ic, "twitter/timeline");
@@ -308,11 +321,12 @@ struct groupchat *twitter_groupchat_init(struct im_connection *ic)
for (l = ic->bee->users; l; l = l->next) {
bee_user_t *bu = l->data;
- if (bu->ic == ic)
+ if (bu->ic == ic) {
imcb_chat_add_buddy(gc, bu->handle);
+ }
}
imcb_chat_add_buddy(gc, ic->acc->user);
-
+
return gc;
}
@@ -324,14 +338,15 @@ void twitter_login_finish(struct im_connection *ic)
td->flags &= ~TWITTER_DOING_TIMELINE;
- if (set_getbool(&ic->acc->set, "oauth") && !td->oauth_info)
+ if (set_getbool(&ic->acc->set, "oauth") && !td->oauth_info) {
twitter_oauth_start(ic);
- else if (!(td->flags & TWITTER_MODE_ONE) &&
- !(td->flags & TWITTER_HAVE_FRIENDS)) {
+ } else if (!(td->flags & TWITTER_MODE_ONE) &&
+ !(td->flags & TWITTER_HAVE_FRIENDS)) {
imcb_log(ic, "Getting contact list");
twitter_get_friends_ids(ic, -1);
- } else
+ } else {
twitter_main_loop_start(ic);
+ }
}
static const struct oauth_service twitter_oauth = {
@@ -356,10 +371,11 @@ static const struct oauth_service *get_oauth_service(struct im_connection *ic)
{
struct twitter_data *td = ic->proto_data;
- if (strstr(td->url_host, "identi.ca"))
+ if (strstr(td->url_host, "identi.ca")) {
return &identica_oauth;
- else
+ } else {
return &twitter_oauth;
+ }
/* Could add more services, or allow configuring your own base URL +
API keys. */
@@ -371,10 +387,11 @@ static void twitter_oauth_start(struct im_connection *ic)
const char *url = set_getstr(&ic->acc->set, "base_url");
imcb_log(ic, "Requesting OAuth request token");
-
- if (!strstr(url, "twitter.com") && !strstr(url, "identi.ca"))
+
+ if (!strstr(url, "twitter.com") && !strstr(url, "identi.ca")) {
imcb_log(ic, "Warning: OAuth only works with identi.ca and "
- "Twitter.");
+ "Twitter.");
+ }
td->oauth_info = oauth_request_token(get_oauth_service(ic), twitter_oauth_callback, ic);
@@ -388,8 +405,9 @@ static gboolean twitter_oauth_callback(struct oauth_info *info)
struct im_connection *ic = info->data;
struct twitter_data *td;
- if (!g_slist_find(twitter_connections, ic))
+ if (!g_slist_find(twitter_connections, ic)) {
return FALSE;
+ }
td = ic->proto_data;
if (info->stage == OAUTH_REQUEST_TOKEN) {
@@ -403,24 +421,25 @@ static gboolean twitter_oauth_callback(struct oauth_info *info)
name = g_strdup_printf("%s_%s", td->prefix, ic->acc->user);
msg = g_strdup_printf("To finish OAuth authentication, please visit "
- "%s and respond with the resulting PIN code.",
- info->auth_url);
+ "%s and respond with the resulting PIN code.",
+ info->auth_url);
imcb_buddy_msg(ic, name, msg, 0, 0);
g_free(name);
g_free(msg);
} else if (info->stage == OAUTH_ACCESS_TOKEN) {
const char *sn;
-
+
if (info->token == NULL || info->token_secret == NULL) {
imcb_error(ic, "OAuth error: %s", twitter_parse_error(info->http));
imc_logout(ic, TRUE);
return FALSE;
}
-
+
if ((sn = oauth_params_get(&info->params, "screen_name"))) {
- if (ic->acc->prpl->handle_cmp(sn, ic->acc->user) != 0)
+ if (ic->acc->prpl->handle_cmp(sn, ic->acc->user) != 0) {
imcb_log(ic, "Warning: You logged in via OAuth as %s "
"instead of %s.", sn, ic->acc->user);
+ }
g_free(td->user);
td->user = g_strdup(sn);
}
@@ -443,16 +462,18 @@ int twitter_url_len_diff(gchar *msg, unsigned int target_len)
static GRegex *regex = NULL;
GMatchInfo *match_info;
- if (regex == NULL)
+ if (regex == NULL) {
regex = g_regex_new("(^|\\s)(http(s)?://[^\\s$]+)", 0, 0, NULL);
-
+ }
+
g_regex_match(regex, msg, 0, &match_info);
while (g_match_info_matches(match_info)) {
gchar *url = g_match_info_fetch(match_info, 2);
url_len_diff += target_len - g_utf8_strlen(url, -1);
/* Add another character for https://t.co/... URLs */
- if (g_match_info_fetch(match_info, 3) != NULL)
+ if (g_match_info_fetch(match_info, 3) != NULL) {
url_len_diff += 1;
+ }
g_free(url);
g_match_info_next(match_info, NULL);
}
@@ -467,11 +488,13 @@ static gboolean twitter_length_check(struct im_connection *ic, gchar * msg)
int target_len = set_getint(&ic->acc->set, "target_url_length");
int url_len_diff = 0;
- if (target_len > 0)
+ if (target_len > 0) {
url_len_diff = twitter_url_len_diff(msg, target_len);
+ }
- if (max == 0 || (len = g_utf8_strlen(msg, -1) + url_len_diff) <= max)
+ if (max == 0 || (len = g_utf8_strlen(msg, -1) + url_len_diff) <= max) {
return TRUE;
+ }
twitter_log(ic, "Maximum message length exceeded: %d > %d", len, max);
@@ -480,19 +503,21 @@ static gboolean twitter_length_check(struct im_connection *ic, gchar * msg)
static char *set_eval_commands(set_t * set, char *value)
{
- if (g_strcasecmp(value, "strict") == 0 )
+ if (g_strcasecmp(value, "strict") == 0) {
return value;
- else
+ } else {
return set_eval_bool(set, value);
+ }
}
static char *set_eval_mode(set_t * set, char *value)
{
if (g_strcasecmp(value, "one") == 0 ||
- g_strcasecmp(value, "many") == 0 || g_strcasecmp(value, "chat") == 0)
+ g_strcasecmp(value, "many") == 0 || g_strcasecmp(value, "chat") == 0) {
return value;
- else
+ } else {
return NULL;
+ }
}
static void twitter_init(account_t * acc)
@@ -506,7 +531,7 @@ static void twitter_init(account_t * acc)
def_url = TWITTER_API_URL;
def_tul = "22";
def_mentions = "true";
- } else { /* if( strcmp( acc->prpl->name, "identica" ) == 0 ) */
+ } else { /* if( strcmp( acc->prpl->name, "identica" ) == 0 ) */
def_url = IDENTICA_API_URL;
def_tul = "0";
def_mentions = "false";
@@ -538,7 +563,7 @@ static void twitter_init(account_t * acc)
s = set_add(&acc->set, "show_old_mentions", "0", set_eval_int, acc);
s = set_add(&acc->set, "strip_newlines", "false", set_eval_bool, acc);
-
+
s = set_add(&acc->set, "_last_tweet", "0", NULL, acc);
s->flags |= SET_HIDDEN | SET_NOSAVE;
@@ -559,7 +584,7 @@ static void twitter_login(account_t * acc)
char name[strlen(acc->user) + 9];
url_t url;
char *s;
-
+
if (!url_set(&url, set_getstr(&ic->acc->set, "base_url")) ||
(url.proto != PROTO_HTTP && url.proto != PROTO_HTTPS)) {
imcb_error(ic, "Incorrect API base URL: %s", set_getstr(&ic->acc->set, "base_url"));
@@ -570,7 +595,7 @@ static void twitter_login(account_t * acc)
if (!strstr(url.host, "twitter.com") &&
set_getbool(&ic->acc->set, "stream")) {
imcb_error(ic, "Warning: The streaming API is only supported by Twitter, "
- "and you seem to be connecting to a different service.");
+ "and you seem to be connecting to a different service.");
}
imcb_log(ic, "Connecting");
@@ -583,21 +608,23 @@ static void twitter_login(account_t * acc)
td->url_ssl = url.proto == PROTO_HTTPS;
td->url_port = url.port;
td->url_host = g_strdup(url.host);
- if (strcmp(url.file, "/") != 0)
+ if (strcmp(url.file, "/") != 0) {
td->url_path = g_strdup(url.file);
- else {
+ } else {
td->url_path = g_strdup("");
- if (g_str_has_suffix(url.host, "twitter.com"))
+ if (g_str_has_suffix(url.host, "twitter.com")) {
/* May fire for people who turned on HTTPS. */
imcb_error(ic, "Warning: Twitter requires a version number in API calls "
- "now. Try resetting the base_url account setting.");
+ "now. Try resetting the base_url account setting.");
+ }
}
-
+
/* Hacky string mangling: Turn identi.ca into identi.ca and api.twitter.com
into twitter, and try to be sensible if we get anything else. */
td->prefix = g_strdup(url.host);
- if (g_str_has_suffix(td->prefix, ".com"))
+ if (g_str_has_suffix(td->prefix, ".com")) {
td->prefix[strlen(url.host) - 4] = '\0';
+ }
if ((s = strrchr(td->prefix, '.')) && strlen(s) > 4) {
/* If we have at least 3 chars after the last dot, cut off the rest.
(mostly a www/api prefix or sth) */
@@ -605,9 +632,10 @@ static void twitter_login(account_t * acc)
g_free(td->prefix);
td->prefix = s;
}
-
- if (strstr(acc->pass, "oauth_token="))
+
+ if (strstr(acc->pass, "oauth_token=")) {
td->oauth_info = oauth_from_string(acc->pass, get_oauth_service(ic));
+ }
sprintf(name, "%s_%s", td->prefix, acc->user);
imcb_add_buddy(ic, name, NULL);
@@ -615,14 +643,15 @@ static void twitter_login(account_t * acc)
td->log = g_new0(struct twitter_log_data, TWITTER_LOG_LENGTH);
td->log_id = -1;
-
+
s = set_getstr(&ic->acc->set, "mode");
- if (g_strcasecmp(s, "one") == 0)
+ if (g_strcasecmp(s, "one") == 0) {
td->flags |= TWITTER_MODE_ONE;
- else if (g_strcasecmp(s, "many") == 0)
+ } else if (g_strcasecmp(s, "many") == 0) {
td->flags |= TWITTER_MODE_MANY;
- else
+ } else {
td->flags |= TWITTER_MODE_CHAT;
+ }
twitter_login_finish(ic);
}
@@ -640,12 +669,14 @@ static void twitter_logout(struct im_connection *ic)
// Remove the main_loop function from the function queue.
b_event_remove(td->main_loop_id);
- if (td->timeline_gc)
+ if (td->timeline_gc) {
imcb_chat_free(td->timeline_gc);
+ }
if (td) {
- if (td->filter_update_id > 0)
+ if (td->filter_update_id > 0) {
b_event_remove(td->filter_update_id);
+ }
http_close(td->stream);
twitter_filter_remove_all(ic);
@@ -678,19 +709,21 @@ static int twitter_buddy_msg(struct im_connection *ic, char *who, char *message,
char pin[strlen(message) + 1], *s;
strcpy(pin, message);
- for (s = pin + sizeof(pin) - 2; s > pin && g_ascii_isspace(*s); s--)
+ for (s = pin + sizeof(pin) - 2; s > pin && g_ascii_isspace(*s); s--) {
*s = '\0';
+ }
for (s = pin; *s && g_ascii_isspace(*s); s++) {
}
if (!oauth_access_token(s, td->oauth_info)) {
imcb_error(ic, "OAuth error: %s",
- "Failed to send access token request");
+ "Failed to send access token request");
imc_logout(ic, TRUE);
return FALSE;
}
- } else
+ } else {
twitter_handle_command(ic, message);
+ }
} else {
twitter_direct_messages_new(ic, who, message);
}
@@ -713,8 +746,9 @@ static void twitter_remove_buddy(struct im_connection *ic, char *who, char *grou
static void twitter_chat_msg(struct groupchat *c, char *message, int flags)
{
- if (c && message)
+ if (c && message) {
twitter_handle_command(c->ic, message);
+ }
}
static void twitter_chat_invite(struct groupchat *c, char *who, char *message)
@@ -736,17 +770,20 @@ static struct groupchat *twitter_chat_join(struct im_connection *ic,
for (l = fs; l; l = g_slist_next(l)) {
tf = l->data;
- if (topic->len > 0)
+ if (topic->len > 0) {
g_string_append(topic, ", ");
+ }
- if (tf->type == TWITTER_FILTER_TYPE_FOLLOW)
+ if (tf->type == TWITTER_FILTER_TYPE_FOLLOW) {
g_string_append_c(topic, '@');
+ }
g_string_append(topic, tf->text);
}
- if (topic->len > 0)
+ if (topic->len > 0) {
g_string_prepend(topic, "Twitter Filter: ");
+ }
imcb_chat_topic(c, NULL, topic->str, 0);
imcb_chat_add_buddy(c, ic->acc->user);
@@ -819,40 +856,48 @@ static void twitter_buddy_data_free(struct bee_user *bu)
*
* Returns 0 if the user provides garbage.
*/
-static guint64 twitter_message_id_from_command_arg(struct im_connection *ic, char *arg, bee_user_t **bu_) {
+static guint64 twitter_message_id_from_command_arg(struct im_connection *ic, char *arg, bee_user_t **bu_)
+{
struct twitter_data *td = ic->proto_data;
struct twitter_user_data *tud;
bee_user_t *bu = NULL;
guint64 id = 0;
-
- if (bu_)
+
+ if (bu_) {
*bu_ = NULL;
- if (!arg || !arg[0])
+ }
+ if (!arg || !arg[0]) {
return 0;
-
+ }
+
if (arg[0] != '#' && (bu = bee_user_by_handle(ic->bee, ic, arg))) {
- if ((tud = bu->data))
+ if ((tud = bu->data)) {
id = tud->last_id;
+ }
} else {
- if (arg[0] == '#')
+ if (arg[0] == '#') {
arg++;
+ }
if (sscanf(arg, "%" G_GINT64_MODIFIER "x", &id) == 1 &&
id < TWITTER_LOG_LENGTH) {
bu = td->log[id].bu;
id = td->log[id].id;
/* Beware of dangling pointers! */
- if (!g_slist_find(ic->bee->users, bu))
+ if (!g_slist_find(ic->bee->users, bu)) {
bu = NULL;
+ }
} else if (sscanf(arg, "%" G_GINT64_MODIFIER "d", &id) == 1) {
/* Allow normal tweet IDs as well; not a very useful
feature but it's always been there. Just ignore
very low IDs to avoid accidents. */
- if (id < 1000000)
+ if (id < 1000000) {
id = 0;
+ }
}
}
- if (bu_)
+ if (bu_) {
*bu_ = bu;
+ }
return id;
}
@@ -862,7 +907,7 @@ static void twitter_handle_command(struct im_connection *ic, char *message)
char *cmds, **cmd, *new = NULL;
guint64 in_reply_to = 0, id;
gboolean allow_post =
- g_strcasecmp(set_getstr(&ic->acc->set, "commands"), "strict") != 0;
+ g_strcasecmp(set_getstr(&ic->acc->set, "commands"), "strict") != 0;
bee_user_t *bu = NULL;
cmds = g_strdup(message);
@@ -873,17 +918,18 @@ static void twitter_handle_command(struct im_connection *ic, char *message)
} else if (!set_getbool(&ic->acc->set, "commands") && allow_post) {
/* Not supporting commands if "commands" is set to true/strict. */
} else if (g_strcasecmp(cmd[0], "undo") == 0) {
- if (cmd[1] == NULL)
+ if (cmd[1] == NULL) {
twitter_status_destroy(ic, td->last_status_id);
- else if ((id = twitter_message_id_from_command_arg(ic, cmd[1], NULL)))
+ } else if ((id = twitter_message_id_from_command_arg(ic, cmd[1], NULL))) {
twitter_status_destroy(ic, id);
- else
+ } else {
twitter_log(ic, "Could not undo last action");
+ }
goto eof;
} else if ((g_strcasecmp(cmd[0], "favourite") == 0 ||
- g_strcasecmp(cmd[0], "favorite") == 0 ||
- g_strcasecmp(cmd[0], "fav") == 0) && cmd[1]) {
+ g_strcasecmp(cmd[0], "favorite") == 0 ||
+ g_strcasecmp(cmd[0], "fav") == 0) && cmd[1]) {
if ((id = twitter_message_id_from_command_arg(ic, cmd[1], NULL))) {
twitter_favourite_tweet(ic, id);
} else {
@@ -899,33 +945,35 @@ static void twitter_handle_command(struct im_connection *ic, char *message)
} else if ((g_strcasecmp(cmd[0], "report") == 0 ||
g_strcasecmp(cmd[0], "spam") == 0) && cmd[1]) {
char *screen_name;
-
+
/* Report nominally works on users but look up the user who
posted the given ID if the user wants to do it that way */
twitter_message_id_from_command_arg(ic, cmd[1], &bu);
- if (bu)
+ if (bu) {
screen_name = bu->handle;
- else
+ } else {
screen_name = cmd[1];
-
+ }
+
twitter_report_spam(ic, screen_name);
goto eof;
} else if (g_strcasecmp(cmd[0], "rt") == 0 && cmd[1]) {
id = twitter_message_id_from_command_arg(ic, cmd[1], NULL);
td->last_status_id = 0;
- if (id)
+ if (id) {
twitter_status_retweet(ic, id);
- else
+ } else {
twitter_log(ic, "User `%s' does not exist or didn't "
- "post any statuses recently", cmd[1]);
+ "post any statuses recently", cmd[1]);
+ }
goto eof;
} else if (g_strcasecmp(cmd[0], "reply") == 0 && cmd[1] && cmd[2]) {
id = twitter_message_id_from_command_arg(ic, cmd[1], &bu);
if (!id || !bu) {
twitter_log(ic, "User `%s' does not exist or didn't "
- "post any statuses recently", cmd[1]);
+ "post any statuses recently", cmd[1]);
goto eof;
}
message = new = g_strdup_printf("@%s %s", bu->handle, cmd[2]);
@@ -948,8 +996,9 @@ static void twitter_handle_command(struct im_connection *ic, char *message)
if (allow_post) {
char *s;
- if (!twitter_length_check(ic, message))
+ if (!twitter_length_check(ic, message)) {
goto eof;
+ }
s = cmd[0] + strlen(cmd[0]) - 1;
if (!new && s > cmd[0] && (*s == ':' || *s == ',')) {
@@ -959,12 +1008,13 @@ static void twitter_handle_command(struct im_connection *ic, char *message)
struct twitter_user_data *tud = bu->data;
new = g_strdup_printf("@%s %s", bu->handle,
- message + (s - cmd[0]) + 2);
+ message + (s - cmd[0]) + 2);
message = new;
if (time(NULL) < tud->last_time +
- set_getint(&ic->acc->set, "auto_reply_timeout"))
+ set_getint(&ic->acc->set, "auto_reply_timeout")) {
in_reply_to = tud->last_id;
+ }
}
}
@@ -980,21 +1030,22 @@ eof:
g_free(cmds);
}
-void twitter_log(struct im_connection *ic, char *format, ... )
+void twitter_log(struct im_connection *ic, char *format, ...)
{
struct twitter_data *td = ic->proto_data;
va_list params;
char *text;
-
+
va_start(params, format);
text = g_strdup_vprintf(format, params);
va_end(params);
-
- if (td->timeline_gc)
+
+ if (td->timeline_gc) {
imcb_chat_log(td->timeline_gc, "%s", text);
- else
+ } else {
imcb_log(ic, "%s", text);
-
+ }
+
g_free(text);
}