Mercurial > pidgin
annotate src/protocols/jabber/message.c @ 13771:463259ea22ff
[gaim-migrate @ 16183]
Apparently if you just use --with-python the autotools decide you must mean
you want to use yes(1) as your python interpreter, this results in an
infinitely growing output file the first time the dbus stuff tries to generate
a header. That's bad. This should make it a bit clearer.
committer: Tailor Script <tailor@pidgin.im>
| author | Etan Reisner <pidgin@unreliablesource.net> |
|---|---|
| date | Fri, 12 May 2006 22:08:34 +0000 |
| parents | 8d972f41b4de |
| children | 25e63008d3bb |
| rev | line source |
|---|---|
| 7014 | 1 /* |
| 2 * gaim - Jabber Protocol Plugin | |
| 3 * | |
| 4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
| 5 * | |
| 6 * This program is free software; you can redistribute it and/or modify | |
| 7 * it under the terms of the GNU General Public License as published by | |
| 8 * the Free Software Foundation; either version 2 of the License, or | |
| 9 * (at your option) any later version. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License | |
| 17 * along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 * | |
| 20 */ | |
| 21 #include "internal.h" | |
| 22 | |
| 23 #include "debug.h" | |
| 24 #include "notify.h" | |
| 25 #include "server.h" | |
|
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7014
diff
changeset
|
26 #include "util.h" |
| 7014 | 27 |
| 28 #include "buddy.h" | |
| 29 #include "chat.h" | |
| 30 #include "message.h" | |
| 31 #include "xmlnode.h" | |
| 32 | |
| 33 void jabber_message_free(JabberMessage *jm) | |
| 34 { | |
| 13483 | 35 g_free(jm->from); |
| 36 g_free(jm->to); | |
| 37 g_free(jm->id); | |
| 38 g_free(jm->subject); | |
| 39 g_free(jm->body); | |
| 40 g_free(jm->xhtml); | |
| 41 g_free(jm->password); | |
| 42 g_list_free(jm->etc); | |
| 7014 | 43 |
| 44 g_free(jm); | |
| 45 } | |
| 46 | |
| 7145 | 47 static void handle_chat(JabberMessage *jm) |
| 7014 | 48 { |
| 49 JabberID *jid = jabber_id_new(jm->from); | |
| 50 char *from; | |
| 51 | |
| 52 JabberBuddy *jb; | |
| 53 JabberBuddyResource *jbr; | |
| 54 | |
| 7310 | 55 if(!jid) |
| 56 return; | |
| 57 | |
| 7014 | 58 jb = jabber_buddy_find(jm->js, jm->from, TRUE); |
| 7306 | 59 jbr = jabber_buddy_find_resource(jb, jid->resource); |
| 7014 | 60 |
| 8043 | 61 if(jabber_find_unnormalized_conv(jm->from, jm->js->gc->account)) { |
| 7014 | 62 from = g_strdup(jm->from); |
| 7258 | 63 } else if(jid->node) { |
| 10490 | 64 if(jid->resource) { |
| 65 GaimConversation *conv; | |
| 7258 | 66 |
| 10490 | 67 from = g_strdup_printf("%s@%s", jid->node, jid->domain); |
| 13303 | 68 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, from, jm->js->gc->account); |
| 10490 | 69 if(conv) { |
| 70 gaim_conversation_set_name(conv, jm->from); | |
| 13303 | 71 } |
| 10490 | 72 g_free(from); |
| 73 } | |
| 7258 | 74 from = g_strdup(jm->from); |
| 75 } else { | |
| 7014 | 76 from = g_strdup(jid->domain); |
| 7258 | 77 } |
| 7014 | 78 |
| 79 if(!jm->xhtml && !jm->body) { | |
| 13706 | 80 if(JM_STATE_COMPOSING == jm->chat_state) |
| 7014 | 81 serv_got_typing(jm->js->gc, from, 0, GAIM_TYPING); |
| 13706 | 82 else if(JM_STATE_PAUSED == jm->chat_state) |
| 83 serv_got_typing(jm->js->gc, from, 0, GAIM_TYPED); | |
| 7014 | 84 else |
| 85 serv_got_typing_stopped(jm->js->gc, from); | |
| 86 } else { | |
| 8400 | 87 if(jbr) { |
| 13706 | 88 if(JM_TS_JEP_0085 == (jm->typing_style & JM_TS_JEP_0085)) { |
| 89 jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED; | |
| 90 } else { | |
| 91 jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED; | |
| 92 } | |
| 93 | |
| 94 if(JM_TS_JEP_0022 == (jm->typing_style & JM_TS_JEP_0022)) { | |
| 8400 | 95 jbr->capabilities |= JABBER_CAP_COMPOSING; |
| 13706 | 96 } |
| 97 | |
| 8400 | 98 if(jbr->thread_id) |
| 99 g_free(jbr->thread_id); | |
| 100 jbr->thread_id = g_strdup(jbr->thread_id); | |
| 101 } | |
| 7014 | 102 serv_got_im(jm->js->gc, from, jm->xhtml ? jm->xhtml : jm->body, 0, |
| 103 jm->sent); | |
| 104 } | |
| 105 | |
| 13706 | 106 |
| 7014 | 107 g_free(from); |
| 108 jabber_id_free(jid); | |
| 109 } | |
| 110 | |
| 7145 | 111 static void handle_headline(JabberMessage *jm) |
| 112 { | |
| 113 char *title; | |
| 114 GString *body = g_string_new(""); | |
| 115 GList *etc; | |
| 116 | |
| 117 title = g_strdup_printf(_("Message from %s"), jm->from); | |
| 118 | |
| 119 if(jm->xhtml) | |
| 120 g_string_append(body, jm->xhtml); | |
| 121 else if(jm->body) | |
| 122 g_string_append(body, jm->body); | |
| 123 | |
| 124 for(etc = jm->etc; etc; etc = etc->next) { | |
| 125 xmlnode *x = etc->data; | |
| 126 const char *xmlns = xmlnode_get_attrib(x, "xmlns"); | |
| 127 if(xmlns && !strcmp(xmlns, "jabber:x:oob")) { | |
| 128 xmlnode *url, *desc; | |
| 129 char *urltxt, *desctxt; | |
| 130 | |
| 131 url = xmlnode_get_child(x, "url"); | |
| 132 desc = xmlnode_get_child(x, "desc"); | |
| 133 | |
| 134 if(!url || !desc) | |
| 135 continue; | |
| 136 | |
| 137 urltxt = xmlnode_get_data(url); | |
| 138 desctxt = xmlnode_get_data(desc); | |
| 139 | |
| 140 /* I'm all about ugly hacks */ | |
| 141 if(body->len && !strcmp(body->str, jm->body)) | |
| 142 g_string_printf(body, "<a href='%s'>%s</a>", | |
| 143 urltxt, desctxt); | |
| 144 else | |
| 145 g_string_append_printf(body, "<br/><a href='%s'>%s</a>", | |
| 146 urltxt, desctxt); | |
| 147 | |
| 148 g_free(urltxt); | |
| 149 g_free(desctxt); | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 gaim_notify_formatted(jm->js->gc, title, jm->subject ? jm->subject : title, | |
| 154 NULL, body->str, NULL, NULL); | |
| 155 | |
| 156 g_free(title); | |
| 157 g_string_free(body, TRUE); | |
| 158 } | |
| 159 | |
| 160 static void handle_groupchat(JabberMessage *jm) | |
| 7014 | 161 { |
| 162 JabberID *jid = jabber_id_new(jm->from); | |
| 7310 | 163 JabberChat *chat; |
| 164 | |
| 165 if(!jid) | |
| 166 return; | |
| 167 | |
| 168 chat = jabber_chat_find(jm->js, jid->node, jid->domain); | |
| 7014 | 169 |
| 170 if(!chat) | |
| 171 return; | |
| 172 | |
| 7971 | 173 if(jm->subject) { |
| 7183 | 174 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(chat->conv), jid->resource, |
| 175 jm->subject); | |
| 7971 | 176 if(!jm->xhtml && !jm->body) { |
| 9762 | 177 char *msg, *tmp, *tmp2; |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10607
diff
changeset
|
178 tmp = g_markup_escape_text(jm->subject, -1); |
| 9762 | 179 tmp2 = gaim_markup_linkify(tmp); |
| 7971 | 180 if(jid->resource) |
| 9762 | 181 msg = g_strdup_printf(_("%s has set the topic to: %s"), jid->resource, tmp2); |
| 7971 | 182 else |
| 9762 | 183 msg = g_strdup_printf(_("The topic is: %s"), tmp2); |
| 7971 | 184 gaim_conv_chat_write(GAIM_CONV_CHAT(chat->conv), "", msg, GAIM_MESSAGE_SYSTEM, jm->sent); |
| 9762 | 185 g_free(tmp); |
| 186 g_free(tmp2); | |
| 7971 | 187 g_free(msg); |
| 188 } | |
| 189 } | |
| 7014 | 190 |
| 7630 | 191 if(jm->xhtml || jm->body) { |
| 192 if(jid->resource) | |
| 9584 | 193 serv_got_chat_in(jm->js->gc, chat->id, jid->resource, |
| 12216 | 194 jm->delayed ? GAIM_MESSAGE_DELAYED : 0, |
| 7630 | 195 jm->xhtml ? jm->xhtml : jm->body, jm->sent); |
| 196 else if(chat->muc) | |
| 197 gaim_conv_chat_write(GAIM_CONV_CHAT(chat->conv), "", | |
| 198 jm->xhtml ? jm->xhtml : jm->body, | |
| 199 GAIM_MESSAGE_SYSTEM, jm->sent); | |
| 200 } | |
| 201 | |
| 7014 | 202 jabber_id_free(jid); |
| 203 } | |
| 204 | |
| 7145 | 205 static void handle_groupchat_invite(JabberMessage *jm) |
| 7014 | 206 { |
| 7310 | 207 GHashTable *components; |
| 7014 | 208 JabberID *jid = jabber_id_new(jm->to); |
| 209 | |
| 7310 | 210 if(!jid) |
| 211 return; | |
| 212 | |
| 213 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
| 214 | |
| 7332 | 215 g_hash_table_replace(components, g_strdup("room"), g_strdup(jid->node)); |
| 7448 | 216 g_hash_table_replace(components, g_strdup("server"), g_strdup(jid->domain)); |
| 7332 | 217 g_hash_table_replace(components, g_strdup("handle"), |
| 218 g_strdup(jm->js->user->node)); | |
| 219 g_hash_table_replace(components, g_strdup("password"), | |
| 220 g_strdup(jm->password)); | |
| 7014 | 221 |
| 222 jabber_id_free(jid); | |
| 10774 | 223 serv_got_chat_invite(jm->js->gc, jm->to, jm->from, jm->body, components); |
| 7014 | 224 } |
| 225 | |
| 7145 | 226 static void handle_error(JabberMessage *jm) |
| 7014 | 227 { |
| 228 char *buf; | |
| 229 | |
| 230 if(!jm->body) | |
| 231 return; | |
| 232 | |
| 233 buf = g_strdup_printf(_("Message delivery to %s failed: %s"), | |
|
13764
8d972f41b4de
[gaim-migrate @ 16176]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13706
diff
changeset
|
234 jm->from, jm->error ? jm->error : ""); |
| 7014 | 235 |
| 7944 | 236 gaim_notify_formatted(jm->js->gc, _("Jabber Message Error"), _("Jabber Message Error"), buf, |
| 237 jm->xhtml ? jm->xhtml : jm->body, NULL, NULL); | |
| 7014 | 238 |
| 239 g_free(buf); | |
| 240 } | |
| 241 | |
| 242 void jabber_message_parse(JabberStream *js, xmlnode *packet) | |
| 243 { | |
| 244 JabberMessage *jm; | |
| 245 const char *type; | |
| 246 xmlnode *child; | |
| 247 | |
| 248 if(strcmp(packet->name, "message")) | |
| 249 return; | |
| 250 | |
| 251 jm = g_new0(JabberMessage, 1); | |
| 252 jm->js = js; | |
| 253 jm->sent = time(NULL); | |
| 9584 | 254 jm->delayed = FALSE; |
| 7014 | 255 |
| 256 type = xmlnode_get_attrib(packet, "type"); | |
| 257 | |
| 258 if(type) { | |
| 259 if(!strcmp(type, "normal")) | |
| 260 jm->type = JABBER_MESSAGE_NORMAL; | |
| 261 else if(!strcmp(type, "chat")) | |
| 262 jm->type = JABBER_MESSAGE_CHAT; | |
| 263 else if(!strcmp(type, "groupchat")) | |
| 264 jm->type = JABBER_MESSAGE_GROUPCHAT; | |
| 265 else if(!strcmp(type, "headline")) | |
| 266 jm->type = JABBER_MESSAGE_HEADLINE; | |
| 267 else if(!strcmp(type, "error")) | |
| 268 jm->type = JABBER_MESSAGE_ERROR; | |
| 269 else | |
| 270 jm->type = JABBER_MESSAGE_OTHER; | |
| 271 } else { | |
| 272 jm->type = JABBER_MESSAGE_NORMAL; | |
| 273 } | |
| 274 | |
| 275 jm->from = g_strdup(xmlnode_get_attrib(packet, "from")); | |
| 276 jm->to = g_strdup(xmlnode_get_attrib(packet, "to")); | |
| 13483 | 277 jm->id = g_strdup(xmlnode_get_attrib(packet, "id")); |
| 7014 | 278 |
| 279 for(child = packet->child; child; child = child->next) { | |
| 8135 | 280 if(child->type != XMLNODE_TYPE_TAG) |
| 7014 | 281 continue; |
| 282 | |
| 283 if(!strcmp(child->name, "subject")) { | |
| 284 if(!jm->subject) | |
| 285 jm->subject = xmlnode_get_data(child); | |
| 8400 | 286 } else if(!strcmp(child->name, "thread")) { |
| 287 if(!jm->thread_id) | |
| 288 jm->thread_id = xmlnode_get_data(child); | |
| 7014 | 289 } else if(!strcmp(child->name, "body")) { |
| 13384 | 290 if(!jm->body) { |
| 291 char *msg = xmlnode_to_str(child, NULL); | |
| 292 jm->body = gaim_strdup_withhtml(msg); | |
| 293 g_free(msg); | |
| 294 } | |
| 7241 | 295 } else if(!strcmp(child->name, "html")) { |
| 11788 | 296 if(!jm->xhtml && xmlnode_get_child(child, "body")) |
| 7642 | 297 jm->xhtml = xmlnode_to_str(child, NULL); |
| 13706 | 298 } else if(!strcmp(child->name, "active")) { |
| 299 jm->chat_state = JM_STATE_ACTIVE; | |
| 300 jm->typing_style |= JM_TS_JEP_0085; | |
| 301 } else if(!strcmp(child->name, "composing")) { | |
| 302 jm->chat_state = JM_STATE_COMPOSING; | |
| 303 jm->typing_style |= JM_TS_JEP_0085; | |
| 304 } else if(!strcmp(child->name, "paused")) { | |
| 305 jm->chat_state = JM_STATE_PAUSED; | |
| 306 jm->typing_style |= JM_TS_JEP_0085; | |
| 307 } else if(!strcmp(child->name, "inactive")) { | |
| 308 jm->chat_state = JM_STATE_INACTIVE; | |
| 309 jm->typing_style |= JM_TS_JEP_0085; | |
| 310 } else if(!strcmp(child->name, "gone")) { | |
| 311 jm->chat_state = JM_STATE_GONE; | |
| 312 jm->typing_style |= JM_TS_JEP_0085; | |
| 7014 | 313 } else if(!strcmp(child->name, "error")) { |
| 314 const char *code = xmlnode_get_attrib(child, "code"); | |
| 315 char *code_txt = NULL; | |
| 316 char *text = xmlnode_get_data(child); | |
| 317 | |
| 318 if(code) | |
| 319 code_txt = g_strdup_printf(_(" (Code %s)"), code); | |
| 320 | |
| 321 if(!jm->error) | |
| 322 jm->error = g_strdup_printf("%s%s", text ? text : "", | |
| 323 code_txt ? code_txt : ""); | |
| 324 | |
| 325 g_free(code_txt); | |
| 326 g_free(text); | |
| 327 } else if(!strcmp(child->name, "x")) { | |
| 328 const char *xmlns = xmlnode_get_attrib(child, "xmlns"); | |
| 329 if(xmlns && !strcmp(xmlns, "jabber:x:event")) { | |
| 13706 | 330 if(xmlnode_get_child(child, "composing")) { |
| 331 if(jm->chat_state == JM_STATE_ACTIVE) | |
| 332 jm->chat_state = JM_STATE_COMPOSING; | |
| 333 jm->typing_style |= JM_TS_JEP_0022; | |
| 334 } | |
| 7014 | 335 } else if(xmlns && !strcmp(xmlns, "jabber:x:delay")) { |
| 336 const char *timestamp = xmlnode_get_attrib(child, "stamp"); | |
| 9584 | 337 jm->delayed = TRUE; |
| 7014 | 338 if(timestamp) |
|
13119
fcde3faa1f57
[gaim-migrate @ 15481]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
339 jm->sent = gaim_str_to_time(timestamp, TRUE, NULL, NULL, NULL); |
| 7014 | 340 } else if(xmlns && !strcmp(xmlns, "jabber:x:conference") && |
| 11230 | 341 jm->type != JABBER_MESSAGE_GROUPCHAT_INVITE && |
| 342 jm->type != JABBER_MESSAGE_ERROR) { | |
| 7014 | 343 const char *jid = xmlnode_get_attrib(child, "jid"); |
| 344 if(jid) { | |
| 345 jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE; | |
| 346 g_free(jm->to); | |
| 347 jm->to = g_strdup(jid); | |
| 348 } | |
| 349 } else if(xmlns && !strcmp(xmlns, | |
| 11230 | 350 "http://jabber.org/protocol/muc#user") && |
| 351 jm->type != JABBER_MESSAGE_ERROR) { | |
| 7014 | 352 xmlnode *invite = xmlnode_get_child(child, "invite"); |
| 353 if(invite) { | |
| 354 xmlnode *reason, *password; | |
| 7968 | 355 const char *jid = xmlnode_get_attrib(invite, "from"); |
| 7014 | 356 g_free(jm->to); |
| 357 jm->to = jm->from; | |
| 358 jm->from = g_strdup(jid); | |
| 359 if((reason = xmlnode_get_child(invite, "reason"))) { | |
| 360 g_free(jm->body); | |
| 361 jm->body = xmlnode_get_data(reason); | |
| 362 } | |
|
11576
c66b972519e8
[gaim-migrate @ 13845]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11230
diff
changeset
|
363 if((password = xmlnode_get_child(child, "password"))) |
| 7014 | 364 jm->password = xmlnode_get_data(password); |
| 365 | |
| 366 jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE; | |
| 367 } | |
| 7145 | 368 } else { |
| 369 jm->etc = g_list_append(jm->etc, child); | |
| 7014 | 370 } |
| 371 } | |
| 372 } | |
| 373 | |
| 374 switch(jm->type) { | |
| 375 case JABBER_MESSAGE_NORMAL: | |
| 376 case JABBER_MESSAGE_CHAT: | |
| 7145 | 377 handle_chat(jm); |
| 378 break; | |
| 7014 | 379 case JABBER_MESSAGE_HEADLINE: |
| 7145 | 380 handle_headline(jm); |
| 7014 | 381 break; |
| 382 case JABBER_MESSAGE_GROUPCHAT: | |
| 383 handle_groupchat(jm); | |
| 384 break; | |
| 385 case JABBER_MESSAGE_GROUPCHAT_INVITE: | |
| 386 handle_groupchat_invite(jm); | |
| 387 break; | |
| 388 case JABBER_MESSAGE_ERROR: | |
| 389 handle_error(jm); | |
| 390 break; | |
| 391 case JABBER_MESSAGE_OTHER: | |
| 392 gaim_debug(GAIM_DEBUG_INFO, "jabber", | |
| 393 "Received message of unknown type: %s\n", type); | |
| 394 break; | |
| 395 } | |
| 396 jabber_message_free(jm); | |
| 397 } | |
| 398 | |
| 399 void jabber_message_send(JabberMessage *jm) | |
| 400 { | |
| 401 xmlnode *message, *child; | |
| 402 const char *type = NULL; | |
| 403 | |
| 404 message = xmlnode_new("message"); | |
| 405 | |
| 406 switch(jm->type) { | |
| 407 case JABBER_MESSAGE_NORMAL: | |
| 408 type = "normal"; | |
| 409 break; | |
| 410 case JABBER_MESSAGE_CHAT: | |
| 411 case JABBER_MESSAGE_GROUPCHAT_INVITE: | |
| 412 type = "chat"; | |
| 413 break; | |
| 414 case JABBER_MESSAGE_HEADLINE: | |
| 415 type = "headline"; | |
| 416 break; | |
| 417 case JABBER_MESSAGE_GROUPCHAT: | |
| 418 type = "groupchat"; | |
| 419 break; | |
| 420 case JABBER_MESSAGE_ERROR: | |
| 421 type = "error"; | |
| 422 break; | |
| 423 case JABBER_MESSAGE_OTHER: | |
| 424 type = NULL; | |
| 425 break; | |
| 426 } | |
| 427 | |
| 428 if(type) | |
| 429 xmlnode_set_attrib(message, "type", type); | |
| 13483 | 430 |
| 431 if (jm->id) | |
| 432 xmlnode_set_attrib(message, "id", jm->id); | |
| 7014 | 433 |
| 434 xmlnode_set_attrib(message, "to", jm->to); | |
| 435 | |
| 8400 | 436 if(jm->thread_id) { |
| 437 child = xmlnode_new_child(message, "thread"); | |
| 438 xmlnode_insert_data(child, jm->thread_id, -1); | |
| 439 } | |
| 440 | |
| 13706 | 441 if(JM_TS_JEP_0022 == (jm->typing_style & JM_TS_JEP_0022)) { |
| 7014 | 442 child = xmlnode_new_child(message, "x"); |
| 443 xmlnode_set_attrib(child, "xmlns", "jabber:x:event"); | |
| 13706 | 444 if(jm->chat_state == JM_STATE_COMPOSING || jm->body) |
| 7014 | 445 xmlnode_new_child(child, "composing"); |
| 446 } | |
| 447 | |
| 13706 | 448 if(JM_TS_JEP_0085 == (jm->typing_style & JM_TS_JEP_0085)) { |
| 449 child = NULL; | |
| 450 switch(jm->chat_state) | |
| 451 { | |
| 452 case JM_STATE_ACTIVE: | |
| 453 child = xmlnode_new_child(message, "active"); | |
| 454 break; | |
| 455 case JM_STATE_COMPOSING: | |
| 456 child = xmlnode_new_child(message, "composing"); | |
| 457 break; | |
| 458 case JM_STATE_PAUSED: | |
| 459 child = xmlnode_new_child(message, "paused"); | |
| 460 break; | |
| 461 case JM_STATE_INACTIVE: | |
| 462 child = xmlnode_new_child(message, "inactive"); | |
| 463 break; | |
| 464 case JM_STATE_GONE: | |
| 465 child = xmlnode_new_child(message, "gone"); | |
| 466 break; | |
| 467 } | |
| 468 if(child) | |
| 469 xmlnode_set_attrib(child, "xmlns", "http://jabber.org/protocol/chatstates"); | |
| 470 } | |
| 471 | |
| 7014 | 472 if(jm->subject) { |
| 473 child = xmlnode_new_child(message, "subject"); | |
| 474 xmlnode_insert_data(child, jm->subject, -1); | |
| 475 } | |
| 476 | |
| 477 if(jm->body) { | |
| 478 child = xmlnode_new_child(message, "body"); | |
| 479 xmlnode_insert_data(child, jm->body, -1); | |
| 480 } | |
| 481 | |
| 482 if(jm->xhtml) { | |
| 483 child = xmlnode_from_str(jm->xhtml, -1); | |
| 484 if(child) { | |
| 485 xmlnode_insert_child(message, child); | |
| 486 } else { | |
| 487 gaim_debug(GAIM_DEBUG_ERROR, "jabber", | |
| 488 "XHTML translation/validation failed, returning: %s\n", | |
| 489 jm->xhtml); | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 jabber_send(jm->js, message); | |
| 494 | |
| 495 xmlnode_free(message); | |
| 496 } | |
| 497 | |
| 498 int jabber_message_send_im(GaimConnection *gc, const char *who, const char *msg, | |
| 12216 | 499 GaimMessageFlags flags) |
| 7014 | 500 { |
| 501 JabberMessage *jm; | |
| 502 JabberBuddy *jb; | |
| 503 JabberBuddyResource *jbr; | |
| 504 char *buf; | |
| 7135 | 505 char *xhtml; |
| 7306 | 506 char *resource; |
| 7014 | 507 |
| 508 if(!who || !msg) | |
| 509 return 0; | |
| 510 | |
| 7306 | 511 resource = jabber_get_resource(who); |
| 512 | |
| 7014 | 513 jb = jabber_buddy_find(gc->proto_data, who, TRUE); |
| 7306 | 514 jbr = jabber_buddy_find_resource(jb, resource); |
| 515 | |
| 516 g_free(resource); | |
| 7014 | 517 |
| 518 jm = g_new0(JabberMessage, 1); | |
| 519 jm->js = gc->proto_data; | |
| 520 jm->type = JABBER_MESSAGE_CHAT; | |
| 13706 | 521 jm->chat_state = JM_STATE_ACTIVE; |
| 7014 | 522 jm->to = g_strdup(who); |
| 13483 | 523 jm->id = jabber_get_next_id(jm->js); |
| 13706 | 524 jm->chat_state = JM_STATE_ACTIVE; |
| 525 | |
| 526 if(jbr) { | |
| 527 if(jbr->thread_id) | |
| 528 jm->thread_id = jbr->thread_id; | |
| 529 | |
| 530 if(jbr->chat_states != JABBER_CHAT_STATES_UNSUPPORTED) { | |
| 531 jm->typing_style |= JM_TS_JEP_0085; | |
| 532 /* if(JABBER_CHAT_STATES_UNKNOWN == jbr->chat_states) | |
| 533 jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED; */ | |
| 534 } | |
| 535 | |
| 536 if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED) | |
| 537 jm->typing_style |= JM_TS_JEP_0022; | |
| 538 } | |
| 7014 | 539 |
| 7773 | 540 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); |
| 7014 | 541 |
| 7135 | 542 gaim_markup_html_to_xhtml(buf, &xhtml, &jm->body); |
| 7014 | 543 g_free(buf); |
| 544 | |
| 545 if(!jbr || jbr->capabilities & JABBER_CAP_XHTML) | |
| 546 jm->xhtml = xhtml; | |
| 547 else | |
| 548 g_free(xhtml); | |
| 549 | |
| 550 jabber_message_send(jm); | |
| 551 jabber_message_free(jm); | |
| 552 return 1; | |
| 553 } | |
| 554 | |
| 12216 | 555 int jabber_message_send_chat(GaimConnection *gc, int id, const char *msg, GaimMessageFlags flags) |
| 7014 | 556 { |
| 557 JabberChat *chat; | |
| 558 JabberMessage *jm; | |
| 8042 | 559 JabberStream *js; |
| 9130 | 560 char *buf; |
| 7014 | 561 |
| 8042 | 562 if(!msg || !gc) |
| 7014 | 563 return 0; |
| 564 | |
| 8042 | 565 js = gc->proto_data; |
| 7014 | 566 chat = jabber_chat_find_by_id(js, id); |
| 567 | |
| 8043 | 568 if(!chat) |
| 569 return 0; | |
| 570 | |
| 9130 | 571 jm = g_new0(JabberMessage, 1); |
| 572 jm->js = gc->proto_data; | |
| 573 jm->type = JABBER_MESSAGE_GROUPCHAT; | |
| 574 jm->to = g_strdup_printf("%s@%s", chat->room, chat->server); | |
| 13483 | 575 jm->id = jabber_get_next_id(jm->js); |
| 9130 | 576 |
| 8858 | 577 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); |
| 9130 | 578 gaim_markup_html_to_xhtml(buf, &jm->xhtml, &jm->body); |
| 8858 | 579 g_free(buf); |
| 580 | |
| 9130 | 581 if(!chat->xhtml) { |
| 582 g_free(jm->xhtml); | |
| 583 jm->xhtml = NULL; | |
| 7923 | 584 } |
| 585 | |
| 9130 | 586 jabber_message_send(jm); |
| 587 jabber_message_free(jm); | |
| 588 | |
| 7014 | 589 return 1; |
| 590 } | |
| 591 | |
| 592 int jabber_send_typing(GaimConnection *gc, const char *who, int typing) | |
| 593 { | |
| 594 JabberMessage *jm; | |
| 595 JabberBuddy *jb; | |
| 596 JabberBuddyResource *jbr; | |
| 7306 | 597 char *resource = jabber_get_resource(who); |
| 7014 | 598 |
| 599 jb = jabber_buddy_find(gc->proto_data, who, TRUE); | |
| 7306 | 600 jbr = jabber_buddy_find_resource(jb, resource); |
| 601 | |
| 602 g_free(resource); | |
| 7014 | 603 |
| 13706 | 604 if(!jbr || !((jbr->capabilities & JABBER_CAP_COMPOSING) || (jbr->chat_states != JABBER_CHAT_STATES_UNSUPPORTED))) |
| 7014 | 605 return 0; |
| 606 | |
| 13706 | 607 /* TODO: figure out threading */ |
| 7014 | 608 jm = g_new0(JabberMessage, 1); |
| 609 jm->js = gc->proto_data; | |
| 610 jm->type = JABBER_MESSAGE_CHAT; | |
| 611 jm->to = g_strdup(who); | |
| 13483 | 612 jm->id = jabber_get_next_id(jm->js); |
| 7014 | 613 |
| 13706 | 614 if(GAIM_TYPING == typing) |
| 615 jm->chat_state = JM_STATE_COMPOSING; | |
| 616 else if(GAIM_TYPED == typing) | |
| 617 jm->chat_state = JM_STATE_PAUSED; | |
| 618 else | |
| 619 jm->chat_state = JM_STATE_ACTIVE; | |
| 620 | |
| 621 if(jbr->chat_states != JABBER_CHAT_STATES_UNSUPPORTED) { | |
| 622 jm->typing_style |= JM_TS_JEP_0085; | |
| 623 /* if(JABBER_CHAT_STATES_UNKNOWN == jbr->chat_states) | |
| 624 jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED; */ | |
| 625 } | |
| 626 | |
| 627 if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED) | |
| 628 jm->typing_style |= JM_TS_JEP_0022; | |
| 7014 | 629 |
| 630 jabber_message_send(jm); | |
| 631 jabber_message_free(jm); | |
| 632 | |
| 13706 | 633 return 0; |
| 7014 | 634 } |
| 635 |
