diff options
author | Olivier LE MOAL <olivier.lemoal@winamax.fr> | 2015-02-02 11:10:05 +0100 |
---|---|---|
committer | Olivier LE MOAL <olivier.lemoal@winamax.fr> | 2015-02-10 11:32:22 +0100 |
commit | 48f9f3b3b0d4e12f55ba5ea2c34695e899916c3d (patch) | |
tree | 374b896113ea765bbaf05545bc42da0ff66d3570 /src | |
parent | 5c9dd2802a6aefcaa67cbf03a65128b595b587c9 (diff) | |
download | profani-tty-48f9f3b3b0d4e12f55ba5ea2c34695e899916c3d.tar.gz |
Add XEP-0280 support
Diffstat (limited to 'src')
-rw-r--r-- | src/command/command.c | 9 | ||||
-rw-r--r-- | src/command/commands.c | 18 | ||||
-rw-r--r-- | src/command/commands.h | 1 | ||||
-rw-r--r-- | src/config/preferences.c | 3 | ||||
-rw-r--r-- | src/config/preferences.h | 1 | ||||
-rw-r--r-- | src/server_events.c | 5 | ||||
-rw-r--r-- | src/server_events.h | 1 | ||||
-rw-r--r-- | src/ui/console.c | 9 | ||||
-rw-r--r-- | src/ui/ui.h | 1 | ||||
-rw-r--r-- | src/xmpp/connection.c | 5 | ||||
-rw-r--r-- | src/xmpp/iq.c | 20 | ||||
-rw-r--r-- | src/xmpp/message.c | 38 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 38 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 8 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 2 |
15 files changed, 158 insertions, 1 deletions
diff --git a/src/command/command.c b/src/command/command.c index f05d2a79..b4daadcc 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -859,6 +859,15 @@ static struct cmd_t command_defs[] = "shared : Share logs between all instances, accepts 'on' or 'off', defaults to 'on'.", NULL } } }, + { "/carbons", + cmd_carbons, parse_args, 1, 1, &cons_carbons_setting, + { "/carbons on|off", "Message carbons.", + { "/carbons on|off", + "---------------", + "Enable or disable message carbons.", + "The message carbons feature ensures that both sides of all conversations are shared with all the user's clients that implement this protocol.", + NULL } } }, + { "/reconnect", cmd_reconnect, parse_args, 1, 1, &cons_reconnect_setting, { "/reconnect seconds", "Set reconnect interval.", diff --git a/src/command/commands.c b/src/command/commands.c index 6eca1bd1..f6784fb5 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -730,7 +730,7 @@ cmd_help(gchar **args, struct cmd_help_t help) } else if (strcmp(args[0], "settings") == 0) { gchar *filter[] = { "/account", "/autoaway", "/autoping", "/autoconnect", "/beep", - "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype", + "/carbons", "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype", "/log", "/mouse", "/notify", "/outtype", "/prefs", "/priority", "/reconnect", "/roster", "/splash", "/states", "/statuses", "/theme", "/titlebar", "/vercheck", "/privileges", "/occupants", "/presence", "/wrap" }; @@ -3888,6 +3888,22 @@ cmd_history(gchar **args, struct cmd_help_t help) } gboolean +cmd_carbons(gchar **args, struct cmd_help_t help) +{ + gboolean result = _cmd_set_boolean_preference(args[0], help, + "Carbons message", PREF_CARBONS); + + // enable carbons + if (strcmp(args[0], "on") == 0) { + iq_enable_carbons(); + } + else if (strcmp(args[0], "off") == 0){ + iq_disable_carbons(); + } + return result; +} + +gboolean cmd_away(gchar **args, struct cmd_help_t help) { _update_presence(RESOURCE_AWAY, "away", args); diff --git a/src/command/commands.h b/src/command/commands.h index f4e040a9..1c16d635 100644 --- a/src/command/commands.h +++ b/src/command/commands.h @@ -85,6 +85,7 @@ gboolean cmd_grlog(gchar **args, struct cmd_help_t help); gboolean cmd_group(gchar **args, struct cmd_help_t help); gboolean cmd_help(gchar **args, struct cmd_help_t help); gboolean cmd_history(gchar **args, struct cmd_help_t help); +gboolean cmd_carbons(gchar **args, struct cmd_help_t help); gboolean cmd_info(gchar **args, struct cmd_help_t help); gboolean cmd_intype(gchar **args, struct cmd_help_t help); gboolean cmd_invite(gchar **args, struct cmd_help_t help); diff --git a/src/config/preferences.c b/src/config/preferences.c index 67f12b18..7753ad71 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -558,6 +558,7 @@ _get_group(preference_t pref) return PREF_GROUP_PRESENCE; case PREF_CONNECT_ACCOUNT: case PREF_DEFAULT_ACCOUNT: + case PREF_CARBONS: return PREF_GROUP_CONNECTION; case PREF_OTR_WARN: case PREF_OTR_LOG: @@ -593,6 +594,8 @@ _get_key(preference_t pref) return "intype"; case PREF_HISTORY: return "history"; + case PREF_CARBONS: + return "carbons"; case PREF_MOUSE: return "mouse"; case PREF_OCCUPANTS: diff --git a/src/config/preferences.h b/src/config/preferences.h index 68286f09..aa23e48a 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -59,6 +59,7 @@ typedef enum { PREF_FLASH, PREF_INTYPE, PREF_HISTORY, + PREF_CARBONS, PREF_MOUSE, PREF_OCCUPANTS, PREF_OCCUPANTS_SIZE, diff --git a/src/server_events.c b/src/server_events.c index fbf534ac..bf880a9d 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -297,6 +297,11 @@ handle_incoming_private_message(char *fulljid, char *message) } void +handle_carbon(char *barejid, char *message){ + ui_outgoing_chat_msg("me", barejid, message); +} + +void handle_incoming_message(char *barejid, char *resource, char *message) { #ifdef HAVE_LIBOTR diff --git a/src/server_events.h b/src/server_events.h index 6a12dc6e..3ec6a332 100644 --- a/src/server_events.h +++ b/src/server_events.h @@ -101,6 +101,7 @@ void handle_group_remove(const char * const contact, void handle_roster_remove(const char * const barejid); void handle_roster_add(const char * const barejid, const char * const name); void handle_autoping_cancel(void); +void handle_carbon(char *barejid, char *message); void handle_message_error(const char * const from, const char * const type, const char * const err_msg); void handle_presence_error(const char *from, const char * const type, diff --git a/src/ui/console.c b/src/ui/console.c index 2c37c40c..e5383f06 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1173,6 +1173,15 @@ cons_history_setting(void) } void +cons_carbons_setting(void) +{ + if (prefs_get_boolean(PREF_CARBONS)) + cons_show("Message carbons (/carbons) : ON"); + else + cons_show("Message carbons (/carbons) : OFF"); +} + +void cons_show_chat_prefs(void) { cons_show("Chat preferences:"); diff --git a/src/ui/ui.h b/src/ui/ui.h index 99e73b4a..44ff42f4 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -308,6 +308,7 @@ void cons_outtype_setting(void); void cons_intype_setting(void); void cons_gone_setting(void); void cons_history_setting(void); +void cons_carbons_setting(void); void cons_log_setting(void); void cons_chlog_setting(void); void cons_grlog_setting(void); diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 915525e4..34fba22d 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -466,6 +466,11 @@ _connection_handler(xmpp_conn_t * const conn, roster_request(); bookmark_request(); + + if (prefs_get_boolean(PREF_CARBONS)){ + iq_enable_carbons(); + } + jabber_conn.conn_status = JABBER_CONNECTED; if (prefs_get_reconnect() != 0) { diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index bc12b780..90b87676 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -153,6 +153,26 @@ iq_room_list_request(gchar *conferencejid) } void +iq_enable_carbons() +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_enable_carbons(ctx); + xmpp_send(conn, iq); + xmpp_stanza_release(iq); +} + +void +iq_disable_carbons() +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_disable_carbons(ctx); + xmpp_send(conn, iq); + xmpp_stanza_release(iq); +} + +void iq_disco_info_request(gchar *jid) { xmpp_conn_t * const conn = connection_get_conn(); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index e96c1a74..4f341f6a 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -423,6 +423,44 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, return 1; } + // check if carbon message + xmpp_stanza_t *received = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS); + if(received != NULL){ + xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(received, STANZA_NS_FORWARD); + xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE); + + xmpp_ctx_t *ctx = connection_get_ctx(); + + gchar *to = xmpp_stanza_get_attribute(message, STANZA_ATTR_TO); + gchar *from = xmpp_stanza_get_attribute(message, STANZA_ATTR_FROM); + + Jid *jid_from = jid_create(from); + Jid *jid_to = jid_create(to); + Jid *my_jid = jid_create(jabber_get_fulljid()); + + // check for and deal with message + xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(message, STANZA_NAME_BODY); + if (body != NULL) { + char *message = xmpp_stanza_get_text(body); + if (message != NULL) { + // if we are the recipient, treat as standard incoming message + if(g_strcmp0(my_jid->barejid, jid_to->barejid) == 0){ + handle_incoming_message(jid_from->barejid, jid_from->resourcepart, message); + } + // else treat as a sent message + else{ + handle_carbon(jid_to->barejid, message); + } + xmpp_free(ctx, message); + } + } + + jid_destroy(jid_from); + jid_destroy(jid_to); + jid_destroy(my_jid); + return 1; + } + // ignore handled namespaces xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 4f1d412d..b0d7de86 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -199,6 +199,44 @@ stanza_create_bookmarks_pubsub_add(xmpp_ctx_t *ctx, const char * const jid, #endif xmpp_stanza_t * +stanza_enable_carbons(xmpp_ctx_t *ctx){ + xmpp_stanza_t *iq = xmpp_stanza_new(ctx); + char *id = create_unique_id(NULL); + + xmpp_stanza_set_name(iq, STANZA_NAME_IQ); + xmpp_stanza_set_type(iq, STANZA_TYPE_SET); + xmpp_stanza_set_id(iq, id); + free(id); + + xmpp_stanza_t *carbons_enable = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(carbons_enable, STANZA_NAME_ENABLE); + xmpp_stanza_set_ns(carbons_enable, STANZA_NS_CARBONS); + + xmpp_stanza_add_child(iq, carbons_enable); + + return iq; +} + +xmpp_stanza_t * +stanza_disable_carbons(xmpp_ctx_t *ctx){ + xmpp_stanza_t *iq = xmpp_stanza_new(ctx); + char *id = create_unique_id(NULL); + + xmpp_stanza_set_name(iq, STANZA_NAME_IQ); + xmpp_stanza_set_type(iq, STANZA_TYPE_SET); + xmpp_stanza_set_id(iq, id); + free(id); + + xmpp_stanza_t *carbons_disable = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(carbons_disable, STANZA_NAME_DISABLE); + xmpp_stanza_set_ns(carbons_disable, STANZA_NS_CARBONS); + + xmpp_stanza_add_child(iq, carbons_disable); + + return iq; +} + +xmpp_stanza_t * stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state) { xmpp_stanza_t *msg, *chat_state; diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 84282401..e4f3ce57 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -77,6 +77,8 @@ #define STANZA_NAME_VALUE "value" #define STANZA_NAME_DESTROY "destroy" #define STANZA_NAME_ACTOR "actor" +#define STANZA_NAME_ENABLE "enable" +#define STANZA_NAME_DISABLE "disable" // error conditions #define STANZA_NAME_BAD_REQUEST "bad-request" @@ -154,6 +156,8 @@ #define STANZA_NS_CONFERENCE "jabber:x:conference" #define STANZA_NS_CAPTCHA "urn:xmpp:captcha" #define STANZA_NS_PUBSUB "http://jabber.org/protocol/pubsub" +#define STANZA_NS_CARBONS "urn:xmpp:carbons:2" +#define STANZA_NS_FORWARD "urn:xmpp:forward:0" #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" @@ -178,6 +182,10 @@ typedef enum { xmpp_stanza_t* stanza_create_bookmarks_storage_request(xmpp_ctx_t *ctx); +xmpp_stanza_t * stanza_enable_carbons(xmpp_ctx_t *ctx); + +xmpp_stanza_t * stanza_disable_carbons(xmpp_ctx_t *ctx); + xmpp_stanza_t* stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index a004a4bf..1fc32665 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -172,6 +172,8 @@ void presence_update(resource_presence_t status, const char * const msg, gboolean presence_sub_request_exists(const char * const bare_jid); // iq functions +void iq_enable_carbons(); +void iq_disable_carbons(); void iq_send_software_version(const char * const fulljid); void iq_room_list_request(gchar *conferencejid); void iq_disco_info_request(gchar *jid); |