about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command/cmd_ac.c2
-rw-r--r--src/command/cmd_defs.c12
-rw-r--r--src/command/cmd_funcs.c52
-rw-r--r--src/xmpp/blocking.c27
-rw-r--r--src/xmpp/iq.c4
-rw-r--r--src/xmpp/stanza.h4
-rw-r--r--src/xmpp/xmpp.h9
7 files changed, 91 insertions, 19 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index 6b46d079..77cd1adc 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -951,6 +951,8 @@ cmd_ac_init(void)
     blocked_ac = autocomplete_new();
     autocomplete_add(blocked_ac, "add");
     autocomplete_add(blocked_ac, "remove");
+    autocomplete_add(blocked_ac, "report-abuse");
+    autocomplete_add(blocked_ac, "report-spam");
 
     clear_ac = autocomplete_new();
     autocomplete_add(clear_ac, "persist_history");
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index e04ba2a1..63cb8780 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -420,7 +420,7 @@ static struct cmd_t command_defs[] = {
     },
 
     { "/blocked",
-      parse_args, 0, 2, NULL,
+      parse_args_with_freetext, 0, 3, NULL,
       CMD_NOSUBFUNCS
       CMD_MAINFUNC(cmd_blocked)
       CMD_TAGS(
@@ -429,15 +429,21 @@ static struct cmd_t command_defs[] = {
       CMD_SYN(
               "/blocked",
               "/blocked add [<jid>]",
+              "/blocked report-abuse [<jid>] [<message>]",
+              "/blocked report-spam [<jid>] [<message>]",
               "/blocked remove <jid>")
       CMD_DESC(
               "Manage blocked users (XEP-0191), calling with no arguments shows the current list of blocked users. "
-              "To blog a certain user in a MUC use the following as jid: room@conference.example.org/spammy-user")
+              "To blog a certain user in a MUC use the following as jid: room@conference.example.org/spammy-user"
+              "It is also possible to block and report (XEP-0377) a user with the report-abuse and report-spam commands.")
       CMD_ARGS(
               { "add [<jid>]", "Block the specified Jabber ID. If in a chat window and no jid is specified, the current recipient will be blocked." },
-              { "remove <jid>", "Remove the specified Jabber ID from the blocked list." })
+              { "remove <jid>", "Remove the specified Jabber ID from the blocked list." },
+              { "report-abuse <jid> [<message>]", "Report the jid as abuse with an optional message to the service operator." },
+              { "report-spam <jid> [<message>]", "Report the jid as spam with an optional message to the service operator." })
       CMD_EXAMPLES(
               "/blocked add hel@helheim.edda",
+              "/blocked report-spam hel@helheim.edda Very annoying guy",
               "/blocked add profanity@rooms.dismail.de/spammy-user")
     },
 
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index e1108982..9b092939 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -3008,23 +3008,29 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args)
     }
 
     if (!connection_supports(XMPP_FEATURE_BLOCKING)) {
-        cons_show("Blocking not supported by server.");
+        cons_show("Blocking (%s) not supported by server.", XMPP_FEATURE_BLOCKING);
         return TRUE;
     }
 
+    blocked_report br = BLOCKED_NO_REPORT;
+
     if (g_strcmp0(args[0], "add") == 0) {
         char* jid = args[1];
-        if (jid == NULL && (window->type == WIN_CHAT)) {
-            ProfChatWin* chatwin = (ProfChatWin*)window;
-            jid = chatwin->barejid;
-        }
 
-        if (jid == NULL) {
-            cons_bad_cmd_usage(command);
-            return TRUE;
+        // /blocked add jid or /blocked add (in window)
+        if (g_strv_length(args) < 3) {
+            if (jid == NULL && (window->type == WIN_CHAT)) {
+                ProfChatWin* chatwin = (ProfChatWin*)window;
+                jid = chatwin->barejid;
+            }
+
+            if (jid == NULL) {
+                cons_bad_cmd_usage(command);
+                return TRUE;
+            }
         }
 
-        gboolean res = blocked_add(jid);
+        gboolean res = blocked_add(jid, br, NULL);
         if (!res) {
             cons_show("User %s already blocked.", jid);
         }
@@ -3046,6 +3052,28 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args)
         return TRUE;
     }
 
+    if (strncmp(args[0], "report-", 7) == 0) {
+        if (args[1] && g_strcmp0(args[0], "report-abuse") == 0) {
+            br = BLOCKED_REPORT_ABUSE;
+        } else if (args[1] && g_strcmp0(args[0], "report-spam") == 0) {
+            br = BLOCKED_REPORT_SPAM;
+        } else {
+            cons_bad_cmd_usage(command);
+            return TRUE;
+        }
+
+        if (!connection_supports(XMPP_FEATURE_SPAM_REPORTING)) {
+            cons_show("Spam reporting (%s) not supported by server.", XMPP_FEATURE_SPAM_REPORTING);
+            return TRUE;
+        }
+
+        // args[3] is an optional message
+        gboolean res = blocked_add(args[1], br, args[3]);
+        if (!res) {
+            cons_show("User %s already blocked.", args[1]);
+        }
+    }
+
     GList* blocked = blocked_list();
     GList* curr = blocked;
     if (curr) {
@@ -6497,7 +6525,7 @@ cmd_ping(ProfWin* window, const char* const command, gchar** args)
     }
 
     if (args[0] == NULL && connection_supports(XMPP_FEATURE_PING) == FALSE) {
-        cons_show("Server does not support ping requests.");
+        cons_show("Server does not support ping requests (%s).", XMPP_FEATURE_PING);
         return TRUE;
     }
 
