diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2012-12-02 12:53:12 +0000 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2012-12-02 12:53:12 +0000 |
commit | 3ca001bcb054e861ef9ad6e818fbb6615a519804 (patch) | |
tree | fd3c1bdd9ff87387789bf74f98758e5de3ef4f1a /protocols/twitter/twitter.c | |
parent | e8161ec5bf893d935148fe48925d1315f3aab949 (diff) |
Extend twitter_message_id_from_command_arg() a little bit and use it for all
commands. Also fixed reply command in strict commands mode.
Diffstat (limited to 'protocols/twitter/twitter.c')
-rw-r--r-- | protocols/twitter/twitter.c | 154 |
1 files changed, 66 insertions, 88 deletions
diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 91050578..651bf345 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -552,21 +552,40 @@ 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, struct twitter_data *td, char *arg) { +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; + bee_user_t *bu = NULL; guint64 id = 0; - if (g_str_has_prefix(arg, "#") && - sscanf(arg + 1, "%" G_GINT64_MODIFIER "x", &id) == 1) { - if (id < TWITTER_LOG_LENGTH && td->log) - id = td->log[id].id; - } else if ((bu = bee_user_by_handle(ic->bee, ic, arg)) && - (tud = bu->data) && tud->last_id) - id = tud->last_id; - else if (sscanf(arg, "%" G_GINT64_MODIFIER "x", &id) == 1){ - if (id < TWITTER_LOG_LENGTH && td->log) + + if (bu_) + *bu_ = NULL; + if (!arg || !arg[0]) + return 0; + + if (arg[0] != '#' && (bu = bee_user_by_handle(ic->bee, ic, arg))) { + if ((tud = bu->data)) + id = tud->last_id; + } else { + 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)) + 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) + id = 0; + } } + if (bu_) + *bu_ = bu; return id; } @@ -574,70 +593,56 @@ static void twitter_handle_command(struct im_connection *ic, char *message) { struct twitter_data *td = ic->proto_data; char *cmds, **cmd, *new = NULL; - guint64 in_reply_to = 0; - gboolean strict_commands = - g_strcasecmp(set_getstr(&ic->acc->set, "commands"), "strict") == 0; + guint64 in_reply_to = 0, id; + gboolean allow_post = + g_strcasecmp(set_getstr(&ic->acc->set, "commands"), "strict") != 0; + bee_user_t *bu = NULL; cmds = g_strdup(message); cmd = split_command_parts(cmds); if (cmd[0] == NULL) { - g_free(cmds); - return; - } else if (!(strict_commands || set_getbool(&ic->acc->set, "commands"))) { - /* Not supporting commands. */ + goto eof; + } 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) { - guint64 id; - if (cmd[1] == NULL) twitter_status_destroy(ic, td->last_status_id); - else if (sscanf(cmd[1], "%" G_GINT64_MODIFIER "x", &id) == 1) { - if (id < TWITTER_LOG_LENGTH && td->log) - id = td->log[id].id; - + 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"); - g_free(cmds); - return; + goto eof; } else if (g_strcasecmp(cmd[0], "favourite") == 0 && cmd[1]) { - guint64 id; - if ((id = twitter_message_id_from_command_arg(ic, td, cmd[1]))) { + if ((id = twitter_message_id_from_command_arg(ic, cmd[1], NULL))) { twitter_favourite_tweet(ic, id); } else { twitter_log(ic, "Please provide a message ID or username."); } - g_free(cmds); - return; + goto eof; } else if (g_strcasecmp(cmd[0], "follow") == 0 && cmd[1]) { twitter_add_buddy(ic, cmd[1], NULL); - g_free(cmds); - return; + goto eof; } else if (g_strcasecmp(cmd[0], "unfollow") == 0 && cmd[1]) { twitter_remove_buddy(ic, cmd[1], NULL); - g_free(cmds); - return; + goto eof; } else if ((g_strcasecmp(cmd[0], "report") == 0 || g_strcasecmp(cmd[0], "spam") == 0) && cmd[1]) { - char * screen_name; - guint64 id; - screen_name = 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 */ - if (g_str_has_prefix(cmd[1], "#") && - sscanf(cmd[1] + 1, "%" G_GINT64_MODIFIER "x", &id) == 1) { - if (id < TWITTER_LOG_LENGTH && td->log) { - if (g_slist_find(ic->bee->users, td->log[id].bu)) { - screen_name = td->log[id].bu->handle; - } - } - } + twitter_message_id_from_command_arg(ic, cmd[1], &bu); + if (bu) + screen_name = bu->handle; + else + screen_name = cmd[1]; + twitter_report_spam(ic, screen_name); - g_free(cmds); - return; + goto eof; } else if (g_strcasecmp(cmd[0], "rt") == 0 && cmd[1]) { - guint64 id = twitter_message_id_from_command_arg(ic, td, cmd[1]); + id = twitter_message_id_from_command_arg(ic, cmd[1], NULL); td->last_status_id = 0; if (id) @@ -646,57 +651,27 @@ static void twitter_handle_command(struct im_connection *ic, char *message) twitter_log(ic, "User `%s' does not exist or didn't " "post any statuses recently", cmd[1]); - g_free(cmds); - return; + goto eof; } else if (g_strcasecmp(cmd[0], "reply") == 0 && cmd[1] && cmd[2]) { - struct twitter_user_data *tud; - bee_user_t *bu = NULL; - guint64 id = 0; - - if (g_str_has_prefix(cmd[1], "#") && - sscanf(cmd[1] + 1, "%" G_GINT64_MODIFIER "x", &id) == 1 && - (id < TWITTER_LOG_LENGTH) && td->log) { - bu = td->log[id].bu; - if (g_slist_find(ic->bee->users, bu)) - id = td->log[id].id; - else - bu = NULL; - } else if ((bu = bee_user_by_handle(ic->bee, ic, cmd[1])) && - (tud = bu->data) && tud->last_id) { - id = tud->last_id; - } else if (sscanf(cmd[1], "%" G_GINT64_MODIFIER "x", &id) == 1 && - (id < TWITTER_LOG_LENGTH) && td->log) { - bu = td->log[id].bu; - if (g_slist_find(ic->bee->users, bu)) - id = td->log[id].id; - else - bu = NULL; - } - + 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]); - g_free(cmds); - return; + goto eof; } message = new = g_strdup_printf("@%s %s", bu->handle, message + (cmd[2] - cmd[0])); in_reply_to = id; + allow_post = TRUE; } else if (g_strcasecmp(cmd[0], "post") == 0) { message += 5; - strict_commands = FALSE; + allow_post = TRUE; } - if (strict_commands) { - twitter_log(ic, "Unknown command: %s", cmd[0]); - } else { + if (allow_post) { char *s; - bee_user_t *bu; - if (!twitter_length_check(ic, message)) { - g_free(new); - g_free(cmds); - return; - } + if (!twitter_length_check(ic, message)) + goto eof; s = cmd[0] + strlen(cmd[0]) - 1; if (!new && s > cmd[0] && (*s == ':' || *s == ',')) { @@ -719,8 +694,11 @@ static void twitter_handle_command(struct im_connection *ic, char *message) this would delete the second-last Tweet. Prevent that. */ td->last_status_id = 0; twitter_post_status(ic, message, in_reply_to); - g_free(new); + } else { + twitter_log(ic, "Unknown command: %s", cmd[0]); } +eof: + g_free(new); g_free(cmds); } |