Mercurial > pidgin.yaz
diff src/oscar.c @ 1535:1e2cc8c8bf3c
[gaim-migrate @ 1545]
libfaim updates.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Mon, 05 Mar 2001 03:59:32 +0000 |
parents | d98b92e3d9ff |
children | 2157d91c2eb9 |
line wrap: on
line diff
--- a/src/oscar.c Sun Mar 04 22:37:18 2001 +0000 +++ b/src/oscar.c Mon Mar 05 03:59:32 2001 +0000 @@ -40,7 +40,7 @@ #include "multi.h" #include "prpl.h" #include "gaim.h" -#include "faim/aim.h" +#include "aim.h" #include "pixmaps/cancel.xpm" #include "pixmaps/admin_icon.xpm" @@ -61,12 +61,18 @@ struct aim_session_t *sess; struct aim_conn_t *conn; - int cnpa; - int paspa; + guint cnpa; + guint paspa; int create_exchange; char *create_name; + gboolean conf; + gboolean reqemail; + gboolean chpass; + char *oldp; + char *newp; + GSList *oscar_chats; GSList *direct_ims; GSList *getfiles; @@ -183,21 +189,6 @@ return c; } -static struct gaim_connection *find_gaim_conn_by_aim_sess(struct aim_session_t *sess) { - GSList *g = connections; - struct gaim_connection *gc = NULL; - - while (g) { - gc = (struct gaim_connection *)g->data; - if (sess == ((struct oscar_data *)gc->proto_data)->sess) - break; - g = g->next; - gc = NULL; - } - - return gc; -} - static struct gaim_connection *find_gaim_conn_by_oscar_conn(struct aim_conn_t *conn) { GSList *g = connections; struct gaim_connection *c = NULL; @@ -227,6 +218,8 @@ static int gaim_parse_login (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_server_ready (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_handle_redirect (struct aim_session_t *, struct command_rx_struct *, ...); +static int gaim_info_change (struct aim_session_t *, struct command_rx_struct *, ...); +static int gaim_account_confirm (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_parse_oncoming (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_parse_offgoing (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_parse_incoming_im(struct aim_session_t *, struct command_rx_struct *, ...); @@ -241,6 +234,8 @@ static int gaim_parse_msgack (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_parse_ratechange (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_parse_evilnotify (struct aim_session_t *, struct command_rx_struct *, ...); +static int gaim_parse_searcherror(struct aim_session_t *, struct command_rx_struct *, ...); +static int gaim_parse_searchreply(struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_bosrights (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_rateresp (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_reportinterval (struct aim_session_t *, struct command_rx_struct *, ...); @@ -320,19 +315,25 @@ char buf[BUF_LONG]; debug_printf("disconnected from chat room %s\n", c->name); c->conn = NULL; - if (c->inpa > -1) + if (c->inpa > 0) gdk_input_remove(c->inpa); - c->inpa = -1; + c->inpa = 0; c->fd = -1; aim_conn_kill(odata->sess, &conn); sprintf(buf, _("You have been disconnected from chat room %s."), c->name); do_error_dialog(buf, _("Chat Error!")); } else if (conn->type == AIM_CONN_TYPE_CHATNAV) { - if (odata->cnpa > -1) + if (odata->cnpa > 0) gdk_input_remove(odata->cnpa); - odata->cnpa = -1; + odata->cnpa = 0; debug_printf("removing chatnav input watcher\n"); aim_conn_kill(odata->sess, &conn); + } else if (conn->type == AIM_CONN_TYPE_AUTH) { + if (odata->paspa > 0) + gdk_input_remove(odata->paspa); + odata->paspa = 0; + debug_printf("removing authconn input watcher\n"); + aim_conn_kill(odata->sess, &conn); } else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) { debug_printf("No handler for rendezvous disconnect (%d).\n", source); @@ -347,6 +348,21 @@ } } +static void oscar_debug(struct aim_session_t *sess, int level, const char *format, va_list va) { + char *s = g_strdup_vprintf(format, va); + char buf[256]; + char *t; + struct gaim_connection *gc = sess->aux_data; + + g_snprintf(buf, sizeof(buf), "%s %d: ", gc->username, level); + t = g_strconcat(buf, s, NULL); + debug_printf(t); + if (t[strlen(t)-1] != '\n') + debug_printf("\n"); + g_free(t); + g_free(s); +} + void oscar_login(struct aim_user *user) { struct aim_session_t *sess; struct aim_conn_t *conn; @@ -360,7 +376,8 @@ sess = g_new0(struct aim_session_t, 1); - aim_session_init(sess, AIM_SESS_FLAGS_NONBLOCKCONNECT); + aim_session_init(sess, AIM_SESS_FLAGS_NONBLOCKCONNECT, 0); + aim_setdebuggingcb(sess, oscar_debug); if (user->proto_opt[USEROPT_SOCKSHOST][0]) { char *finalproxy; @@ -383,8 +400,9 @@ /* we need an immediate queue because we don't use a while-loop to * see if things need to be sent. */ - sess->tx_enqueue = &aim_tx_enqueue__immediate; + aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL); odata->sess = sess; + sess->aux_data = gc; conn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, finalauth ? finalauth : FAIM_LOGIN_SERVER); @@ -459,7 +477,7 @@ char *latestreleaseurl = NULL, *latestbetaurl = NULL; char *latestreleaseinfo = NULL, *latestbetainfo = NULL; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_start(ap, command); sn = va_arg(ap, char *); @@ -555,11 +573,11 @@ aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, gaim_parse_misses, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, gaim_parse_ratechange, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, gaim_parse_evilnotify, 0); + aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, gaim_parse_searcherror, 0); + aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, 0x0003, gaim_parse_searchreply, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, gaim_parse_msgerr, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parse_user_info, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, gaim_parse_msgack, 0); - aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_CTN, AIM_CB_CTN_DEFAULT, aim_parse_unknown, 0); - aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0); aim_conn_addhandler(sess, bosconn, 0x0001, 0x0001, gaim_parse_genericerr, 0); aim_conn_addhandler(sess, bosconn, 0x0003, 0x0001, gaim_parse_genericerr, 0); @@ -578,7 +596,7 @@ struct client_info_s info = {"AOL Instant Messenger (SM), version 4.1.2010/WIN32", 4, 30, 3141, "us", "en", 0x0004, 0x0001, 0x055}; char *key; va_list ap; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_start(ap, command); key = va_arg(ap, char *); @@ -591,9 +609,32 @@ int gaim_server_ready(struct aim_session_t *sess, struct command_rx_struct *command, ...) { static int id = 1; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; + struct oscar_data *od = gc->proto_data; struct chat_connection *chatcon; switch (command->conn->type) { + case AIM_CONN_TYPE_AUTH: + aim_auth_setversions(sess, command->conn); + aim_bos_reqrate(sess, command->conn); + debug_printf("done with AUTH ServerReady\n"); + if (od->chpass) { + debug_printf("changing password\n"); + aim_auth_changepasswd(sess, command->conn, od->newp, od->oldp); + g_free(od->oldp); + g_free(od->newp); + od->chpass = FALSE; + } + if (od->conf) { + debug_printf("confirming account\n"); + aim_auth_reqconfirm(sess, command->conn); + od->conf = FALSE; + } + if (od->reqemail) { + debug_printf("requesting email\n"); + aim_auth_getinfo(sess, command->conn, 0x0011); + od->reqemail = FALSE; + } + break; case AIM_CONN_TYPE_BOS: aim_setversions(sess, command->conn); aim_bos_reqrate(sess, command->conn); /* request rate info */ @@ -635,7 +676,7 @@ int serviceid; char *ip; unsigned char *cookie; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *odata = (struct oscar_data *)gc->proto_data; va_start(ap, command); @@ -651,6 +692,11 @@ if (tstconn == NULL || tstconn->status & AIM_CONN_STATUS_RESOLVERR) debug_printf("unable to reconnect with authorizer\n"); else { + aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0); + aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, gaim_rateresp, 0); + aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, gaim_info_change, 0); + aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, gaim_info_change, 0); + aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, gaim_account_confirm, 0); odata->paspa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, tstconn); @@ -716,7 +762,7 @@ struct aim_userinfo_s *info; time_t time_idle; int type = 0; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_list ap; va_start(ap, command); @@ -750,7 +796,7 @@ struct command_rx_struct *command, ...) { char *sn; va_list ap; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_start(ap, command); sn = va_arg(ap, char *); @@ -834,6 +880,7 @@ return TRUE; } +/* static void cancel_getfile(gpointer w, struct ask_getfile *g) { g_free(g->ip); g_free(g->cookie); @@ -869,7 +916,7 @@ } static int gaim_getfile_filereq(struct aim_session_t *sess, struct command_rx_struct *command, ...) { - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = (struct oscar_data *)gc->proto_data; struct getfile_transfer *gt; char buf[2048]; @@ -935,7 +982,7 @@ } static int gaim_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...) { - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = (struct oscar_data *)gc->proto_data; struct getfile_transfer *gt; @@ -971,7 +1018,7 @@ } static int gaim_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...) { - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = (struct oscar_data *)gc->proto_data; struct getfile_transfer *gt; @@ -994,7 +1041,7 @@ } static int gaim_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...) { - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = (struct oscar_data *)gc->proto_data; struct getfile_transfer *gt; @@ -1117,12 +1164,13 @@ return TRUE; } +*/ int gaim_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...) { int channel; va_list ap; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_start(ap, command); channel = va_arg(ap, int); @@ -1166,6 +1214,7 @@ msg); } else if (rendtype & AIM_CAPS_SENDFILE) { } else if (rendtype & AIM_CAPS_GETFILE) { + /* char *ip, *cookie; struct ask_getfile *g = g_new0(struct ask_getfile, 1); char buf[256]; @@ -1185,6 +1234,7 @@ g_snprintf(buf, sizeof buf, "%s has just asked to get a file from %s.", userinfo->sn, gc->username); do_ask_dialog(buf, g, accept_getfile, cancel_getfile); + */ } else if (rendtype & AIM_CAPS_VOICE) { } else if (rendtype & AIM_CAPS_BUDDYICON) { } else if (rendtype & AIM_CAPS_IMIMAGE) { @@ -1302,7 +1352,7 @@ char *prof_enc = NULL, *prof = NULL; u_short infotype; char buf[BUF_LONG]; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_list ap; va_start(ap, command); @@ -1362,7 +1412,7 @@ struct command_rx_struct *command, ...) { va_list ap; u_short type; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *odata = (struct oscar_data *)gc->proto_data; va_start(ap, command); @@ -1435,7 +1485,7 @@ va_list ap; int count, i = 0; struct aim_userinfo_s *info; - struct gaim_connection *g = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *g = sess->aux_data; GSList *bcs = g->buddy_chats; struct conversation *b = NULL; @@ -1466,7 +1516,7 @@ va_list ap; int count, i = 0; struct aim_userinfo_s *info; - struct gaim_connection *g = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *g = sess->aux_data; GSList *bcs = g->buddy_chats; struct conversation *b = NULL; @@ -1503,7 +1553,7 @@ va_list ap; struct aim_userinfo_s *info; char *msg; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; GSList *bcs = gc->buddy_chats; struct conversation *b = NULL; @@ -1595,7 +1645,7 @@ va_list ap; int newevil; struct aim_userinfo_s *userinfo; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_start(ap, command); newevil = va_arg(ap, int); @@ -1608,7 +1658,7 @@ } int gaim_rateresp(struct aim_session_t *sess, struct command_rx_struct *command, ...) { - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; switch (command->conn->type) { case AIM_CONN_TYPE_BOS: aim_bos_ackrateresp(sess, command->conn); @@ -1634,6 +1684,11 @@ AIM_PRIVFLAGS_ALLOWMEMBERSINCE); break; + case AIM_CONN_TYPE_AUTH: + aim_bos_ackrateresp(sess, command->conn); + aim_auth_clientready(sess, command->conn); + debug_printf("connected to auth (admin)\n"); + break; default: debug_printf("got rate response for unhandled connection type %04x\n", command->conn->type); @@ -1683,6 +1738,96 @@ return 1; } +int gaim_parse_searchreply(struct aim_session_t *sess, struct command_rx_struct *command, ...) { + va_list ap; + char *address, *SNs; + int i, num; + char *buf; + int at = 0, len; + + va_start(ap, command); + address = va_arg(ap, char *); + num = va_arg(ap, int); + SNs = va_arg(ap, char *); + va_end(ap); + + len = num * (MAXSNLEN + 1) + 1024; + buf = g_malloc(len); + at += g_snprintf(buf + at, len - at, "<B>%s has the following screen names:</B><BR>", address); + for (i = 0; i < num; i++) + at += g_snprintf(buf + at, len - at, "%s<BR>", &SNs[i * (MAXSNLEN + 1)]); + g_show_info_text(buf); + g_free(buf); + + return 1; +} + +int gaim_parse_searcherror(struct aim_session_t *sess, struct command_rx_struct *command, ...) { + va_list ap; + char *address; + char buf[BUF_LONG]; + + va_start(ap, command); + address = va_arg(ap, char *); + va_end(ap); + + g_snprintf(buf, sizeof(buf), "No results found for email address %s", address); + do_error_dialog(buf, _("Error")); + + return 1; +} + +int gaim_account_confirm(struct aim_session_t *sess, struct command_rx_struct *command, ...) { + int status; + va_list ap; + char msg[256]; + struct gaim_connection *gc = sess->aux_data; + + va_start(ap, command); + status = va_arg(ap, int); /* status code of confirmation request */ + va_end(ap); + + debug_printf("account confirmation returned status 0x%04x (%s)\n", status, + status ? "email sent" : "unknown"); + if (status) { + g_snprintf(msg, sizeof(msg), "You should receive an email asking to confirm %s.", + gc->username); + do_error_dialog(msg, "Confirm"); + } + + return 1; +} + +int gaim_info_change(struct aim_session_t *sess, struct command_rx_struct *command, ...) { + unsigned short change = 0; + int perms, type, length, str; + char *val; + va_list ap; + char buf[BUF_LONG]; + struct gaim_connection *gc = sess->aux_data; + + va_start(ap, command); + perms = va_arg(ap, int); + type = va_arg(ap, int); + length = va_arg(ap, int); + val = va_arg(ap, char *); + str = va_arg(ap, int); + va_end(ap); + + if (aimutil_get16(command->data+2) == 0x0005) + change = 1; + + debug_printf("info%s: perms = %d, type = %x, length = %d, val = %s\n", + change ? " change" : "", perms, type, length, str ? val : "(not string)"); + + if ((type == 0x0011) && str) { + g_snprintf(buf, sizeof(buf), "The email address for %s is %s", gc->username, val); + do_error_dialog(buf, "Email"); + } + + return 1; +} + static void oscar_keepalive(struct gaim_connection *gc) { struct oscar_data *odata = (struct oscar_data *)gc->proto_data; aim_flap_nop(odata->sess, odata->conn); @@ -1903,7 +2048,7 @@ static int gaim_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...) { va_list ap; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = (struct oscar_data *)gc->proto_data; struct aim_directim_priv *priv; struct aim_conn_t *newconn; @@ -1944,7 +2089,7 @@ va_list ap; char *sn = NULL, *msg = NULL; struct aim_conn_t *conn; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; va_start(ap, command); conn = va_arg(ap, struct aim_conn_t *); @@ -1963,7 +2108,7 @@ va_list ap; struct aim_conn_t *conn; char *sn; - struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); + struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = (struct oscar_data *)gc->proto_data; struct direct_im *dim; char buf[256]; @@ -2281,8 +2426,27 @@ static void oscar_do_action(struct gaim_connection *gc, char *act) { + struct oscar_data *od = gc->proto_data; + if (!strcmp(act, "Set User Info")) { show_set_info(gc); + } else if (!strcmp(act, "Change Password")) { + show_change_passwd(gc); + } else if (!strcmp(act, "Confirm Account")) { + if (od->paspa == 0) { + od->conf = TRUE; + aim_bos_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH); + } else + aim_auth_reqconfirm(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH)); + } else if (!strcmp(act, "Change Email")) { + } else if (!strcmp(act, "Display Current Registered Address")) { + if (od->paspa == 0) { + od->reqemail = TRUE; + aim_bos_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH); + } else + aim_auth_getinfo(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH), 0x11); + } else if (!strcmp(act, "Search for Buddy by Email")) { + show_find_email(gc); } } @@ -2291,10 +2455,33 @@ GList *m = NULL; m = g_list_append(m, "Set User Info"); + m = g_list_append(m, NULL); + m = g_list_append(m, "Change Password"); + m = g_list_append(m, "Confirm Account"); + /* + m = g_list_append(m, "Change Email"); + */ + m = g_list_append(m, "Display Current Registered Address"); + m = g_list_append(m, NULL); + m = g_list_append(m, "Search for Buddy by Email"); return m; } +static void oscar_change_passwd(struct gaim_connection *gc, char *old, char *new) +{ + struct oscar_data *od = gc->proto_data; + if (od->paspa == 0) { + od->chpass = TRUE; + od->oldp = g_strdup(old); + od->newp = g_strdup(new); + aim_bos_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH); + } else { + aim_auth_changepasswd(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH), + new, old); + } +} + void oscar_init(struct prpl *ret) { ret->protocol = PROTO_OSCAR; ret->options = OPT_PROTO_HTML | OPT_PROTO_CORRECT_TIME; @@ -2318,7 +2505,7 @@ ret->get_dir = NULL; /* Oscar really doesn't have this */ ret->dir_search = oscar_dir_search; ret->set_idle = oscar_set_idle; - ret->change_passwd = NULL; /* Oscar doesn't have this either */ + ret->change_passwd = oscar_change_passwd; ret->add_buddy = oscar_add_buddy; ret->add_buddies = oscar_add_buddies; ret->remove_buddy = oscar_remove_buddy;