changeset 11638:3a05b53a589e

[gaim-migrate @ 13914] Some bits'n'pieces: A bunch of memory leak fixes Fix newly created accounts to connect in the currently active global status Fix the modify account dialog to only show relevant user options etc. Update sametime to use some more of the new status stuff, it still needs more love though. Some s/online/available/ for consistency across prpls Fix a racyness in disconnecting connections that want to die (fixes the Yahoo crash when signing on somewhere else) Sorry if I caused any conflicts! committer: Tailor Script <tailor@pidgin.im>
author Stu Tomlinson <stu@nosnilmot.com>
date Mon, 10 Oct 2005 17:59:48 +0000
parents cedd48571c90
children 1e2105334505
files src/account.c src/gtkaccount.c src/gtkblist.c src/gtkconn.c src/gtkprefs.c src/gtkstatusbox.c src/gtkstatusbox.h src/gtkutils.c src/protocols/gg/gg.c src/protocols/msn/userlist.c src/protocols/napster/napster.c src/protocols/sametime/sametime.c src/protocols/zephyr/zephyr.c src/status.c
diffstat 14 files changed, 157 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/src/account.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/account.c	Mon Oct 10 17:59:48 2005 +0000
@@ -1282,10 +1282,17 @@
 gaim_account_set_enabled(GaimAccount *account, const char *ui,
 			 gboolean value)
 {
+	GaimConnection *gc;
+
 	g_return_if_fail(account != NULL);
 	g_return_if_fail(ui      != NULL);
 
 	gaim_account_set_ui_bool(account, ui, "auto-login", value);
+	gc = gaim_account_get_connection(account);
+
+	if ((gc != NULL) && (gc->wants_to_die == TRUE))
+		return;
+
 	if (value && gaim_presence_is_online(account->presence))
 		gaim_account_connect(account);
 	else if (!value && !gaim_account_is_disconnected(account))
--- a/src/gtkaccount.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/gtkaccount.c	Mon Oct 10 17:59:48 2005 +0000
@@ -1623,10 +1623,18 @@
 
 	gaim_signal_emit(gaim_gtk_account_get_handle(), "account-modified", ret);
 
-	/* XXX: make the new account sign on with the currently active global status
-	 * instead of hardcoding "online" */
-	if (new)
-		gaim_presence_set_status_active(ret->presence, "online", TRUE);
+	if (new) {
+		GaimGtkBuddyList *gtkblist;
+		GtkGaimStatusBox *status_box;
+		char *status_type_id;
+
+		gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+		status_box = GTK_GAIM_STATUS_BOX(gtkblist->statusbox);
+
+		status_type_id = gtk_gaim_status_box_get_active_type(status_box);
+		gaim_presence_set_status_active(ret->presence, status_type_id, TRUE);
+		g_free(status_type_id);
+	}
 
 	return ret;
 }
@@ -1717,6 +1725,7 @@
 
 	notebook = gtk_notebook_new();
 	gtk_box_pack_start(GTK_BOX(main_vbox), notebook, FALSE, FALSE, 0);
+	gtk_widget_show(GTK_WIDGET(notebook));
 
 	/* Setup the inner vbox */
 	dialog->top_vbox = vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER);
@@ -1734,10 +1743,10 @@
 	gtk_container_set_border_width(GTK_CONTAINER(dbox), GAIM_HIG_BORDER);
 	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dbox,
 			gtk_label_new_with_mnemonic("_Advanced"));
+	gtk_widget_show(dbox);
 
 	/** Setup the bottom frames. */
 	add_protocol_options(dialog, dbox);
-	gtk_widget_show_all(GTK_WIDGET(notebook));
 	add_proxy_options(dialog, dbox);
 
 	/* Setup the button box */
