Mercurial > pidgin
comparison src/protocols/oscar/oscar.c @ 4804:9810ce8e7a96
[gaim-migrate @ 5124]
Here ya go, Rob.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 17 Mar 2003 04:02:30 +0000 |
parents | 4af15fbcb00a |
children | 3f44efdfb4cf |
comparison
equal
deleted
inserted
replaced
4803:6f04901ef729 | 4804:9810ce8e7a96 |
---|---|
85 aim_conn_t *conn; | 85 aim_conn_t *conn; |
86 | 86 |
87 guint cnpa; | 87 guint cnpa; |
88 guint paspa; | 88 guint paspa; |
89 guint emlpa; | 89 guint emlpa; |
90 guint icopa; | |
90 | 91 |
91 GSList *create_rooms; | 92 GSList *create_rooms; |
92 | 93 |
93 gboolean conf; | 94 gboolean conf; |
94 gboolean reqemail; | 95 gboolean reqemail; |
102 | 103 |
103 GSList *oscar_chats; | 104 GSList *oscar_chats; |
104 GSList *direct_ims; | 105 GSList *direct_ims; |
105 GSList *file_transfers; | 106 GSList *file_transfers; |
106 GHashTable *buddyinfo; | 107 GHashTable *buddyinfo; |
108 GSList *requesticon; | |
107 | 109 |
108 gboolean killme; | 110 gboolean killme; |
109 gboolean icq; | 111 gboolean icq; |
110 GSList *evilhack; | 112 GSList *evilhack; |
113 guint icontimer; | |
111 | 114 |
112 struct { | 115 struct { |
113 guint maxwatchers; /* max users who can watch you */ | 116 guint maxwatchers; /* max users who can watch you */ |
114 guint maxbuddies; /* max users you can watch */ | 117 guint maxbuddies; /* max users you can watch */ |
115 guint maxgroups; /* max groups in server list */ | 118 guint maxgroups; /* max groups in server list */ |
180 | 183 |
181 unsigned long ico_me_len; | 184 unsigned long ico_me_len; |
182 unsigned long ico_me_csum; | 185 unsigned long ico_me_csum; |
183 time_t ico_me_time; | 186 time_t ico_me_time; |
184 gboolean ico_informed; | 187 gboolean ico_informed; |
188 | |
189 fu16_t iconstrlen; | |
190 fu8_t iconstr[30]; | |
185 }; | 191 }; |
186 | 192 |
187 struct name_data { | 193 struct name_data { |
188 struct gaim_connection *gc; | 194 struct gaim_connection *gc; |
189 gchar *name; | 195 gchar *name; |
287 static int gaim_chat_join (aim_session_t *, aim_frame_t *, ...); | 293 static int gaim_chat_join (aim_session_t *, aim_frame_t *, ...); |
288 static int gaim_chat_leave (aim_session_t *, aim_frame_t *, ...); | 294 static int gaim_chat_leave (aim_session_t *, aim_frame_t *, ...); |
289 static int gaim_chat_info_update (aim_session_t *, aim_frame_t *, ...); | 295 static int gaim_chat_info_update (aim_session_t *, aim_frame_t *, ...); |
290 static int gaim_chat_incoming_msg(aim_session_t *, aim_frame_t *, ...); | 296 static int gaim_chat_incoming_msg(aim_session_t *, aim_frame_t *, ...); |
291 static int gaim_email_parseupdate(aim_session_t *, aim_frame_t *, ...); | 297 static int gaim_email_parseupdate(aim_session_t *, aim_frame_t *, ...); |
298 static int gaim_icon_error (aim_session_t *, aim_frame_t *, ...); | |
299 static int gaim_icon_parseicon (aim_session_t *, aim_frame_t *, ...); | |
292 static int gaim_parse_msgack (aim_session_t *, aim_frame_t *, ...); | 300 static int gaim_parse_msgack (aim_session_t *, aim_frame_t *, ...); |
293 static int gaim_parse_ratechange (aim_session_t *, aim_frame_t *, ...); | 301 static int gaim_parse_ratechange (aim_session_t *, aim_frame_t *, ...); |
294 static int gaim_parse_evilnotify (aim_session_t *, aim_frame_t *, ...); | 302 static int gaim_parse_evilnotify (aim_session_t *, aim_frame_t *, ...); |
295 static int gaim_parse_searcherror(aim_session_t *, aim_frame_t *, ...); | 303 static int gaim_parse_searcherror(aim_session_t *, aim_frame_t *, ...); |
296 static int gaim_parse_searchreply(aim_session_t *, aim_frame_t *, ...); | 304 static int gaim_parse_searchreply(aim_session_t *, aim_frame_t *, ...); |
299 static int conninitdone_admin (aim_session_t *, aim_frame_t *, ...); | 307 static int conninitdone_admin (aim_session_t *, aim_frame_t *, ...); |
300 static int conninitdone_bos (aim_session_t *, aim_frame_t *, ...); | 308 static int conninitdone_bos (aim_session_t *, aim_frame_t *, ...); |
301 static int conninitdone_chatnav (aim_session_t *, aim_frame_t *, ...); | 309 static int conninitdone_chatnav (aim_session_t *, aim_frame_t *, ...); |
302 static int conninitdone_chat (aim_session_t *, aim_frame_t *, ...); | 310 static int conninitdone_chat (aim_session_t *, aim_frame_t *, ...); |
303 static int conninitdone_email (aim_session_t *, aim_frame_t *, ...); | 311 static int conninitdone_email (aim_session_t *, aim_frame_t *, ...); |
312 static int conninitdone_icon (aim_session_t *, aim_frame_t *, ...); | |
304 static int gaim_parse_msgerr (aim_session_t *, aim_frame_t *, ...); | 313 static int gaim_parse_msgerr (aim_session_t *, aim_frame_t *, ...); |
305 static int gaim_parse_mtn (aim_session_t *, aim_frame_t *, ...); | 314 static int gaim_parse_mtn (aim_session_t *, aim_frame_t *, ...); |
306 static int gaim_parse_locaterights(aim_session_t *, aim_frame_t *, ...); | 315 static int gaim_parse_locaterights(aim_session_t *, aim_frame_t *, ...); |
307 static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...); | 316 static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...); |
308 static int gaim_parse_locerr (aim_session_t *, aim_frame_t *, ...); | 317 static int gaim_parse_locerr (aim_session_t *, aim_frame_t *, ...); |
335 /* for file transfer */ | 344 /* for file transfer */ |
336 static int oscar_sendfile_estblsh(aim_session_t *, aim_frame_t *, ...); | 345 static int oscar_sendfile_estblsh(aim_session_t *, aim_frame_t *, ...); |
337 static int oscar_sendfile_prompt (aim_session_t *, aim_frame_t *, ...); | 346 static int oscar_sendfile_prompt (aim_session_t *, aim_frame_t *, ...); |
338 static int oscar_sendfile_ack (aim_session_t *, aim_frame_t *, ...); | 347 static int oscar_sendfile_ack (aim_session_t *, aim_frame_t *, ...); |
339 static int oscar_sendfile_done (aim_session_t *, aim_frame_t *, ...); | 348 static int oscar_sendfile_done (aim_session_t *, aim_frame_t *, ...); |
349 | |
350 /* for icons */ | |
351 static gboolean gaim_icon_timerfunc(gpointer data); | |
340 | 352 |
341 static fu32_t check_encoding(const char *utf8); | 353 static fu32_t check_encoding(const char *utf8); |
342 static fu32_t parse_encoding(const char *enc); | 354 static fu32_t parse_encoding(const char *enc); |
343 | 355 |
344 static char *msgerrreason[] = { | 356 static char *msgerrreason[] = { |
477 if (od->emlpa > 0) | 489 if (od->emlpa > 0) |
478 gaim_input_remove(od->emlpa); | 490 gaim_input_remove(od->emlpa); |
479 od->emlpa = 0; | 491 od->emlpa = 0; |
480 debug_printf("removing email input watcher\n"); | 492 debug_printf("removing email input watcher\n"); |
481 aim_conn_kill(od->sess, &conn); | 493 aim_conn_kill(od->sess, &conn); |
494 } else if (conn->type == AIM_CONN_TYPE_ICON) { | |
495 if (od->icopa > 0) | |
496 gaim_input_remove(od->icopa); | |
497 od->icopa = 0; | |
498 debug_printf("removing icon input watcher\n"); | |
499 aim_conn_kill(od->sess, &conn); | |
482 } else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) { | 500 } else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) { |
483 if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) | 501 if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) |
484 gaim_odc_disconnect(od->sess, conn); | 502 gaim_odc_disconnect(od->sess, conn); |
485 aim_conn_kill(od->sess, &conn); | 503 aim_conn_kill(od->sess, &conn); |
486 } else { | 504 } else { |
609 if (n->watcher > 0) | 627 if (n->watcher > 0) |
610 gaim_input_remove(n->watcher); | 628 gaim_input_remove(n->watcher); |
611 od->direct_ims = g_slist_remove(od->direct_ims, n); | 629 od->direct_ims = g_slist_remove(od->direct_ims, n); |
612 g_free(n); | 630 g_free(n); |
613 } | 631 } |
614 | |
615 /* BBB */ | 632 /* BBB */ |
616 while (od->file_transfers) { | 633 while (od->file_transfers) { |
617 struct gaim_xfer *xfer; | 634 struct gaim_xfer *xfer; |
618 xfer = (struct gaim_xfer *)od->file_transfers->data; | 635 xfer = (struct gaim_xfer *)od->file_transfers->data; |
619 gaim_xfer_destroy(xfer); | 636 gaim_xfer_destroy(xfer); |
620 } | 637 } |
621 | 638 while (od->requesticon) { |
639 char *sn = od->requesticon->data; | |
640 od->requesticon = g_slist_remove(od->requesticon, sn); | |
641 free(sn); | |
642 } | |
622 g_hash_table_destroy(od->buddyinfo); | 643 g_hash_table_destroy(od->buddyinfo); |
623 while (od->evilhack) { | 644 while (od->evilhack) { |
624 g_free(od->evilhack->data); | 645 g_free(od->evilhack->data); |
625 od->evilhack = g_slist_remove(od->evilhack, od->evilhack->data); | 646 od->evilhack = g_slist_remove(od->evilhack, od->evilhack->data); |
626 } | 647 } |
642 gaim_input_remove(od->cnpa); | 663 gaim_input_remove(od->cnpa); |
643 if (od->paspa > 0) | 664 if (od->paspa > 0) |
644 gaim_input_remove(od->paspa); | 665 gaim_input_remove(od->paspa); |
645 if (od->emlpa > 0) | 666 if (od->emlpa > 0) |
646 gaim_input_remove(od->emlpa); | 667 gaim_input_remove(od->emlpa); |
668 if (od->icopa > 0) | |
669 gaim_input_remove(od->icopa); | |
647 aim_session_kill(od->sess); | 670 aim_session_kill(od->sess); |
648 g_free(od->sess); | 671 g_free(od->sess); |
649 od->sess = NULL; | 672 od->sess = NULL; |
650 g_free(gc->proto_data); | 673 g_free(gc->proto_data); |
651 gc->proto_data = NULL; | 674 gc->proto_data = NULL; |
1345 aim_clientready(sess, fr->conn); | 1368 aim_clientready(sess, fr->conn); |
1346 | 1369 |
1347 return 1; | 1370 return 1; |
1348 } | 1371 } |
1349 | 1372 |
1373 static int conninitdone_icon(aim_session_t *sess, aim_frame_t *fr, ...) { | |
1374 struct gaim_connection *gc = sess->aux_data; | |
1375 struct oscar_data *od = gc->proto_data; | |
1376 | |
1377 aim_conn_addhandler(sess, fr->conn, 0x0018, 0x0001, gaim_parse_genericerr, 0); | |
1378 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ICO, AIM_CB_ICO_ERROR, gaim_icon_error, 0); | |
1379 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ICO, AIM_CB_ICO_RESPONSE, gaim_icon_parseicon, 0); | |
1380 | |
1381 aim_clientready(sess, fr->conn); | |
1382 | |
1383 if (od->icontimer) | |
1384 g_source_remove(od->icontimer); | |
1385 od->icontimer = g_timeout_add(100, gaim_icon_timerfunc, gc); | |
1386 | |
1387 return 1; | |
1388 } | |
1389 | |
1350 static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) { | 1390 static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) { |
1351 struct gaim_connection *gc = data; | 1391 struct gaim_connection *gc = data; |
1352 struct oscar_data *od; | 1392 struct oscar_data *od; |
1353 aim_session_t *sess; | 1393 aim_session_t *sess; |
1354 aim_conn_t *tstconn; | 1394 aim_conn_t *tstconn; |
1459 } | 1499 } |
1460 | 1500 |
1461 aim_conn_completeconnect(sess, tstconn); | 1501 aim_conn_completeconnect(sess, tstconn); |
1462 od->emlpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn); | 1502 od->emlpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn); |
1463 debug_printf("email: connected\n"); | 1503 debug_printf("email: connected\n"); |
1504 } | |
1505 | |
1506 static void oscar_icon_connect(gpointer data, gint source, GaimInputCondition cond) { | |
1507 struct gaim_connection *gc = data; | |
1508 struct oscar_data *od; | |
1509 aim_session_t *sess; | |
1510 aim_conn_t *tstconn; | |
1511 | |
1512 if (!g_slist_find(connections, gc)) { | |
1513 close(source); | |
1514 return; | |
1515 } | |
1516 | |
1517 od = gc->proto_data; | |
1518 sess = od->sess; | |
1519 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_ICON); | |
1520 tstconn->fd = source; | |
1521 | |
1522 if (source < 0) { | |
1523 aim_conn_kill(sess, &tstconn); | |
1524 debug_printf("unable to connect to icon server\n"); | |
1525 return; | |
1526 } | |
1527 | |
1528 aim_conn_completeconnect(sess, tstconn); | |
1529 od->icopa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn); | |
1530 debug_printf("icon: connected\n"); | |
1464 } | 1531 } |
1465 | 1532 |
1466 /* Hrmph. I don't know how to make this look better. --mid */ | 1533 /* Hrmph. I don't know how to make this look better. --mid */ |
1467 static int gaim_handle_redirect(aim_session_t *sess, aim_frame_t *fr, ...) { | 1534 static int gaim_handle_redirect(aim_session_t *sess, aim_frame_t *fr, ...) { |
1468 va_list ap; | 1535 va_list ap; |
1566 g_free(ccon); | 1633 g_free(ccon); |
1567 return 1; | 1634 return 1; |
1568 } | 1635 } |
1569 aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie); | 1636 aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie); |
1570 debug_printf("Connected to chat room %s exchange %hu\n", ccon->name, ccon->exchange); | 1637 debug_printf("Connected to chat room %s exchange %hu\n", ccon->name, ccon->exchange); |
1638 } break; | |
1639 | |
1640 case 0x0010: { /* icon */ | |
1641 if (!(tstconn = aim_newconn(sess, AIM_CONN_TYPE_ICON, NULL))) { | |
1642 debug_printf("unable to connect to icon server\n"); | |
1643 g_free(host); | |
1644 return 1; | |
1645 } | |
1646 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0); | |
1647 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_icon, 0); | |
1648 | |
1649 tstconn->status |= AIM_CONN_STATUS_INPROGRESS; | |
1650 if (proxy_connect(account, host, port, oscar_icon_connect, gc) != 0) { | |
1651 aim_conn_kill(sess, &tstconn); | |
1652 debug_printf("unable to connect to icon server\n"); | |
1653 g_free(host); | |
1654 return 1; | |
1655 } | |
1656 aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie); | |
1571 } break; | 1657 } break; |
1572 | 1658 |
1573 case 0x0018: { /* email */ | 1659 case 0x0018: { /* email */ |
1574 if (!(tstconn = aim_newconn(sess, AIM_CONN_TYPE_EMAIL, NULL))) { | 1660 if (!(tstconn = aim_newconn(sess, AIM_CONN_TYPE_EMAIL, NULL))) { |
1575 debug_printf("unable to connect to email server\n"); | 1661 debug_printf("unable to connect to email server\n"); |
1660 } | 1746 } |
1661 bi->signon = info->onlinesince ? info->onlinesince : (info->sessionlen + time(NULL)); | 1747 bi->signon = info->onlinesince ? info->onlinesince : (info->sessionlen + time(NULL)); |
1662 bi->caps = caps; | 1748 bi->caps = caps; |
1663 bi->typingnot = FALSE; | 1749 bi->typingnot = FALSE; |
1664 bi->ico_informed = FALSE; | 1750 bi->ico_informed = FALSE; |
1751 | |
1752 /* Server stored icon stuff */ | |
1753 if (info->iconstrlen) { | |
1754 od->requesticon = g_slist_append(od->requesticon, strdup(normalize(info->sn))); | |
1755 if (od->icontimer) | |
1756 g_source_remove(od->icontimer); | |
1757 od->icontimer = g_timeout_add(500, gaim_icon_timerfunc, gc); | |
1758 } | |
1759 bi->iconstrlen = info->iconstrlen; | |
1760 memcpy(bi->iconstr, info->iconstr, info->iconstrlen); | |
1665 | 1761 |
1666 serv_got_update(gc, info->sn, 1, info->warnlevel/10, signon, | 1762 serv_got_update(gc, info->sn, 1, info->warnlevel/10, signon, |
1667 time_idle, type); | 1763 time_idle, type); |
1668 | 1764 |
1669 return 1; | 1765 return 1; |
3224 } | 3320 } |
3225 | 3321 |
3226 return 1; | 3322 return 1; |
3227 } | 3323 } |
3228 | 3324 |
3325 static int gaim_icon_error(aim_session_t *sess, aim_frame_t *fr, ...) { | |
3326 struct gaim_connection *gc = sess->aux_data; | |
3327 struct oscar_data *od = gc->proto_data; | |
3328 char *sn; | |
3329 | |
3330 sn = od->requesticon->data; | |
3331 debug_printf("removing %s from hash table\n", sn); | |
3332 od->requesticon = g_slist_remove(od->requesticon, sn); | |
3333 free(sn); | |
3334 | |
3335 if (od->icontimer) | |
3336 g_source_remove(od->icontimer); | |
3337 od->icontimer = g_timeout_add(500, gaim_icon_timerfunc, gc); | |
3338 | |
3339 return 1; | |
3340 } | |
3341 | |
3342 static int gaim_icon_parseicon(aim_session_t *sess, aim_frame_t *fr, ...) { | |
3343 struct gaim_connection *gc = sess->aux_data; | |
3344 struct oscar_data *od = gc->proto_data; | |
3345 GSList *cur; | |
3346 va_list ap; | |
3347 char *sn; | |
3348 fu8_t *iconstr, *icon; | |
3349 fu16_t iconstrlen, iconlen; | |
3350 | |
3351 va_start(ap, fr); | |
3352 sn = va_arg(ap, char *); | |
3353 iconstr = va_arg(ap, fu8_t *); | |
3354 iconstrlen = va_arg(ap, int); | |
3355 icon = va_arg(ap, fu8_t *); | |
3356 iconlen = va_arg(ap, int); | |
3357 va_end(ap); | |
3358 | |
3359 if (iconlen > 0) | |
3360 set_icon_data(gc, sn, icon, iconlen); | |
3361 | |
3362 cur = od->requesticon; | |
3363 while (cur) { | |
3364 char *cursn = cur->data; | |
3365 if (!aim_sncmp(cursn, sn)) { | |
3366 od->requesticon = g_slist_remove(od->requesticon, cursn); | |
3367 free(cursn); | |
3368 cur = od->requesticon; | |
3369 } else | |
3370 cur = cur->next; | |
3371 } | |
3372 | |
3373 if (od->icontimer) | |
3374 g_source_remove(od->icontimer); | |
3375 od->icontimer = g_timeout_add(250, gaim_icon_timerfunc, gc); | |
3376 | |
3377 return 1; | |
3378 } | |
3379 | |
3380 static gboolean gaim_icon_timerfunc(gpointer data) { | |
3381 struct gaim_connection *gc = data; | |
3382 struct oscar_data *od = gc->proto_data; | |
3383 struct buddy *b; | |
3384 struct buddyinfo *bi; | |
3385 aim_conn_t *conn; | |
3386 char *buddy_icon; | |
3387 | |
3388 if (!od->requesticon) { | |
3389 debug_printf("no more icons to request\n"); | |
3390 return FALSE; | |
3391 } | |
3392 | |
3393 conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_ICON); | |
3394 if (!conn) { | |
3395 aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_ICON); | |
3396 return FALSE; | |
3397 } | |
3398 | |
3399 bi = g_hash_table_lookup(od->buddyinfo, (char *)od->requesticon->data); | |
3400 b = gaim_find_buddy(gc->account, (char *)od->requesticon->data); | |
3401 buddy_icon = gaim_buddy_get_setting(b, "buddy_icon"); | |
3402 if (bi && (bi->iconstrlen > 0) && !buddy_icon) { | |
3403 aim_icon_requesticon(od->sess, od->requesticon->data, bi->iconstr, bi->iconstrlen); | |
3404 return FALSE; | |
3405 } else { | |
3406 char *sn = od->requesticon->data; | |
3407 od->requesticon = g_slist_remove(od->requesticon, sn); | |
3408 free(sn); | |
3409 } | |
3410 free(buddy_icon); | |
3411 | |
3412 return TRUE; | |
3413 } | |
3414 | |
3229 /* | 3415 /* |
3230 * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option. | 3416 * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option. |
3231 */ | 3417 */ |
3232 static int gaim_parse_msgack(aim_session_t *sess, aim_frame_t *fr, ...) { | 3418 static int gaim_parse_msgack(aim_session_t *sess, aim_frame_t *fr, ...) { |
3233 va_list ap; | 3419 va_list ap; |