Mercurial > pidgin
comparison src/protocols/msn/servconn.c @ 9193:502707ca1836
[gaim-migrate @ 9988]
Patch by Felipe Contreras to add MSN file transfer and buddy icons. Please
test and report any bugs!
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Sun, 06 Jun 2004 02:39:08 +0000 |
parents | 43ea2b858112 |
children | ab6636c5a136 |
comparison
equal
deleted
inserted
replaced
9192:5655dcd94d0f | 9193:502707ca1836 |
---|---|
32 char *tmp; | 32 char *tmp; |
33 char *cmd; | 33 char *cmd; |
34 | 34 |
35 const char *names[] = { "Notification", "Switchboard" }; | 35 const char *names[] = { "Notification", "Switchboard" }; |
36 const char *name; | 36 const char *name; |
37 | 37 |
38 gc = gaim_account_get_connection(servconn->session->account); | 38 gc = gaim_account_get_connection(servconn->session->account); |
39 name = names[servconn->type]; | 39 name = names[servconn->type]; |
40 | 40 |
41 switch (servconn->cmdproc->error) | 41 switch (servconn->cmdproc->error) |
42 { | 42 { |
56 tmp = g_strdup_printf(_("Unknown error from %s server"), name); | 56 tmp = g_strdup_printf(_("Unknown error from %s server"), name); |
57 break; | 57 break; |
58 } | 58 } |
59 | 59 |
60 if (servconn->type != MSN_SERVER_SB) | 60 if (servconn->type != MSN_SERVER_SB) |
61 { | |
61 gaim_connection_error(gc, tmp); | 62 gaim_connection_error(gc, tmp); |
63 } | |
62 else | 64 else |
63 { | 65 { |
64 GaimAccount *account = gaim_connection_get_account(gc); | 66 GaimAccount *account; |
65 char *primary = g_strdup_printf(_("MSN error for account %s"), | 67 char *primary; |
66 gaim_account_get_username(account)); | 68 |
69 account = gaim_connection_get_account(gc); | |
70 primary = g_strdup_printf(_("MSN error for account %s"), | |
71 gaim_account_get_username(account)); | |
67 | 72 |
68 gaim_notify_error(gc, NULL, primary, tmp); | 73 gaim_notify_error(gc, NULL, primary, tmp); |
69 | 74 |
70 g_free(primary); | 75 g_free(primary); |
71 } | 76 } |
114 servconn->http_data = g_new0(MsnHttpMethodData, 1); | 119 servconn->http_data = g_new0(MsnHttpMethodData, 1); |
115 servconn->http_data->virgin = TRUE; | 120 servconn->http_data->virgin = TRUE; |
116 } | 121 } |
117 | 122 |
118 servconn->num = session->servconns_count++; | 123 servconn->num = session->servconns_count++; |
119 session->servconns = g_list_append(session->servconns, servconn); | |
120 | 124 |
121 return servconn; | 125 return servconn; |
122 } | 126 } |
123 | 127 |
124 void | 128 void |
125 msn_servconn_destroy(MsnServConn *servconn) | 129 msn_servconn_destroy(MsnServConn *servconn) |
126 { | 130 { |
127 MsnSession *session; | |
128 | |
129 g_return_if_fail(servconn != NULL); | 131 g_return_if_fail(servconn != NULL); |
130 | 132 |
131 if (servconn->processing) | 133 if (servconn->processing) |
132 { | 134 { |
133 servconn->wasted = TRUE; | 135 servconn->wasted = TRUE; |
134 return; | 136 return; |
135 } | 137 } |
136 | 138 |
137 session = servconn->session; | |
138 | |
139 session->servconns = g_list_remove(session->servconns, servconn); | |
140 | |
141 if (servconn->connected) | 139 if (servconn->connected) |
142 msn_servconn_disconnect(servconn); | 140 msn_servconn_disconnect(servconn); |
143 | 141 |
142 if (servconn->http_data != NULL) | |
143 g_free(servconn->http_data); | |
144 | |
145 #if 0 | |
146 if (servconn->rx_buf != NULL) | |
147 g_free(servconn->rx_buf); | |
148 #endif | |
149 | |
144 msn_cmdproc_destroy(servconn->cmdproc); | 150 msn_cmdproc_destroy(servconn->cmdproc); |
145 | |
146 g_free(servconn); | 151 g_free(servconn); |
147 } | 152 } |
148 | 153 |
149 gboolean | 154 gboolean |
150 msn_servconn_connect(MsnServConn *servconn, const char *host, int port) | 155 msn_servconn_connect(MsnServConn *servconn, const char *host, int port) |
161 if (servconn->connected) | 166 if (servconn->connected) |
162 msn_servconn_disconnect(servconn); | 167 msn_servconn_disconnect(servconn); |
163 | 168 |
164 if (session->http_method) | 169 if (session->http_method) |
165 { | 170 { |
171 if (servconn->http_data->gateway_host != NULL) | |
172 g_free(servconn->http_data->gateway_host); | |
173 | |
166 servconn->http_data->gateway_host = g_strdup(host); | 174 servconn->http_data->gateway_host = g_strdup(host); |
167 } | 175 } |
168 | 176 |
169 r = gaim_proxy_connect(session->account, host, port, connect_cb, | 177 r = gaim_proxy_connect(session->account, host, port, connect_cb, |
170 servconn); | 178 servconn); |
171 | 179 |
172 if (r == 0) | 180 if (r == 0) |
181 { | |
173 servconn->connected = TRUE; | 182 servconn->connected = TRUE; |
174 | 183 servconn->cmdproc->ready = TRUE; |
175 return servconn->connected; | 184 return TRUE; |
185 } | |
186 else | |
187 return FALSE; | |
176 } | 188 } |
177 | 189 |
178 void | 190 void |
179 msn_servconn_disconnect(MsnServConn *servconn) | 191 msn_servconn_disconnect(MsnServConn *servconn) |
180 { | 192 { |
181 MsnSession *session; | |
182 | |
183 g_return_if_fail(servconn != NULL); | 193 g_return_if_fail(servconn != NULL); |
184 g_return_if_fail(servconn->connected); | 194 g_return_if_fail(servconn->connected); |
185 | 195 |
186 session = servconn->session; | |
187 | |
188 if (servconn->inpa > 0) | 196 if (servconn->inpa > 0) |
189 { | 197 { |
190 gaim_input_remove(servconn->inpa); | 198 gaim_input_remove(servconn->inpa); |
191 servconn->inpa = 0; | 199 servconn->inpa = 0; |
192 } | 200 } |
204 if (servconn->http_data->gateway_host != NULL) | 212 if (servconn->http_data->gateway_host != NULL) |
205 g_free(servconn->http_data->gateway_host); | 213 g_free(servconn->http_data->gateway_host); |
206 | 214 |
207 if (servconn->http_data->timer) | 215 if (servconn->http_data->timer) |
208 gaim_timeout_remove(servconn->http_data->timer); | 216 gaim_timeout_remove(servconn->http_data->timer); |
209 | |
210 g_free(servconn->http_data); | |
211 servconn->http_data = NULL; | |
212 } | 217 } |
213 | 218 |
214 servconn->rx_len = 0; | 219 servconn->rx_len = 0; |
215 servconn->payload_len = 0; | 220 servconn->payload_len = 0; |
216 | 221 |
222 servconn->connected = FALSE; | |
223 servconn->cmdproc->ready = FALSE; | |
224 | |
217 if (servconn->disconnect_cb != NULL) | 225 if (servconn->disconnect_cb != NULL) |
218 servconn->disconnect_cb(servconn); | 226 servconn->disconnect_cb(servconn); |
219 | |
220 servconn->connected = FALSE; | |
221 } | 227 } |
222 | 228 |
223 void | 229 void |
224 msn_servconn_set_connect_cb(MsnServConn *servconn, | 230 msn_servconn_set_connect_cb(MsnServConn *servconn, void (*connect_cb)(MsnServConn *)) |
225 gboolean (*connect_cb)(MsnServConn *servconn)) | |
226 { | 231 { |
227 g_return_if_fail(servconn != NULL); | 232 g_return_if_fail(servconn != NULL); |
228 | |
229 servconn->connect_cb = connect_cb; | 233 servconn->connect_cb = connect_cb; |
230 } | 234 } |
231 | 235 |
232 void | 236 void |
233 msn_servconn_set_disconnect_cb(MsnServConn *servconn, | 237 msn_servconn_set_disconnect_cb(MsnServConn *servconn, void (*disconnect_cb)(MsnServConn *)) |
234 void (*disconnect_cb)(MsnServConn | |
235 *servconn)) | |
236 { | 238 { |
237 g_return_if_fail(servconn != NULL); | 239 g_return_if_fail(servconn != NULL); |
238 | 240 |
239 servconn->disconnect_cb = disconnect_cb; | 241 servconn->disconnect_cb = disconnect_cb; |
240 } | 242 } |
254 { | 256 { |
255 size_t ret = FALSE; | 257 size_t ret = FALSE; |
256 | 258 |
257 g_return_val_if_fail(servconn != NULL, 0); | 259 g_return_val_if_fail(servconn != NULL, 0); |
258 | 260 |
259 if (servconn->session->http_method) | 261 if (servconn->http_data == NULL) |
262 { | |
263 switch (servconn->type) | |
264 { | |
265 case MSN_SERVER_NS: | |
266 case MSN_SERVER_SB: | |
267 ret = write(servconn->fd, buf, len); | |
268 break; | |
269 case MSN_SERVER_DC: | |
270 ret = write(servconn->fd, &buf, sizeof(len)); | |
271 ret = write(servconn->fd, buf, len); | |
272 break; | |
273 default: | |
274 ret = write(servconn->fd, buf, len); | |
275 break; | |
276 } | |
277 } | |
278 else | |
260 { | 279 { |
261 ret = msn_http_servconn_write(servconn, buf, len, | 280 ret = msn_http_servconn_write(servconn, buf, len, |
262 servconn->http_data->server_type); | 281 servconn->http_data->server_type); |
263 } | 282 } |
264 else | 283 |
265 { | 284 if (ret == -1) |
266 ret = write(servconn->fd, buf, len); | |
267 } | |
268 | |
269 if (ret < 0) | |
270 { | 285 { |
271 servconn->cmdproc->error = MSN_ERROR_WRITE; | 286 servconn->cmdproc->error = MSN_ERROR_WRITE; |
272 failed_io(servconn); | 287 failed_io(servconn); |
273 } | 288 } |
274 | 289 |
286 | 301 |
287 servconn = data; | 302 servconn = data; |
288 session = servconn->session; | 303 session = servconn->session; |
289 | 304 |
290 len = read(servconn->fd, buf, sizeof(buf) - 1); | 305 len = read(servconn->fd, buf, sizeof(buf) - 1); |
306 | |
307 if (len <= 0) | |
308 { | |
309 servconn->cmdproc->error = MSN_ERROR_READ; | |
310 | |
311 failed_io(servconn); | |
312 | |
313 return; | |
314 } | |
315 | |
291 buf[len] = '\0'; | 316 buf[len] = '\0'; |
292 | 317 |
293 if (len <= 0) | 318 servconn->rx_buf = g_realloc(servconn->rx_buf, len + servconn->rx_len + 1); |
294 { | 319 memcpy(servconn->rx_buf + servconn->rx_len, buf, len + 1); |
295 servconn->cmdproc->error = MSN_ERROR_READ; | |
296 | |
297 failed_io(servconn); | |
298 | |
299 return; | |
300 } | |
301 | |
302 servconn->rx_buf = g_realloc(servconn->rx_buf, len + servconn->rx_len); | |
303 memcpy(servconn->rx_buf + servconn->rx_len, buf, len); | |
304 servconn->rx_len += len; | 320 servconn->rx_len += len; |
305 | 321 |
306 if (session->http_method) | 322 if (session->http_method) |
307 { | 323 { |
308 char *result_msg = NULL; | 324 char *result_msg = NULL; |
385 } | 401 } |
386 else | 402 else |
387 { | 403 { |
388 end = strstr(cur, "\r\n"); | 404 end = strstr(cur, "\r\n"); |
389 | 405 |
390 if (!end) | 406 if (end == NULL) |
391 /* The command is still not complete. */ | 407 /* The command is still not complete. */ |
392 break; | 408 break; |
393 | 409 |
394 *end = '\0'; | 410 *end = '\0'; |
395 cur_len = end - cur + 2; | |
396 end += 2; | 411 end += 2; |
412 cur_len = end - cur; | |
397 } | 413 } |
398 | 414 |
399 servconn->rx_len -= cur_len; | 415 servconn->rx_len -= cur_len; |
400 | 416 |
401 if (servconn->payload_len) | 417 if (servconn->payload_len) |
405 } | 421 } |
406 else | 422 else |
407 { | 423 { |
408 msn_cmdproc_process_cmd_text(servconn->cmdproc, cur); | 424 msn_cmdproc_process_cmd_text(servconn->cmdproc, cur); |
409 } | 425 } |
410 } while (servconn->connected && servconn->rx_len); | 426 } while (servconn->connected && servconn->rx_len > 0); |
411 | 427 |
412 if (servconn->connected) | 428 if (servconn->connected) |
413 { | 429 { |
414 if (servconn->rx_len) | 430 if (servconn->rx_len > 0) |
415 servconn->rx_buf = g_memdup(cur, servconn->rx_len); | 431 servconn->rx_buf = g_memdup(cur, servconn->rx_len); |
416 else | 432 else |
417 servconn->rx_buf = NULL; | 433 servconn->rx_buf = NULL; |
418 } | 434 } |
419 | 435 |
422 if (servconn->wasted) | 438 if (servconn->wasted) |
423 msn_servconn_destroy(servconn); | 439 msn_servconn_destroy(servconn); |
424 | 440 |
425 g_free(old_rx_buf); | 441 g_free(old_rx_buf); |
426 } | 442 } |
443 | |
444 #if 0 | |
445 static int | |
446 create_listener(int port) | |
447 { | |
448 int fd; | |
449 const int on = 1; | |
450 | |
451 #if 0 | |
452 struct addrinfo hints; | |
453 struct addrinfo *c, *res; | |
454 char port_str[5]; | |
455 | |
456 snprintf(port_str, sizeof(port_str), "%d", port); | |
457 | |
458 memset(&hints, 0, sizeof(hints)); | |
459 | |
460 hints.ai_flags = AI_PASSIVE; | |
461 hints.ai_family = AF_UNSPEC; | |
462 hints.ai_socktype = SOCK_STREAM; | |
463 | |
464 if (getaddrinfo(NULL, port_str, &hints, &res) != 0) | |
465 { | |
466 gaim_debug_error("msn", "Could not get address info: %s.\n", | |
467 port_str); | |
468 return -1; | |
469 } | |
470 | |
471 for (c = res; c != NULL; c = c->ai_next) | |
472 { | |
473 fd = socket(c->ai_family, c->ai_socktype, c->ai_protocol); | |
474 | |
475 if (fd < 0) | |
476 continue; | |
477 | |
478 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); | |
479 | |
480 if (bind(fd, c->ai_addr, c->ai_addrlen) == 0) | |
481 break; | |
482 | |
483 close(fd); | |
484 } | |
485 | |
486 if (c == NULL) | |
487 { | |
488 gaim_debug_error("msn", "Could not find socket: %s.\n", port_str); | |
489 return -1; | |
490 } | |
491 | |
492 freeaddrinfo(res); | |
493 #else | |
494 struct sockaddr_in sockin; | |
495 | |
496 fd = socket(AF_INET, SOCK_STREAM, 0); | |
497 | |
498 if (fd < 0) | |
499 return -1; | |
500 | |
501 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) | |
502 { | |
503 close(fd); | |
504 return -1; | |
505 } | |
506 | |
507 memset(&sockin, 0, sizeof(struct sockaddr_in)); | |
508 sockin.sin_family = AF_INET; | |
509 sockin.sin_port = htons(port); | |
510 | |
511 if (bind(fd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) | |
512 { | |
513 close(fd); | |
514 return -1; | |
515 } | |
516 #endif | |
517 | |
518 if (listen (fd, 4) != 0) | |
519 { | |
520 close (fd); | |
521 return -1; | |
522 } | |
523 | |
524 fcntl(fd, F_SETFL, O_NONBLOCK); | |
525 | |
526 return fd; | |
527 } | |
528 #endif |