changeset 999:0b5db8cdd30f

[gaim-migrate @ 1009] update to work with new per-protocol-connection data, i think committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sun, 15 Oct 2000 03:55:23 +0000
parents 70c685de2be5
children 91b7377e7b45
files plugins/oscar.c
diffstat 1 files changed, 133 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/oscar.c	Sun Oct 15 03:50:32 2000 +0000
+++ b/plugins/oscar.c	Sun Oct 15 03:55:23 2000 +0000
@@ -48,10 +48,22 @@
 
 int gaim_caps = AIM_CAPS_CHAT | AIM_CAPS_SENDFILE | AIM_CAPS_GETFILE |
 		AIM_CAPS_VOICE | AIM_CAPS_IMIMAGE | AIM_CAPS_BUDDYICON;
-int keepalv = -1;
+
+struct oscar_data {
+	struct aim_session_t *sess;
+	struct aim_conn_t *conn;
+
+	int cnpa;
+	int paspa;
+
+	int create_exchange;
+	char *create_name;
+
+	GSList *oscar_chats;
+};
 
 struct chat_connection *find_oscar_chat(struct gaim_connection *gc, char *name) {
-	GSList *g = gc->oscar_chats;
+	GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats;
 	struct chat_connection *c = NULL;
 	if (gc->protocol != PROTO_OSCAR) return NULL;
 
@@ -68,7 +80,7 @@
 
 static struct chat_connection *find_oscar_chat_by_conn(struct gaim_connection *gc,
 							struct aim_conn_t *conn) {
-	GSList *g = gc->oscar_chats;
+	GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats;
 	struct chat_connection *c = NULL;
 
 	while (g) {
@@ -88,7 +100,7 @@
 
 	while (g) {
 		gc = (struct gaim_connection *)g->data;
-		if (sess == gc->oscar_sess)
+		if (sess == ((struct oscar_data *)gc->proto_data)->sess)
 			break;
 		g = g->next;
 		gc = NULL;
@@ -108,7 +120,7 @@
 			g = g->next;
 			continue;
 		}
-		s = c->oscar_sess->connlist;
+		s = ((struct oscar_data *)c->proto_data)->sess->connlist;
 		while (s) {
 			if (conn == s)
 				break;
@@ -184,6 +196,7 @@
 				GdkInputCondition condition) {
 	struct aim_conn_t *conn = (struct aim_conn_t *)data;
 	struct gaim_connection *gc = find_gaim_conn_by_oscar_conn(conn);
+	struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
 	if (!gc) {
 		/* oh boy. this is probably bad. i guess the only thing we can really do
 		 * is return? */
@@ -192,19 +205,19 @@
 	}
 
 	if (condition & GDK_INPUT_EXCEPTION) {
-		hide_login_progress(gc->username, _("Disconnected."));
+		hide_login_progress(gc, _("Disconnected."));
 		signoff(gc);
 		return;
 	}
 	if (condition & GDK_INPUT_READ) {
 		if (conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
 			debug_print("got information on rendezvous\n");
-			if (aim_handlerendconnect(gc->oscar_sess, conn) < 0) {
+			if (aim_handlerendconnect(odata->sess, conn) < 0) {
 				debug_print(_("connection error (rend)\n"));
 			}
 		} else {
-			if (aim_get_command(gc->oscar_sess, conn) >= 0) {
-				aim_rxdispatch(gc->oscar_sess);
+			if (aim_get_command(odata->sess, conn) >= 0) {
+				aim_rxdispatch(odata->sess);
 			} else {
 				if (conn->type == AIM_CONN_TYPE_RENDEZVOUS &&
 				    conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) {
@@ -214,11 +227,11 @@
 					if (cnv) {
 						make_direct(cnv, FALSE, NULL, 0);
 					}
-					aim_conn_kill(gc->oscar_sess, &conn);
+					aim_conn_kill(odata->sess, &conn);
 				} else if ((conn->type == AIM_CONN_TYPE_BOS) ||
-					   !(aim_getconn_type(gc->oscar_sess, AIM_CONN_TYPE_BOS))) {
+					   !(aim_getconn_type(odata->sess, AIM_CONN_TYPE_BOS))) {
 					debug_print(_("major connection error\n"));
-					hide_login_progress(gc->username, _("Disconnected."));
+					hide_login_progress(gc, _("Disconnected."));
 					signoff(gc);
 				} else if (conn->type == AIM_CONN_TYPE_CHAT) {
 					struct chat_connection *c = find_oscar_chat_by_conn(gc, conn);
@@ -230,20 +243,20 @@
 						gdk_input_remove(c->inpa);
 					c->inpa = -1;
 					c->fd = -1;
-					aim_conn_kill(gc->oscar_sess, &conn);
+					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 (gc->cnpa > -1)
-						gdk_input_remove(gc->cnpa);
-					gc->cnpa = -1;
+					if (odata->cnpa > -1)
+						gdk_input_remove(odata->cnpa);
+					odata->cnpa = -1;
 					debug_print("removing chatnav input watcher\n");
-					aim_conn_kill(gc->oscar_sess, &conn);
+					aim_conn_kill(odata->sess, &conn);
 				} else {
 					sprintf(debug_buff, "holy crap! generic connection error! %d\n",
 							conn->type);
 					debug_print(debug_buff);
-					aim_conn_kill(gc->oscar_sess, &conn);
+					aim_conn_kill(odata->sess, &conn);
 				}
 			}
 		}
@@ -254,41 +267,46 @@
 	struct aim_session_t *sess;
 	struct aim_conn_t *conn;
 	char buf[256];
-	struct gaim_connection *gc;
+	struct gaim_connection *gc = new_gaim_conn(PROTO_OSCAR, user->username, user->password);
+	struct oscar_data *odata = gc->proto_data = g_new0(struct oscar_data, 1);
 
 	sprintf(debug_buff, _("Logging in %s\n"), user->username);
 	debug_print(debug_buff);
 
-	gc = new_gaim_conn(PROTO_OSCAR, user->username, user->password);
 	sess = g_new0(struct aim_session_t, 1);
 	aim_session_init(sess);
 	/* 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;
-	gc->oscar_sess = sess;
+	odata->sess = sess;
 
 	sprintf(buf, _("Looking up %s"), FAIM_LOGIN_SERVER);
+	set_login_progress(gc, 1, buf);
+	/* this creates a possible race condition, but hey, what can you do */
+	while (gtk_events_pending())
+		gtk_main_iteration();
 	conn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, FAIM_LOGIN_SERVER);
 
 	if (conn == NULL) {
 		debug_print(_("internal connection error\n"));
-		hide_login_progress(gc->username, _("Unable to login to AIM"));
+		hide_login_progress(gc, _("Unable to login to AIM"));
 		destroy_gaim_conn(gc);
 		return;
 	} else if (conn->fd == -1) {
 		if (conn->status & AIM_CONN_STATUS_RESOLVERR) {
 			sprintf(debug_buff, _("couldn't resolve host"));
 			debug_print(debug_buff); debug_print("\n");
-			hide_login_progress(gc->username, debug_buff);
+			hide_login_progress(gc, debug_buff);
 		} else if (conn->status & AIM_CONN_STATUS_CONNERR) {
 			sprintf(debug_buff, _("couldn't connect to host"));
 			debug_print(debug_buff); debug_print("\n");
-			hide_login_progress(gc->username, debug_buff);
+			hide_login_progress(gc, debug_buff);
 		}
 		destroy_gaim_conn(gc);
 		return;
 	}
 	g_snprintf(buf, sizeof(buf), _("Signon: %s"), gc->username);
+	set_login_progress(gc, 2, buf);
 
 	aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0);
 	aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0);
@@ -306,18 +324,17 @@
 }
 
 void oscar_close(struct gaim_connection *gc) {
+	struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
 	if (gc->protocol != PROTO_OSCAR) return;
 	if (gc->inpa > 0)
 		gdk_input_remove(gc->inpa);
-	gc->inpa = -1;
-	if (gc->cnpa > 0)
-		gdk_input_remove(gc->cnpa);
-	gc->cnpa = -1;
-	if (gc->paspa > 0)
-		gdk_input_remove(gc->paspa);
-	gc->paspa = -1;
-	aim_logoff(gc->oscar_sess);
-	g_free(gc->oscar_sess);
+	if (odata->cnpa > 0)
+		gdk_input_remove(odata->cnpa);
+	if (odata->paspa > 0)
+		gdk_input_remove(odata->paspa);
+	aim_logoff(odata->sess);
+	g_free(odata->sess);
+	g_free(gc->proto_data);
 	debug_print(_("Signed off.\n"));
 }
 
@@ -357,7 +374,7 @@
 		set_user_state(offline);
 #endif
 		gdk_input_remove(gc->inpa);
-		hide_login_progress(gc->username, _("Authentication Failed"));
+		hide_login_progress(gc, _("Authentication Failed"));
 		signoff(gc);
 		return 0;
 	}
@@ -379,14 +396,14 @@
 #ifdef USE_APPLET
 		set_user_state(offline);
 #endif
-		hide_login_progress(gc->username, _("Internal Error"));
+		hide_login_progress(gc, _("Internal Error"));
 		destroy_gaim_conn(gc);
 		return -1;
 	} else if (bosconn->status != 0) {
 #ifdef USE_APPLET
 		set_user_state(offline);
 #endif
-		hide_login_progress(gc->username, _("Could Not Connect"));
+		hide_login_progress(gc, _("Could Not Connect"));
 		destroy_gaim_conn(gc);
 		return -1;
 	}
@@ -414,9 +431,10 @@
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0);
 
 	aim_auth_sendcookie(sess, bosconn, sess->logininfo.cookie);
