Mercurial > pidgin.yaz
annotate src/protocols/msn/directconn.c @ 11620:fbc4eeab2227
[gaim-migrate @ 13894]
this lets you leave a highlighted tab by control-tab (forward) or
control-shift-tab (backwards). its not 100% intuitive though, because it
leaves the tab highlighed, which means that in the case of 1 highlighted
tab, the current one, you will leave the tab on the first control-tab,
then immediately return to it on the second one. For this reason, removing
the highlighting of current tabs would be a better permanent solution.
In talking with Tim however, he suggested we do both, on the off chance we
change our minds about the tab highlighting and go back to the
autoswitching.
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Thu, 06 Oct 2005 15:01:08 +0000 |
parents | 1e6bdc7175e9 |
children | fc464a0abccc |
rev | line source |
---|---|
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
1 /** |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
2 * @file directconn.c MSN direct connection functions |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
3 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
4 * gaim |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
5 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
6 * Gaim is the legal property of its developers, whose names are too numerous |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
7 * to list here. Please refer to the COPYRIGHT file distributed with this |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
8 * source distribution. |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
9 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
10 * This program is free software; you can redistribute it and/or modify |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
11 * it under the terms of the GNU General Public License as published by |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
12 * the Free Software Foundation; either version 2 of the License, or |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
13 * (at your option) any later version. |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
14 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
15 * This program is distributed in the hope that it will be useful, |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
18 * GNU General Public License for more details. |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
19 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
20 * You should have received a copy of the GNU General Public License |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
21 * along with this program; if not, write to the Free Software |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
23 */ |
9193 | 24 #include "msn.h" |
25 #include "directconn.h" | |
26 | |
27 #include "slp.h" | |
28 #include "slpmsg.h" | |
29 | |
30 /************************************************************************** | |
31 * Directconn Specific | |
32 **************************************************************************/ | |
33 | |
34 void | |
35 msn_directconn_send_handshake(MsnDirectConn *directconn) | |
36 { | |
37 MsnSlpLink *slplink; | |
38 MsnSlpMessage *slpmsg; | |
39 | |
40 g_return_if_fail(directconn != NULL); | |
41 | |
42 slplink = directconn->slplink; | |
43 | |
44 slpmsg = msn_slpmsg_new(slplink); | |
45 slpmsg->flags = 0x100; | |
46 | |
47 if (directconn->nonce != NULL) | |
48 { | |
49 guint32 t1; | |
50 guint16 t2; | |
51 guint16 t3; | |
52 guint16 t4; | |
53 guint64 t5; | |
54 | |
10112 | 55 sscanf (directconn->nonce, "%08X-%04hX-%04hX-%04hX-%012" G_GINT64_MODIFIER "X", &t1, &t2, &t3, &t4, &t5); |
9193 | 56 |
57 t1 = GUINT32_TO_LE(t1); | |
58 t2 = GUINT16_TO_LE(t2); | |
59 t3 = GUINT16_TO_LE(t3); | |
60 t4 = GUINT16_TO_BE(t4); | |
61 t5 = GUINT64_TO_BE(t5); | |
62 | |
63 slpmsg->ack_id = t1; | |
64 slpmsg->ack_sub_id = t2 | (t3 << 16); | |
65 slpmsg->ack_size = t4 | t5; | |
66 } | |
67 | |
68 g_free(directconn->nonce); | |
69 | |
70 msn_slplink_send_slpmsg(slplink, slpmsg); | |
71 | |
72 directconn->acked =TRUE; | |
73 } | |
74 | |
75 /************************************************************************** | |
76 * Connection Functions | |
77 **************************************************************************/ | |
78 | |
79 static int | |
80 create_listener(int port) | |
81 { | |
82 int fd; | |
83 const int on = 1; | |
84 | |
85 #if 0 | |
86 struct addrinfo hints; | |
87 struct addrinfo *c, *res; | |
88 char port_str[5]; | |
89 | |
90 snprintf(port_str, sizeof(port_str), "%d", port); | |
91 | |
92 memset(&hints, 0, sizeof(hints)); | |
93 | |
94 hints.ai_flags = AI_PASSIVE; | |
95 hints.ai_family = AF_UNSPEC; | |
96 hints.ai_socktype = SOCK_STREAM; | |
97 | |
98 if (getaddrinfo(NULL, port_str, &hints, &res) != 0) | |
99 { | |
100 gaim_debug_error("msn", "Could not get address info: %s.\n", | |
101 port_str); | |
102 return -1; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
103 } |
9193 | 104 |
105 for (c = res; c != NULL; c = c->ai_next) | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
106 { |
9193 | 107 fd = socket(c->ai_family, c->ai_socktype, c->ai_protocol); |
108 | |
109 if (fd < 0) | |
110 continue; | |
111 | |
112 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); | |
113 | |
114 if (bind(fd, c->ai_addr, c->ai_addrlen) == 0) | |
115 break; | |
116 | |
117 close(fd); | |
118 } | |
119 | |
120 if (c == NULL) | |
121 { | |
122 gaim_debug_error("msn", "Could not find socket: %s.\n", port_str); | |
123 return -1; | |
124 } | |
125 | |
126 freeaddrinfo(res); | |
127 #else | |
128 struct sockaddr_in sockin; | |
129 | |
130 fd = socket(AF_INET, SOCK_STREAM, 0); | |
131 | |
132 if (fd < 0) | |
133 return -1; | |
134 | |
135 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) | |
136 { | |
137 close(fd); | |
138 return -1; | |
139 } | |
140 | |
141 memset(&sockin, 0, sizeof(struct sockaddr_in)); | |
142 sockin.sin_family = AF_INET; | |
143 sockin.sin_port = htons(port); | |
144 | |
145 if (bind(fd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) | |
146 { | |
147 close(fd); | |
148 return -1; | |
149 } | |
150 #endif | |
151 | |
152 if (listen (fd, 4) != 0) | |
153 { | |
154 close (fd); | |
155 return -1; | |
156 } | |
157 | |
158 fcntl(fd, F_SETFL, O_NONBLOCK); | |
159 | |
160 return fd; | |
161 } | |
162 | |
163 size_t | |
164 msn_directconn_write(MsnDirectConn *directconn, | |
165 const char *data, size_t len) | |
166 { | |
167 char *buffer, *tmp; | |
168 size_t buf_size; | |
169 size_t ret; | |
170 guint32 sent_len; | |
171 | |
172 g_return_val_if_fail(directconn != NULL, 0); | |
173 | |
174 buf_size = len + 4; | |
175 buffer = tmp = g_malloc(buf_size); | |
176 | |
177 sent_len = GUINT32_TO_LE(len); | |
178 | |
179 memcpy(tmp, &sent_len, 4); | |
180 tmp += 4; | |
181 memcpy(tmp, data, len); | |
182 tmp += len; | |
183 | |
184 ret = write(directconn->fd, buffer, buf_size); | |
185 | |
186 #ifdef DEBUG_DC | |
187 char *str; | |
188 str = g_strdup_printf("%s/msntest/w%.4d.bin", g_get_home_dir(), directconn->c); | |
189 | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10388
diff
changeset
|
190 FILE *tf = g_fopen(str, "w"); |
9193 | 191 fwrite(buffer, 1, buf_size, tf); |
192 fclose(tf); | |
193 | |
194 g_free(str); | |
195 #endif | |
196 | |
197 g_free(buffer); | |
198 | |
199 #if 0 | |
200 /* Let's write the length of the data. */ | |
201 ret = write(directconn->fd, &len, sizeof(len)); | |
202 | |
203 /* Let's write the data. */ | |
204 ret = write(directconn->fd, data, len); | |
205 | |
206 char *str; | |
207 str = g_strdup_printf("/home/revo/msntest/w%.4d.bin", directconn->c); | |
208 | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10388
diff
changeset
|
209 FILE *tf = g_fopen(str, "w"); |
9193 | 210 fwrite(&len, 1, sizeof(len), tf); |
211 fwrite(data, 1, len, tf); | |
212 fclose(tf); | |
213 | |
214 g_free(str); | |
215 #endif | |
216 | |
217 directconn->c++; | |
218 | |
219 return ret; | |
220 } | |
221 | |
222 #if 0 | |
223 void | |
224 msn_directconn_parse_nonce(MsnDirectConn *directconn, const char *nonce) | |
225 { | |
226 guint32 t1; | |
227 guint16 t2; | |
228 guint16 t3; | |
229 guint16 t4; | |
230 guint64 t5; | |
231 | |
232 g_return_if_fail(directconn != NULL); | |
233 g_return_if_fail(nonce != NULL); | |
234 | |
235 sscanf (nonce, "%08X-%04hX-%04hX-%04hX-%012llX", &t1, &t2, &t3, &t4, &t5); | |
236 | |
237 t1 = GUINT32_TO_LE(t1); | |
238 t2 = GUINT16_TO_LE(t2); | |
239 t3 = GUINT16_TO_LE(t3); | |
240 t4 = GUINT16_TO_BE(t4); | |
241 t5 = GUINT64_TO_BE(t5); | |
242 | |
243 directconn->slpheader = g_new0(MsnSlpHeader, 1); | |
244 | |
245 directconn->slpheader->ack_id = t1; | |
246 directconn->slpheader->ack_sub_id = t2 | (t3 << 16); | |
247 directconn->slpheader->ack_size = t4 | t5; | |
248 } | |
249 #endif | |
250 | |
251 void | |
252 msn_directconn_send_msg(MsnDirectConn *directconn, MsnMessage *msg) | |
253 { | |
254 char *body; | |
255 size_t body_len; | |
256 | |
257 body = msn_message_gen_slp_body(msg, &body_len); | |
258 | |
259 msn_directconn_write(directconn, body, body_len); | |
260 } | |
261 | |
262 void | |
263 msn_directconn_process_msg(MsnDirectConn *directconn, MsnMessage *msg) | |
264 { | |
265 gaim_debug_info("msn", "directconn: process_msg\n"); | |
266 | |
267 msn_slplink_process_msg(directconn->slplink, msg); | |
268 } | |
269 | |
270 static void | |
271 read_cb(gpointer data, gint source, GaimInputCondition cond) | |
272 { | |
273 MsnDirectConn* directconn; | |
274 char *body; | |
275 size_t len, body_len; | |
276 | |
277 gaim_debug_info("msn", "read_cb: %d, %d\n", source, cond); | |
278 | |
279 directconn = data; | |
280 | |
281 /* Let's read the length of the data. */ | |
282 len = read(directconn->fd, &body_len, sizeof(body_len)); | |
283 | |
284 if (len <= 0) | |
285 { | |
286 /* ERROR */ | |
287 gaim_debug_error("msn", "error reading\n"); | |
288 | |
289 if (directconn->inpa) | |
290 gaim_input_remove(directconn->inpa); | |
291 | |
292 close(directconn->fd); | |
293 | |
294 msn_directconn_destroy(directconn); | |
295 | |
296 return; | |
297 } | |
298 | |
299 body_len = GUINT32_FROM_LE(body_len); | |
300 | |
301 gaim_debug_info("msn", "body_len=%d\n", body_len); | |
302 | |
303 if (body_len <= 0) | |
304 { | |
305 /* ERROR */ | |
306 gaim_debug_error("msn", "error reading\n"); | |
307 | |
308 if (directconn->inpa) | |
309 gaim_input_remove(directconn->inpa); | |
310 | |
311 close(directconn->fd); | |
312 | |
313 msn_directconn_destroy(directconn); | |
314 | |
315 return; | |
316 } | |
317 | |
10899 | 318 body = g_try_malloc(body_len); |
319 | |
320 if (body != NULL) | |
321 { | |
322 /* Let's read the data. */ | |
323 len = read(directconn->fd, body, body_len); | |
9193 | 324 |
10899 | 325 gaim_debug_info("msn", "len=%d\n", len); |
326 } | |
327 else | |
328 { | |
329 gaim_debug_error("msn", "Failed to allocate memory for read\n"); | |
330 len = 0; | |
331 } | |
9193 | 332 |
333 if (len > 0) | |
334 { | |
335 MsnMessage *msg; | |
336 | |
337 #ifdef DEBUG_DC | |
338 str = g_strdup_printf("/home/revo/msntest/r%.4d.bin", directconn->c); | |
339 | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10388
diff
changeset
|
340 FILE *tf = g_fopen(str, "w"); |
9193 | 341 fwrite(body, 1, len, tf); |
342 fclose(tf); | |
343 | |
344 g_free(str); | |
345 #endif | |
346 | |
347 directconn->c++; | |
348 | |
349 msg = msn_message_new_msnslp(); | |
350 msn_message_parse_slp_body(msg, body, body_len); | |
351 | |
352 msn_directconn_process_msg(directconn, msg); | |
353 } | |
354 else | |
355 { | |
356 /* ERROR */ | |
357 gaim_debug_error("msn", "error reading\n"); | |
358 | |
359 if (directconn->inpa) | |
360 gaim_input_remove(directconn->inpa); | |
361 | |
362 close(directconn->fd); | |
363 | |
364 msn_directconn_destroy(directconn); | |
365 } | |
366 } | |
367 | |
368 static void | |
369 connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
370 { | |
371 MsnDirectConn* directconn; | |
372 int fd; | |
373 | |
374 gaim_debug_misc("msn", "directconn: connect_cb: %d, %d.\n", source, cond); | |
375 | |
376 directconn = data; | |
377 | |
378 if (TRUE) | |
379 { | |
380 fd = source; | |
381 } | |
382 else | |
383 { | |
384 struct sockaddr_in client_addr; | |
10388 | 385 unsigned int client; |
9193 | 386 fd = accept (source, (struct sockaddr *)&client_addr, &client); |
387 } | |
388 | |
389 directconn->fd = fd; | |
390 | |
391 if (fd > 0) | |
392 { | |
393 directconn->inpa = gaim_input_add(fd, GAIM_INPUT_READ, read_cb, | |
394 directconn); | |
395 | |
396 if (TRUE) | |
397 { | |
398 /* Send foo. */ | |
399 msn_directconn_write(directconn, "foo", strlen("foo") + 1); | |
400 | |
401 /* Send Handshake */ | |
402 msn_directconn_send_handshake(directconn); | |
403 } | |
404 else | |
405 { | |
406 } | |
407 } | |
408 else | |
409 { | |
410 /* ERROR */ | |
411 gaim_debug_error("msn", "could not add input\n"); | |
412 | |
413 if (directconn->inpa) | |
414 gaim_input_remove(directconn->inpa); | |
415 | |
416 close(directconn->fd); | |
417 } | |
418 } | |
419 | |
420 gboolean | |
421 msn_directconn_connect(MsnDirectConn *directconn, const char *host, int port) | |
422 { | |
423 MsnSession *session; | |
424 int r; | |
425 | |
426 g_return_val_if_fail(directconn != NULL, FALSE); | |
427 g_return_val_if_fail(host != NULL, TRUE); | |
428 g_return_val_if_fail(port > 0, FALSE); | |
429 | |
430 session = directconn->slplink->session; | |
431 | |
432 #if 0 | |
433 if (session->http_method) | |
434 { | |
435 servconn->http_data->gateway_host = g_strdup(host); | |
436 } | |
437 #endif | |
438 | |
439 r = gaim_proxy_connect(session->account, host, port, connect_cb, | |
440 directconn); | |
441 | |
442 if (r == 0) | |
443 { | |
444 return TRUE; | |
445 } | |
446 else | |
447 return FALSE; | |
448 } | |
449 | |
450 void | |
451 msn_directconn_listen(MsnDirectConn *directconn) | |
452 { | |
453 int port; | |
454 int fd; | |
455 | |
456 port = 7000; | |
457 | |
458 for (fd = -1; fd < 0;) | |
459 fd = create_listener(++port); | |
460 | |
461 directconn->fd = fd; | |
462 | |
463 directconn->inpa = gaim_input_add(fd, GAIM_INPUT_READ, | |
464 connect_cb, directconn); | |
465 | |
466 directconn->port = port; | |
467 directconn->c = 0; | |
468 } | |
469 | |
470 MsnDirectConn* | |
471 msn_directconn_new(MsnSlpLink *slplink) | |
472 { | |
473 MsnDirectConn *directconn; | |
474 | |
475 directconn = g_new0(MsnDirectConn, 1); | |
476 | |
477 directconn->slplink = slplink; | |
478 | |
479 if (slplink->directconn != NULL) | |
480 gaim_debug_info("msn", "got_transresp: LEAK\n"); | |
481 | |
482 slplink->directconn = directconn; | |
483 | |
484 return directconn; | |
485 } | |
486 | |
487 void | |
488 msn_directconn_destroy(MsnDirectConn *directconn) | |
489 { | |
490 if (directconn->nonce != NULL) | |
491 g_free(directconn->nonce); | |
492 | |
493 directconn->slplink->directconn = NULL; | |
494 | |
495 g_free(directconn); | |
496 } |