diff options
Diffstat (limited to 'protocols/skype/skype.c')
-rw-r--r-- | protocols/skype/skype.c | 176 |
1 files changed, 117 insertions, 59 deletions
diff --git a/protocols/skype/skype.c b/protocols/skype/skype.c index 8638b5c1..7ce562d4 100644 --- a/protocols/skype/skype.c +++ b/protocols/skype/skype.c @@ -1,7 +1,7 @@ /* * skype.c - Skype plugin for BitlBee * - * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012 by Miklos Vajna <vmiklos@frugalware.org> + * Copyright (c) 2007-2013 by Miklos Vajna <vmiklos@vmiklos.hu> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ #define SKYPE_DEFAULT_SERVER "localhost" #define SKYPE_DEFAULT_PORT "2727" -#define IRC_LINE_SIZE 1024 +#define IRC_LINE_SIZE 16384 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) /* @@ -45,6 +45,8 @@ enum { enum { SKYPE_FILETRANSFER_NEW = 1, + SKYPE_FILETRANSFER_TRANSFERRING, + SKYPE_FILETRANSFER_COMPLETED, SKYPE_FILETRANSFER_FAILED }; @@ -80,6 +82,8 @@ struct skype_data { int call_out; /* Same for file transfers. */ int filetransfer_status; + /* Path of the file being transferred. */ + char *filetransfer_path; /* Using /j #nick we want to have a groupchat with two people. Usually * not (default). */ char *groupchat_with; @@ -113,6 +117,8 @@ struct skype_data { /* Pending user which has to be added to the next group which is * created. */ char *pending_user; + /* If the info command was used, to determine what to do with FULLNAME result. */ + int is_info; }; struct skype_away_state { @@ -189,7 +195,7 @@ int skype_printf(struct im_connection *ic, char *fmt, ...) static void skype_buddy_ask_yes(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET USER %s ISAUTHORIZED TRUE", + skype_printf(bla->ic, "SET USER %s ISAUTHORIZED TRUE\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -198,7 +204,7 @@ static void skype_buddy_ask_yes(void *data) static void skype_buddy_ask_no(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET USER %s ISAUTHORIZED FALSE", + skype_printf(bla->ic, "SET USER %s ISAUTHORIZED FALSE\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -213,8 +219,7 @@ void skype_buddy_ask(struct im_connection *ic, char *handle, char *message) bla->ic = ic; bla->handle = g_strdup(handle); - buf = g_strdup_printf("The user %s wants to add you to " - "his/her buddy list, saying: '%s'.", handle, message); + buf = g_strdup_printf("The user %s wants to add you to his/her buddy list, saying: '%s'.", handle, message); imcb_ask(ic, buf, bla, skype_buddy_ask_yes, skype_buddy_ask_no); g_free(buf); } @@ -222,7 +227,7 @@ void skype_buddy_ask(struct im_connection *ic, char *handle, char *message) static void skype_call_ask_yes(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET CALL %s STATUS INPROGRESS", + skype_printf(bla->ic, "SET CALL %s STATUS INPROGRESS\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -231,7 +236,7 @@ static void skype_call_ask_yes(void *data) static void skype_call_ask_no(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET CALL %s STATUS FINISHED", + skype_printf(bla->ic, "SET CALL %s STATUS FINISHED\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -316,8 +321,10 @@ static void skype_parse_users(struct im_connection *ic, char *line) char **i, **nicks; nicks = g_strsplit(line + 6, ", ", 0); - for (i = nicks; *i; i++) + for (i = nicks; *i; i++) { skype_printf(ic, "GET USER %s ONLINESTATUS\n", *i); + skype_printf(ic, "GET USER %s FULLNAME\n", *i); + } g_strfreev(nicks); } @@ -371,9 +378,17 @@ static void skype_parse_user(struct im_connection *ic, char *line) *buf ? buf : NULL); if (set_getbool(&ic->acc->set, "show_moods")) imcb_log(ic, "User `%s' changed mood text to `%s'", user, buf); - } else if (!strncmp(ptr, "FULLNAME ", 9)) - sd->info_fullname = g_strdup(ptr + 9); - else if (!strncmp(ptr, "PHONE_HOME ", 11)) + } else if (!strncmp(ptr, "FULLNAME ", 9)) { + char *name = ptr + 9; + if (sd->is_info) { + sd->is_info = FALSE; + sd->info_fullname = g_strdup(name); + } else { + char *buf = g_strdup_printf("%s@skype.com", user); + imcb_rename_buddy(ic, buf, name); + g_free(buf); + } + } else if (!strncmp(ptr, "PHONE_HOME ", 11)) sd->info_phonehome = g_strdup(ptr + 11); else if (!strncmp(ptr, "PHONE_OFFICE ", 13)) sd->info_phoneoffice = g_strdup(ptr + 13); @@ -408,8 +423,7 @@ static void skype_parse_user(struct im_connection *ic, char *line) sd->info_about = g_strdup(st->str); g_string_free(st, TRUE); } - } - else if (!strncmp(ptr, "BIRTHDAY ", 9)) { + } else if (!strncmp(ptr, "BIRTHDAY ", 9)) { sd->info_birthday = g_strdup(ptr + 9); GString *st = g_string_new("Contact Information\n"); @@ -565,10 +579,30 @@ static void skype_parse_user(struct im_connection *ic, char *line) } } -static void skype_parse_chatmessage(struct im_connection *ic, char *line) +static void skype_parse_chatmessage_said_emoted(struct im_connection *ic, struct groupchat *gc, char *body) { struct skype_data *sd = ic->proto_data; char buf[IRC_LINE_SIZE]; + if (!strcmp(sd->type, "SAID")) { + if (!sd->is_edit) + g_snprintf(buf, IRC_LINE_SIZE, "%s", body); + else { + g_snprintf(buf, IRC_LINE_SIZE, "%s %s", set_getstr(&ic->acc->set, "edit_prefix"), body); + sd->is_edit = 0; + } + } else + g_snprintf(buf, IRC_LINE_SIZE, "/me %s", body); + if (!gc) + /* Private message */ + imcb_buddy_msg(ic, sd->handle, buf, 0, 0); + else + /* Groupchat message */ + imcb_chat_msg(gc, sd->handle, buf, 0, 0); +} + +static void skype_parse_chatmessage(struct im_connection *ic, char *line) +{ + struct skype_data *sd = ic->proto_data; char *id = strchr(line, ' '); if (!++id) @@ -626,27 +660,7 @@ static void skype_parse_chatmessage(struct im_connection *ic, char *line) char *body = g_list_nth_data(sd->body, i); if (!strcmp(sd->type, "SAID") || !strcmp(sd->type, "EMOTED")) { - if (!strcmp(sd->type, "SAID")) { - if (!sd->is_edit) - g_snprintf(buf, IRC_LINE_SIZE, "%s", - body); - else { - g_snprintf(buf, IRC_LINE_SIZE, "%s %s", - set_getstr(&ic->acc->set, "edit_prefix"), - body); - sd->is_edit = 0; - } - } else - g_snprintf(buf, IRC_LINE_SIZE, "/me %s", - body); - if (!gc) - /* Private message */ - imcb_buddy_msg(ic, - sd->handle, buf, 0, 0); - else - /* Groupchat message */ - imcb_chat_msg(gc, - sd->handle, buf, 0, 0); + skype_parse_chatmessage_said_emoted(ic, gc, body); } else if (!strcmp(sd->type, "SETTOPIC") && gc) imcb_chat_topic(gc, sd->handle, body, 0); @@ -715,8 +729,7 @@ static void skype_parse_call(struct im_connection *ic, char *line) switch (sd->call_status) { case SKYPE_CALL_RINGING: if (sd->call_out) - imcb_log(ic, "You are currently ringing " - "the user %s.", info); + imcb_log(ic, "You are currently ringing the user %s.", info); else { g_snprintf(buf, IRC_LINE_SIZE, "The user %s is currently ringing you.", @@ -785,6 +798,15 @@ static void skype_parse_filetransfer(struct im_connection *ic, char *line) skype_printf(ic, "GET FILETRANSFER %s PARTNER_HANDLE\n", id); sd->filetransfer_status = SKYPE_FILETRANSFER_FAILED; + } else if (!strcmp(info, "STATUS COMPLETED")) { + skype_printf(ic, "GET FILETRANSFER %s PARTNER_HANDLE\n", id); + sd->filetransfer_status = SKYPE_FILETRANSFER_COMPLETED; + } else if (!strcmp(info, "STATUS TRANSFERRING")) { + skype_printf(ic, "GET FILETRANSFER %s PARTNER_HANDLE\n", id); + sd->filetransfer_status = SKYPE_FILETRANSFER_TRANSFERRING; + } else if (!strncmp(info, "FILEPATH ", 9)) { + info += 9; + sd->filetransfer_path = g_strdup(info); } else if (!strncmp(info, "PARTNER_HANDLE ", 15)) { info += 15; if (!sd->filetransfer_status) @@ -798,6 +820,16 @@ static void skype_parse_filetransfer(struct im_connection *ic, char *line) imcb_log(ic, "Failed to transfer file from user %s.", info); break; + case SKYPE_FILETRANSFER_COMPLETED: + imcb_log(ic, "File transfer from user %s completed.", info); + break; + case SKYPE_FILETRANSFER_TRANSFERRING: + if (sd->filetransfer_path) { + imcb_log(ic, "File transfer from user %s started, saving to %s.", info, sd->filetransfer_path); + g_free(sd->filetransfer_path); + sd->filetransfer_path = NULL; + } + break; } sd->filetransfer_status = 0; } @@ -897,7 +929,7 @@ static void skype_parse_group(struct im_connection *ic, char *line) if (!sd->pending_user) { /* Number of users changed in this group, query its type to see * if it's a custom one we should care about. */ - skype_printf(ic, "GET GROUP %s TYPE", id); + skype_printf(ic, "GET GROUP %s TYPE\n", id); return; } @@ -906,7 +938,7 @@ static void skype_parse_group(struct im_connection *ic, char *line) struct skype_group *sg = skype_group_by_id(ic, atoi(id)); if (sg) { - skype_printf(ic, "ALTER GROUP %d ADDUSER %s", sg->id, sd->pending_user); + skype_printf(ic, "ALTER GROUP %d ADDUSER %s\n", sg->id, sd->pending_user); g_free(sd->pending_user); sd->pending_user = NULL; } else @@ -914,7 +946,7 @@ static void skype_parse_group(struct im_connection *ic, char *line) "No skype group with id %s. That's probably a bug.", id); } else if (!strcmp(info, "TYPE CUSTOM_GROUP")) /* This one is interesting, query its users. */ - skype_printf(ic, "GET GROUP %s USERS", id); + skype_printf(ic, "GET GROUP %s USERS\n", id); } static void skype_parse_chat(struct im_connection *ic, char *line) @@ -982,8 +1014,8 @@ static void skype_parse_chat(struct im_connection *ic, char *line) g_free(sd->adder); sd->adder = NULL; } - } else if (!strncmp(info, "ACTIVEMEMBERS ", 14)) { - info += 14; + } else if (!strncmp(info, "MEMBERS ", 8) || !strncmp(info, "ACTIVEMEMBERS ", 14) ) { + info += 8; gc = bee_chat_by_title(ic->bee, ic, id); /* Hack! We set ->data to TRUE * while we're on the channel @@ -1045,6 +1077,9 @@ static void skype_parse_chats(struct im_connection *ic, char *line) static void skype_parse_groups(struct im_connection *ic, char *line) { + if (!set_getbool(&ic->acc->set, "read_groups")) + return; + char **i; char **groups = g_strsplit(line + 7, ", ", 0); @@ -1123,6 +1158,13 @@ static gboolean skype_read_callback(gpointer data, gint fd, return FALSE; /* Read the whole data. */ st = ssl_read(sd->ssl, buf, sizeof(buf)); + if (st >= IRC_LINE_SIZE-1) { + /* As we don't buffer incoming data, if IRC_LINE_SIZE amount of bytes + * were received, there's a good chance last message was truncated + * and the next recv() will yield garbage. */ + imcb_error(ic, "Unable to handle incoming data from skyped"); + st = 0; + } if (st > 0) { buf[st] = '\0'; /* Then split it up to lines. */ @@ -1177,8 +1219,12 @@ gboolean skype_start_stream(struct im_connection *ic) skype_printf(ic, "SET USERSTATUS ONLINE\n"); /* Auto join to bookmarked chats if requested.*/ - if (set_getbool(&ic->acc->set, "auto_join")) + if (set_getbool(&ic->acc->set, "auto_join")) { skype_printf(ic, "SEARCH BOOKMARKEDCHATS\n"); + skype_printf(ic, "SEARCH ACTIVECHATS\n"); + skype_printf(ic, "SEARCH MISSEDCHATS\n"); + skype_printf(ic, "SEARCH RECENTCHATS\n"); + } return st; } @@ -1227,7 +1273,7 @@ static void skype_logout(struct im_connection *ic) skype_printf(ic, "SET USERSTATUS OFFLINE\n"); - while( ic->groupchats ) + while (ic->groupchats) imcb_chat_free(ic->groupchats->data); for (i = 0; i < g_list_length(sd->groups); i++) { @@ -1314,7 +1360,16 @@ static char *skype_set_display_name(set_t *set, char *value) account_t *acc = set->data; struct im_connection *ic = acc->ic; - skype_printf(ic, "SET PROFILE FULLNAME %s", value); + skype_printf(ic, "SET PROFILE FULLNAME %s\n", value); + return value; +} + +static char *skype_set_mood_text(set_t *set, char *value) +{ + account_t *acc = set->data; + struct im_connection *ic = acc->ic; + + skype_printf(ic, "SET PROFILE MOOD_TEXT %s\n", value); return value; } @@ -1323,7 +1378,7 @@ static char *skype_set_balance(set_t *set, char *value) account_t *acc = set->data; struct im_connection *ic = acc->ic; - skype_printf(ic, "GET PROFILE PSTN_BALANCE"); + skype_printf(ic, "GET PROFILE PSTN_BALANCE\n"); return value; } @@ -1334,7 +1389,7 @@ static void skype_call(struct im_connection *ic, char *value) if (ptr) *ptr = '\0'; - skype_printf(ic, "CALL %s", nick); + skype_printf(ic, "CALL %s\n", nick); g_free(nick); } @@ -1343,7 +1398,7 @@ static void skype_hangup(struct im_connection *ic) struct skype_data *sd = ic->proto_data; if (sd->call_id) { - skype_printf(ic, "SET CALL %s STATUS FINISHED", + skype_printf(ic, "SET CALL %s STATUS FINISHED\n", sd->call_id); g_free(sd->call_id); sd->call_id = 0; @@ -1383,10 +1438,10 @@ static void skype_add_buddy(struct im_connection *ic, char *who, char *group) if (!sg) { /* No such group, we need to create it, then have to * add the user once it's created. */ - skype_printf(ic, "CREATE GROUP %s", group); + skype_printf(ic, "CREATE GROUP %s\n", group); sd->pending_user = g_strdup(nick); } else { - skype_printf(ic, "ALTER GROUP %d ADDUSER %s", sg->id, nick); + skype_printf(ic, "ALTER GROUP %d ADDUSER %s\n", sg->id, nick); } } } @@ -1463,11 +1518,13 @@ struct groupchat *skype_chat_with(struct im_connection *ic, char *who) static void skype_get_info(struct im_connection *ic, char *who) { + struct skype_data *sd = ic->proto_data; char *ptr, *nick; nick = g_strdup(who); ptr = strchr(nick, '@'); if (ptr) *ptr = '\0'; + sd->is_info = TRUE; skype_printf(ic, "GET USER %s FULLNAME\n", nick); skype_printf(ic, "GET USER %s PHONE_HOME\n", nick); skype_printf(ic, "GET USER %s PHONE_OFFICE\n", nick); @@ -1490,11 +1547,6 @@ static void skype_get_info(struct im_connection *ic, char *who) skype_printf(ic, "GET USER %s BIRTHDAY\n", nick); } -static void skype_set_my_name(struct im_connection *ic, char *info) -{ - skype_set_display_name(set_find(&ic->acc->set, "display_name"), info); -} - static void skype_init(account_t *acc) { set_t *s; @@ -1510,6 +1562,9 @@ static void skype_init(account_t *acc) acc); s->flags |= SET_NOSAVE | ACC_SET_ONLINE_ONLY; + s = set_add(&acc->set, "mood_text", NULL, skype_set_mood_text, acc); + s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; + s = set_add(&acc->set, "call", NULL, skype_set_call, acc); s->flags |= SET_NOSAVE | ACC_SET_ONLINE_ONLY; @@ -1535,6 +1590,8 @@ static void skype_init(account_t *acc) s = set_add(&acc->set, "edit_prefix", "EDIT:", NULL, acc); + + s = set_add(&acc->set, "read_groups", "false", set_eval_bool, acc); } #if BITLBEE_VERSION_CODE > BITLBEE_VER(3, 0, 1) @@ -1546,12 +1603,14 @@ GList *skype_buddy_action_list(bee_user_t *bu) bu = bu; if (ret == NULL) { - static const struct buddy_action ba[3] = { + static const struct buddy_action ba[2] = { {"CALL", "Initiate a call" }, {"HANGUP", "Hang up a call" }, }; + int i; - ret = g_list_prepend(ret, (void *) ba + 0); + for (i = 0; i < ARRAY_SIZE(ba); i++) + ret = g_list_prepend(ret, (void *)(ba + i)); } return ret; @@ -1582,7 +1641,6 @@ void init_plugin(void) ret->logout = skype_logout; ret->buddy_msg = skype_buddy_msg; ret->get_info = skype_get_info; - ret->set_my_name = skype_set_my_name; ret->away_states = skype_away_states; ret->set_away = skype_set_away; ret->add_buddy = skype_add_buddy; |