-	gc->oscar_conn = bosconn;
+	((struct oscar_data *)gc->proto_data)->conn = bosconn;
 	gc->inpa = gdk_input_add(bosconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
 			oscar_callback, bosconn);
+	set_login_progress(gc, 4, _("Connection established, cookie sent"));
 	return 1;
 }
 
@@ -482,6 +500,7 @@
 	char *ip;
 	unsigned char *cookie;
 	struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess);
+	struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
 
 	va_start(ap, command);
 	serviceid = va_arg(ap, int);
@@ -496,7 +515,7 @@
 		if (tstconn == NULL || tstconn->status >= AIM_CONN_STATUS_RESOLVERR)
 			debug_print("unable to reconnect with authorizer\n");
 		else {
-			gc->paspa = gdk_input_add(tstconn->fd,
+			odata->paspa = gdk_input_add(tstconn->fd,
 					GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
 					oscar_callback, tstconn);
 			aim_auth_sendcookie(sess, tstconn, cookie);
@@ -512,7 +531,7 @@
 		}
 		aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0);
 		aim_auth_sendcookie(sess, tstconn, cookie);
-		gc->cnpa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
+		odata->cnpa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
 					oscar_callback, tstconn);
 		}
 		debug_print("chatnav: connected\n");
@@ -538,7 +557,7 @@
 				GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
 				oscar_callback, tstconn);
 