--- a/src/gtkblist.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/gtkblist.c	Mon Oct 10 17:59:48 2005 +0000
@@ -1114,11 +1114,12 @@
 static void
 blist_node_menu_cb(GtkMenuItem *item, GaimBlistNode *node)
 {
-	GaimBlistNodeAction *act;
-	act = (GaimBlistNodeAction *) g_object_get_data(G_OBJECT(item),
-			"gaimcallback");
-	if(act->callback)
-		act->callback(node, act->data);
+	void (*callback)(GaimBlistNode *, gpointer);
+	gpointer data;
+	callback = g_object_get_data(G_OBJECT(item), "gaimcallback");
+	data = g_object_get_data(G_OBJECT(item), "gaimcallbackdata");
+	if (callback)
+		callback(node, data);
 }
 
 
@@ -1140,7 +1141,9 @@
 			menuitem = gtk_menu_item_new_with_mnemonic(act->label);
 			if (act->callback != NULL) {
 				g_object_set_data(G_OBJECT(menuitem), "gaimcallback",
-				                  act);
+				                  act->callback);
+				g_object_set_data(G_OBJECT(menuitem), "gaimcallbackdata",
+				                  act->data);
 				g_signal_connect(G_OBJECT(menuitem), "activate",
 				                 G_CALLBACK(blist_node_menu_cb), node);
 			} else {
@@ -1161,11 +1164,11 @@
 				GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data;
 
 				append_blist_node_action(submenu, act, node, dup_separator);
-
-				g_list_free(act->children);
-				act->children = NULL;
 			}
+			g_list_free(act->children);
+			act->children = NULL;
 		}
+		g_free(act);
 	}
 }
 
--- a/src/gtkconn.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/gtkconn.c	Mon Oct 10 17:59:48 2005 +0000
@@ -187,13 +187,15 @@
 				  gaim_account_get_protocol_name(account));
 	    }
 	
-	    p = g_strdup_printf(_("%s could not connect"), n);
-	    s = g_strdup_printf(_("%s was unable to connect due to an error. %s The account has been disabled. "
-				  "Correct the error and reenable to account to connect."), n, text);
+	    p = g_strdup_printf(_("%s disconnected"), n);
+	    s = g_strdup_printf(_("%s was disconnected due to an error. %s The account has been disabled. "
+				  "Correct the error and reenable the account to connect."), n, text);
 	    gaim_notify_error(NULL, NULL, p, s);
 	    g_free(p);
 	    g_free(s);
 	    g_free(n);
+		/* XXX: do we really want to disable the account when it's disconnected by wants_to_die?
+		 *      This normally happens when you sign on from somewhere else. */
 	    gaim_account_set_enabled(account, GAIM_GTK_UI, FALSE);
 	}
 }
--- a/src/gtkprefs.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/gtkprefs.c	Mon Oct 10 17:59:48 2005 +0000
@@ -1330,6 +1330,7 @@
 		label = gaim_gtk_prefs_dropdown_from_list(vbox,_("_Browser:"), GAIM_PREF_STRING,
 										 "/gaim/gtk/browsers/browser",
 										 browsers);
+		g_list_free(browsers);
 		gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 		gtk_size_group_add_widget(sg, label);
 
@@ -1387,6 +1388,7 @@
 	GList *names;
 	GtkWidget *sys_box;
 	GtkWidget *box;
+
 	int syslog_enabled = gaim_prefs_get_bool("/core/logging/log_system");
 
 	ret = gtk_vbox_new(FALSE, GAIM_HIG_CAT_SPACE);
@@ -1398,6 +1400,8 @@
 	gaim_gtk_prefs_dropdown_from_list(vbox, _("Log _Format:"), GAIM_PREF_STRING,
 				 "/core/logging/format", names);
 
+	g_list_free(names);
+
 	gaim_gtk_prefs_checkbox(_("_Log all instant messages"),
 				  "/core/logging/log_ims", vbox);
 	gaim_gtk_prefs_checkbox(_("Log all c_hats"),
--- a/src/gtkstatusbox.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/gtkstatusbox.c	Mon Oct 10 17:59:48 2005 +0000
@@ -432,6 +432,7 @@
 			   TITLE_COLUMN, text,
 			   DESC_COLUMN, sec_text,
 			   TYPE_COLUMN, edit, -1);
+	g_free(t);
 }
 
 void
