changeset 4111:ee884f1d7ae3

[gaim-migrate @ 4326] <Robot101> adds a gc->flag called OPT_CONN_AUTO_RESP so that gc->away can always store the away message even if the prpl doesn't support autoresponding <Robot101> makes all protos correctly free and set gc->away to avoid leaks <Robot101> stores the current away state in gc->away_state whenever gc->away is non-NULL (ie it's not just a plain on-line) <Robot101> also minor change to Jabber to make Chatty an away state, and to Gadu-Gadu to make some other thing an away state too committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sat, 21 Dec 2002 19:33:54 +0000
parents 64d983d6b7bb
children 12552607e88c
files src/multi.c src/multi.h src/protocols/gg/gg.c src/protocols/icq/gaim_icq.c src/protocols/irc/irc.c src/protocols/jabber/jabber.c src/protocols/msn/msn.c src/protocols/oscar/oscar.c src/protocols/toc/toc.c src/protocols/yahoo/yahoo.c src/protocols/zephyr/zephyr.c src/server.c
diffstat 12 files changed, 111 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/src/multi.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/multi.c	Sat Dec 21 19:33:54 2002 +0000
@@ -89,6 +89,8 @@
 	gc->groups = NULL;
 	gc->permit = NULL;
 	gc->deny = NULL;
+	gc->away = NULL;
+	gc->away_state = NULL;
 
 	connections = g_slist_append(connections, gc);
 
@@ -134,6 +136,8 @@
 		g_free(g->data);
 		g = g_slist_remove(g, g->data);
 	}
+	g_free(gc->away);
+	g_free(gc->away_state);
 	g_free(gc);
 
 	if (!connections && mainwindow)
--- a/src/multi.h	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/multi.h	Sat Dec 21 19:33:54 2002 +0000
@@ -59,6 +59,7 @@
 	char displayname[128];
 	char password[32];
 	guint keepalive;
+
 	/* stuff needed for per-connection idle times */
 	guint idle_timer;
 	time_t login_time;
@@ -66,14 +67,19 @@
 	int is_idle;
 	time_t correction_time;
 
-	char *away;
-	int is_auto_away;
+	char *away;		/* set by protos, is NULL when not away, or set *
+				 * to "" or a custom message when away */
+	char *away_state;	/* updated by serv_set_away, keeps the last set *
+				 * away type */
+	int is_auto_away;	/* used by idle.c */
 
-	int evil;
-	gboolean wants_to_die; /* defaults to FALSE */
+	int evil;		/* warning level for AIM (why is this here?) */
+	gboolean wants_to_die;	/* defaults to FALSE */
 };
 
 #define OPT_CONN_HTML		0x00000001
