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