@@ -476,39 +477,45 @@
 
 static void remove_typing_cb(GtkGaimStatusBox *box)
 {
-	gchar *status_type_id;
+	gchar *status_type_id, *title;
 	GList *l;
 	GtkTreeIter iter;
 
 	gtk_combo_box_get_active_iter(GTK_COMBO_BOX(box), &iter);
-	gtk_tree_model_get(GTK_TREE_MODEL(box->dropdown_store), &iter, TYPE_COLUMN, &status_type_id, -1);
+	gtk_tree_model_get(GTK_TREE_MODEL(box->dropdown_store), &iter,
+					   TYPE_COLUMN, &status_type_id,
+					   TITLE_COLUMN, &title, -1);
 	for (l = gaim_accounts_get_all(); l != NULL; l = l->next) {
 		GaimAccount *account = (GaimAccount*)l->data;
 		GaimStatusType *status_type;
+		gchar *msg;
 
 		if (!gaim_account_get_enabled(account, GAIM_GTK_UI))
 			continue;
 
 		/* I am not very comfortable with this, but can't think of a better way. */
+		/* XXX: this is definitely wrong - the specific account's saved status should
+		 * be looked for */
 		if (!strcmp(status_type_id, "saved"))
 		{
-			char *title;
 			GaimSavedStatus *saved = NULL;
 			GaimStatusPrimitive type;
 
-			gtk_tree_model_get(GTK_TREE_MODEL(box->dropdown_store),
-			                   &iter, TITLE_COLUMN, &title, -1);
 			saved = gaim_savedstatus_find(title);
 			type = gaim_savedstatus_get_type(saved);
-			status_type_id = (gchar *)gaim_primitive_get_id_from_type(type);
+			g_free(status_type_id);
+			status_type_id = g_strdup(gaim_primitive_get_id_from_type(type));
 		}
 
 		status_type = gaim_account_get_status_type(account, status_type_id);
 
 		if (status_type == NULL)
 			continue;
+
+		msg = gtk_imhtml_get_markup(GTK_IMHTML(box->imhtml));
 		gaim_account_set_status(account, status_type_id, TRUE,
-					"message",gtk_imhtml_get_markup(GTK_IMHTML(box->imhtml)), NULL);
+					"message", msg, NULL);
+		g_free(msg);
 	}
 	g_source_remove(box->typing);
 	box->typing = 0;
@@ -517,6 +524,8 @@
 	/* How about saving the status here.. where title = first X characters of the message.
 	 * The user can alway edit the title later from Tools->Statuses if necessary
 	 */
+	g_free(status_type_id);
+	g_free(title);
 }
 
 static void gtk_gaim_status_box_changed(GtkComboBox *box)
@@ -536,13 +545,16 @@
 			   TYPE_COLUMN, &status_type_id, -1);
 	if (status_box->title)
 		g_free(status_box->title);
-	status_box->title = g_strdup(text);
+	status_box->title = text;
 	if (status_box->desc && sec_text)
- 		g_free(status_box->desc);
-	status_box->desc = g_strdup(sec_text);
+		g_free(status_box->desc);
+	status_box->desc = sec_text;
 	if (status_box->pixbuf)
 		g_object_unref(status_box->pixbuf);
 	status_box->pixbuf = pixbuf;
+	if (status_box->typing)
+		g_source_remove(status_box->typing);
+	status_box->typing = 0;
 
 	if (!strcmp(status_type_id, "away") || !strcmp(status_type_id, "saved")) {
 		gtk_widget_show_all(status_box->vbox);
@@ -557,10 +569,6 @@
 			gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), gaim_savedstatus_get_message(status), 0);
 		}
 	} else {
-		if (status_box->typing) {
-			g_source_remove(status_box->typing);
-			status_box->typing = 0;
-		}
 		gtk_widget_hide_all(status_box->vbox);
 		for (l = gaim_accounts_get_all(); l != NULL; l = l->next) {
 			GaimAccount *account = (GaimAccount*)l->data;
@@ -576,6 +584,7 @@
 			gaim_account_set_status(account, status_type_id, TRUE, NULL);
 		}
 	}