-		gc->oscar_chats = g_slist_append(gc->oscar_chats, ccon);
+		odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon);
 		
 		aim_chat_attachname(tstconn, roomname);
 		aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0);
@@ -610,19 +629,21 @@
 	struct aim_conn_t *newconn;
 	struct aim_directim_priv *priv;
 	struct gaim_connection *gc;
+	struct oscar_data *odata;
 	int watcher;
 
 	priv = (struct aim_directim_priv *)gtk_object_get_user_data(GTK_OBJECT(m));
 	gc = (struct gaim_connection *)gtk_object_get_user_data(GTK_OBJECT(w));
+	odata = (struct oscar_data *)gc->proto_data;
 	gtk_widget_destroy(m);
 
-	if (!(newconn = aim_directim_connect(gc->oscar_sess, gc->oscar_conn, priv))) {
+	if (!(newconn = aim_directim_connect(odata->sess, odata->conn, priv))) {
 		debug_print("imimage: could not connect\n");
 		return;
 	}
 
-	aim_conn_addhandler(gc->oscar_sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, gaim_directim_incoming, 0);
-	aim_conn_addhandler(gc->oscar_sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, gaim_directim_typing, 0);
+	aim_conn_addhandler(odata->sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, gaim_directim_incoming, 0);
+	aim_conn_addhandler(odata->sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, gaim_directim_typing, 0);
 
 	watcher = gdk_input_add(newconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
 				oscar_callback, newconn);
@@ -907,6 +928,7 @@
 	va_list ap;
 	u_short type;
 	struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess);