+/* set this flag on a gc if you want serv_got_im to autoreply when away */
+#define OPT_CONN_AUTO_RESP	0x00000002
 
 struct proto_user_opt {
 	char *label;
--- a/src/protocols/gg/gg.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/gg/gg.c	Sat Dec 21 19:33:54 2002 +0000
@@ -1,6 +1,6 @@
 /*
  * gaim - Gadu-Gadu Protocol Plugin
- * $Id: gg.c 4269 2002-12-11 02:09:43Z lschiere $
+ * $Id: gg.c 4326 2002-12-21 19:33:54Z chipx86 $
  *
  * Copyright (C) 2001 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
  * 
@@ -194,32 +194,35 @@
 	struct agg_data *gd = (struct agg_data *)gc->proto_data;
 	int status = gd->own_status;
 
-	if (gc->away)
+	if (gc->away) {
+		g_free(gc->away);
 		gc->away = NULL;
+	}
 
 	if (!g_strcasecmp(state, AGG_STATUS_AVAIL))
 		status = GG_STATUS_AVAIL;
-	else if (!g_strcasecmp(state, AGG_STATUS_AVAIL_FRIENDS))
+	else if (!g_strcasecmp(state, AGG_STATUS_AVAIL_FRIENDS)) {
 		status = GG_STATUS_AVAIL | GG_STATUS_FRIENDS_MASK;
-	else if (!g_strcasecmp(state, AGG_STATUS_BUSY)) {
+		gc->away = g_strdup("");
+	} else if (!g_strcasecmp(state, AGG_STATUS_BUSY)) {
 		status = GG_STATUS_BUSY;
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!g_strcasecmp(state, AGG_STATUS_BUSY_FRIENDS)) {
 		status =  GG_STATUS_BUSY | GG_STATUS_FRIENDS_MASK;
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!g_strcasecmp(state, AGG_STATUS_INVISIBLE)) {
 		status = GG_STATUS_INVISIBLE;
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!g_strcasecmp(state, AGG_STATUS_INVISIBLE_FRIENDS)) {
 		status = GG_STATUS_INVISIBLE | GG_STATUS_FRIENDS_MASK;
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!g_strcasecmp(state, AGG_STATUS_NOT_AVAIL)) {
 		status = GG_STATUS_NOT_AVAIL;
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) {
 		if (msg) {
 			status = GG_STATUS_BUSY;
-			gc->away = "";
+			gc->away = g_strdup("");
 		} else
 			status = GG_STATUS_AVAIL;
 
--- a/src/protocols/icq/gaim_icq.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/icq/gaim_icq.c	Sat Dec 21 19:33:54 2002 +0000
@@ -397,33 +397,35 @@
 static void icq_set_away(struct gaim_connection *gc, char *state, char *msg) {
 	struct icq_data *id = (struct icq_data *)gc->proto_data;
 
-	if (gc->away)
+	if (gc->away) {
+		g_free(gc->away);
 		gc->away = NULL;
+	}
 
 	if (!strcmp(state, "Online"))
 		icq_ChangeStatus(id->link, STATUS_ONLINE);
 	else if (!strcmp(state, "Away")) {
 		icq_ChangeStatus(id->link, STATUS_AWAY);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Do Not Disturb")) {
 		icq_ChangeStatus(id->link, STATUS_DND);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Not Available")) {
 		icq_ChangeStatus(id->link, STATUS_NA);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Occupied")) {
 		icq_ChangeStatus(id->link, STATUS_OCCUPIED);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Free For Chat")) {
 		icq_ChangeStatus(id->link, STATUS_FREE_CHAT);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Invisible")) {
 		icq_ChangeStatus(id->link, STATUS_INVISIBLE);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, GAIM_AWAY_CUSTOM)) {
 		if (msg) {
 			icq_ChangeStatus(id->link, STATUS_NA);
-			gc->away = "";
+			gc->away = g_strdup("");
 		} else {
 			icq_ChangeStatus(id->link, STATUS_ONLINE);
 		}
--- a/src/protocols/irc/irc.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/irc/irc.c	Sat Dec 21 19:33:54 2002 +0000
@@ -2290,14 +2290,17 @@
 	struct irc_data *idata = gc->proto_data;
 	char buf[IRC_BUF_LEN];
 
-	if (gc->away)
+	if (gc->away) {
+		g_free(gc->away);
 		gc->away = NULL;
+	}
 
 	if (msg) {
 		g_snprintf(buf, sizeof(buf), "AWAY :%s\r\n", msg);
-		gc->away = "";
+		gc->away = g_strdup(msg);
 	} else
 		g_snprintf(buf, sizeof(buf), "AWAY\r\n");
+
 	irc_write(idata->fd, buf, strlen(buf));
 }
 
--- a/src/protocols/jabber/jabber.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/jabber/jabber.c	Sat Dec 21 19:33:54 2002 +0000
@@ -3313,7 +3313,10 @@
 	char *chatname;
 	gboolean invisible = FALSE;
 
-	gc->away = NULL; /* never send an auto-response */
+	if (gc->away) {
+		g_free(gc->away);
+		gc->away = NULL;
+	}
 
 	x = xmlnode_new_tag("presence");
 
@@ -3325,7 +3328,7 @@
 			xmlnode_insert_cdata(y, "away", -1);
 			y = xmlnode_insert_tag(x, "status");
 			xmlnode_insert_cdata(y, message, -1);
-			gc->away = "";
+			gc->away = g_strdup(message);
 		} else {
 			/* Gaim wants us to not be away */
 			/* but for Jabber, we can just send presence with no other information. */
@@ -3337,21 +3340,22 @@
 		} else if (!strcmp(state, "Chatty")) {
 			y = xmlnode_insert_tag(x, "show");
 			xmlnode_insert_cdata(y, "chat", -1);
+			gc->away = g_strdup("");
 		} else if (!strcmp(state, "Away")) {
 			y = xmlnode_insert_tag(x, "show");
 			xmlnode_insert_cdata(y, "away", -1);
-			gc->away = "";
+			gc->away = g_strdup("");
 		} else if (!strcmp(state, "Extended Away")) {
 			y = xmlnode_insert_tag(x, "show");
 			xmlnode_insert_cdata(y, "xa", -1);
-			gc->away = "";
+			gc->away = g_strdup("");
 		} else if (!strcmp(state, "Do Not Disturb")) {
 			y = xmlnode_insert_tag(x, "show");
 			xmlnode_insert_cdata(y, "dnd", -1);
-			gc->away = "";
+			gc->away = g_strdup("");
 		} else if (!strcmp(state, "Invisible")) {
 			xmlnode_put_attrib(x, "type", "invisible");
-			gc->away = "";
+			gc->away = g_strdup("");
 			invisible = TRUE;
 		}
 	}
