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 | |
| 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')
| -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);  } | 