+	struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
 
 	va_start(ap, command);
 	type = (u_short)va_arg(ap, u_int);
@@ -936,14 +958,14 @@
 				debug_print(debug_buff);
 				i++;
 			}
-			if (gc->create_exchange) {
-				sprintf(debug_buff, "creating room %s\n",
-						gc->create_name);
+			if (odata->create_exchange) {
+				sprintf(debug_buff, "creating room %s\n", odata->create_name);
 				debug_print(debug_buff);
-				aim_chatnav_createroom(sess, command->conn, gc->create_name, gc->create_exchange);
-				gc->create_exchange = 0;
-				g_free(gc->create_name);
-				gc->create_name = NULL;
+				aim_chatnav_createroom(sess, command->conn, odata->create_name,
+						odata->create_exchange);
+				odata->create_exchange = 0;
+				g_free(odata->create_name);
+				odata->create_name = NULL;
 			}
 			}
 			break;
@@ -970,11 +992,11 @@
 			if (flags & 0x4) {
 				sprintf(debug_buff, "joining %s on exchange 5\n", name);
 				debug_print(debug_buff);
-				aim_chat_join(gc->oscar_sess, gc->oscar_conn, 5, ck);
+				aim_chat_join(odata->sess, odata->conn, 5, ck);
 			} else 
 				sprintf(debug_buff, "joining %s on exchange 4\n", name);{
 				debug_print(debug_buff);
-				aim_chat_join(gc->oscar_sess, gc->oscar_conn, 4, ck);
+				aim_chat_join(odata->sess, odata->conn, 4, ck);
 			}
 			}
 			break;
@@ -1295,124 +1317,133 @@
 }
 
 void oscar_do_directim(struct gaim_connection *gc, char *name) {
-	struct aim_conn_t *newconn = aim_directim_initiate(gc->oscar_sess, gc->oscar_conn, NULL, name);
-	struct conversation *cnv = find_conversation(name); /* this will never be null because it just got set up */
+	struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
+	struct aim_conn_t *newconn = aim_directim_initiate(odata->sess, odata->conn, NULL, name);
+	struct conversation *cnv = find_conversation(name); /* this will never be null because
+							       it just got set up */
 	cnv->conn = newconn;
 	cnv->watcher = gdk_input_add(newconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, newconn);
-	aim_conn_addhandler(gc->oscar_sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, gaim_directim_initiate, 0);
+	aim_conn_addhandler(odata->sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, gaim_directim_initiate, 0);
 }
 
 static void oscar_keepalive(struct gaim_connection *gc) {
-	aim_flap_nop(gc->oscar_sess, gc->oscar_conn);
+	struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
+	aim_flap_nop(odata->sess, odata->conn);
 }
 
 static char *oscar_name() {
 	return "Oscar";
 }
 
