Mercurial > pidgin
diff src/protocols/yahoo/yay.c @ 2086:424a40f12a6c
[gaim-migrate @ 2096]
moving protocols from plugins/ to src/protocols. making it so that you can select which protocols are compiled statically.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Tue, 31 Jul 2001 01:00:39 +0000 |
parents | |
children | b66aca8e8dce |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/yahoo/yay.c Tue Jul 31 01:00:39 2001 +0000 @@ -0,0 +1,978 @@ +/* + * gaim + * + * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net> + * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include <netdb.h> +#include <gtk/gtk.h> +#include <unistd.h> +#include <errno.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include "multi.h" +#include "prpl.h" +#include "gaim.h" +#include "yay.h" +#include "proxy.h" + +#include "pixmaps/status-away.xpm" +#include "pixmaps/status-here.xpm" +#include "pixmaps/status-idle.xpm" + +#include "pixmaps/cancel.xpm" + +#define USEROPT_MAIL 0 + +#define USEROPT_AUTHHOST 1 +#define USEROPT_AUTHPORT 2 +#define USEROPT_PAGERHOST 3 +#define USEROPT_PAGERPORT 4 + +struct conn { + int socket; + int type; + int inpa; +}; + +struct connect { + struct yahoo_session *sess; + gpointer data; +}; + +struct yahoo_data { + struct yahoo_session *sess; + int current_status; + GHashTable *hash; + GtkWidget *email_win; + GtkWidget *email_label; + char *active_id; + GList *conns; + gboolean logged_in; + GSList *offline; +}; + +static char *yahoo_name() { + return "Yahoo"; +} + +static int yahoo_status(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + time_t tmptime; + struct buddy *b; + gboolean online; + + va_list ap; + char *who; + int status; + char *msg; + int in_pager, in_chat, in_game; + + va_start(ap, sess); + who = va_arg(ap, char *); + status = va_arg(ap, int); + msg = va_arg(ap, char *); + in_pager = va_arg(ap, int); + in_chat = va_arg(ap, int); + in_game = va_arg(ap, int); + va_end(ap); + + online = in_pager || in_chat || in_game; + + b = find_buddy(gc, who); + if (!b) return 0; + if (!online) + serv_got_update(gc, b->name, 0, 0, 0, 0, 0, 0); + else { + if (status == YAHOO_STATUS_AVAILABLE) + serv_got_update(gc, b->name, 1, 0, 0, 0, UC_NORMAL, 0); + else if (status == YAHOO_STATUS_IDLE) { + time(&tmptime); + serv_got_update(gc, b->name, 1, 0, 0, tmptime - 600, + (status << 5) | UC_NORMAL, 0); + } else + serv_got_update(gc, b->name, 1, 0, 0, 0, + (status << 5) | UC_UNAVAILABLE, 0); + if (status == YAHOO_STATUS_CUSTOM) { + gpointer val = g_hash_table_lookup(yd->hash, b->name); + if (val) + g_free(val); + g_hash_table_insert(yd->hash, g_strdup(b->name), g_strdup(msg)); + } + } + + return 1; +} + +static int yahoo_message(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + char buf[BUF_LEN * 4]; + char *tmp, *c, *e; + time_t tm; + int at = 0; + + va_list ap; + char *id, *nick, *msg; + + va_start(ap, sess); + id = va_arg(ap, char *); + nick = va_arg(ap, char *); + tm = va_arg(ap, time_t); + msg = va_arg(ap, char *); + va_end(ap); + + if (msg) + e = tmp = g_strdup(msg); + else + return 1; + + while ((c = strchr(e, '\033')) != NULL) { + *c++ = '\0'; + at += g_snprintf(buf + at, sizeof(buf) - at, "%s", e); + e = ++c; + while (*e && (*e++ != 'm')); + } + + if (*e) + g_snprintf(buf + at, sizeof(buf) - at, "%s", e); + + g_free(tmp); + + serv_got_im(gc, nick, buf, 0, tm ? tm : time((time_t)NULL)); + + return 1; +} + +static int yahoo_bounce(struct yahoo_session *sess, ...) { + do_error_dialog(_("Your message did not get sent."), _("Gaim - Error")); + + return 1; +} + +static int yahoo_buddyadded(struct yahoo_session *sess, ...) { + va_list ap; + char *id; + char *who; + char *msg; + char buf[2048]; + + va_start(ap, sess); + id = va_arg(ap, char *); + who = va_arg(ap, char *); + msg = va_arg(ap, char *); + va_end(ap); + + g_snprintf(buf, sizeof(buf), _("%s has made %s their buddy%s%s"), who, id, + msg ? ": " : "", msg ? msg : ""); + do_error_dialog(buf, _("Gaim - Buddy")); + + return 1; +} + +static void des_win(GtkWidget *w, struct yahoo_data *yd) { + gtk_widget_destroy(yd->email_win); + if (yd->email_win == w) + yd->email_win = NULL; + yd->email_label = NULL; +} + +static int yahoo_newmail(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + char buf[2048]; + + va_list ap; + int count; + + va_start(ap, sess); + count = va_arg(ap, int); + va_end(ap); + + if (gc->user->proto_opt[USEROPT_MAIL][0] != '1') + return 1; + + if (count) { + g_snprintf(buf, sizeof buf, "%s has %d new message%s on Yahoo Mail.", + gc->username, count, count == 1 ? "" : "s"); + if (!yd->email_win) { + GtkWidget *close; + + yd->email_win = gtk_dialog_new(); + gtk_window_set_policy(GTK_WINDOW(yd->email_win), 0, 0, 1); + gtk_container_set_border_width(GTK_CONTAINER(yd->email_win), 5); + gtk_window_set_title(GTK_WINDOW(yd->email_win), "New Mail"); + gtk_signal_connect(GTK_OBJECT(yd->email_win), "destroy", + GTK_SIGNAL_FUNC(des_win), yd); + gtk_widget_realize(yd->email_win); + aol_icon(yd->email_win->window); + + yd->email_label = gtk_label_new(buf); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(yd->email_win)->vbox), + yd->email_label, 0, 0, 5); + gtk_widget_show(yd->email_label); + + close = picture_button(yd->email_win, _("Close"), cancel_xpm); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(yd->email_win)->action_area), + close, 0, 0, 5); + gtk_signal_connect(GTK_OBJECT(close), "clicked", GTK_SIGNAL_FUNC(des_win), yd); + + gtk_widget_show(yd->email_win); + } + gtk_label_set_text(GTK_LABEL(yd->email_label), buf); + } else if (yd->email_win) + gtk_widget_destroy(yd->email_win); + + return 1; +} + +static int yahoo_disconn(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + hide_login_progress(gc, "Disconnected"); + signoff(gc); + return 1; +} + +static int yahoo_authconnect(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + + set_login_progress(gc, 2, "Connected to Auth"); + if (yahoo_send_login(sess, gc->username, gc->password) < 1) { + hide_login_progress(gc, "Authorizer error"); + signoff(gc); + } + + return 1; +} + +static int yahoo_badpassword(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + hide_login_progress(gc, "Bad Password"); + signoff(gc); + return 1; +} + +static int yahoo_logincookie(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + + set_login_progress(gc, 3, "Got login cookie"); + if (yahoo_major_connect(sess, gc->user->proto_opt[USEROPT_PAGERHOST], + atoi(gc->user->proto_opt[USEROPT_PAGERPORT])) < 1) { + hide_login_progress(gc, "Login error"); + signoff(gc); + } + + return 1; +} + +static int yahoo_mainconnect(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + struct yahoo_data *yd = gc->proto_data; + GList *grps; + + set_login_progress(gc, 4, "Connected to service"); + if (yahoo_finish_logon(sess, YAHOO_STATUS_AVAILABLE) < 1) { + hide_login_progress(gc, "Login error"); + signoff(gc); + } + + if (bud_list_cache_exists(gc)) + do_import(NULL, gc); + + grps = yd->sess->groups; + while (grps) { + struct yahoo_group *grp = grps->data; + int i; + + for (i = 0; grp->buddies[i]; i++) + add_buddy(gc, grp->name, grp->buddies[i], NULL); + + grps = grps->next; + } + + return 1; +} + +static int yahoo_online(struct yahoo_session *sess, ...) { + struct gaim_connection *gc = sess->user_data; + struct yahoo_data *yd = gc->proto_data; + + account_online(gc); + serv_finish_login(gc); + yd->active_id = g_strdup(gc->username); + yd->logged_in = TRUE; + + return 1; +} + +static void yahoo_pending(gpointer data, gint source, GdkInputCondition condition) { + struct gaim_connection *gc = (struct gaim_connection *)data; + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + yahoo_socket_handler(yd->sess, source, condition); +} + +static void yahoo_notify(struct yahoo_session *sess, int socket, int type, int cont) { + struct gaim_connection *gc = sess->user_data; + struct yahoo_data *yd = gc->proto_data; + + if (cont) { + struct conn *c = g_new0(struct conn, 1); + c->socket = socket; + c->type = type; + c->inpa = gdk_input_add(socket, type, yahoo_pending, gc); + yd->conns = g_list_append(yd->conns, c); + } else { + GList *c = yd->conns; + while (c) { + struct conn *m = c->data; + if ((m->socket == socket) && (m->type == type)) { + yd->conns = g_list_remove(yd->conns, m); + gdk_input_remove(m->inpa); + g_free(m); + return; + } + c = g_list_next(c); + } + } +} + +static void yahoo_got_connected(gpointer data, gint source, GdkInputCondition cond) { + struct connect *con = data; + + debug_printf("got connected (possibly)\n"); + yahoo_connected(con->sess, con->data, source); + + g_free(con); +} + +static int yahoo_connect_to(struct yahoo_session *sess, const char *host, int port, gpointer data) { + struct connect *con = g_new0(struct connect, 1); + int fd; + + con->sess = sess; + con->data = data; + fd = proxy_connect((char *)host, port, yahoo_got_connected, con); + if (fd < 0) { + g_free(con); + return -1; + } + + return fd; +} + +static void yahoo_debug(struct yahoo_session *sess, int level, const char *string) { + debug_printf("Level %d: %s\n", level, string); +} + +static void yahoo_login(struct aim_user *user) { + struct gaim_connection *gc = new_gaim_conn(user); + struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); + + yd->sess = yahoo_new(); + yd->sess->user_data = gc; + yd->current_status = YAHOO_STATUS_AVAILABLE; + yd->hash = g_hash_table_new(g_str_hash, g_str_equal); + + set_login_progress(gc, 1, "Connecting"); + + if (!yahoo_connect(yd->sess, user->proto_opt[USEROPT_AUTHHOST], + atoi(user->proto_opt[USEROPT_AUTHPORT]))) { + hide_login_progress(gc, "Connection problem"); + signoff(gc); + return; + } + + yahoo_add_handler(yd->sess, YAHOO_HANDLE_DISCONNECT, yahoo_disconn); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_AUTHCONNECT, yahoo_authconnect); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_BADPASSWORD, yahoo_badpassword); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_LOGINCOOKIE, yahoo_logincookie); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_MAINCONNECT, yahoo_mainconnect); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_ONLINE, yahoo_online); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_NEWMAIL, yahoo_newmail); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_MESSAGE, yahoo_message); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_BOUNCE, yahoo_bounce); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_STATUS, yahoo_status); + yahoo_add_handler(yd->sess, YAHOO_HANDLE_BUDDYADDED, yahoo_buddyadded); +} + +static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) { + g_free(key); + g_free(val); + return TRUE; +} + +static void yahoo_close(struct gaim_connection *gc) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + while (yd->offline) { + g_free(yd->offline->data); + yd->offline = g_slist_remove(yd->offline, yd->offline->data); + } + g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); + g_hash_table_destroy(yd->hash); + yahoo_disconnect(yd->sess); + yahoo_delete(yd->sess); + g_free(yd); +} + +static void yahoo_send_im(struct gaim_connection *gc, char *who, char *message, int away) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + GSList *l = yd->offline; + + if (away || !strlen(message)) return; + + while (l) { + if (!strcmp(who, l->data)) + break; + l = l->next; + } + + if (l) + yahoo_send_message(yd->sess, yd->active_id, who, message); + else + yahoo_send_message_offline(yd->sess, yd->active_id, who, message); +} + +static void yahoo_set_away(struct gaim_connection *gc, char *state, char *msg) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + gc->away = NULL; + + if (msg) { + yahoo_away(yd->sess, YAHOO_STATUS_CUSTOM, msg); + yd->current_status = YAHOO_STATUS_CUSTOM; + gc->away = ""; + } else if (state) { + gc->away = ""; + if (!strcmp(state, "Available")) { + yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, msg); + yd->current_status = YAHOO_STATUS_AVAILABLE; + } else if (!strcmp(state, "Be Right Back")) { + yahoo_away(yd->sess, YAHOO_STATUS_BRB, msg); + yd->current_status = YAHOO_STATUS_BRB; + } else if (!strcmp(state, "Busy")) { + yahoo_away(yd->sess, YAHOO_STATUS_BUSY, msg); + yd->current_status = YAHOO_STATUS_BUSY; + } else if (!strcmp(state, "Not At Home")) { + yahoo_away(yd->sess, YAHOO_STATUS_NOTATHOME, msg); + yd->current_status = YAHOO_STATUS_NOTATHOME; + } else if (!strcmp(state, "Not At Desk")) { + yahoo_away(yd->sess, YAHOO_STATUS_NOTATDESK, msg); + yd->current_status = YAHOO_STATUS_NOTATDESK; + } else if (!strcmp(state, "Not In Office")) { + yahoo_away(yd->sess, YAHOO_STATUS_NOTINOFFICE, msg); + yd->current_status = YAHOO_STATUS_NOTINOFFICE; + } else if (!strcmp(state, "On Phone")) { + yahoo_away(yd->sess, YAHOO_STATUS_ONPHONE, msg); + yd->current_status = YAHOO_STATUS_ONPHONE; + } else if (!strcmp(state, "On Vacation")) { + yahoo_away(yd->sess, YAHOO_STATUS_ONVACATION, msg); + yd->current_status = YAHOO_STATUS_ONVACATION; + } else if (!strcmp(state, "Out To Lunch")) { + yahoo_away(yd->sess, YAHOO_STATUS_OUTTOLUNCH, msg); + yd->current_status = YAHOO_STATUS_OUTTOLUNCH; + } else if (!strcmp(state, "Stepped Out")) { + yahoo_away(yd->sess, YAHOO_STATUS_STEPPEDOUT, msg); + yd->current_status = YAHOO_STATUS_STEPPEDOUT; + } else if (!strcmp(state, "Invisible")) { + yahoo_away(yd->sess, YAHOO_STATUS_INVISIBLE, msg); + yd->current_status = YAHOO_STATUS_INVISIBLE; + } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { + if (gc->is_idle) { + yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); + yd->current_status = YAHOO_STATUS_IDLE; + } else { + yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); + yd->current_status = YAHOO_STATUS_AVAILABLE; + } + gc->away = NULL; + } + } else if (gc->is_idle) { + yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); + yd->current_status = YAHOO_STATUS_IDLE; + } else { + yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); + yd->current_status = YAHOO_STATUS_AVAILABLE; + } +} + +static void yahoo_set_idle(struct gaim_connection *gc, int idle) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { + yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); + yd->current_status = YAHOO_STATUS_IDLE; + } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { + yahoo_back(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); + yd->current_status = YAHOO_STATUS_AVAILABLE; + } +} + +static void yahoo_keepalive(struct gaim_connection *gc) { + yahoo_ping(((struct yahoo_data *)gc->proto_data)->sess); +} + +static void gyahoo_add_buddy(struct gaim_connection *gc, char *name) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct yahoo_group *tmpgroup; + struct group *g = find_group_by_buddy(gc, name); + char *group = NULL; + + if (!yd->logged_in) + return; + + if (g) { + group = g->name; + } else if (yd->sess && yd->sess->groups) { + tmpgroup = yd->sess->groups->data; + group = tmpgroup->name; + } else { + group = "Buddies"; + } + + if (group) + yahoo_add_buddy(yd->sess, yd->active_id, group, name, ""); +} + +static void yahoo_add_buddies(struct gaim_connection *gc, GList *buddies) { + while (buddies) { + gyahoo_add_buddy(gc, buddies->data); + buddies = buddies->next; + } +} + +static void gyahoo_remove_buddy(struct gaim_connection *gc, char *name) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct group *g = find_group_by_buddy(gc, name); + char *group = NULL; + + if (g) { + group = g->name; + } else if (yd->sess && yd->sess->groups) { + GList *x = yd->sess->groups; + while (x) { + struct yahoo_group *tmpgroup = x->data; + char **bds = tmpgroup->buddies; + while (*bds) { + if (!strcmp(*bds, name)) + break; + bds++; + } + if (*bds) { + group = tmpgroup->name; + break; + } + x = x->next; + } + } else { + group = "Buddies"; + } + + if (group) + yahoo_remove_buddy(yd->sess, yd->active_id, group, name, ""); +} + +static char **yahoo_list_icon(int uc) { + if ((uc >> 5) == YAHOO_STATUS_IDLE) + return status_idle_xpm; + else if (uc == UC_NORMAL) + return status_here_xpm; + return status_away_xpm; +} + +static char *yahoo_get_status_string(enum yahoo_status a) { + switch (a) { + case YAHOO_STATUS_BRB: + return "Be Right Back"; + case YAHOO_STATUS_BUSY: + return "Busy"; + case YAHOO_STATUS_NOTATHOME: + return "Not At Home"; + case YAHOO_STATUS_NOTATDESK: + return "Not At Desk"; + case YAHOO_STATUS_NOTINOFFICE: + return "Not In Office"; + case YAHOO_STATUS_ONPHONE: + return "On Phone"; + case YAHOO_STATUS_ONVACATION: + return "On Vacation"; + case YAHOO_STATUS_OUTTOLUNCH: + return "Out To Lunch"; + case YAHOO_STATUS_STEPPEDOUT: + return "Stepped Out"; + default: + return NULL; + } +} + +static void yahoo_buddy_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + GtkWidget *button; + struct buddy *b = find_buddy(gc, who); /* this should never be null. if it is, + segfault and get the bug report. */ + char buf[1024]; + + if (b->uc & UC_NORMAL) + return; + + if ((b->uc >> 5) != YAHOO_STATUS_CUSTOM) + g_snprintf(buf, sizeof buf, "Status: %s", yahoo_get_status_string(b->uc >> 5)); + else + g_snprintf(buf, sizeof buf, "Custom Status: %s", + (char *)g_hash_table_lookup(yd->hash, b->name)); + button = gtk_menu_item_new_with_label(buf); + gtk_menu_append(GTK_MENU(menu), button); + gtk_widget_show(button); +} + +static GList *yahoo_away_states() { + GList *m = NULL; + + m = g_list_append(m, "Available"); + m = g_list_append(m, "Be Right Back"); + m = g_list_append(m, "Busy"); + m = g_list_append(m, "Not At Home"); + m = g_list_append(m, "Not At Desk"); + m = g_list_append(m, "Not In Office"); + m = g_list_append(m, "On Phone"); + m = g_list_append(m, "On Vacation"); + m = g_list_append(m, "Out To Lunch"); + m = g_list_append(m, "Stepped Out"); + m = g_list_append(m, "Invisible"); + m = g_list_append(m, GAIM_AWAY_CUSTOM); + + return m; +} + +static void yahoo_act_id(gpointer data, char *entry) { + struct gaim_connection *gc = data; + struct yahoo_data *yd = gc->proto_data; + + yahoo_activate_id(yd->sess, entry); + if (yd->active_id) + g_free(yd->active_id); + yd->active_id = g_strdup(entry); +} + +static void yahoo_do_action(struct gaim_connection *gc, char *act) { + if (!strcmp(act, "Activate ID")) { + do_prompt_dialog("Activate which ID:", gc, yahoo_act_id, NULL); + } +} + +static GList *yahoo_actions() { + GList *m = NULL; + + m = g_list_append(m, "Activate ID"); + + return m; +} + +struct mod_usr_opt { + struct aim_user *user; + int opt; +}; + +static void mod_opt(GtkWidget *b, struct mod_usr_opt *m) +{ + if (m->user->proto_opt[m->opt][0] == '1') + m->user->proto_opt[m->opt][0] = '\0'; + else + strcpy(m->user->proto_opt[m->opt],"1"); +} + +static void free_muo(GtkWidget *b, struct mod_usr_opt *m) +{ + g_free(m); +} + +static GtkWidget *yahoo_protoopt_button(const char *text, struct aim_user *u, int option, GtkWidget *box) +{ + GtkWidget *button; + struct mod_usr_opt *muo = g_new0(struct mod_usr_opt, 1); + button = gtk_check_button_new_with_label(text); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), (u->proto_opt[option][0] == '1')); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + muo->user = u; + muo->opt = option; + gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(mod_opt), muo); + gtk_signal_connect(GTK_OBJECT(button), "destroy", GTK_SIGNAL_FUNC(free_muo), muo); + gtk_widget_show(button); + return button; +} + +static void yahoo_print_option(GtkEntry *entry, struct aim_user *user) { + int entrynum; + + entrynum = (int) gtk_object_get_user_data(GTK_OBJECT(entry)); + + if (entrynum == USEROPT_AUTHHOST) { + g_snprintf(user->proto_opt[USEROPT_AUTHHOST], + sizeof(user->proto_opt[USEROPT_AUTHHOST]), + "%s", gtk_entry_get_text(entry)); + } else if (entrynum == USEROPT_AUTHPORT) { + g_snprintf(user->proto_opt[USEROPT_AUTHPORT], + sizeof(user->proto_opt[USEROPT_AUTHPORT]), + "%s", gtk_entry_get_text(entry)); + } else if (entrynum == USEROPT_PAGERHOST) { + g_snprintf(user->proto_opt[USEROPT_PAGERHOST], + sizeof(user->proto_opt[USEROPT_PAGERHOST]), + "%s", gtk_entry_get_text(entry)); + } else if (entrynum == USEROPT_PAGERPORT) { + g_snprintf(user->proto_opt[USEROPT_PAGERPORT], + sizeof(user->proto_opt[USEROPT_PAGERPORT]), + "%s", gtk_entry_get_text(entry)); + } +} + +static void yahoo_user_opts(GtkWidget *book, struct aim_user *user) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *entry; + + vbox = gtk_vbox_new(FALSE, 5); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); + gtk_notebook_append_page(GTK_NOTEBOOK(book), vbox, gtk_label_new("Yahoo Options")); + gtk_widget_show(vbox); + + yahoo_protoopt_button("Notify me of new Yahoo! Mail", user, USEROPT_MAIL, vbox); + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + + label = gtk_label_new("Yahoo Auth Host:"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + entry = gtk_entry_new(); + gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); + gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTHHOST); + gtk_signal_connect(GTK_OBJECT(entry), "changed", + GTK_SIGNAL_FUNC(yahoo_print_option), user); + if (user->proto_opt[USEROPT_AUTHHOST][0]) { + debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTHHOST]); + gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHHOST]); + } else { + gtk_entry_set_text(GTK_ENTRY(entry), YAHOO_AUTH_HOST); + } + gtk_widget_show(entry); + + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + + label = gtk_label_new("Yahoo Auth Port:"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + entry = gtk_entry_new(); + gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); + gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTHPORT); + gtk_signal_connect(GTK_OBJECT(entry), "changed", + GTK_SIGNAL_FUNC(yahoo_print_option), user); + if (user->proto_opt[USEROPT_AUTHPORT][0]) { + debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTHPORT]); + gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHPORT]); + } else { + g_snprintf(user->proto_opt[USEROPT_AUTHPORT], sizeof(user->proto_opt[USEROPT_AUTHPORT]), + "%d", YAHOO_AUTH_PORT); + gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHPORT]); + } + gtk_widget_show(entry); + + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + + label = gtk_label_new("Yahoo Pager Host:"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + entry = gtk_entry_new(); + gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); + gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_PAGERHOST); + gtk_signal_connect(GTK_OBJECT(entry), "changed", + GTK_SIGNAL_FUNC(yahoo_print_option), user); + if (user->proto_opt[USEROPT_PAGERHOST][0]) { + debug_printf("setting text %s\n", user->proto_opt[USEROPT_PAGERHOST]); + gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_PAGERHOST]); + } else { + gtk_entry_set_text(GTK_ENTRY(entry), YAHOO_PAGER_HOST); + } + gtk_widget_show(entry); + + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + + label = gtk_label_new("Yahoo Pager Port:"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + entry = gtk_entry_new(); + gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); + gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_PAGERPORT); + gtk_signal_connect(GTK_OBJECT(entry), "changed", + GTK_SIGNAL_FUNC(yahoo_print_option), user); + if (user->proto_opt[USEROPT_PAGERPORT][0]) { + debug_printf("setting text %s\n", user->proto_opt[USEROPT_PAGERPORT]); + gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_PAGERPORT]); + } else { + g_snprintf(user->proto_opt[USEROPT_PAGERPORT], sizeof(user->proto_opt[USEROPT_PAGERPORT]), + "%d", YAHOO_PAGER_PORT); + gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_PAGERPORT]); + } + gtk_widget_show(entry); +} + +static void toggle_offline(GtkToggleButton *button, struct conversation *c) +{ + struct gaim_connection *gc = gtk_object_get_user_data(GTK_OBJECT(button)); + struct yahoo_data *yd = gc->proto_data; + GSList *l = yd->offline; + + while (l) { + if (!strcmp(c->name, l->data)) + break; + l = l->next; + } + if (l) { + g_free(l->data); + yd->offline = g_slist_remove(yd->offline, l->data); + } else + yd->offline = g_slist_append(yd->offline, g_strdup(c->name)); +} + +static void yahoo_insert_convo(struct gaim_connection *gc, struct conversation *c) +{ + GtkWidget *button; + struct yahoo_data *yd = gc->proto_data; + GSList *l = yd->offline; + struct buddy *b = find_buddy(gc, c->name); + + button = gtk_check_button_new_with_label("Send offline message"); + gtk_box_pack_start(GTK_BOX(c->lbox), button, FALSE, FALSE, 5); + gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(toggle_offline), c); + gtk_object_set_user_data(GTK_OBJECT(button), gc); + while (l) { + if (!strcmp(c->name, l->data)) + break; + l = l->next; + } + if (l || (b && !b->present)) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); + gtk_widget_show(button); +} + +static void yahoo_remove_convo(struct gaim_connection *gc, struct conversation *c) +{ + while (GTK_BOX(c->lbox)->children) + gtk_container_remove(GTK_CONTAINER(c->lbox), + ((GtkBoxChild *)GTK_BOX(c->lbox)->children->data)->widget); +} + +static struct prpl *my_protocol = NULL; + +void yahoo_init(struct prpl *ret) { + /* the NULL's aren't required but they're nice to have */ + ret->protocol = PROTO_YAHOO; + ret->name = yahoo_name; + ret->list_icon = yahoo_list_icon; + ret->away_states = yahoo_away_states; + ret->actions = yahoo_actions; + ret->do_action = yahoo_do_action; + ret->buddy_menu = yahoo_buddy_menu; + ret->user_opts = yahoo_user_opts; + ret->insert_convo = yahoo_insert_convo; + ret->remove_convo = yahoo_remove_convo; + ret->login = yahoo_login; + ret->close = yahoo_close; + ret->send_im = yahoo_send_im; + ret->set_info = NULL; + ret->get_info = NULL; + ret->set_away = yahoo_set_away; + ret->get_away_msg = NULL; + ret->set_dir = NULL; + ret->get_dir = NULL; + ret->dir_search = NULL; + ret->set_idle = yahoo_set_idle; + ret->change_passwd = NULL; + ret->add_buddy = gyahoo_add_buddy; + ret->add_buddies = yahoo_add_buddies; + ret->remove_buddy = gyahoo_remove_buddy; + ret->add_permit = NULL; + ret->add_deny = NULL; + ret->rem_permit = NULL; + ret->rem_deny = NULL; + ret->set_permit_deny = NULL; + ret->warn = NULL; + ret->accept_chat = NULL; + ret->join_chat = NULL; + ret->chat_invite = NULL; + ret->chat_leave = NULL; + ret->chat_whisper = NULL; + ret->chat_send = NULL; + ret->keepalive = yahoo_keepalive; + + my_protocol = ret; + + yahoo_socket_notify = yahoo_notify; + yahoo_print = yahoo_debug; + yahoo_connector = yahoo_connect_to; +} + +#ifndef STATIC + +char *gaim_plugin_init(GModule *handle) +{ + load_protocol(yahoo_init, sizeof(struct prpl)); + return NULL; +} + +void gaim_plugin_remove() +{ + struct prpl *p = find_prpl(PROTO_YAHOO); + if (p == my_protocol) + unload_protocol(p); +} + +char *name() +{ + return "Yahoo"; +} + +char *description() +{ + return "Allows gaim to use the Yahoo protocol"; +} + +#endif