+	g_free(status_type_id);
 	gtk_gaim_status_box_refresh(status_box);
 }
 
@@ -590,7 +599,7 @@
 	gtk_gaim_status_box_refresh(box);
 }
 
-const char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box)
+char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box)
 {
 	GtkTreeIter iter;
 	char *type;
@@ -600,7 +609,7 @@
 	return type;
 }
 
-const char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box)
+char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box)
 {
 	if (status_box->imhtml_visible)
 		return gtk_imhtml_get_markup(GTK_IMHTML(status_box->imhtml));
--- a/src/gtkstatusbox.h	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/gtkstatusbox.h	Mon Oct 10 17:59:48 2005 +0000
@@ -119,9 +119,9 @@
 gtk_gaim_status_box_pulse_connecting(GtkGaimStatusBox *status_box);
 
 
-const char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box);
+char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box);
 
-const char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box);
+char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box);
 
 G_END_DECLS
 
--- a/src/gtkutils.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/gtkutils.c	Mon Oct 10 17:59:48 2005 +0000
@@ -1352,12 +1352,14 @@
 gboolean
 gaim_running_gnome(void)
 {
+	gchar *tmp = g_find_program_in_path("gnome-open");
 	if ((g_getenv("GNOME_DESKTOP_SESSION_ID") != NULL) &&
-		(g_find_program_in_path("gnome-open") != NULL))
+		(tmp != NULL))
 	{
+		g_free(tmp);
 		return TRUE;
 	}
-
+	g_free(tmp);
 	return FALSE;
 }
 
--- a/src/protocols/gg/gg.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/protocols/gg/gg.c	Mon Oct 10 17:59:48 2005 +0000
@@ -717,7 +717,7 @@
 			break;
 		case GG_STATUS_AVAIL:
 		case GG_STATUS_AVAIL_DESCR:
-			st = "online";
+			st = "available";
 			break;
 		case GG_STATUS_BUSY:
 		case GG_STATUS_BUSY_DESCR:
@@ -728,7 +728,7 @@
 			st = "blocked";
 			break;
 		default:
-			st = "online";
+			st = "available";
 			gaim_debug_info("gg", "GG_EVENT_NOTIFY: Unknown status: %d\n", status);
 			break;
 	}
@@ -1002,7 +1002,7 @@
 		*se = "offline";
 	} else if (gaim_presence_is_status_active(presence, "away")) {
 		*se = "away";
-	} else if (gaim_presence_is_status_active(presence, "online")) {
+	} else if (gaim_presence_is_status_active(presence, "available")) {
 		*se = "online";
 	} else if (gaim_presence_is_status_active(presence, "offline")) {
 		*se = "offline";
@@ -1084,20 +1084,15 @@
 					       gaim_value_new(GAIM_TYPE_STRING), NULL);
 	types = g_list_append(types, type);
 