--- a/src/protocols/msn/msn.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/msn/msn.c	Sat Dec 21 19:33:54 2002 +0000
@@ -1881,13 +1881,16 @@
 	char buf[MSN_BUF_LEN];
 	char *away;
 
-	gc->away = NULL;
+	if (gc->away) {
+		g_free(gc->away);
+		gc->away = NULL;
+	}
 
 	if (msg) {
-		gc->away = "";
+		gc->away = g_strdup("");
 		away = "AWY";
 	} else if (state) {
-		gc->away = "";
+		gc->away = g_strdup("");
 
 		if (!strcmp(state, _("Away From Computer")))
 			away = "AWY";
@@ -1902,6 +1905,7 @@
 		else if (!strcmp(state, _("Hidden")))
 			away = "HDN";
 		else {
+			g_free(gc->away);
 			gc->away = NULL;
 			away = "NLN";
 		}
--- a/src/protocols/oscar/oscar.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/oscar/oscar.c	Sat Dec 21 19:33:54 2002 +0000
@@ -626,6 +626,7 @@
 	} else {
 		gc->protocol = PROTO_TOC;
 		gc->flags |= OPT_CONN_HTML;
+		gc->flags |= OPT_CONN_AUTO_RESP;
 	}
 	odata->supports_tn = g_hash_table_new(g_str_hash, g_str_equal);
 
@@ -3634,9 +3635,10 @@
 				_("You have probably requested to set your away message before the login procedure completed.  "
 				  "You remain in a \"present\" state; try setting it again when you are fully connected."), GAIM_ERROR);
 	
-	if (gc->away)
+	if (gc->away) {
 		g_free(gc->away);
-	gc->away = NULL;
+		gc->away = NULL;
+	}
 
 	if (!message) {
 		aim_bos_setprofile(od->sess, od->conn, NULL, "", caps_aim);
@@ -3661,33 +3663,35 @@
 static void oscar_set_away_icq(struct gaim_connection *gc, struct oscar_data *od, const char *state, const char *message)
 {
 
-	if (gc->away)
+	if (gc->away) {
+		g_free(gc->away);
 		gc->away = NULL;
+	}
 
 	if (!strcmp(state, "Online"))
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
 	else if (!strcmp(state, "Away")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Do Not Disturb")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Not Available")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Occupied")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Free For Chat")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_CHAT);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, "Invisible")) {
 		aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE);
-		gc->away = "";
+		gc->away = g_strdup("");
 	} else if (!strcmp(state, GAIM_AWAY_CUSTOM)) {
 	 	if (message) {
 			aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY);
-			gc->away = "";
+			gc->away = g_strdup("");
 		} else {
 			aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
 		}
--- a/src/protocols/toc/toc.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/toc/toc.c	Sat Dec 21 19:33:54 2002 +0000
@@ -189,6 +189,7 @@
 	gc = new_gaim_conn(user);
 	gc->proto_data = tdt = g_new0(struct toc_data, 1);
 	gc->flags |= OPT_CONN_HTML;
+	gc->flags |= OPT_CONN_AUTO_RESP;
 
 	g_snprintf(buf, sizeof buf, "Looking up %s",
 		   user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : TOC_HOST);