@@ -8102,7 +8130,7 @@ cmd_command_list(ProfWin* window, const char* const command, gchar** args)
     }
 
     if (connection_supports(XMPP_FEATURE_COMMANDS) == FALSE) {
-        cons_show("Server does not support ad hoc commands.");
+        cons_show("Server does not support ad hoc commands (%s).", XMPP_FEATURE_COMMANDS);
         return TRUE;
     }
 
@@ -8158,7 +8186,7 @@ cmd_command_exec(ProfWin* window, const char* const command, gchar** args)
     }
 
     if (connection_supports(XMPP_FEATURE_COMMANDS) == FALSE) {
-        cons_show("Server does not support ad hoc commands.");
+        cons_show("Server does not support ad hoc commands (%s).", XMPP_FEATURE_COMMANDS);
         return TRUE;
     }
 
diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c
index 34614679..b16f95cb 100644
--- a/src/xmpp/blocking.c
+++ b/src/xmpp/blocking.c
@@ -109,7 +109,7 @@ blocked_ac_reset(void)
 }
 
 gboolean
-blocked_add(char* jid)
+blocked_add(char* jid, blocked_report reportkind, const char* const message)
 {
     GList* found = g_list_find_custom(blocked, jid, (GCompareFunc)g_strcmp0);
     if (found) {
@@ -129,6 +129,31 @@ blocked_add(char* jid)
     xmpp_stanza_set_name(item, STANZA_NAME_ITEM);
     xmpp_stanza_set_attribute(item, STANZA_ATTR_JID, jid);
 
+    if (reportkind != BLOCKED_NO_REPORT) {
+        xmpp_stanza_t* report = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_name(report, STANZA_NAME_REPORT);
+        if (reportkind == BLOCKED_REPORT_ABUSE) {
+            xmpp_stanza_set_attribute(report, STANZA_ATTR_REASON, STANZA_REPORTING_ABUSE);
+        } else {
+            xmpp_stanza_set_attribute(report, STANZA_ATTR_REASON, STANZA_REPORTING_SPAM);
+        }
+
+        if (message) {
+            xmpp_stanza_t* text = xmpp_stanza_new(ctx);
+            xmpp_stanza_set_name(text, STANZA_NAME_TEXT);
+
+            xmpp_stanza_t* txt = xmpp_stanza_new(ctx);
+            xmpp_stanza_set_text(txt, message);
+
+            xmpp_stanza_add_child(text, txt);
+            xmpp_stanza_add_child(report, text);
+            xmpp_stanza_release(txt);
+        }
+
+        xmpp_stanza_add_child(item, report);
+        xmpp_stanza_release(report);
+    }
+
     xmpp_stanza_add_child(block, item);
     xmpp_stanza_release(item);
 
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 19b620e2..42571b9c 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -1385,7 +1385,7 @@ _autoping_timed_send(xmpp_conn_t* const conn, void* const userdata)
     if (connection_supports(XMPP_FEATURE_PING) == FALSE) {
         log_warning("Server doesn't advertise %s feature, disabling autoping.", XMPP_FEATURE_PING);
         prefs_set_autoping(0);
-        cons_show_error("Server ping not supported, autoping disabled.");
+        cons_show_error("Server ping not supported (%s), autoping disabled.", XMPP_FEATURE_PING);
         xmpp_conn_t* conn = connection_get_conn();
         xmpp_timed_handler_delete(conn, _autoping_timed_send);
         return 1;
@@ -2586,7 +2586,7 @@ iq_mam_request(ProfChatWin* win)
 {
     if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) {
         log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2);
-        cons_show_error("Server doesn't support MAM.");
+        cons_show_error("Server doesn't support MAM (%s).", XMPP_FEATURE_MAM2);
         return;
     }
 
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index aeddf6a2..47560ce0 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -122,6 +122,7 @@
 #define STANZA_NAME_AFTER            "after"
 #define STANZA_NAME_USERNAME         "username"
 #define STANZA_NAME_PROPOSE          "propose"
+#define STANZA_NAME_REPORT           "report"
 
 // error conditions
 #define STANZA_NAME_BAD_REQUEST             "bad-request"
@@ -245,6 +246,9 @@
 
 #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
 
+#define STANZA_REPORTING_ABUSE "urn:xmpp:reporting:abuse"
+#define STANZA_REPORTING_SPAM  "urn:xmpp:reporting:spam"
+
 typedef struct caps_stanza_t
 {
     char* hash;
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index 003c3e07..61c7a642 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -70,6 +70,7 @@
 #define XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY "urn:xmpp:avatar:metadata+notify"
 #define XMPP_FEATURE_LAST_MESSAGE_CORRECTION     "urn:xmpp:message-correct:0"
 #define XMPP_FEATURE_MAM2                        "urn:xmpp:mam:2"
+#define XMPP_FEATURE_SPAM_REPORTING              "urn:xmpp:reporting:1"
 
 typedef enum {
     JABBER_CONNECTING,
@@ -89,6 +90,12 @@ typedef enum {
     INVITE_MEDIATED
 } jabber_invite_t;
 
+typedef enum {
+    BLOCKED_NO_REPORT,
+    BLOCKED_REPORT_ABUSE,
+    BLOCKED_REPORT_SPAM
+} blocked_report;
+
 typedef struct bookmark_t
 {
     char* barejid;
@@ -286,7 +293,7 @@ void roster_send_add_new(const char* const barejid, const char* const name);
 void roster_send_remove(const char* const barejid);
 
 GList* blocked_list(void);
-gboolean blocked_add(char* jid);
+gboolean blocked_add(char* jid, blocked_report reportkind, const char* const message);
 gboolean blocked_remove(char* jid);
 char* blocked_ac_find(const char* const search_str, gboolean previous, void* context);
 void blocked_ac_reset(void);