-	type = gaim_status_type_new_with_attrs(GAIM_STATUS_AVAILABLE, "online", _("Online"),
+	type = gaim_status_type_new_with_attrs(GAIM_STATUS_AVAILABLE, "available", _("Online"),
 	                                       TRUE, TRUE, FALSE, "message", _("Message"),
 					       gaim_value_new(GAIM_TYPE_STRING), NULL);
 	types = g_list_append(types, type);
 
 	/*
-	 * Without this selecting Available or Invisible as own status doesn't
+	 * Without this selecting Invisible as own status doesn't
 	 * work. It's not used and not needed to show status of buddies.
 	 */
-	type = gaim_status_type_new_with_attrs(GAIM_STATUS_AVAILABLE, "available", _("Available"),
-					       TRUE, TRUE, FALSE, "message", _("Message"),
-					       gaim_value_new(GAIM_TYPE_STRING), NULL);
-	types = g_list_append(types, type);
-
 	type = gaim_status_type_new_with_attrs(GAIM_STATUS_HIDDEN, "invisible", _("Invisible"),
 					       TRUE, TRUE, FALSE, "message", _("Message"),
 					       gaim_value_new(GAIM_TYPE_STRING), NULL);
--- a/src/protocols/msn/userlist.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/protocols/msn/userlist.c	Mon Oct 10 17:59:48 2005 +0000
@@ -651,10 +651,17 @@
 
 	if (!gaim_email_is_valid(who))
 	{
-		char *str = g_strdup_printf(_("Unable to add \"%s\"."), who);
-		gaim_notify_error(NULL, NULL, str,
-						  _("The screen name specified is invalid."));
-		g_free(str);
+		/* only notify the user about problems adding to the friends list
+		 * maybe we should do something else for other lists, but it probably
+		 * won't cause too many problems if we just ignore it */
+		if (list_id == MSN_LIST_FL)
+		{
+			char *str = g_strdup_printf(_("Unable to add \"%s\"."), who);
+			gaim_notify_error(NULL, NULL, str,
+							  _("The screen name specified is invalid."));
+			g_free(str);
+		}
+
 		return;
 	}
 
--- a/src/protocols/napster/napster.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/protocols/napster/napster.c	Mon Oct 10 17:59:48 2005 +0000
@@ -304,7 +304,7 @@
 
 	case 201: /* MSG_SERVER_SEARCH_RESULT */
 		res = g_strsplit(buf, " ", 0);
-		gaim_prpl_got_user_status(account, res[0], "online", NULL);
+		gaim_prpl_got_user_status(account, res[0], "available", NULL);
 		g_strfreev(res);
 		break;
 
@@ -323,7 +323,7 @@
 	case 209: /* MSG_SERVER_USER_SIGNON */
 		/* USERNAME SPEED */
 		res = g_strsplit(buf, " ", 2);
-		gaim_prpl_got_user_status(account, res[0], "online", NULL);
+		gaim_prpl_got_user_status(account, res[0], "available", NULL);
 		g_strfreev(res);
 		break;
 
@@ -574,7 +574,7 @@
 	types = g_list_append(types, type);
 
 	type = gaim_status_type_new_full(GAIM_STATUS_AVAILABLE,
-									 "online",
+									 "available",
 									 _("Online"), TRUE, TRUE, FALSE);
 	types = g_list_append(types, type);
 
--- a/src/protocols/sametime/sametime.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/protocols/sametime/sametime.c	Mon Oct 10 17:59:48 2005 +0000
@@ -407,38 +407,37 @@
 				   struct mwAwareSnapshot *aware) {
 
   GaimConnection *gc;
+  GaimAccount *acct;
   struct mwGaimPluginData *pd;
-
-  time_t idle = 0;
+  const char *status_id = MW_STATE_ACTIVE;
+  gboolean idle = FALSE;
+
   guint stat = aware->status.status;
 
   const char *id = aware->id.user;
 
   gc = mwAwareList_getClientData(list);
   pd = gc->proto_data;
+  acct = gaim_connection_get_account(gc);
   
   switch(stat) {
   case mwStatus_IDLE:
-    idle = -1;
+    idle = TRUE;
     break;
     
   case mwStatus_AWAY:
+  	status_id = MW_STATE_AWAY;
+	break;
   case mwStatus_BUSY:
-    /* need to let gaim know that these are 'unavailable' states */
-
-    /* XXX */
-    /* stat |= UC_UNAVAILABLE; */
-
+    status_id = MW_STATE_BUSY;
     break;
   }
   
   if(aware->group) {
-    GaimAccount *acct;
     GaimGroup *group;
     GaimBuddy *buddy;
     GaimBlistNode *bnode;
 
-    acct = gaim_connection_get_account(gc);
     group = g_hash_table_lookup(pd->group_list_map, list);
     buddy = gaim_find_buddy_in_group(acct, id, group);
     bnode = (GaimBlistNode *) buddy;
@@ -467,8 +466,13 @@
     gaim_blist_node_set_int(bnode, BUDDY_KEY_TYPE, mwSametimeUser_NORMAL);
   }
   
-  /* XXX */
-  /* serv_got_update(gc, id, aware->online, 0, 0, idle, stat); */
+  gaim_prpl_got_user_status(acct, id, status_id, NULL);
+  gaim_prpl_got_user_login_time(acct, id, aware->online - time(NULL));
+
+  if (idle)
+    gaim_prpl_got_user_idle(acct, id, TRUE, -1);
+  else
+    gaim_prpl_got_user_idle(acct, id, FALSE, 0);
 }
 
 
