Mercurial > pidgin.yaz
annotate src/protocols/bonjour/jabber.c @ 11837:fa742ad8068c
[gaim-migrate @ 14128]
Don't pass our active GaimStatus to the login PRPL callback...
It's not used by most PRPLS, and that ones that DO use it
probably shouldn't. Ideally the PRPLs won't store any info
about their own status, message, etc. All that should be in
the core status API, and when it needs some info it should
query the core to get it.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 26 Oct 2005 05:40:02 +0000 |
parents | 9cd233ea2799 |
children | 488a305f9aff |
rev | line source |
---|---|
11477 | 1 /* |
2 * gaim - Bonjour Protocol Plugin | |
3 * | |
4 * Gaim is the legal property of its developers, whose names are too numerous | |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 */ | |
11688
1fd2a974379f
[gaim-migrate @ 13974]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11539
diff
changeset
|
22 #ifndef _WIN32 |
11477 | 23 #include <sys/socket.h> |
24 #include <netinet/in.h> | |
25 #include <arpa/inet.h> | |
11688
1fd2a974379f
[gaim-migrate @ 13974]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11539
diff
changeset
|
26 #else |
1fd2a974379f
[gaim-migrate @ 13974]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11539
diff
changeset
|
27 #include "libc_interface.h" |
1fd2a974379f
[gaim-migrate @ 13974]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11539
diff
changeset
|
28 #endif |
1fd2a974379f
[gaim-migrate @ 13974]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11539
diff
changeset
|
29 #include <sys/types.h> |
11477 | 30 #include <glib.h> |
31 #include <glib/gprintf.h> | |
32 #include <unistd.h> | |
33 #include <fcntl.h> | |
34 | |
35 #include "network.h" | |
36 #include "eventloop.h" | |
37 #include "connection.h" | |
38 #include "blist.h" | |
39 #include "xmlnode.h" | |
40 #include "debug.h" | |
41 #include "notify.h" | |
42 #include "util.h" | |
43 | |
44 #include "jabber.h" | |
45 #include "bonjour.h" | |
46 #include "buddy.h" | |
47 | |
11539 | 48 gint |
49 _connect_to_buddy(GaimBuddy *gb) | |
11477 | 50 { |
51 gint socket_fd; | |
52 gint retorno = 0; | |
53 struct sockaddr_in buddy_address; | |
11539 | 54 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
55 /* Create a socket and make it non-blocking */ |
11477 | 56 socket_fd = socket(PF_INET, SOCK_STREAM, 0); |
11539 | 57 |
11477 | 58 buddy_address.sin_family = PF_INET; |
59 buddy_address.sin_port = htons(((BonjourBuddy*)(gb->proto_data))->port_p2pj); | |
60 inet_aton(((BonjourBuddy*)(gb->proto_data))->ip, &(buddy_address.sin_addr)); | |
61 memset(&(buddy_address.sin_zero), '\0', 8); | |
11539 | 62 |
11477 | 63 retorno = connect(socket_fd, (struct sockaddr*)&buddy_address, sizeof(struct sockaddr)); |
64 if (retorno == -1) { | |
11823 | 65 gaim_debug_warning("bonjour", "connect error: %s\n", strerror(errno)); |
11477 | 66 } |
67 fcntl(socket_fd, F_SETFL, O_NONBLOCK); | |
68 | |
69 return socket_fd; | |
70 } | |
71 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
72 const char * |
11539 | 73 _font_size_gaim_to_ichat(int size) |
11477 | 74 { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
75 switch (size) { |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
76 case 1: |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
77 return "8"; |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
78 case 2: |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
79 return "10"; |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
80 case 3: |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
81 return "12"; |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
82 case 4: |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
83 return "14"; |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
84 case 5: |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
85 return "17"; |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
86 case 6: |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
87 return "21"; |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
88 case 7: |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
89 return "24"; |
11477 | 90 } |
11539 | 91 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
92 return "12"; |
11477 | 93 } |
94 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
95 const char * |
11539 | 96 _font_size_ichat_to_gaim(int size) |
11477 | 97 { |
98 if (size > 24) { | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
99 return "7"; |
11539 | 100 } else if (size >= 21) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
101 return "6"; |
11539 | 102 } else if (size >= 17) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
103 return "5"; |
11539 | 104 } else if (size >= 14) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
105 return "4"; |
11539 | 106 } else if (size >= 12) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
107 return "3"; |
11539 | 108 } else if (size >= 10) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
109 return "2"; |
11477 | 110 } |
111 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
112 return "1"; |
11477 | 113 } |
11539 | 114 void |
115 _jabber_parse_and_write_message_to_ui(char *message, GaimConnection *connection, GaimBuddy *gb) | |
11477 | 116 { |
11539 | 117 xmlnode *body_node = NULL; |
118 char *body = NULL; | |
119 xmlnode *html_node = NULL; | |
11477 | 120 gboolean isHTML = FALSE; |
11539 | 121 xmlnode *html_body_node = NULL; |
122 const char *ichat_balloon_color = NULL; | |
123 const char *ichat_text_color = NULL; | |
124 xmlnode *html_body_font_node = NULL; | |
125 const char *font_face = NULL; | |
126 const char *font_size = NULL; | |
127 const char *font_color = NULL; | |
128 char *html_body = NULL; | |
129 xmlnode *events_node = NULL; | |
11477 | 130 gboolean composing_event = FALSE; |
131 gint garbage = -1; | |
11539 | 132 xmlnode *message_node = NULL; |
11477 | 133 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
134 /* Parsing of the message */ |
11477 | 135 message_node = xmlnode_from_str(message, strlen(message)); |
136 if (message_node == NULL) { | |
137 return; | |
138 } | |
11539 | 139 |
11477 | 140 body_node = xmlnode_get_child(message_node, "body"); |
141 if (body_node != NULL) { | |
142 body = xmlnode_get_data(body_node); | |
143 } else { | |
144 return; | |
145 } | |
11539 | 146 |
11477 | 147 html_node = xmlnode_get_child(message_node, "html"); |
11539 | 148 if (html_node != NULL) |
149 { | |
11477 | 150 isHTML = TRUE; |
151 html_body_node = xmlnode_get_child(html_node, "body"); | |
11539 | 152 if (html_body_node != NULL) |
153 { | |
11477 | 154 ichat_balloon_color = xmlnode_get_attrib(html_body_node, "ichatballooncolor"); |
155 ichat_text_color = xmlnode_get_attrib(html_body_node, "ichattextcolor"); | |
156 html_body_font_node = xmlnode_get_child(html_body_node, "font"); | |
11539 | 157 if (html_body_font_node != NULL) |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
158 { /* Types of messages sent by iChat */ |
11477 | 159 font_face = xmlnode_get_attrib(html_body_font_node, "face"); |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
160 /* The absolute iChat font sizes should be converted to 1..7 range */ |
11477 | 161 font_size = xmlnode_get_attrib(html_body_font_node, "ABSZ"); |
11539 | 162 if (font_size != NULL) |
163 { | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
164 font_size = _font_size_ichat_to_gaim(atoi(font_size)); |
11477 | 165 } |
166 font_color = xmlnode_get_attrib(html_body_font_node, "color"); | |
167 html_body = xmlnode_get_data(html_body_font_node); | |
11539 | 168 if (html_body == NULL) |
169 { | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
170 /* This is the kind of formated messages that Gaim creates */ |
11477 | 171 html_body = xmlnode_to_str(html_body_font_node, &garbage); |
172 } | |
173 } else { | |
174 isHTML = FALSE; | |
175 } | |
176 } else { | |
177 isHTML = FALSE; | |
178 } | |
11539 | 179 |
11477 | 180 } |
11539 | 181 |
11477 | 182 events_node = xmlnode_get_child_with_namespace(message_node, "x", "jabber:x:event"); |
11539 | 183 if (events_node != NULL) |
184 { | |
185 if (xmlnode_get_child(events_node, "composing") != NULL) | |
186 { | |
11477 | 187 composing_event = TRUE; |
188 } | |
11539 | 189 if (xmlnode_get_child(events_node, "id") != NULL) |
190 { | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
191 /* The user is just typing */ |
11477 | 192 xmlnode_free(message_node); |
193 g_free(body); | |
194 g_free(html_body); | |
195 return; | |
196 } | |
197 } | |
11539 | 198 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
199 /* Compose the message */ |
11539 | 200 if (isHTML) |
201 { | |
11477 | 202 if (font_face == NULL) font_face = "Helvetica"; |
203 if (font_size == NULL) font_size = "3"; | |
204 if (ichat_text_color == NULL) ichat_text_color = "#000000"; | |
205 if (ichat_balloon_color == NULL) ichat_balloon_color = "#FFFFFF"; | |
11539 | 206 body = g_strconcat("<font face='", font_face, "' size='", font_size, "' color='", ichat_text_color, |
11477 | 207 "' back='", ichat_balloon_color, "'>", html_body, "</font>", NULL); |
208 } | |
11539 | 209 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
210 /* Send the message to the UI */ |
11477 | 211 serv_got_im(connection, gb->name, body, 0, time(NULL)); |
11539 | 212 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
213 /* Free all the strings and nodes (the attributes are freed with their nodes) */ |
11477 | 214 xmlnode_free(message_node); |
215 g_free(body); | |
216 g_free(html_body); | |
217 } | |
218 | |
11539 | 219 gboolean |
220 _check_buddy_by_address(gpointer key, gpointer value, gpointer address) | |
11477 | 221 { |
11539 | 222 GaimBuddy *gb = (GaimBuddy*)value; |
223 BonjourBuddy *bb = (BonjourBuddy*)gb->proto_data; | |
224 | |
225 if (bb != NULL) | |
226 { | |
11477 | 227 if (g_strcasecmp(bb->ip, (char*)address) == 0) { |
228 return TRUE; | |
229 } else { | |
230 return FALSE; | |
231 } | |
232 } else { | |
11539 | 233 return FALSE; |
11477 | 234 } |
235 } | |
236 | |
11539 | 237 gint |
238 _read_data(gint socket, char **message) | |
11477 | 239 { |
11539 | 240 GString *data = g_string_new(""); |
11477 | 241 char parcial_data[512]; |
242 gint total_message_length = 0; | |
243 gint parcial_message_length = 0; | |
244 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
245 /* Read chunks of 512 bytes till the end of the data */ |
11539 | 246 while ((parcial_message_length = recv(socket, parcial_data, 512, 0)) > 0) |
247 { | |
11477 | 248 g_string_append_len(data, parcial_data, parcial_message_length); |
249 total_message_length += parcial_message_length; | |
250 } | |
11539 | 251 |
252 if (parcial_message_length == -1) | |
253 { | |
11823 | 254 gaim_debug_warning("bonjour", "receive error: %s\n", strerror(errno)); |
11477 | 255 if (total_message_length == 0) { |
256 return -1; | |
257 } | |
258 } | |
259 | |
260 *message = data->str; | |
261 g_string_free(data, FALSE); | |
11539 | 262 if (total_message_length != 0) |
263 gaim_debug_info("bonjour", "Receive: -%s- %d bytes\n", *message, total_message_length); | |
264 | |
11477 | 265 return total_message_length; |
266 } | |
267 | |
11539 | 268 gint |
269 _send_data(gint socket, char *message) | |
11477 | 270 { |
271 gint message_len = strlen(message); | |
272 gint parcial_sent = 0; | |
11539 | 273 gchar *parcial_message = message; |
274 | |
275 while ((parcial_sent = send(socket, parcial_message, message_len, 0)) < message_len) | |
276 { | |
11477 | 277 if (parcial_sent != -1) { |
278 parcial_message += parcial_sent; | |
279 message_len -= parcial_sent; | |
280 } else { | |
281 return -1; | |
282 } | |
283 } | |
11539 | 284 |
11477 | 285 return strlen(message); |
286 } | |
287 | |
11539 | 288 void |
289 _client_socket_handler(gpointer data, gint socket, GaimInputCondition condition) | |
11477 | 290 { |
11539 | 291 char *message = NULL; |
11477 | 292 gint message_length; |
11539 | 293 GaimBuddy *gb = (GaimBuddy*)data; |
294 GaimAccount *account = gb->account; | |
295 GaimConversation *conversation; | |
296 char *closed_conv_message; | |
297 BonjourBuddy *bb = (BonjourBuddy*)gb->proto_data; | |
11477 | 298 gboolean closed_conversation = FALSE; |
299 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
300 /* Read the data from the socket */ |
11477 | 301 if ((message_length = _read_data(socket, &message)) == -1) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
302 /* There have been an error reading from the socket */ |
11477 | 303 return; |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
304 } else if (message_length == 0) { /* The other end has closed the socket */ |
11477 | 305 closed_conversation = TRUE; |
306 } else { | |
307 message[message_length] = '\0'; | |
11539 | 308 |
11477 | 309 while (g_ascii_iscntrl(message[message_length - 1])) { |
310 message[message_length - 1] = '\0'; | |
311 message_length--; | |
312 } | |
313 } | |
11539 | 314 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
315 /* Check if the start of the doctype has been received, if not check that the current */ |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
316 /* data is the doctype */ |
11539 | 317 if (!(bb->conversation->start_step_one)) |
318 { | |
319 if (g_str_has_prefix(message, DOCTYPE_DECLARATION)) | |
320 { | |
11477 | 321 bb->conversation->start_step_one = TRUE; |
322 } | |
323 } | |
11539 | 324 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
325 /* Check if the start of the stream has been received, if not check that the current */ |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
326 /* data is the start of the stream */ |
11539 | 327 if (!(bb->conversation->start_step_two)) |
328 { | |
11477 | 329 if (g_str_has_suffix(message, STREAM_START)) { |
330 bb->conversation->start_step_two = TRUE; | |
11539 | 331 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
332 /* If we haven't done it yet, we have to sent the start of the stream to the other buddy */ |
11477 | 333 if (!(bb->conversation->stream_started)) { |
334 if (send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0) == -1) { | |
335 gaim_debug_error("bonjour", "Unable to start a conversation with %s\n", bb->name); | |
336 } | |
337 } | |
338 } | |
339 return; | |
340 } | |
11539 | 341 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
342 /* Check that this is not the end of the conversation */ |
11477 | 343 if (g_str_has_prefix(message, STREAM_END) || (closed_conversation == TRUE)) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
344 /* Close the socket, clear the watcher and free memory */ |
11477 | 345 if (bb->conversation != NULL) { |
346 close(bb->conversation->socket); | |
347 gaim_input_remove(bb->conversation->watcher_id); | |
348 g_free(bb->conversation->buddy_name); | |
349 g_free(bb->conversation); | |
350 bb->conversation = NULL; | |
351 } | |
11539 | 352 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
353 /* Inform the user that the conversation has been closed */ |
11498 | 354 conversation = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, gb->name, account); |
11477 | 355 closed_conv_message = g_strconcat(gb->name, " has closed the conversation.", NULL); |
356 gaim_conversation_write(conversation, NULL, closed_conv_message, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
357 } else { | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
358 /* Parse the message to get the data and send to the ui */ |
11477 | 359 _jabber_parse_and_write_message_to_ui(message, account->gc, gb); |
360 } | |
361 } | |
362 | |
11539 | 363 void |
364 _server_socket_handler(gpointer data, int server_socket, GaimInputCondition condition) | |
11477 | 365 { |
11539 | 366 GaimBuddy *gb = NULL; |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
367 struct sockaddr_in their_addr; /* connector's address information */ |
11515 | 368 socklen_t sin_size = sizeof(struct sockaddr); |
11477 | 369 int client_socket; |
11539 | 370 BonjourBuddy *bb = NULL; |
371 char *address_text = NULL; | |
372 GaimBuddyList *bl = gaim_get_blist(); | |
11477 | 373 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
374 /* Check that it is a read condition */ |
11477 | 375 if (condition != GAIM_INPUT_READ) { |
376 return; | |
377 } | |
378 | |
11539 | 379 if ((client_socket = accept(server_socket, (struct sockaddr *)&their_addr, &sin_size)) == -1) |
380 { | |
11477 | 381 return; |
382 } | |
383 fcntl(client_socket, F_SETFL, O_NONBLOCK); | |
384 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
385 /* Look for the buddy that has open the conversation and fill information */ |
11477 | 386 address_text = inet_ntoa(their_addr.sin_addr); |
387 gb = (GaimBuddy*)g_hash_table_find(bl->buddies, _check_buddy_by_address, address_text); | |
11539 | 388 if (gb == NULL) |
389 { | |
11477 | 390 gaim_debug_info("bonjour", "We don't like invisible buddies, this is not a superheros comic\n"); |
391 close(client_socket); | |
392 return; | |
393 } | |
394 bb = (BonjourBuddy*)gb->proto_data; | |
395 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
396 /* Check if the conversation has been previously started */ |
11539 | 397 if (bb->conversation == NULL) |
398 { | |
11477 | 399 bb->conversation = g_new(BonjourJabberConversation, 1); |
400 bb->conversation->socket = client_socket; | |
401 bb->conversation->start_step_one = FALSE; | |
402 bb->conversation->start_step_two = FALSE; | |
403 bb->conversation->stream_started = FALSE; | |
404 bb->conversation->buddy_name = g_strdup(gb->name); | |
405 bb->conversation->message_id = 1; | |
11539 | 406 |
11477 | 407 if (bb->conversation->stream_started == FALSE) { |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
408 /* Start the stream */ |
11477 | 409 send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0); |
410 bb->conversation->stream_started = TRUE; | |
411 } | |
412 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
413 /* Open a watcher for the client socket */ |
11539 | 414 bb->conversation->watcher_id = gaim_input_add(client_socket, GAIM_INPUT_READ, |
11477 | 415 _client_socket_handler, gb); |
416 } else { | |
417 close(client_socket); | |
418 } | |
419 } | |
420 | |
11539 | 421 gint |
422 bonjour_jabber_start(BonjourJabber *data) | |
11477 | 423 { |
424 struct sockaddr_in my_addr; | |
425 int yes = 1; | |
11539 | 426 char *error_message = NULL; |
11477 | 427 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
428 /* Open a listening socket for incoming conversations */ |
11539 | 429 if ((data->socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) |
430 { | |
11477 | 431 gaim_debug_error("bonjour", "Cannot get socket\n"); |
432 error_message = strerror(errno); | |
433 gaim_debug_error("bonjour", "%s\n", error_message); | |
434 gaim_connection_error(data->account->gc, "Cannot open socket"); | |
435 return -1; | |
436 } | |
11539 | 437 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
438 /* Make the socket reusable */ |
11539 | 439 if (setsockopt(data->socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) != 0) |
440 { | |
11477 | 441 gaim_debug_error("bonjour", "Cannot make socket reusable\n"); |
442 error_message = strerror(errno); | |
443 gaim_debug_error("bonjour", "%s\n", error_message); | |
444 gaim_connection_error(data->account->gc, "Error setting socket options"); | |
445 return -1; | |
446 } | |
447 | |
448 memset(&my_addr, 0, sizeof(struct sockaddr_in)); | |
449 my_addr.sin_family = PF_INET; | |
450 my_addr.sin_port = htons(data->port); | |
11539 | 451 |
452 if (bind(data->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) != 0) | |
453 { | |
11477 | 454 gaim_debug_error("bonjour", "Cannot bind socket\n"); |
455 error_message = strerror(errno); | |
456 gaim_debug_error("bonjour", "%s\n", error_message); | |
457 gaim_connection_error(data->account->gc, "Cannot bind socket to port"); | |
458 return -1; | |
459 } | |
11539 | 460 |
461 if (listen(data->socket, 10) != 0) | |
462 { | |
11477 | 463 gaim_debug_error("bonjour", "Cannot listen to socket\n"); |
464 error_message = strerror(errno); | |
465 gaim_debug_error("bonjour", "%s\n", error_message); | |
466 gaim_connection_error(data->account->gc, "Cannot listen to socket"); | |
467 return -1; | |
468 } | |
469 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
470 #if 0 |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
471 data->socket = gaim_network_listen(data->port); |
11477 | 472 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
473 if (data->socket == -1) |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
474 { |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
475 gaim_debug_error("bonjour", "No se ha podido crear el socket\n"); |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
476 } |
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
477 #endif |
11477 | 478 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
479 /* Open a watcher in the socket we have just opened */ |
11477 | 480 data->watcher_id = gaim_input_add(data->socket, GAIM_INPUT_READ, _server_socket_handler, data); |
11539 | 481 |
11477 | 482 return 0; |
483 } | |
484 | |
11693 | 485 int |
11539 | 486 bonjour_jabber_send_message(BonjourJabber *data, const gchar *to, const gchar *body) |
11477 | 487 { |
11539 | 488 xmlnode *message_node = NULL; |
489 gchar *message = NULL; | |
11477 | 490 gint message_length = -1; |
11539 | 491 xmlnode *message_body_node = NULL; |
492 xmlnode *message_html_node = NULL; | |
493 xmlnode *message_html_body_node = NULL; | |
494 xmlnode *message_html_body_font_node = NULL; | |
495 xmlnode *message_x_node = NULL; | |
11693 | 496 GaimBuddy *gb = NULL; |
497 BonjourBuddy *bb = NULL; | |
11539 | 498 char *conv_message = NULL; |
499 GaimConversation *conversation = NULL; | |
500 char *message_from_ui = NULL; | |
501 char *stripped_message = NULL; | |
502 | |
11693 | 503 gb = gaim_find_buddy(data->account, to); |
504 if (gb == NULL) | |
505 /* You can not send a message to an offline buddy */ | |
506 return -10000; | |
507 | |
508 bb = (BonjourBuddy *)gb->proto_data; | |
509 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
510 /* Enclose the message from the UI within a "font" node */ |
11477 | 511 message_body_node = xmlnode_new("body"); |
512 stripped_message = gaim_markup_strip_html(body); | |
513 xmlnode_insert_data(message_body_node, stripped_message, strlen(stripped_message)); | |
11539 | 514 |
11477 | 515 message_from_ui = g_strconcat("<font>", body, "</font>", NULL); |
516 message_html_body_font_node = xmlnode_from_str(message_from_ui, strlen(message_from_ui)); | |
11539 | 517 |
11477 | 518 message_html_body_node = xmlnode_new("body"); |
519 xmlnode_insert_child(message_html_body_node, message_html_body_font_node); | |
11539 | 520 |
11477 | 521 message_html_node = xmlnode_new("html"); |
522 xmlnode_set_attrib(message_html_node, "xmlns", "http://www.w3.org/1999/xhtml"); | |
523 xmlnode_insert_child(message_html_node, message_html_body_node); | |
524 | |
525 message_x_node = xmlnode_new("x"); | |
526 xmlnode_set_attrib(message_x_node, "xmlns", "jabber:x:event"); | |
527 xmlnode_insert_child(message_x_node, xmlnode_new("composing")); | |
11539 | 528 |
11477 | 529 message_node = xmlnode_new("message"); |
530 xmlnode_set_attrib(message_node, "to", ((BonjourBuddy*)(gb->proto_data))->name); | |
531 xmlnode_set_attrib(message_node, "type", "chat"); | |
532 xmlnode_insert_child(message_node, message_body_node); | |
533 xmlnode_insert_child(message_node, message_html_node); | |
534 xmlnode_insert_child(message_node, message_x_node); | |
11539 | 535 |
11477 | 536 message = xmlnode_to_str(message_node, &message_length); |
537 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
538 /* Check if there is a previously open conversation */ |
11539 | 539 if (bb->conversation == NULL) |
540 { | |
11477 | 541 bb->conversation = g_new(BonjourJabberConversation, 1); |
542 bb->conversation->socket = _connect_to_buddy(gb);; | |
543 bb->conversation->start_step_one = FALSE; | |
544 bb->conversation->start_step_two = FALSE; | |
545 bb->conversation->stream_started = FALSE; | |
546 bb->conversation->buddy_name = g_strdup(gb->name); | |
11539 | 547 bb->conversation->watcher_id = gaim_input_add(bb->conversation->socket, |
11477 | 548 GAIM_INPUT_READ, _client_socket_handler, gb); |
549 } | |
550 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
551 /* Check if the stream for the conversation has been started */ |
11539 | 552 if (bb->conversation->stream_started == FALSE) |
553 { | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
554 /* Start the stream */ |
11539 | 555 if (send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0) == -1) |
556 { | |
11477 | 557 gaim_debug_error("bonjour", "Unable to start a conversation\n"); |
11823 | 558 gaim_debug_warning("bonjour", "send error: %s\n", strerror(errno)); |
11477 | 559 conv_message = g_strdup("Unable to send the message, the conversation couldn't be started."); |
11498 | 560 conversation = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, bb->name, data->account); |
11477 | 561 gaim_conversation_write(conversation, NULL, conv_message, GAIM_MESSAGE_SYSTEM, time(NULL)); |
562 close(bb->conversation->socket); | |
563 gaim_input_remove(bb->conversation->watcher_id); | |
11539 | 564 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
565 /* Free all the data related to the conversation */ |
11477 | 566 g_free(bb->conversation->buddy_name); |
567 g_free(bb->conversation); | |
568 bb->conversation = NULL; | |
11693 | 569 return 0; |
11477 | 570 } |
11539 | 571 |
11477 | 572 bb->conversation->stream_started = TRUE; |
573 } | |
11539 | 574 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
575 /* Send the message */ |
11539 | 576 if (_send_data(bb->conversation->socket, message) == -1) |
11693 | 577 return -10000; |
578 | |
579 return 1; | |
11477 | 580 } |
581 | |
11539 | 582 void |
583 bonjour_jabber_close_conversation(BonjourJabber *data, GaimBuddy *gb) | |
11477 | 584 { |
11539 | 585 BonjourBuddy *bb = (BonjourBuddy*)gb->proto_data; |
586 | |
587 if (bb->conversation != NULL) | |
588 { | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
589 /* Send the end of the stream to the other end of the conversation */ |
11477 | 590 send(bb->conversation->socket, STREAM_END, strlen(STREAM_END), 0); |
11539 | 591 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
592 /* Close the socket and remove the watcher */ |
11477 | 593 close(bb->conversation->socket); |
594 gaim_input_remove(bb->conversation->watcher_id); | |
11539 | 595 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
596 /* Free all the data related to the conversation */ |
11477 | 597 g_free(bb->conversation->buddy_name); |
598 g_free(bb->conversation); | |
599 bb->conversation = NULL; | |
600 } | |
601 } | |
602 | |
11539 | 603 void |
604 bonjour_jabber_stop(BonjourJabber *data) | |
11477 | 605 { |
11539 | 606 GaimBuddy *gb = NULL; |
607 BonjourBuddy *bb = NULL; | |
608 GSList *buddies; | |
609 GSList *l; | |
610 | |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
611 /* Close the server socket and remove all the watcher */ |
11477 | 612 close(data->socket); |
613 gaim_input_remove(data->watcher_id); | |
11539 | 614 |
11826
e05778d4f12d
[gaim-migrate @ 14117]
Richard Laager <rlaager@wiktel.com>
parents:
11823
diff
changeset
|
615 /* Close all the sockets and remove all the watchers after sending end streams */ |
11539 | 616 if (data->account->gc != NULL) |
617 { | |
11477 | 618 buddies = gaim_find_buddies(data->account, data->account->username); |
11539 | 619 for (l = buddies; l; l = l->next) |
620 { | |
11477 | 621 gb = (GaimBuddy*)l->data; |
622 bb = (BonjourBuddy*)gb->proto_data; | |
11539 | 623 if (bb->conversation != NULL) |
624 { | |
11477 | 625 send(bb->conversation->socket, STREAM_END, strlen(STREAM_END), 0); |
626 close(bb->conversation->socket); | |
627 gaim_input_remove(bb->conversation->watcher_id); | |
628 } | |
629 } | |
630 g_slist_free(buddies); | |
631 } | |
632 } |