protocols/ircv3/purpleircv3messagehandlers.c

changeset 42769
c488d7af2923
parent 42652
225762d4e206
child 42775
98b71fc8a330
equal deleted inserted replaced
42768:5ebb4beb29b7 42769:c488d7af2923
23 #include <glib/gi18n-lib.h> 23 #include <glib/gi18n-lib.h>
24 24
25 #include "purpleircv3messagehandlers.h" 25 #include "purpleircv3messagehandlers.h"
26 26
27 #include "purpleircv3connection.h" 27 #include "purpleircv3connection.h"
28 #include "purpleircv3constants.h"
29 #include "purpleircv3core.h" 28 #include "purpleircv3core.h"
30 #include "purpleircv3ctcp.h"
31 #include "purpleircv3formatting.h"
32 #include "purpleircv3source.h"
33
34 /******************************************************************************
35 * Fallback
36 *****************************************************************************/
37 gboolean
38 purple_ircv3_message_handler_fallback(PurpleIRCv3Message *message,
39 G_GNUC_UNUSED GError **error,
40 gpointer data)
41 {
42 PurpleIRCv3Connection *connection = data;
43 char *new_command = NULL;
44 const char *command = NULL;
45
46 command = purple_ircv3_message_get_command(message);
47
48 new_command = g_strdup_printf(_("unknown command '%s'"), command);
49 purple_ircv3_message_set_command(message, new_command);
50 purple_ircv3_connection_add_status_message(connection, message);
51
52 g_clear_pointer(&new_command, g_free);
53
54 return TRUE;
55 }
56
57 /******************************************************************************
58 * Status Messages
59 *****************************************************************************/
60 gboolean
61 purple_ircv3_message_handler_status(PurpleIRCv3Message *message,
62 G_GNUC_UNUSED GError **error,
63 gpointer data)
64 {
65 purple_ircv3_connection_add_status_message(data, message);
66
67 return TRUE;
68 }
69
70 gboolean
71 purple_ircv3_message_handler_status_ignore_param0(PurpleIRCv3Message *message,
72 GError **error,
73 gpointer data)
74 {
75 GStrv params = NULL;
76 GStrv new_params = NULL;
77 guint n_params = 0;
78
79 params = purple_ircv3_message_get_params(message);
80 if(params != NULL) {
81 n_params = g_strv_length(params);
82 }
83
84 if(n_params <= 1) {
85 g_set_error(error, PURPLE_IRCV3_DOMAIN, 0,
86 "expected n_params > 1, got %u", n_params);
87
88 return FALSE;
89 }
90
91 /* We need to make a copy because otherwise we'd get a use after free in
92 * set_params.
93 */
94 new_params = g_strdupv(params + 1);
95 purple_ircv3_message_set_params(message, new_params);
96 g_clear_pointer(&new_params, g_strfreev);
97
98 purple_ircv3_connection_add_status_message(data, message);
99
100 return TRUE;
101 }
102 29
103 /****************************************************************************** 30 /******************************************************************************
104 * General Commands 31 * General Commands
105 *****************************************************************************/ 32 *****************************************************************************/
106 gboolean 33 gboolean
107 purple_ircv3_message_handler_ping(PurpleIRCv3Message *message, 34 purple_ircv3_message_handler_privmsg(G_GNUC_UNUSED IbisClient *client,
108 G_GNUC_UNUSED GError **error, 35 const char *command,
109 gpointer data) 36 IbisMessage *ibis_message, gpointer data)
110 {
111 PurpleIRCv3Connection *connection = data;
112 GStrv params = NULL;
113
114 params = purple_ircv3_message_get_params(message);
115
116 if(params != NULL && g_strv_length(params) == 1) {
117 purple_ircv3_connection_writef(connection, "PONG %s", params[0]);
118 } else {
119 purple_ircv3_connection_writef(connection, "PONG");
120 }
121
122 return TRUE;
123 }
124
125 gboolean
126 purple_ircv3_message_handler_privmsg(PurpleIRCv3Message *v3_message,
127 G_GNUC_UNUSED GError **error,
128 gpointer data)
129 { 37 {
130 PurpleIRCv3Connection *connection = data; 38 PurpleIRCv3Connection *connection = data;
131 PurpleContact *contact = NULL; 39 PurpleContact *contact = NULL;
132 PurpleConversation *conversation = NULL; 40 PurpleConversation *conversation = NULL;
133 PurpleMessage *message = NULL; 41 PurpleMessage *message = NULL;
134 PurpleMessageFlags flags = PURPLE_MESSAGE_RECV; 42 PurpleMessageFlags flags = PURPLE_MESSAGE_RECV;
135 GDateTime *dt = NULL; 43 GDateTime *dt = NULL;
136 GHashTable *tags = NULL; 44 IbisTags *tags = NULL;
137 GStrv params = NULL; 45 GStrv params = NULL;
138 gpointer raw_id = NULL;
139 gpointer raw_timestamp = NULL;
140 char *nick = NULL; 46 char *nick = NULL;
141 char *stripped = NULL; 47 char *stripped = NULL;
142 const char *command = NULL;
143 const char *id = NULL; 48 const char *id = NULL;
49 const char *raw_tag = NULL;
144 const char *source = NULL; 50 const char *source = NULL;
145 const char *target = NULL; 51 const char *target = NULL;
146 52
147 command = purple_ircv3_message_get_command(v3_message); 53 params = ibis_message_get_params(ibis_message);
148 params = purple_ircv3_message_get_params(v3_message); 54 source = ibis_message_get_source(ibis_message);
149 source = purple_ircv3_message_get_source(v3_message); 55 tags = ibis_message_get_tags(ibis_message);
150 tags = purple_ircv3_message_get_tags(v3_message);
151 56
152 if(params == NULL) { 57 if(params == NULL) {
153 g_warning("privmsg received with no parameters"); 58 g_warning("privmsg received with no parameters");
154 59
155 return FALSE; 60 return FALSE;
161 g_free(body); 66 g_free(body);
162 67
163 return FALSE; 68 return FALSE;
164 } 69 }
165 70
166 purple_ircv3_source_parse(source, &nick, NULL, NULL); 71 ibis_source_parse(source, &nick, NULL, NULL);
167 72
168 /* Find or create the conversation. */ 73 /* Find or create the conversation. */
169 target = params[0]; 74 target = params[0];
170 if(!purple_ircv3_connection_is_channel(connection, target)) { 75 if(!purple_ircv3_connection_is_channel(connection, target)) {
171 target = nick; 76 target = nick;
188 PURPLE_CONTACT_INFO(contact), 93 PURPLE_CONTACT_INFO(contact),
189 FALSE, NULL); 94 FALSE, NULL);
190 } 95 }
191 } 96 }
192 97
98 if(purple_strequal(command, IBIS_MSG_NOTICE)) {
99 flags |= PURPLE_MESSAGE_NOTIFY;
100 }
101
193 /* Grab the msgid if one was provided. */ 102 /* Grab the msgid if one was provided. */
194 if(g_hash_table_lookup_extended(tags, "msgid", NULL, &raw_id)) { 103 raw_tag = ibis_tags_lookup(tags, "msgid");
195 if(!purple_strempty(raw_id)) { 104 if(!purple_strempty(raw_tag)) {
196 id = raw_id; 105 id = raw_tag;
197 }
198 }
199
200 if(purple_strequal(command, PURPLE_IRCV3_MSG_NOTICE)) {
201 flags |= PURPLE_MESSAGE_NOTIFY;
202 } 106 }
203 107
204 /* Determine the timestamp of the message. */ 108 /* Determine the timestamp of the message. */
205 if(g_hash_table_lookup_extended(tags, "time", NULL, &raw_timestamp)) { 109 raw_tag = ibis_tags_lookup(tags, "time");
206 const char *timestamp = raw_timestamp; 110 if(!purple_strempty(raw_tag)) {
207 111 GTimeZone *tz = g_time_zone_new_utc();
208 if(!purple_strempty(timestamp)) { 112
209 GTimeZone *tz = g_time_zone_new_utc(); 113 dt = g_date_time_new_from_iso8601(raw_tag, tz);
210 114
211 dt = g_date_time_new_from_iso8601(timestamp, tz); 115 g_time_zone_unref(tz);
212
213 g_time_zone_unref(tz);
214 }
215 } 116 }
216 117
217 /* If the server didn't provide a time, use the current local time. */ 118 /* If the server didn't provide a time, use the current local time. */
218 if(dt == NULL) { 119 if(dt == NULL) {
219 dt = g_date_time_new_now_local(); 120 dt = g_date_time_new_now_local();
220 } 121 }
221 122
222 stripped = purple_ircv3_formatting_strip(params[1]); 123 stripped = ibis_formatting_strip(params[1]);
223 message = g_object_new( 124 message = g_object_new(
224 PURPLE_TYPE_MESSAGE, 125 PURPLE_TYPE_MESSAGE,
225 "author", source, 126 "author", source,
226 "contents", stripped, 127 "contents", stripped,
227 "flags", flags, 128 "flags", flags,
231 g_free(stripped); 132 g_free(stripped);
232 133
233 g_date_time_unref(dt); 134 g_date_time_unref(dt);
234 135
235 /* Check if this is a CTCP message. */ 136 /* Check if this is a CTCP message. */
236 if(!purple_ircv3_ctcp_handle(connection, conversation, message)) { 137 if(ibis_message_get_ctcp(ibis_message)) {
237 purple_conversation_write_message(conversation, message); 138 /* TODO: later... */
238 } 139 }
140
141 purple_conversation_write_message(conversation, message);
239 142
240 g_clear_pointer(&nick, g_free); 143 g_clear_pointer(&nick, g_free);
241 g_clear_object(&message); 144 g_clear_object(&message);
242 145
243 return TRUE; 146 return TRUE;
244 } 147 }
245 148
246 gboolean 149 gboolean
247 purple_ircv3_message_handler_topic(PurpleIRCv3Message *message, 150 purple_ircv3_message_handler_topic(G_GNUC_UNUSED IbisClient *client,
248 GError **error, 151 const char *command, IbisMessage *message,
249 gpointer data) 152 gpointer data)
250 { 153 {
251 PurpleIRCv3Connection *connection = data; 154 PurpleIRCv3Connection *connection = data;
252 PurpleConversation *conversation = NULL; 155 PurpleConversation *conversation = NULL;
253 GStrv params = NULL; 156 GStrv params = NULL;
254 const char *channel = NULL; 157 const char *channel = NULL;
255 const char *command = NULL;
256 const char *topic = NULL; 158 const char *topic = NULL;
257 guint n_params = 0; 159 guint n_params = 0;
258 160
259 command = purple_ircv3_message_get_command(message); 161 params = ibis_message_get_params(message);
260 params = purple_ircv3_message_get_params(message);
261 n_params = g_strv_length(params); 162 n_params = g_strv_length(params);
262 163
263 if(purple_strequal(command, PURPLE_IRCV3_MSG_TOPIC)) { 164 if(purple_strequal(command, IBIS_MSG_TOPIC)) {
264 if(n_params != 2) { 165 if(n_params != 2) {
265 g_set_error(error, PURPLE_IRCV3_DOMAIN, 0, 166 g_message("received TOPIC with %u parameters, expected 2",
266 "received TOPIC with %u parameters, expected 2", 167 n_params);
267 n_params);
268 168
269 return FALSE; 169 return FALSE;
270 } 170 }
271 171
272 channel = params[0]; 172 channel = params[0];
273 topic = params[1]; 173 topic = params[1];
274 } else if(purple_strequal(command, PURPLE_IRCV3_RPL_NOTOPIC)) { 174 } else if(purple_strequal(command, IBIS_RPL_NOTOPIC)) {
275 if(n_params != 3) { 175 if(n_params != 3) {
276 g_set_error(error, PURPLE_IRCV3_DOMAIN, 0, 176 g_message("received RPL_NOTOPIC with %u parameters, expected 3",
277 "received RPL_NOTOPIC with %u parameters, expected 3", 177 n_params);
278 n_params);
279 178
280 return FALSE; 179 return FALSE;
281 } 180 }
282 181
283 channel = params[1]; 182 channel = params[1];
284 topic = ""; 183 topic = "";
285 } else if(purple_strequal(command, PURPLE_IRCV3_RPL_TOPIC)) { 184 } else if(purple_strequal(command, IBIS_RPL_TOPIC)) {
286 if(n_params != 3) { 185 if(n_params != 3) {
287 g_set_error(error, PURPLE_IRCV3_DOMAIN, 0, 186 g_message("received RPL_TOPIC with %u parameters, expected 3",
288 "received RPL_TOPIC with %u parameters, expected 3", 187 n_params);
289 n_params);
290 188
291 return FALSE; 189 return FALSE;
292 } 190 }
293 191
294 channel = params[1]; 192 channel = params[1];
295 topic = params[2]; 193 topic = params[2];
296 } else { 194 } else {
297 g_set_error(error, PURPLE_IRCV3_DOMAIN, 0, "unexpected command %s", 195 g_message("unexpected command %s", command);
298 command);
299 196
300 return FALSE; 197 return FALSE;
301 } 198 }
302 199
303 conversation = purple_ircv3_connection_find_or_create_conversation(connection, 200 conversation = purple_ircv3_connection_find_or_create_conversation(connection,
304 channel); 201 channel);
305 if(!PURPLE_IS_CONVERSATION(conversation)) { 202 if(!PURPLE_IS_CONVERSATION(conversation)) {
306 g_set_error(error, PURPLE_IRCV3_DOMAIN, 0, 203 g_message("failed to find or create channel '%s'", channel);
307 "failed to find or create channel '%s'", channel);
308 204
309 return FALSE; 205 return FALSE;
310 } 206 }
311 207
312 purple_conversation_set_topic(conversation, topic); 208 purple_conversation_set_topic(conversation, topic);

mercurial