comparison src/oscar.c @ 2034:6bdf9954097c

[gaim-migrate @ 2044] oscar is much less segfaulty. and more reliable. yes. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sat, 16 Jun 2001 05:28:08 +0000
parents 705783e5ab8c
children 38c06d8b7863
comparison
equal deleted inserted replaced
2033:705783e5ab8c 2034:6bdf9954097c
101 struct aim_conn_t *conn; 101 struct aim_conn_t *conn;
102 int inpa; 102 int inpa;
103 int id; 103 int id;
104 struct gaim_connection *gc; /* i hate this. */ 104 struct gaim_connection *gc; /* i hate this. */
105 struct conversation *cnv; /* bah. */ 105 struct conversation *cnv; /* bah. */
106 gpointer priv; /* don't ask. */
107 }; 106 };
108 107
109 struct direct_im { 108 struct direct_im {
110 struct gaim_connection *gc; 109 struct gaim_connection *gc;
111 char name[80]; 110 char name[80];
158 int curframe; 157 int curframe;
159 int timer; 158 int timer;
160 }; 159 };
161 #endif 160 #endif
162 161
163 static gpointer memdup(gconstpointer mem, guint size)
164 {
165 gpointer new_mem;
166
167 if (mem) {
168 new_mem = malloc(size);
169 memcpy(new_mem, mem, size);
170 return new_mem;
171 } else
172 return NULL;
173 }
174
175 static struct direct_im *find_direct_im(struct oscar_data *od, char *who) { 162 static struct direct_im *find_direct_im(struct oscar_data *od, char *who) {
176 GSList *d = od->direct_ims; 163 GSList *d = od->direct_ims;
177 char *n = g_strdup(normalize(who)); 164 char *n = g_strdup(normalize(who));
178 struct direct_im *m = NULL; 165 struct direct_im *m = NULL;
179 166
254 241
255 while (g) { 242 while (g) {
256 c = (struct chat_connection *)g->data; 243 c = (struct chat_connection *)g->data;
257 if (c->conn == conn) 244 if (c->conn == conn)
258 break; 245 break;
259 g = g->next;
260 c = NULL;
261 }
262
263 return c;
264 }
265
266 static struct gaim_connection *find_gaim_conn_by_oscar_conn(struct aim_conn_t *conn) {
267 GSList *g = connections;
268 struct gaim_connection *c = NULL;
269 struct aim_conn_t *s;
270 while (g) {
271 c = (struct gaim_connection *)g->data;
272 if (c->protocol != PROTO_OSCAR) {
273 c = NULL;
274 g = g->next;
275 continue;
276 }
277 s = ((struct oscar_data *)c->proto_data)->sess->connlist;
278 while (s) {
279 if (conn == s)
280 break;
281 s = s->next;
282 }
283 if (s) break;
284 g = g->next; 246 g = g->next;
285 c = NULL; 247 c = NULL;
286 } 248 }
287 249
288 return c; 250 return c;
354 static int msgerrreasonlen = 25; 316 static int msgerrreasonlen = 25;
355 317
356 static void oscar_callback(gpointer data, gint source, 318 static void oscar_callback(gpointer data, gint source,
357 GdkInputCondition condition) { 319 GdkInputCondition condition) {
358 struct aim_conn_t *conn = (struct aim_conn_t *)data; 320 struct aim_conn_t *conn = (struct aim_conn_t *)data;
359 struct gaim_connection *gc = find_gaim_conn_by_oscar_conn(conn); 321 struct aim_session_t *sess = aim_conn_getsess(conn);
322 struct gaim_connection *gc = sess ? sess->aux_data : NULL;
360 struct oscar_data *odata; 323 struct oscar_data *odata;
361 324
362 if (!gc) { 325 if (!gc) {
363 /* gc is null. we return, else we seg SIGSEG on next line. */ 326 /* gc is null. we return, else we seg SIGSEG on next line. */
364 debug_printf("oscar callback for closed connection (1).\n"); 327 debug_printf("oscar callback for closed connection (1).\n");
365 return; 328 return;
366 } 329 }
367 330
368 odata = (struct oscar_data *)gc->proto_data; 331 odata = (struct oscar_data *)gc->proto_data;
369 332
370 if (!g_slist_find(connections, gc)) { 333 if (!g_slist_find(connections, gc)) {
466 return; 429 return;
467 } 430 }
468 431
469 odata = gc->proto_data; 432 odata = gc->proto_data;
470 sess = odata->sess; 433 sess = odata->sess;
471 conn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); 434 conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH);
472 435
473 if (source < 0) { 436 if (source < 0) {
474 hide_login_progress(gc, _("Couldn't connect to host")); 437 hide_login_progress(gc, _("Couldn't connect to host"));
475 signoff(gc); 438 signoff(gc);
476 return; 439 return;
477 } 440 }
478 441
479 if (conn->fd != source) 442 aim_conn_completeconnect(sess, conn);
480 conn->fd = source;
481
482 aim_request_login(sess, conn, gc->username);
483
484 gc->inpa = gdk_input_add(conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, 443 gc->inpa = gdk_input_add(conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
485 oscar_callback, conn); 444 oscar_callback, conn);
486
487 debug_printf(_("Password sent, waiting for response\n")); 445 debug_printf(_("Password sent, waiting for response\n"));
488 } 446 }
489 447
490 static void oscar_login(struct aim_user *user) { 448 static void oscar_login(struct aim_user *user) {
491 struct aim_session_t *sess; 449 struct aim_session_t *sess;
520 set_login_progress(gc, 2, buf); 478 set_login_progress(gc, 2, buf);
521 479
522 aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0); 480 aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0);
523 aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); 481 aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0);
524 482
483 conn->status |= AIM_CONN_STATUS_INPROGRESS;
525 conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ? 484 conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ?
526 user->proto_opt[USEROPT_AUTH] : FAIM_LOGIN_SERVER, 485 user->proto_opt[USEROPT_AUTH] : FAIM_LOGIN_SERVER,
527 user->proto_opt[USEROPT_AUTHPORT][0] ? 486 user->proto_opt[USEROPT_AUTHPORT][0] ?
528 atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT, 487 atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT,
529 oscar_login_connect, gc); 488 oscar_login_connect, gc);
530 if (!user->gc || (conn->fd < 0)) { 489 if (conn->fd < 0) {
531 hide_login_progress(gc, _("Couldn't connect to host")); 490 hide_login_progress(gc, _("Couldn't connect to host"));
532 signoff(gc); 491 signoff(gc);
533 return; 492 return;
534 } 493 }
494 aim_request_login(sess, conn, gc->username);
535 } 495 }
536 496
537 static void oscar_close(struct gaim_connection *gc) { 497 static void oscar_close(struct gaim_connection *gc) {
538 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 498 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
539 if (gc->protocol != PROTO_OSCAR) return; 499 if (gc->protocol != PROTO_OSCAR) return;
597 return; 557 return;
598 } 558 }
599 559
600 odata = gc->proto_data; 560 odata = gc->proto_data;
601 sess = odata->sess; 561 sess = odata->sess;
602 bosconn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); 562 bosconn = odata->conn;
603 563
604 if (source < 0) { 564 if (source < 0) {
605 if (bosconn->priv)
606 g_free(bosconn->priv);
607 bosconn->priv = NULL;
608 hide_login_progress(gc, _("Could Not Connect")); 565 hide_login_progress(gc, _("Could Not Connect"));
609 signoff(gc); 566 signoff(gc);
610 return; 567 return;
611 } 568 }
612 569
613 if (bosconn->fd != source) 570 aim_conn_completeconnect(sess, bosconn);
614 bosconn->fd = source;
615
616 aim_auth_sendcookie(sess, bosconn, bosconn->priv);
617 free(bosconn->priv);
618 bosconn->priv = NULL;
619 gc->inpa = gdk_input_add(bosconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, 571 gc->inpa = gdk_input_add(bosconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
620 oscar_callback, bosconn); 572 oscar_callback, bosconn);
621 set_login_progress(gc, 4, _("Connection established, cookie sent")); 573 set_login_progress(gc, 4, _("Connection established, cookie sent"));
622 } 574 }
623 575
748 port = atoi(&(bosip[i+1])); 700 port = atoi(&(bosip[i+1]));
749 break; 701 break;
750 } 702 }
751 } 703 }
752 host = g_strndup(bosip, i); 704 host = g_strndup(bosip, i);
753 bosconn->priv = memdup(cookie, AIM_COOKIELEN); 705 bosconn->status |= AIM_CONN_STATUS_INPROGRESS;
754 bosconn->fd = proxy_connect(host, port, oscar_bos_connect, gc); 706 bosconn->fd = proxy_connect(host, port, oscar_bos_connect, gc);
755 g_free(host); 707 g_free(host);
756 if (!user->gc || (bosconn->fd < 0)) { 708 if (bosconn->fd < 0) {
757 if (bosconn->priv)
758 g_free(bosconn->priv);
759 bosconn->priv = NULL;
760 hide_login_progress(gc, _("Could Not Connect")); 709 hide_login_progress(gc, _("Could Not Connect"));
761 signoff(gc); 710 signoff(gc);
762 return -1; 711 return -1;
763 } 712 }
713 aim_auth_sendcookie(sess, bosconn, cookie);
764 return 1; 714 return 1;
765 } 715 }
766 716
767 struct pieceofcrap { 717 struct pieceofcrap {
768 struct gaim_connection *gc; 718 struct gaim_connection *gc;
821 if (pos->modname) 771 if (pos->modname)
822 g_free(pos->modname); 772 g_free(pos->modname);
823 g_free(pos); 773 g_free(pos);
824 return; 774 return;
825 } 775 }
826
827 if (pos->fd != source)
828 pos->fd = source;
829 776
830 g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA 777 g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA
831 "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n", 778 "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n",
832 pos->offset, pos->len, pos->modname ? pos->modname : ""); 779 pos->offset, pos->len, pos->modname ? pos->modname : "");
833 write(pos->fd, buf, strlen(buf)); 780 write(pos->fd, buf, strlen(buf));
1014 return; 961 return;
1015 } 962 }
1016 963
1017 odata = gc->proto_data; 964 odata = gc->proto_data;
1018 sess = odata->sess; 965 sess = odata->sess;
1019 tstconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV); 966 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_CHATNAV);
1020 967
1021 if (source < 0) { 968 if (source < 0) {
1022 if (tstconn->priv)
1023 g_free(tstconn->priv);
1024 tstconn->priv = NULL;
1025 aim_conn_kill(sess, &tstconn); 969 aim_conn_kill(sess, &tstconn);
1026 debug_printf("unable to connect to chatnav server\n"); 970 debug_printf("unable to connect to chatnav server\n");
1027 return; 971 return;
1028 } 972 }
1029 973
1030 if (tstconn->fd != source) 974 aim_conn_completeconnect(sess, tstconn);
1031 tstconn->fd = source;
1032
1033 aim_auth_sendcookie(sess, tstconn, tstconn->priv);
1034 free(tstconn->priv);
1035 tstconn->priv = NULL;
1036 odata->cnpa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, 975 odata->cnpa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
1037 oscar_callback, tstconn); 976 oscar_callback, tstconn);
1038 debug_printf("chatnav: connected\n"); 977 debug_printf("chatnav: connected\n");
1039 } 978 }
1040 979
1050 return; 989 return;
1051 } 990 }
1052 991
1053 odata = gc->proto_data; 992 odata = gc->proto_data;
1054 sess = odata->sess; 993 sess = odata->sess;
1055 tstconn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); 994 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH);
1056 995
1057 if (source < 0) { 996 if (source < 0) {
1058 if (tstconn->priv)
1059 g_free(tstconn->priv);
1060 tstconn->priv = NULL;
1061 aim_conn_kill(sess, &tstconn); 997 aim_conn_kill(sess, &tstconn);
1062 debug_printf("unable to connect to authorizer\n"); 998 debug_printf("unable to connect to authorizer\n");
1063 return; 999 return;
1064 } 1000 }
1065 1001
1066 if (tstconn->fd != source) 1002 aim_conn_completeconnect(sess, tstconn);
1067 tstconn->fd = source;
1068
1069 aim_auth_sendcookie(sess, tstconn, tstconn->priv);
1070 free(tstconn->priv);
1071 tstconn->priv = NULL;
1072 odata->paspa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, 1003 odata->paspa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
1073 oscar_callback, tstconn); 1004 oscar_callback, tstconn);
1074 debug_printf("chatnav: connected\n"); 1005 debug_printf("chatnav: connected\n");
1075 } 1006 }
1076 1007
1082 struct aim_session_t *sess; 1013 struct aim_session_t *sess;
1083 struct aim_conn_t *tstconn; 1014 struct aim_conn_t *tstconn;
1084 1015
1085 if (!g_slist_find(connections, gc)) { 1016 if (!g_slist_find(connections, gc)) {
1086 close(source); 1017 close(source);
1087 g_free(ccon->priv);
1088 g_free(ccon->show); 1018 g_free(ccon->show);
1089 g_free(ccon->name); 1019 g_free(ccon->name);
1090 g_free(ccon); 1020 g_free(ccon);
1091 return; 1021 return;
1092 } 1022 }
1095 sess = odata->sess; 1025 sess = odata->sess;
1096 tstconn = ccon->conn; 1026 tstconn = ccon->conn;
1097 1027
1098 if (source < 0) { 1028 if (source < 0) {
1099 aim_conn_kill(sess, &tstconn); 1029 aim_conn_kill(sess, &tstconn);
1100 g_free(ccon->priv);
1101 g_free(ccon->show); 1030 g_free(ccon->show);
1102 g_free(ccon->name); 1031 g_free(ccon->name);
1103 g_free(ccon); 1032 g_free(ccon);
1104 return; 1033 return;
1105 } 1034 }
1106 1035
1107 if (ccon->fd != source) 1036 aim_conn_completeconnect(sess, ccon->conn);
1108 ccon->fd = tstconn->fd = source;
1109
1110 ccon->inpa = gdk_input_add(tstconn->fd, 1037 ccon->inpa = gdk_input_add(tstconn->fd,
1111 GDK_INPUT_READ | GDK_INPUT_EXCEPTION, 1038 GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
1112 oscar_callback, tstconn); 1039 oscar_callback, tstconn);
1113 odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon); 1040 odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon);
1114 aim_chat_attachname(tstconn, ccon->name); 1041 aim_chat_attachname(tstconn, ccon->name);
1115 aim_auth_sendcookie(sess, tstconn, ccon->priv); 1042 }
1116 g_free(ccon->priv); 1043
1117 ccon->priv = NULL;
1118 }
1119 int gaim_handle_redirect(struct aim_session_t *sess, 1044 int gaim_handle_redirect(struct aim_session_t *sess,
1120 struct command_rx_struct *command, ...) { 1045 struct command_rx_struct *command, ...) {
1121 va_list ap; 1046 va_list ap;
1122 int serviceid; 1047 int serviceid;
1123 char *ip; 1048 char *ip;
1126 struct aim_user *user = gc->user; 1051 struct aim_user *user = gc->user;
1127 struct aim_conn_t *tstconn; 1052 struct aim_conn_t *tstconn;
1128 int i; 1053 int i;
1129 char *host; 1054 char *host;
1130 int port; 1055 int port;
1131 int fd;
1132 1056
1133 port = user->proto_opt[USEROPT_AUTHPORT][0] ? 1057 port = user->proto_opt[USEROPT_AUTHPORT][0] ?
1134 atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT, 1058 atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT,
1135 1059
1136 va_start(ap, command); 1060 va_start(ap, command);
1159 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, gaim_rateresp, 0); 1083 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, gaim_rateresp, 0);
1160 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, gaim_info_change, 0); 1084 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, gaim_info_change, 0);
1161 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, gaim_info_change, 0); 1085 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, gaim_info_change, 0);
1162 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, gaim_account_confirm, 0); 1086 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, gaim_account_confirm, 0);
1163 1087
1164 tstconn->priv = memdup(cookie, AIM_COOKIELEN); 1088 tstconn->status |= AIM_CONN_STATUS_INPROGRESS;
1165 fd = proxy_connect(host, port, oscar_auth_connect, gc); 1089 tstconn->fd = proxy_connect(host, port, oscar_auth_connect, gc);
1166 if (fd < 0) { 1090 if (tstconn->fd < 0) {
1167 if (tstconn->priv)
1168 g_free(tstconn->priv);
1169 tstconn->priv = NULL;
1170 aim_conn_kill(sess, &tstconn); 1091 aim_conn_kill(sess, &tstconn);
1171 debug_printf("unable to reconnect with authorizer\n"); 1092 debug_printf("unable to reconnect with authorizer\n");
1172 g_free(host); 1093 g_free(host);
1173 return 1; 1094 return 1;
1174 } 1095 }
1175 tstconn->fd = fd; 1096 aim_auth_sendcookie(sess, tstconn, cookie);
1176 break; 1097 break;
1177 case 0xd: /* ChatNav */ 1098 case 0xd: /* ChatNav */
1178 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, NULL); 1099 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, NULL);
1179 if (tstconn == NULL) { 1100 if (tstconn == NULL) {
1180 debug_printf("unable to connect to chatnav server\n"); 1101 debug_printf("unable to connect to chatnav server\n");
1181 g_free(host); 1102 g_free(host);
1182 return 1; 1103 return 1;
1183 } 1104 }
1184 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0); 1105 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0);
1185 1106
1186 tstconn->priv = memdup(cookie, AIM_COOKIELEN); 1107 tstconn->status |= AIM_CONN_STATUS_INPROGRESS;
1187 fd = proxy_connect(host, port, oscar_chatnav_connect, gc); 1108 tstconn->fd = proxy_connect(host, port, oscar_chatnav_connect, gc);
1188 if (fd < 0) { 1109 if (tstconn->fd < 0) {
1189 if (tstconn->priv)
1190 g_free(tstconn->priv);
1191 tstconn->priv = NULL;
1192 aim_conn_kill(sess, &tstconn); 1110 aim_conn_kill(sess, &tstconn);
1193 debug_printf("unable to connect to chatnav server\n"); 1111 debug_printf("unable to connect to chatnav server\n");
1194 g_free(host); 1112 g_free(host);
1195 return 1; 1113 return 1;
1196 } 1114 }
1197 tstconn->fd = fd; 1115 aim_auth_sendcookie(sess, tstconn, cookie);
1198 break; 1116 break;
1199 case 0xe: /* Chat */ 1117 case 0xe: /* Chat */
1200 { 1118 {
1201 char *roomname = va_arg(ap, char *); 1119 char *roomname = va_arg(ap, char *);
1202 int exchange = va_arg(ap, int); 1120 int exchange = va_arg(ap, int);
1215 ccon->fd = -1; 1133 ccon->fd = -1;
1216 ccon->name = g_strdup(roomname); 1134 ccon->name = g_strdup(roomname);
1217 ccon->exchange = exchange; 1135 ccon->exchange = exchange;
1218 ccon->show = extract_name(roomname); 1136 ccon->show = extract_name(roomname);
1219 1137
1220 ccon->priv = memdup(cookie, AIM_COOKIELEN); 1138 ccon->conn->status |= AIM_CONN_STATUS_INPROGRESS;
1221 fd = proxy_connect(host, port, oscar_chat_connect, ccon); 1139 ccon->conn->fd = proxy_connect(host, port, oscar_chat_connect, ccon);
1222 if (fd < 0) { 1140 if (ccon->conn->fd < 0) {
1223 aim_conn_kill(sess, &tstconn); 1141 aim_conn_kill(sess, &tstconn);
1224 debug_printf("unable to connect to chat server\n"); 1142 debug_printf("unable to connect to chat server\n");
1225 g_free(host); 1143 g_free(host);
1226 g_free(ccon->priv);
1227 g_free(ccon->show); 1144 g_free(ccon->show);
1228 g_free(ccon->name); 1145 g_free(ccon->name);
1229 g_free(ccon); 1146 g_free(ccon);
1230 return 1; 1147 return 1;
1231 } 1148 }
1232 ccon->fd = tstconn->fd = fd; 1149 aim_auth_sendcookie(sess, tstconn, cookie);
1233 debug_printf("Connected to chat room %s exchange %d\n", roomname, exchange); 1150 debug_printf("Connected to chat room %s exchange %d\n", roomname, exchange);
1234 } 1151 }
1235 break; 1152 break;
1236 default: /* huh? */ 1153 default: /* huh? */
1237 debug_printf("got redirect for unknown service 0x%04x\n", serviceid); 1154 debug_printf("got redirect for unknown service 0x%04x\n", serviceid);
1314 struct direct_im *dim = data; 1231 struct direct_im *dim = data;
1315 struct gaim_connection *gc = dim->gc; 1232 struct gaim_connection *gc = dim->gc;
1316 struct oscar_data *od = gc->proto_data; 1233 struct oscar_data *od = gc->proto_data;
1317 char buf[256]; 1234 char buf[256];
1318 1235
1319 if (source < 0) { 1236 if (!g_slist_find(connections, gc)) {
1320 od->direct_ims = g_slist_remove(od->direct_ims, dim);
1321 g_free(dim); 1237 g_free(dim);
1322 return; 1238 return;
1323 } 1239 }
1324 1240
1325 if (dim->conn->fd != source) 1241 if (source < 0) {
1326 dim->conn->fd = source; 1242 g_free(dim);
1327 1243 return;
1244 }
1245
1246 aim_conn_completeconnect(od->sess, dim->conn);
1328 if (!(dim->cnv = find_conversation(dim->name))) dim->cnv = new_conversation(dim->name); 1247 if (!(dim->cnv = find_conversation(dim->name))) dim->cnv = new_conversation(dim->name);
1329 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), dim->name); 1248 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), dim->name);
1330 write_to_conv(dim->cnv, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL)); 1249 write_to_conv(dim->cnv, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL));
1250
1251 od->direct_ims = g_slist_append(od->direct_ims, dim);
1331 1252
1332 gtk_signal_connect(GTK_OBJECT(dim->cnv->window), "destroy", 1253 gtk_signal_connect(GTK_OBJECT(dim->cnv->window), "destroy",
1333 GTK_SIGNAL_FUNC(delete_direct_im), dim); 1254 GTK_SIGNAL_FUNC(delete_direct_im), dim);
1334 1255
1335 dim->watcher = gdk_input_add(dim->conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, 1256 dim->watcher = gdk_input_add(dim->conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
1373 port = atoi(&(d->priv->ip[i+1])); 1294 port = atoi(&(d->priv->ip[i+1]));
1374 break; 1295 break;
1375 } 1296 }
1376 } 1297 }
1377 host = g_strndup(d->priv->ip, i); 1298 host = g_strndup(d->priv->ip, i);
1299 dim->conn->status |= AIM_CONN_STATUS_INPROGRESS;
1378 dim->conn->fd = proxy_connect(host, port, oscar_directim_callback, dim); 1300 dim->conn->fd = proxy_connect(host, port, oscar_directim_callback, dim);
1379 g_free(host); 1301 g_free(host);
1380 if (dim->conn->fd < 0) { 1302 if (dim->conn->fd < 0) {
1381 aim_conn_kill(od->sess, &dim->conn); 1303 aim_conn_kill(od->sess, &dim->conn);
1382 g_free(dim); 1304 g_free(dim);
1383 cancel_direct_im(w, d); 1305 cancel_direct_im(w, d);
1384 return TRUE; 1306 return TRUE;
1385 } 1307 }
1386
1387 od->direct_ims = g_slist_append(od->direct_ims, dim);
1388 1308
1389 cancel_direct_im(w, d); 1309 cancel_direct_im(w, d);
1390 1310
1391 return TRUE; 1311 return TRUE;
1392 } 1312 }