@@ -1037,9 +1038,10 @@
 static void toc_set_away(struct gaim_connection *g, char *state, char *message)
 {
 	char buf[BUF_LEN * 2];
-	if (g->away)
+	if (g->away) {
 		g_free (g->away);
-	g->away = NULL;
+		g->away = NULL;
+	}
 	if (message) {
 		char *tmp = g_malloc(strlen(message) * 4 + 1);
 		strcpy(tmp, message);
--- a/src/protocols/yahoo/yahoo.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/yahoo/yahoo.c	Sat Dec 21 19:33:54 2002 +0000
@@ -1186,15 +1186,19 @@
 	int service;
 	char s[4];
 
-	gc->away = NULL;
+	if (gc->away) {
+		g_free(gc->away);
+		gc->away = NULL;
+	}
 
 	if (msg) {
 		yd->current_status = YAHOO_STATUS_CUSTOM;
-		gc->away = "";
+		gc->away = g_strdup(msg);
 	} else if (state) {
-		gc->away = "";
+		gc->away = g_strdup("");
 		if (!strcmp(state, "Available")) {
 			yd->current_status = YAHOO_STATUS_AVAILABLE;
+			g_free(gc->away);
 			gc->away = NULL;
 		} else if (!strcmp(state, "Be Right Back")) {
 			yd->current_status = YAHOO_STATUS_BRB;
@@ -1222,6 +1226,7 @@
 			} else {
 				yd->current_status = YAHOO_STATUS_AVAILABLE;
 			}
+			g_free(gc->away);
 			gc->away = NULL;
 		}
 	} else if (gc->is_idle) {
--- a/src/protocols/zephyr/zephyr.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/protocols/zephyr/zephyr.c	Sat Dec 21 19:33:54 2002 +0000
@@ -843,12 +843,15 @@
 
 static void zephyr_set_away(struct gaim_connection *gc, char *state, char *msg)
 {
-	if (gc->away)
+	if (gc->away) {
 		g_free(gc->away);
-	gc->away = NULL;
-	if (!g_strcasecmp(state, "Hidden"))
+		gc->away = NULL;
+	}
+
+	if (!g_strcasecmp(state, "Hidden")) {
 		ZSetLocation(EXPOSE_OPSTAFF);
-	else if (!g_strcasecmp(state, "Online"))
+		gc->away = g_strdup("");
+	} else if (!g_strcasecmp(state, "Online"))
 		ZSetLocation(get_exposure_level());
 	else /* state is GAIM_AWAY_CUSTOM */ if (msg)
 		gc->away = g_strdup(msg);
--- a/src/server.c	Sat Dec 21 05:37:45 2002 +0000
+++ b/src/server.c	Sat Dec 21 19:33:54 2002 +0000
@@ -232,6 +232,12 @@
 {
 	if (gc && gc->prpl && gc->prpl->set_away) {
 		char *buf = NULL;
+
+		if (gc->away_state) {
+			g_free(gc->away_state);
+			gc->away_state = NULL;
+		}
+
 		if (message) {
 			buf = g_malloc(strlen(message) + 1);
 			if (gc->flags & OPT_CONN_HTML)
@@ -242,6 +248,10 @@
 
 		gc->prpl->set_away(gc, state, buf);
 
+		if (gc->away && state) {
+			gc->away_state = g_strdup(state);
+		}
+
 		plugin_event(event_away, gc, state, buf);
 
 		if (buf)
@@ -671,10 +681,15 @@
 			write_to_conv(cnv, message, away | WFLAG_RECV, NULL, mtime, len);
 		}
 
-		/* regardless of whether we queue it or not, we should send an auto-response. That is,
-		 * of course, unless the horse.... no wait. */
-		if ((away_options & OPT_AWAY_NO_AUTO_RESP) || !strlen(gc->away) ||
-				((away_options & OPT_AWAY_IDLE_RESP) && !gc->is_idle)) {
+		/* regardless of whether we queue it or not, we should send an auto-response.
+		 * that is, of course, unless the horse.... no wait. don't autorespond if:
+		 *  - it's not supported on this connection
+		 *  - or it's disabled
+		 *  - or the away message is empty
+		 *  - or we're not idle and the 'only auto respond if idle' pref is set
+		 */
+		if (!(gc->flags & OPT_CONN_AUTO_RESP) || (away_options & OPT_AWAY_NO_AUTO_RESP) ||
+		      !strlen(gc->away) || ((away_options & OPT_AWAY_IDLE_RESP) && !gc->is_idle)) {
 			g_free(name);
 			g_free(message);
 			return;