Mercurial > pidgin
comparison src/protocols/oscar/oscar.c @ 3952:07283934dedd
[gaim-migrate @ 4133]
Ok, big commit with little functionality change.
Most of it is me shuffling crap around because I'm one of them neat freaks. Lots of general code
cleanup too. I'm trying to move to that whole "one-family-per-file" thing.
The details...
I added libfaim support for aim's new search family, 0x000f. I only tested this briefly, so if
anyone uses it for anything, be aware that it could be buggy. I'll add oscar support sometime.
Advantages of this family are... when you search for someone, you get the directory info for that
person. So like, first name, middle name, last name, maiden name, city, state, country, zip,
address, interests, nickname, and maybe some other stuff. Basically all the info that they've set in
their directory info thing. Info. Oh, and I'm calling it "new search" because seach was already
taken, and cookie monster ate my right brain.
The reason I didn't add support to oscar.c... the new search family requires making a connection to
another server. While moving stuff around I realized that I didn't really like how new connections
are made. It's kind of sloppy. I'm thinking it would be nice to have an outgoing queue for each
type of connection, and then let the client queue messages as much as they want. Then, if libfaim
sees that there is a message for a certain type of connection, and there is no open connection of
that type, it will connect, and then flush the queue when the connection is made. This seems a lot
cleaner, but it also seems like a pain in the ass. I should do ssi for icq first, anyway :-)
Also, I think it would be neat if there was an ICBM file that handled channels 1 through 4. Then
im.c and chat.c could pass the ICBM part to the icbm stuff and it could get parsed there. im.c is
really huge right now.
I applied a patch from Graham Booker that paves the way for unicode in direct IMs. Thanks Graham.
Now we just need Paco-Paco to git a little free time and write a patch for this.
http://sourceforge.net/tracker/index.php?func=detail&aid=633589&group_id=235&atid=300235
I applied 2 patches from Will Mahan dealing with file transfer/oft/rendezous/whatever. Here's some
info on them, from The Man himself:
Patch 1
"Currently the Rendezvous code is rather messy; this
patch attempts to bring it up to speed with the rest of
the Oscar prpl. Its changes include:
* Rewrite several ft.c functions to use bstreams.
Apparently the code in question was written before
bstreams were implemented.
* Handle incoming Rendezvous packets through the
rxqueue like FLAP packets, rather than handling them as
a special case as soon as they are received. This
takes advantage of the bstream cleanup to unify some
code and simplify the aim_frame_t struct.
* Change some names used to try to clarify the
distinction between OFT, which refers specifically to
file transfer, and Rendezvous, which encompasses OFT as
well as other types of client-to-client connections."
Patch 2
"* Add some comments I inadvertently left out of my last patch.
* Fix a double-free that occurs when connections time out.
* Correct a bug causing filenames to be truncated by 4 characters on
some clients.
* Preserve directory structure when sending multiple files.
* Handle (throw away) resource forks sent by Mac clients."
I also changed all indents to tabs in ft.c.
And split all the bstream stuff from rxqueue.c and put it in bstream.c. It really is a separate
thing. Especially since it can be used for outgoing connections.
Also, I was going to look over the whole patch tonight to make sure it's all good, but it's like 6000
lines, so, uh, I'll do it later.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 13 Nov 2002 07:01:37 +0000 |
parents | e73c48cf1645 |
children | 4f3fb54ee669 |
comparison
equal
deleted
inserted
replaced
3951:32942c49dced | 3952:07283934dedd |
---|---|
345 static int gaim_parse_ratechange (aim_session_t *, aim_frame_t *, ...); | 345 static int gaim_parse_ratechange (aim_session_t *, aim_frame_t *, ...); |
346 static int gaim_parse_evilnotify (aim_session_t *, aim_frame_t *, ...); | 346 static int gaim_parse_evilnotify (aim_session_t *, aim_frame_t *, ...); |
347 static int gaim_parse_searcherror(aim_session_t *, aim_frame_t *, ...); | 347 static int gaim_parse_searcherror(aim_session_t *, aim_frame_t *, ...); |
348 static int gaim_parse_searchreply(aim_session_t *, aim_frame_t *, ...); | 348 static int gaim_parse_searchreply(aim_session_t *, aim_frame_t *, ...); |
349 static int gaim_bosrights (aim_session_t *, aim_frame_t *, ...); | 349 static int gaim_bosrights (aim_session_t *, aim_frame_t *, ...); |
350 static int conninitdone_admin (aim_session_t *, aim_frame_t *, ...); | |
350 static int conninitdone_bos (aim_session_t *, aim_frame_t *, ...); | 351 static int conninitdone_bos (aim_session_t *, aim_frame_t *, ...); |
351 static int conninitdone_admin (aim_session_t *, aim_frame_t *, ...); | 352 static int conninitdone_chatnav (aim_session_t *, aim_frame_t *, ...); |
352 static int conninitdone_chat (aim_session_t *, aim_frame_t *, ...); | 353 static int conninitdone_chat (aim_session_t *, aim_frame_t *, ...); |
353 static int conninitdone_chatnav (aim_session_t *, aim_frame_t *, ...); | |
354 static int conninitdone_email (aim_session_t *, aim_frame_t *, ...); | 354 static int conninitdone_email (aim_session_t *, aim_frame_t *, ...); |
355 static int gaim_parse_msgerr (aim_session_t *, aim_frame_t *, ...); | 355 static int gaim_parse_msgerr (aim_session_t *, aim_frame_t *, ...); |
356 static int gaim_parse_mtn (aim_session_t *, aim_frame_t *, ...); | 356 static int gaim_parse_mtn (aim_session_t *, aim_frame_t *, ...); |
357 static int gaim_parse_locaterights(aim_session_t *, aim_frame_t *, ...); | 357 static int gaim_parse_locaterights(aim_session_t *, aim_frame_t *, ...); |
358 static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...); | 358 static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...); |
409 "Queue full", | 409 "Queue full", |
410 "Not while on AOL" | 410 "Not while on AOL" |
411 }; | 411 }; |
412 static int msgerrreasonlen = 25; | 412 static int msgerrreasonlen = 25; |
413 | 413 |
414 static void oscar_file_transfer_disconnect(aim_session_t *sess, | 414 /* |
415 aim_conn_t *conn) { | 415 * This is called to clean up whenever a file transfer is no longer in progress, |
416 * whether because it finished sucessfully, it was canceled, or there was an error. | |
417 */ | |
418 static void oscar_file_transfer_disconnect(aim_session_t *sess, aim_conn_t *conn) { | |
416 struct gaim_connection *gc = sess->aux_data; | 419 struct gaim_connection *gc = sess->aux_data; |
417 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | 420 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
418 struct oscar_file_transfer *oft = find_oft_by_conn(gc, | 421 struct oscar_file_transfer *oft = find_oft_by_conn(gc, |
419 conn); | 422 conn); |
420 | 423 |
1483 | 1486 |
1484 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, | 1487 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, |
1485 oscar_callback, dim->conn); | 1488 oscar_callback, dim->conn); |
1486 } | 1489 } |
1487 | 1490 |
1491 /* | |
1492 * This is called every time we are finished sending a file and the receiving buddy | |
1493 * has sent back an acknowledgement; we start the next file or tear down the | |
1494 * connection as appropriate. | |
1495 */ | |
1488 static int oscar_sendfile_out_done(aim_session_t *sess, aim_frame_t *fr, ...) { | 1496 static int oscar_sendfile_out_done(aim_session_t *sess, aim_frame_t *fr, ...) { |
1489 struct gaim_connection *gc = sess->aux_data; | 1497 struct gaim_connection *gc = sess->aux_data; |
1490 va_list ap; | 1498 va_list ap; |
1491 aim_conn_t *conn; | 1499 aim_conn_t *conn; |
1492 const char *cook; | 1500 const char *cook; |
1512 struct oscar_file_transfer *oft) { | 1520 struct oscar_file_transfer *oft) { |
1513 char *name; | 1521 char *name; |
1514 int size; | 1522 int size; |
1515 | 1523 |
1516 transfer_get_file_info(oft->xfer, &size, &name); | 1524 transfer_get_file_info(oft->xfer, &size, &name); |
1525 /* AAA convert the name to UCS-2 if necessary, and pass the encoding to the call below */ | |
1517 aim_oft_sendfile_request(sess, oft->conn, name, oft->filesdone, | 1526 aim_oft_sendfile_request(sess, oft->conn, name, oft->filesdone, |
1518 oft->totfiles, size, oft->totsize); | 1527 oft->totfiles, size, oft->totsize); |
1519 | 1528 |
1520 return 0; | 1529 return 0; |
1521 } | 1530 } |
1522 | 1531 |
1532 /* | |
1533 * This is called when sending a file and a direct connection has been set up with | |
1534 * the buddy; we can now transmit the appropriate headers describing the transfer. | |
1535 */ | |
1523 static int oscar_sendfile_accepted(aim_session_t *sess, aim_frame_t *fr, ...) { | 1536 static int oscar_sendfile_accepted(aim_session_t *sess, aim_frame_t *fr, ...) { |
1524 struct gaim_connection *gc = sess->aux_data; | 1537 struct gaim_connection *gc = sess->aux_data; |
1525 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | 1538 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
1526 struct oscar_file_transfer *oft; | 1539 struct oscar_file_transfer *oft; |
1527 va_list ap; | 1540 va_list ap; |
1553 oscar_sendfile_request(sess, oft); | 1566 oscar_sendfile_request(sess, oft); |
1554 | 1567 |
1555 return 0; | 1568 return 0; |
1556 } | 1569 } |
1557 | 1570 |
1571 /* | |
1572 * This is called when we requested to send a file to a buddy, but he or she didn't | |
1573 * respond; we need to clean up. | |
1574 */ | |
1558 static int oscar_sendfile_timeout(aim_session_t *sess, aim_frame_t *fr, ...) { | 1575 static int oscar_sendfile_timeout(aim_session_t *sess, aim_frame_t *fr, ...) { |
1559 struct gaim_connection *gc = sess->aux_data; | 1576 struct gaim_connection *gc = sess->aux_data; |
1560 va_list ap; | 1577 va_list ap; |
1561 struct oscar_file_transfer *oft; | 1578 struct oscar_file_transfer *oft; |
1562 char *cookie; | 1579 char *cookie; |
1605 0); | 1622 0); |
1606 oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ, | 1623 oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ, |
1607 oscar_callback, oft->conn); | 1624 oscar_callback, oft->conn); |
1608 } | 1625 } |
1609 | 1626 |
1627 /* | |
1628 * This is called after a chunk of data has been sent out or received; it is used | |
1629 * to update the checksum. | |
1630 */ | |
1610 static void oscar_file_transfer_data_chunk(struct gaim_connection *gc, | 1631 static void oscar_file_transfer_data_chunk(struct gaim_connection *gc, |
1611 struct file_transfer *xfer, const char *buf, int len) | 1632 struct file_transfer *xfer, const char *buf, int len) |
1612 { | 1633 { |
1613 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); | 1634 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); |
1614 aim_session_t *sess = aim_conn_getsess(oft->conn); | 1635 aim_session_t *sess = aim_conn_getsess(oft->conn); |
1615 | 1636 |
1616 if (oft->type == OFT_SENDFILE_IN) | 1637 if (oft->type == OFT_SENDFILE_IN) |
1617 aim_update_checksum(sess, oft->conn, buf, len); | 1638 aim_update_checksum(sess, oft->conn, buf, len); |
1618 } | 1639 } |
1619 | 1640 |
1641 /* Called once at the beginning of an incoming transfer session. */ | |
1620 static void oscar_file_transfer_in(struct gaim_connection *gc, | 1642 static void oscar_file_transfer_in(struct gaim_connection *gc, |
1621 struct file_transfer *xfer, int offset) { | 1643 struct file_transfer *xfer, int offset) { |
1622 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | 1644 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
1623 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); | 1645 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); |
1624 | 1646 |
1626 oft->conn = aim_accepttransfer(od->sess, od->conn, oft->sn, | 1648 oft->conn = aim_accepttransfer(od->sess, od->conn, oft->sn, |
1627 oft->cookie, oft->ip, | 1649 oft->cookie, oft->ip, |
1628 oft->port, | 1650 oft->port, |
1629 AIM_CAPS_SENDFILE); | 1651 AIM_CAPS_SENDFILE); |
1630 if (!oft->conn) { | 1652 if (!oft->conn) { |
1653 /* XXX implement reverse connections for receiving from behind a firewall */ | |
1631 char *buf = g_strdup_printf("Couldn't connect to remote host"); | 1654 char *buf = g_strdup_printf("Couldn't connect to remote host"); |
1632 do_error_dialog(buf, NULL, GAIM_ERROR); | 1655 do_error_dialog(buf, NULL, GAIM_ERROR); |
1633 g_free(buf); | 1656 g_free(buf); |
1634 return; | 1657 return; |
1635 } | 1658 } |
1640 | 1663 |
1641 oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ, | 1664 oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ, |
1642 oscar_callback, oft->conn); | 1665 oscar_callback, oft->conn); |
1643 } | 1666 } |
1644 | 1667 |
1645 static void oscar_file_transfer_cancel(struct gaim_connection *gc, | 1668 /* |
1646 struct file_transfer *xfer) { | 1669 * This is called when the user began a file transfer, but subsequently canceled. |
1670 */ | |
1671 static void oscar_file_transfer_cancel(struct gaim_connection *gc, struct file_transfer *xfer) { | |
1647 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | 1672 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
1648 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); | 1673 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); |
1649 | 1674 |
1650 if (oft->type == OFT_SENDFILE_IN) | 1675 if (oft->type == OFT_SENDFILE_IN) |
1651 aim_denytransfer(od->sess, oft->sn, oft->cookie, | 1676 aim_denytransfer(od->sess, oft->sn, oft->cookie, |
1910 GAIM_INPUT_READ, oscar_callback, | 1935 GAIM_INPUT_READ, oscar_callback, |
1911 oft->conn); | 1936 oft->conn); |
1912 return 0; | 1937 return 0; |
1913 } | 1938 } |
1914 | 1939 |
1940 /* Someone wants to send a file (or files) to us */ | |
1915 debug_printf("%s (%s) requests to send a file to %s\n", | 1941 debug_printf("%s (%s) requests to send a file to %s\n", |
1916 userinfo->sn, args->verifiedip, gc->username); | 1942 userinfo->sn, args->verifiedip, gc->username); |
1917 | 1943 |
1918 oft = g_new0(struct oscar_file_transfer, 1); | 1944 oft = g_new0(struct oscar_file_transfer, 1); |
1919 | 1945 |
2010 } | 2036 } |
2011 | 2037 |
2012 static int incomingim_chan4(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch4_args *args) { | 2038 static int incomingim_chan4(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch4_args *args) { |
2013 struct gaim_connection *gc = sess->aux_data; | 2039 struct gaim_connection *gc = sess->aux_data; |
2014 | 2040 |
2015 switch (args->type) | 2041 switch (args->type) { |
2016 { | |
2017 case 0x0001: { /* An almost-normal instant message. Mac ICQ sends this. It's peculiar. */ | 2042 case 0x0001: { /* An almost-normal instant message. Mac ICQ sends this. It's peculiar. */ |
2018 gchar *uin, *message; | 2043 gchar *uin, *message; |
2019 uin = g_strdup_printf("%lu", args->uin); | 2044 uin = g_strdup_printf("%lu", args->uin); |
2020 message = g_strdup(args->msg); | 2045 message = g_strdup(args->msg); |
2021 strip_linefeed(message); | 2046 strip_linefeed(message); |
2265 va_start(ap, fr); | 2290 va_start(ap, fr); |
2266 chan = (fu16_t)va_arg(ap, unsigned int); | 2291 chan = (fu16_t)va_arg(ap, unsigned int); |
2267 who = va_arg(ap, char *); | 2292 who = va_arg(ap, char *); |
2268 reason = (fu16_t)va_arg(ap, unsigned int); | 2293 reason = (fu16_t)va_arg(ap, unsigned int); |
2269 | 2294 |
2270 if (chan == 2) { | 2295 if (chan == 0x0002) { /* File transfer declined */ |
2271 char *cookie = va_arg(ap, char *); | 2296 char *cookie = va_arg(ap, char *); |
2272 va_end(ap); | 2297 return gaim_parse_clientauto_rend(sess, who, reason, cookie); |
2273 | 2298 } else if (chan == 0x0004) { /* ICQ message */ |
2274 return gaim_parse_clientauto_rend(sess, who, reason, | 2299 switch(reason) { |
2275 cookie); | 2300 case 0x0003: { /* Reply from an ICQ status message request */ |
2276 } | 2301 int state = (int)va_arg(ap, fu32_t); |
2277 | 2302 char *msg = va_arg(ap, char *); |
2278 switch(reason) { | 2303 char *status_msg = gaim_icq_status(state); |
2279 case 0x0003: { /* Reply from an ICQ status message request */ | 2304 char *dialog_msg, **splitmsg; |
2280 int state = (int)va_arg(ap, fu32_t); | 2305 struct oscar_data *od = gc->proto_data; |
2281 char *msg = va_arg(ap, char *); | 2306 GSList *l = od->evilhack; |
2282 char *status_msg = gaim_icq_status(state); | 2307 gboolean evilhack = FALSE; |
2283 char *dialog_msg, **splitmsg; | 2308 |
2284 struct oscar_data *od = gc->proto_data; | 2309 /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ |
2285 GSList *l = od->evilhack; | 2310 splitmsg = g_strsplit(msg, "\r\n", 0); |
2286 gboolean evilhack = FALSE; | 2311 |
2287 | 2312 /* If who is in od->evilhack, then we're just getting the away message, otherwise this |
2288 /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ | 2313 * will just get appended to the info box (which is already showing). */ |
2289 splitmsg = g_strsplit(msg, "\r\n", 0); | 2314 while (l) { |
2290 | 2315 char *x = l->data; |
2291 /* If who is in od->evilhack, then we're just getting the away message, otherwise this | 2316 if (!strcmp(x, normalize(who))) { |
2292 * will just get appended to the info box (which is already showing). */ | 2317 evilhack = TRUE; |
2293 while (l) { | 2318 g_free(x); |
2294 char *x = l->data; | 2319 od->evilhack = g_slist_remove(od->evilhack, x); |
2295 if (!strcmp(x, normalize(who))) { | 2320 break; |
2296 evilhack = TRUE; | 2321 } |
2297 g_free(x); | 2322 l = l->next; |
2298 od->evilhack = g_slist_remove(od->evilhack, x); | |
2299 break; | |
2300 } | 2323 } |
2301 l = l->next; | 2324 |
2302 } | 2325 if (evilhack) |
2303 | 2326 dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR>%s<BR>"), who, status_msg, g_strjoinv("<BR>", splitmsg)); |
2304 if (evilhack) | 2327 else |
2305 dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><BR>%s<BR>"), who, status_msg, g_strjoinv("<BR>", splitmsg)); | 2328 dialog_msg = g_strdup_printf(_("<B>Status:</B> %s<BR><HR>%s<BR>"), status_msg, g_strjoinv("<BR>", splitmsg)); |
2306 else | 2329 g_show_info_text(gc, who, 2, dialog_msg, NULL); |
2307 dialog_msg = g_strdup_printf(_("<B>Status:</B> %s<BR><HR><BR>%s<BR>"), status_msg, g_strjoinv("<BR>", splitmsg)); | 2330 |
2308 g_show_info_text(gc, who, 2, dialog_msg, NULL); | 2331 g_free(status_msg); |
2309 | 2332 g_free(dialog_msg); |
2310 g_free(status_msg); | 2333 g_strfreev(splitmsg); |
2311 g_free(dialog_msg); | 2334 } break; |
2312 g_strfreev(splitmsg); | 2335 |
2313 } break; | 2336 default: { |
2314 | 2337 debug_printf("Received an unknown client auto-response from %s. Type 0x%04x\n", who, reason); |
2315 default: { | 2338 } break; |
2316 debug_printf("Received an unknown client auto-response from %s. Type 0x%04x\n", who, reason); | 2339 } /* end of switch */ |
2317 } break; | 2340 |
2318 } | 2341 } /* end of if */ |
2342 | |
2319 va_end(ap); | 2343 va_end(ap); |
2320 | 2344 |
2321 return 1; | 2345 return 1; |
2322 } | 2346 } |
2323 | 2347 |
2528 prof = va_arg(ap, char *); | 2552 prof = va_arg(ap, char *); |
2529 va_end(ap); | 2553 va_end(ap); |
2530 | 2554 |
2531 if (!od->icq) { | 2555 if (!od->icq) { |
2532 g_snprintf(legend, sizeof legend, | 2556 g_snprintf(legend, sizeof legend, |
2533 _("<br><BODY BGCOLOR=WHITE><hr><I>Legend:</I><br><br>" | 2557 _("<BODY BGCOLOR=WHITE><hr><I>Legend:</I><br><br>" |
2534 "<IMG SRC=\"free_icon.gif\"> : Normal AIM User<br>" | 2558 "<IMG SRC=\"free_icon.gif\"> : Normal AIM User<br>" |
2535 "<IMG SRC=\"aol_icon.gif\"> : AOL User <br>" | 2559 "<IMG SRC=\"aol_icon.gif\"> : AOL User <br>" |
2536 "<IMG SRC=\"dt_icon.gif\"> : Trial AIM User <br>" | 2560 "<IMG SRC=\"dt_icon.gif\"> : Trial AIM User <br>" |
2537 "<IMG SRC=\"admin_icon.gif\"> : Administrator <br>" | 2561 "<IMG SRC=\"admin_icon.gif\"> : Administrator <br>" |
2538 "<IMG SRC=\"ab_icon.gif\"> : ActiveBuddy Interactive Agent<br>" | 2562 "<IMG SRC=\"ab_icon.gif\"> : ActiveBuddy Interactive Agent<br>" |
2561 _("Username : <B>%s</B> %s <BR>\n" | 2585 _("Username : <B>%s</B> %s <BR>\n" |
2562 "Warning Level : <B>%d %%</B><BR>\n" | 2586 "Warning Level : <B>%d %%</B><BR>\n" |
2563 "%s" | 2587 "%s" |
2564 "%s" | 2588 "%s" |
2565 "%s<BR>\n" | 2589 "%s<BR>\n" |
2566 "<HR><BR>\n"), | 2590 "<HR>\n"), |
2567 info->sn, images(info->flags), | 2591 info->sn, images(info->flags), |
2568 info->warnlevel/10, | 2592 info->warnlevel/10, |
2569 onlinesince ? onlinesince : "", | 2593 onlinesince ? onlinesince : "", |
2570 membersince ? membersince : "", | 2594 membersince ? membersince : "", |
2571 idle ? idle : ""); | 2595 idle ? idle : ""); |
2594 legend, NULL); | 2618 legend, NULL); |
2595 } else { | 2619 } else { |
2596 g_show_info_text(gc, info->sn, 0, | 2620 g_show_info_text(gc, info->sn, 0, |
2597 header, | 2621 header, |
2598 (prof && *prof) ? away_subs(prof, gc->username) : NULL, | 2622 (prof && *prof) ? away_subs(prof, gc->username) : NULL, |
2599 (prof && *prof) ? "<BR><HR><BR>" : NULL, | 2623 (prof && *prof) ? "<BR><HR>" : NULL, |
2600 NULL); | 2624 NULL); |
2601 } | 2625 } |
2602 } else if (infotype == AIM_GETINFO_CAPABILITIES) { | 2626 } else if (infotype == AIM_GETINFO_CAPABILITIES) { |
2603 g_show_info_text(gc, info->sn, 2, | 2627 g_show_info_text(gc, info->sn, 2, |
2604 header, | 2628 header, |
3088 | 3112 |
3089 debug_printf("buddy list loaded\n"); | 3113 debug_printf("buddy list loaded\n"); |
3090 | 3114 |
3091 aim_clientready(sess, fr->conn); | 3115 aim_clientready(sess, fr->conn); |
3092 | 3116 |
3117 /* XXX - Should call aim_bos_setidle with 0x0000 */ | |
3118 | |
3119 /* XXX - Should only call reqofflinemsgs when using ICQ? */ | |
3093 aim_icq_reqofflinemsgs(sess); | 3120 aim_icq_reqofflinemsgs(sess); |
3094 | 3121 |
3095 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV); | 3122 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV); |
3096 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_EMAIL); | 3123 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_EMAIL); |
3097 | 3124 |
3196 if ((budlight->uc >> 16) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT)) { | 3223 if ((budlight->uc >> 16) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT)) { |
3197 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) | 3224 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) |
3198 g_show_info_text(gc, who, 0, buf, NULL); | 3225 g_show_info_text(gc, who, 0, buf, NULL); |
3199 else { | 3226 else { |
3200 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); | 3227 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); |
3201 g_show_info_text(gc, who, 2, buf, "<B>Status:</B> ", state_msg, "<BR>\n<HR><BR><I>Remote client does not support sending status messages.</I><BR>\n", NULL); | 3228 g_show_info_text(gc, who, 2, buf, "<B>Status:</B> ", state_msg, "<BR>\n<HR><I>Remote client does not support sending status messages.</I><BR>\n", NULL); |
3202 free(state_msg); | 3229 free(state_msg); |
3203 } | 3230 } |
3204 } else { | 3231 } else { |
3205 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); | 3232 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); |
3206 g_show_info_text(gc, who, 2, buf, "<B>Status:</B> ", state_msg, NULL); | 3233 g_show_info_text(gc, who, 2, buf, "<B>Status:</B> ", state_msg, NULL); |
3388 int ret = 0; | 3415 int ret = 0; |
3389 GError *err = NULL; | 3416 GError *err = NULL; |
3390 | 3417 |
3391 if (dim) { | 3418 if (dim) { |
3392 if (dim->connected) { /* If we're not connected yet, send through server */ | 3419 if (dim->connected) { /* If we're not connected yet, send through server */ |
3393 ret = aim_send_im_direct(odata->sess, dim->conn, message, len == -1 ? strlen(message) : len); | 3420 /* AAA - The last parameter below is the encoding. Let Paco-Paco do something with it. */ |
3421 ret = aim_send_im_direct(odata->sess, dim->conn, message, len == -1 ? strlen(message) : len, 0); | |
3394 if (ret == 0) | 3422 if (ret == 0) |
3395 return 1; | 3423 return 1; |
3396 else return ret; | 3424 else return ret; |
3397 } | 3425 } |
3398 debug_printf("Direct IM pending, but not connected; sending through server\n"); | 3426 debug_printf("Direct IM pending, but not connected; sending through server\n"); |
4183 if (uc & UC_NORMAL) | 4211 if (uc & UC_NORMAL) |
4184 return (char **)free_icon_xpm; | 4212 return (char **)free_icon_xpm; |
4185 return NULL; | 4213 return NULL; |
4186 } | 4214 } |
4187 | 4215 |
4216 /* | |
4217 * This is called after the raw data for a file has been transferred (whether | |
4218 * we are sending or receiving), but there are other files remaining. | |
4219 */ | |
4188 void oscar_file_transfer_nextfile(struct gaim_connection *gc, | 4220 void oscar_file_transfer_nextfile(struct gaim_connection *gc, |
4189 struct file_transfer *xfer) { | 4221 struct file_transfer *xfer) { |
4190 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); | 4222 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); |
4191 aim_conn_t *conn = oft->conn; | 4223 aim_conn_t *conn = oft->conn; |
4192 aim_session_t *sess = aim_conn_getsess(conn); | 4224 aim_session_t *sess = aim_conn_getsess(conn); |
4204 | 4236 |
4205 if (oft->type == OFT_SENDFILE_IN) | 4237 if (oft->type == OFT_SENDFILE_IN) |
4206 aim_oft_end(sess, conn); | 4238 aim_oft_end(sess, conn); |
4207 } | 4239 } |
4208 | 4240 |
4241 /* | |
4242 * This is called after the raw data for a file has been transferred (whether | |
4243 * we are sending or receiving), and it is the last file in the set, so we | |
4244 * can tear down the connection. | |
4245 */ | |
4209 void oscar_file_transfer_done(struct gaim_connection *gc, | 4246 void oscar_file_transfer_done(struct gaim_connection *gc, |
4210 struct file_transfer *xfer) { | 4247 struct file_transfer *xfer) { |
4211 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); | 4248 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); |
4212 aim_conn_t *conn = oft->conn; | 4249 aim_conn_t *conn = oft->conn; |
4213 aim_session_t *sess = aim_conn_getsess(conn); | 4250 aim_session_t *sess = aim_conn_getsess(conn); |
4222 oft->watcher = gaim_input_add(conn->fd, GAIM_INPUT_READ, | 4259 oft->watcher = gaim_input_add(conn->fd, GAIM_INPUT_READ, |
4223 oscar_callback, conn); | 4260 oscar_callback, conn); |
4224 } | 4261 } |
4225 } | 4262 } |
4226 | 4263 |
4264 /* | |
4265 * This is called when there is raw data ready to be sent or received; all the | |
4266 * protocol details have been taken care of. | |
4267 */ | |
4227 static int oscar_file_transfer_do(aim_session_t *sess, aim_frame_t *fr, ...) { | 4268 static int oscar_file_transfer_do(aim_session_t *sess, aim_frame_t *fr, ...) { |
4228 struct gaim_connection *gc = sess->aux_data; | 4269 struct gaim_connection *gc = sess->aux_data; |
4229 va_list ap; | 4270 va_list ap; |
4230 aim_conn_t *conn; | 4271 aim_conn_t *conn; |
4231 struct oscar_file_transfer *oft; | 4272 struct oscar_file_transfer *oft; |
4242 /* Don't use the regular input handler for the raw data. */ | 4283 /* Don't use the regular input handler for the raw data. */ |
4243 gaim_input_remove(oft->watcher); | 4284 gaim_input_remove(oft->watcher); |
4244 oft->watcher = 0; | 4285 oft->watcher = 0; |
4245 | 4286 |
4246 if (oft->type == OFT_SENDFILE_IN) { | 4287 if (oft->type == OFT_SENDFILE_IN) { |
4247 err = transfer_in_do(oft->xfer, conn->fd, | 4288 /* AAA convert fh->name from UCS-2 to UTF-8 if (fh->nencode == 0x0002) */ |
4248 fh->name, fh->size); | 4289 err = transfer_in_do(oft->xfer, conn->fd, fh->name, fh->size); |
4249 } | 4290 } |
4250 else { | 4291 else { |
4251 err = transfer_out_do(oft->xfer, conn->fd, fh->nrecvd); | 4292 err = transfer_out_do(oft->xfer, conn->fd, fh->nrecvd); |
4252 } | 4293 } |
4253 | 4294 |
4338 } | 4379 } |
4339 | 4380 |
4340 static int gaim_directim_incoming(aim_session_t *sess, aim_frame_t *fr, ...) { | 4381 static int gaim_directim_incoming(aim_session_t *sess, aim_frame_t *fr, ...) { |
4341 va_list ap; | 4382 va_list ap; |
4342 char *msg, *sn; | 4383 char *msg, *sn; |
4343 int len; | 4384 int len, encoding; |
4344 struct gaim_connection *gc = sess->aux_data; | 4385 struct gaim_connection *gc = sess->aux_data; |
4345 | 4386 |
4346 va_start(ap, fr); | 4387 va_start(ap, fr); |
4347 sn = va_arg(ap, char *); | 4388 sn = va_arg(ap, char *); |
4348 msg = va_arg(ap, char *); | 4389 msg = va_arg(ap, char *); |
4349 len = va_arg(ap, int); | 4390 len = va_arg(ap, int); |
4391 encoding = va_arg(ap, int); | |
4350 va_end(ap); | 4392 va_end(ap); |
4351 | 4393 |
4352 debug_printf("Got DirectIM message from %s\n", sn); | 4394 debug_printf("Got DirectIM message from %s\n", sn); |
4353 | 4395 |
4396 /* AAA - I imagine Paco-Paco will want to do some voodoo with the encoding here */ | |
4354 serv_got_im(gc, sn, msg, 0, time(NULL), len); | 4397 serv_got_im(gc, sn, msg, 0, time(NULL), len); |
4355 | 4398 |
4356 return 1; | 4399 return 1; |
4357 } | 4400 } |
4358 | 4401 |
4437 if ((budlight->uc >> 16) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT)) | 4480 if ((budlight->uc >> 16) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT)) |
4438 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) | 4481 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) |
4439 aim_send_im_ch2_geticqmessage(od->sess, who, (budlight->uc & 0xffff0000) >> 16); | 4482 aim_send_im_ch2_geticqmessage(od->sess, who, (budlight->uc & 0xffff0000) >> 16); |
4440 else { | 4483 else { |
4441 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); | 4484 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); |
4442 char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><BR><I>Remote client does not support sending status messages.</I><BR>"), who, state_msg); | 4485 char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><I>Remote client does not support sending status messages.</I><BR>"), who, state_msg); |
4443 g_show_info_text(gc, who, 2, dialog_msg, NULL); | 4486 g_show_info_text(gc, who, 2, dialog_msg, NULL); |
4444 free(state_msg); | 4487 free(state_msg); |
4445 free(dialog_msg); | 4488 free(dialog_msg); |
4446 } | 4489 } |
4447 else { | 4490 else { |
4448 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); | 4491 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); |
4449 char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><BR><I>User has no status message.</I><BR>"), who, state_msg); | 4492 char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><I>User has no status message.</I><BR>"), who, state_msg); |
4450 g_show_info_text(gc, who, 2, dialog_msg, NULL); | 4493 g_show_info_text(gc, who, 2, dialog_msg, NULL); |
4451 free(state_msg); | 4494 free(state_msg); |
4452 free(dialog_msg); | 4495 free(dialog_msg); |
4453 } | 4496 } |
4454 else | 4497 else |