-char *name() {
-	return "Oscar";
-}
-
-char *description() {
-	return "Allows gaim to use the Oscar protocol";
-}
-
 static void oscar_send_im(struct gaim_connection *gc, char *name, char *message, int away) {
+	struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
 	struct conversation *cnv = find_conversation(name);
 	if (cnv && cnv->is_direct) {
 		debug_printf("Sending DirectIM to %s\n", name);
-		aim_send_im_direct(gc->oscar_sess, cnv->conn, message);
+		aim_send_im_direct(odata->sess, cnv->conn, message);
 	} else {
 		if (away)
-			aim_send_im(gc->oscar_sess, gc->oscar_conn, name, AIM_IMFLAGS_AWAY, message);
+			aim_send_im(odata->sess, odata->conn, name, AIM_IMFLAGS_AWAY, message);
 		else
-			aim_send_im(gc->oscar_sess, gc->oscar_conn, name, AIM_IMFLAGS_ACK, message);
+			aim_send_im(odata->sess, odata->conn, name, AIM_IMFLAGS_ACK, message);
 	}
 }
 
 static void oscar_get_info(struct gaim_connection *g, char *name) {
-	aim_getinfo(g->oscar_sess, g->oscar_conn, name, AIM_GETINFO_GENERALINFO);
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_GENERALINFO);
 }
 
 static void oscar_get_away_msg(struct gaim_connection *g, char *name) {
-	aim_getinfo(g->oscar_sess, g->oscar_conn, name, AIM_GETINFO_AWAYMESSAGE);
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_AWAYMESSAGE);
 }
 
 static void oscar_set_dir(struct gaim_connection *g, char *first, char *middle, char *last,
 			  char *maiden, char *city, char *state, char *country, int web) {
 	/* FIXME : some of these things are wrong, but i'm lazy */
-	aim_setdirectoryinfo(g->oscar_sess, g->oscar_conn, first, middle, last,
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_setdirectoryinfo(odata->sess, odata->conn, first, middle, last,
 				maiden, NULL, NULL, city, state, NULL, 0, web);
 }
 
 
 static void oscar_set_idle(struct gaim_connection *g, int time) {
-	aim_bos_setidle(g->oscar_sess, g->oscar_conn, time);
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_bos_setidle(odata->sess, odata->conn, time);
 }
 
 static void oscar_set_info(struct gaim_connection *g, char *info) {
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
 	if (awaymessage)
-		aim_bos_setprofile(g->oscar_sess, g->oscar_conn, info,
+		aim_bos_setprofile(odata->sess, odata->conn, info,
 					awaymessage->message, gaim_caps);
 	else
-		aim_bos_setprofile(g->oscar_sess, g->oscar_conn, info,
+		aim_bos_setprofile(odata->sess, odata->conn, info,
 					NULL, gaim_caps);
 }
 
 static void oscar_set_away(struct gaim_connection *g, char *message) {
-	aim_bos_setprofile(g->oscar_sess, g->oscar_conn, g->user_info, message, gaim_caps);
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_bos_setprofile(odata->sess, odata->conn, g->user_info, message, gaim_caps);
 }
 
 static void oscar_warn(struct gaim_connection *g, char *name, int anon) {
-	aim_send_warning(g->oscar_sess, g->oscar_conn, name, anon);
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_send_warning(odata->sess, odata->conn, name, anon);
 }
 
 static void oscar_dir_search(struct gaim_connection *g, char *first, char *middle, char *last,
 			     char *maiden, char *city, char *state, char *country, char *email) {
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
 	if (strlen(email))
-		aim_usersearch_address(g->oscar_sess, g->oscar_conn, email);
+		aim_usersearch_address(odata->sess, odata->conn, email);
 }
 
 static void oscar_add_buddy(struct gaim_connection *g, char *name) {
-	aim_add_buddy(g->oscar_sess, g->oscar_conn, name);
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_add_buddy(odata->sess, odata->conn, name);
 }
 
 static void oscar_add_buddies(struct gaim_connection *g, GList *buddies) {
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
 	char buf[MSG_LEN];
 	int n = 0;
 	while (buddies) {
 		if (n > MSG_LEN - 18) {
-			aim_bos_setbuddylist(g->oscar_sess, g->oscar_conn, buf);
+			aim_bos_setbuddylist(odata->sess, odata->conn, buf);
 			n = 0;
 		}
 		n += g_snprintf(buf + n, sizeof(buf) - n, "%s&", (char *)buddies->data);
 		buddies = buddies->next;
 	}
-	aim_bos_setbuddylist(g->oscar_sess, g->oscar_conn, buf);
+	aim_bos_setbuddylist(odata->sess, odata->conn, buf);
 }
 
 static void oscar_remove_buddy(struct gaim_connection *g, char *name) {
-	aim_remove_buddy(g->oscar_sess, g->oscar_conn, name);
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	aim_remove_buddy(odata->sess, odata->conn, name);
 }
 
 static void oscar_join_chat(struct gaim_connection *g, int exchange, char *name) {
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
 	struct aim_conn_t *cur = NULL;
 	sprintf(debug_buff, "Attempting to join chat room %s.\n", name);
 	debug_print(debug_buff);
-	if ((cur = aim_getconn_type(g->oscar_sess, AIM_CONN_TYPE_CHATNAV))) {
+	if ((cur = aim_getconn_type(odata->sess, AIM_CONN_TYPE_CHATNAV))) {
 		debug_print("chatnav exists, creating room\n");
-		aim_chatnav_createroom(g->oscar_sess, cur, name, exchange);
+		aim_chatnav_createroom(odata->sess, cur, name, exchange);
 	} else {
 		/* this gets tricky */
 		debug_print("chatnav does not exist, opening chatnav\n");
-		g->create_exchange = exchange;
-		g->create_name = g_strdup(name);
-		aim_bos_reqservice(g->oscar_sess, g->oscar_conn, AIM_CONN_TYPE_CHATNAV);
+		odata->create_exchange = exchange;
+		odata->create_name = g_strdup(name);
+		aim_bos_reqservice(odata->sess, odata->conn, AIM_CONN_TYPE_CHATNAV);
 	}
 }
 
 static void oscar_chat_invite(struct gaim_connection *g, int id, char *message, char *name) {
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
 	GSList *bcs = g->buddy_chats;
 	struct conversation *b = NULL;
 
@@ -1427,11 +1458,12 @@
 	if (!b)
 		return;
 
-	aim_chat_invite(g->oscar_sess, g->oscar_conn, name,
+	aim_chat_invite(odata->sess, odata->conn, name,
 			message ? message : "", 0x4, b->name, 0x0);
 }
 
 static void oscar_chat_leave(struct gaim_connection *g, int id) {
+	struct oscar_data *odata = g ? (struct oscar_data *)g->proto_data : NULL;
 	GSList *bcs = g->buddy_chats;
 	struct conversation *b = NULL;
 	struct chat_connection *c = NULL;
@@ -1455,10 +1487,11 @@
 	
 	c = find_oscar_chat(g, b->name);
 	if (c != NULL) {
-		g->oscar_chats = g_slist_remove(g->oscar_chats, c);
+		if (odata)
+			odata->oscar_chats = g_slist_remove(odata->oscar_chats, c);
 		gdk_input_remove(c->inpa);
-		if (g && g->oscar_sess)
-			aim_conn_kill(g->oscar_sess, &c->conn);
+		if (g && odata->sess)
+			aim_conn_kill(odata->sess, &c->conn);
 		g_free(c->name);
 		g_free(c);
 	}
@@ -1472,6 +1505,7 @@
 }
 
 static void oscar_chat_send(struct gaim_connection *g, int id, char *message) {
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
 	struct aim_conn_t *cn; 
 	GSList *bcs = g->buddy_chats;
 	struct conversation *b = NULL;
@@ -1486,8 +1520,8 @@
 	if (!b)
 		return;
 
-	cn = aim_chat_getconn(g->oscar_sess, b->name);
-	aim_chat_send_im(g->oscar_sess, cn, message);
+	cn = aim_chat_getconn(odata->sess, b->name);
+	aim_chat_send_im(odata->sess, cn, message);
 }
 
 struct prpl *oscar_init() {
@@ -1524,6 +1558,14 @@
 	return ret;
 }
 
+char *name() {
+	return "Oscar";
+}
+
+char *description() {
+	return "Allows gaim to use the Oscar protocol";
+}
+
 int gaim_plugin_init(void *handle) {
 	protocols = g_slist_append(protocols, oscar_init());
 	return 0;