@@ -3474,17 +3478,31 @@
 }
 
 
-#if 0
-static void mw_prpl_set_away(GaimConnection *gc,
-			     const char *state,
-			     const char *message) {
-  GaimAccount *acct;
+static void mw_prpl_set_status(GaimAccount *acct, GaimStatus *status) {
+  GaimConnection *gc;
+  const char *state;
+  char *message;
   struct mwSession *session;
   struct mwUserStatus stat;
-  
-  acct = gaim_connection_get_account(gc);
+
   g_return_if_fail(acct != NULL);
-    
+  gc = gaim_account_get_connection(acct);
+
+  state = gaim_status_get_id(status);
+
+  gaim_debug_info("meanwhile", "Set status to %s\n", gaim_status_get_name(status));
+
+  if (!strcmp(state, "offline") && (gc != NULL)) {
+     gaim_account_disconnect(acct);
+     return;
+  }
+  else if (strcmp(state, "offline") && (gc == NULL)) {
+     gaim_account_connect(acct);
+     return;
+  }
+
+  g_return_if_fail(gc != NULL);
+
   session = gc_to_session(gc);
   g_return_if_fail(session != NULL);
 
@@ -3492,47 +3510,24 @@
   mwUserStatus_clone(&stat, mwSession_getUserStatus(session));
 
   /* determine the state */
-  if(state) {
-    if(! strcmp(state, GAIM_AWAY_CUSTOM)) {
-      if(message) {
-	stat.status = mwStatus_AWAY;
-      } else {
-	stat.status = mwStatus_ACTIVE;
-      }
-
-    } else if(! strcmp(state, MW_STATE_AWAY)) {
-      stat.status = mwStatus_AWAY;
-
-    } else if(! strcmp(state, MW_STATE_BUSY)) {
-      stat.status = mwStatus_BUSY;
-
-    } else if(! strcmp(state, MW_STATE_ACTIVE)) {
-      stat.status = mwStatus_ACTIVE;
-    }
-
-  } else {
+  if(! strcmp(state, MW_STATE_ACTIVE)) {
     stat.status = mwStatus_ACTIVE;
+
+  } else if(! strcmp(state, MW_STATE_AWAY)) {
+    stat.status = mwStatus_AWAY;
+
+  } else if(! strcmp(state, MW_STATE_BUSY)) {
+    stat.status = mwStatus_BUSY;
   }
 
   /* determine the message */
-  if(! message) {
-    switch(stat.status) {
-    case mwStatus_AWAY:
-      message = gaim_account_get_string(acct, MW_KEY_AWAY_MSG,
-					MW_PLUGIN_DEFAULT_AWAY_MSG);
-      break;
-
-    case mwStatus_BUSY:
-      message = gaim_account_get_string(acct, MW_KEY_BUSY_MSG,
-					MW_PLUGIN_DEFAULT_BUSY_MSG);
-      break;
-
-    case mwStatus_ACTIVE:
-      message = gaim_account_get_string(acct, MW_KEY_ACTIVE_MSG,
-					MW_PLUGIN_DEFAULT_ACTIVE_MSG);
-      stat.time = 0;
-      break;
-    }
+  switch(stat.status) {
+  case mwStatus_ACTIVE:
+    stat.time = 0;
+  case mwStatus_AWAY:
+  case mwStatus_BUSY:
+    message = (char *)gaim_status_get_attr_string(status, MW_STATE_MESSAGE);
+    break;
   }
 
   if(message) {
@@ -3543,16 +3538,13 @@
 
   /* out with the old */
   g_free(stat.desc);
-  g_free(gc->away);
 
   /* in with the new */
   stat.desc = (char *) message;
-  gc->away = g_strdup(message);
 
   mwSession_setUserStatus(session, &stat);
-  mwUserStatus_clear(&stat);  
+  mwUserStatus_clear(&stat);
 }
-#endif
 
 
 static void mw_prpl_set_idle(GaimConnection *gc, int time) {
@@ -4386,6 +4378,7 @@
   .set_info                  = NULL,
   .send_typing               = mw_prpl_send_typing,
   .get_info                  = mw_prpl_get_info,
+  .set_status                = mw_prpl_set_status,
   .set_idle                  = mw_prpl_set_idle,
   .change_passwd             = NULL,
   .add_buddy                 = mw_prpl_add_buddy,
--- a/src/protocols/zephyr/zephyr.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/protocols/zephyr/zephyr.c	Mon Oct 10 17:59:48 2005 +0000
@@ -732,7 +732,7 @@
 				g_string_free(str, TRUE);
 			} else {
 				if (nlocs>0) 
-					gaim_prpl_got_user_status(gc->account,b->name,"online",NULL);
+					gaim_prpl_got_user_status(gc->account,b->name,"available",NULL);
 				else 
 					gaim_prpl_got_user_status(gc->account,b->name,"offline",NULL);
 			}
@@ -1147,7 +1147,7 @@
 					g_string_free(str, TRUE);
 				} else {
 					if (nlocs>0) 
-						gaim_prpl_got_user_status(gc->account,b->name,"online",NULL);
+						gaim_prpl_got_user_status(gc->account,b->name,"available",NULL);
 					else 
 						gaim_prpl_got_user_status(gc->account,b->name,"offline",NULL);
 				}
@@ -1286,7 +1286,7 @@
 							for(i=0;i<numlocs;i++) {
 								ZGetLocations(&locations,&one);
 								if (nlocs>0) 
-									gaim_prpl_got_user_status(gc->account,b->name,"online",NULL);
+									gaim_prpl_got_user_status(gc->account,b->name,"available",NULL);
 								else 
 									gaim_prpl_got_user_status(gc->account,b->name,"offline",NULL);
 							}
@@ -2208,7 +2208,7 @@
 	if (!strcmp(status_id,"away")) {
 		zephyr->away = g_strdup(gaim_status_get_attr_string(status,"message"));
 	} 
-	else if (!strcmp(status_id,"online")) {
+	else if (!strcmp(status_id,"available")) {
 		if (use_zeph02(zephyr)) {
 			ZSetLocation(zephyr->exposure);
 		}
@@ -2249,7 +2249,7 @@
 	   Away won't change their exposure but will set an auto away message (for IMs only)
 	*/
 	
-	type = gaim_status_type_new(GAIM_STATUS_AVAILABLE, "online", _("Online"), FALSE);
+	type = gaim_status_type_new(GAIM_STATUS_AVAILABLE, "available", _("Online"), FALSE);
 	types = g_list_append(types,type);
 
 	type = gaim_status_type_new(GAIM_STATUS_HIDDEN, "hidden", _("Hidden"), FALSE);
--- a/src/status.c	Mon Oct 10 12:29:30 2005 +0000
+++ b/src/status.c	Mon Oct 10 17:59:48 2005 +0000
@@ -598,7 +598,8 @@
 	g_return_if_fail(status != NULL);
 
 	/* TODO: Don't do this is if the status is exclusive */
-	gaim_status_set_active(status, FALSE);
+	/* XXX: why do this at all?
+	gaim_status_set_active(status, FALSE); */
 
 	g_hash_table_destroy(status->attr_values);
 
@@ -1107,7 +1108,7 @@
 
 	presence->status_table =
 		g_hash_table_new_full(g_str_hash, g_str_equal,
-							  g_free, (GFreeFunc)gaim_status_destroy);
+							  g_free, NULL);
 
 	return presence;
 }
@@ -1203,8 +1204,10 @@
 			g_free(presence->u.chat.user);
 	}
 
-	if (presence->statuses != NULL)
+	if (presence->statuses != NULL) {
+		g_list_foreach(presence->statuses, (GFunc)gaim_status_destroy, NULL);
 		g_list_free(presence->statuses);
+	}
 
 	g_hash_table_destroy(presence->status_table);