summary refs log tree commit diff stats
path: root/src/common/outbound.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/outbound.c')
-rw-r--r--src/common/outbound.c441
1 files changed, 199 insertions, 242 deletions
diff --git a/src/common/outbound.c b/src/common/outbound.c
index 651558ce..a4611927 100644
--- a/src/common/outbound.c
+++ b/src/common/outbound.c
@@ -90,7 +90,7 @@ random_line (char *file_name)
 	{
 	 nofile:
 		/* reason is not a file, an actual reason! */
-		return strdup (file_name);
+		return g_strdup (file_name);
 	}
 
 	/* count number of lines in file */
@@ -111,7 +111,7 @@ random_line (char *file_name)
 	}
 	while (lines > ran);
 	fclose (fh);
-	return strdup (buf);
+	return g_strdup (buf);
 }
 
 void
@@ -121,7 +121,7 @@ server_sendpart (server * serv, char *channel, char *reason)
 	{
 		reason = random_line (prefs.hex_irc_part_reason);
 		serv->p_part (serv, channel, reason);
-		free (reason);
+		g_free (reason);
 	} else
 	{
 		/* reason set by /quit, /close argument */
@@ -136,12 +136,12 @@ server_sendquit (session * sess)
 
 	if (!sess->quitreason)
 	{
-		colrea = strdup (prefs.hex_irc_quit_reason);
+		colrea = g_strdup (prefs.hex_irc_quit_reason);
 		check_special_chars (colrea, FALSE);
 		rea = random_line (colrea);
-		free (colrea);
+		g_free (colrea);
 		sess->server->p_quit (sess->server, rea);
-		free (rea);
+		g_free (rea);
 	} else
 	{
 		/* reason set by /quit, /close argument */
@@ -269,7 +269,7 @@ cmd_addserver (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 		if (!network)
 		{
 			network = servlist_net_add (word[2], "", TRUE);
-			network->encoding = strdup (IRC_DEFAULT_CHARSET);
+			network->encoding = g_strdup (IRC_DEFAULT_CHARSET);
 		}
 		/* if we had the network already, check if the given server already exists */
 		else if (servlist_server_find (network, word_eol[3], NULL))
@@ -379,11 +379,10 @@ cmd_away (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 
 	if (sess->server->last_away_reason != reason)
 	{
-		if (sess->server->last_away_reason)
-			free (sess->server->last_away_reason);
+		g_free (sess->server->last_away_reason);
 
 		if (reason == word_eol[2])
-			sess->server->last_away_reason = strdup (reason);
+			sess->server->last_away_reason = g_strdup (reason);
 		else
 			sess->server->last_away_reason = reason;
 	}
@@ -406,8 +405,7 @@ cmd_back (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 		PrintText (sess, _("Already marked back.\n"));
 	}
 
-	if (sess->server->last_away_reason)
-		free (sess->server->last_away_reason);
+	g_free (sess->server->last_away_reason);
 	sess->server->last_away_reason = NULL;
 
 	return TRUE;
@@ -483,19 +481,19 @@ create_mask (session * sess, char *mask, char *mode, char *typestr, int deop)
 			switch (type)
 			{
 			case 0:
-				snprintf (buf, sizeof (buf), "%s %s *!*@%s.*", mode, p2, domain);
+				g_snprintf (buf, sizeof (buf), "%s %s *!*@%s.*", mode, p2, domain);
 				break;
 
 			case 1:
-				snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
+				g_snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
 				break;
 
 			case 2:
-				snprintf (buf, sizeof (buf), "%s %s *!%s@%s.*", mode, p2, username, domain);
+				g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s.*", mode, p2, username, domain);
 				break;
 
 			case 3:
-				snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
+				g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
 				break;
 			}
 		} else
@@ -503,26 +501,26 @@ create_mask (session * sess, char *mask, char *mode, char *typestr, int deop)
 			switch (type)
 			{
 			case 0:
-				snprintf (buf, sizeof (buf), "%s %s *!*@*%s", mode, p2, domain);
+				g_snprintf (buf, sizeof (buf), "%s %s *!*@*%s", mode, p2, domain);
 				break;
 
 			case 1:
-				snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
+				g_snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
 				break;
 
 			case 2:
-				snprintf (buf, sizeof (buf), "%s %s *!%s@*%s", mode, p2, username, domain);
+				g_snprintf (buf, sizeof (buf), "%s %s *!%s@*%s", mode, p2, username, domain);
 				break;
 
 			case 3:
-				snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
+				g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
 				break;
 			}
 		}
 
 	} else
 	{
-		snprintf (buf, sizeof (buf), "%s %s", mode, mask);
+		g_snprintf (buf, sizeof (buf), "%s %s", mode, mask);
 	}
 	
 	return g_strdup (buf);
@@ -592,7 +590,6 @@ static int
 cmd_charset (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 {
 	server *serv = sess->server;
-	const char *locale = NULL;
 	int offset = 0;
 
 	if (strcmp (word[2], "-quiet") == 0)
@@ -600,9 +597,7 @@ cmd_charset (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 
 	if (!word[2 + offset][0])
 	{
-		g_get_charset (&locale);
-		PrintTextf (sess, "Current charset: %s\n",
-						serv->encoding ? serv->encoding : locale);
+		PrintTextf (sess, "Current charset: %s\n", serv->encoding);
 		return TRUE;
 	}
 
@@ -1002,14 +997,14 @@ mdehop_cb (struct User *user, multidata *data)
 static int
 cmd_mdehop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 {
-	char **nicks = malloc (sizeof (char *) * sess->hops);
+	char **nicks = g_new0 (char *, sess->hops);
 	multidata data;
 
 	data.nicks = nicks;
 	data.i = 0;
 	tree_foreach (sess->usertree, (tree_traverse_func *)mdehop_cb, &data);
 	send_channel_modes (sess, tbuf, nicks, 0, data.i, '-', 'h', 0);
-	free (nicks);
+	g_free (nicks);
 
 	return TRUE;
 }
@@ -1028,14 +1023,14 @@ mdeop_cb (struct User *user, multidata *data)
 static int
 cmd_mdeop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 {
-	char **nicks = malloc (sizeof (char *) * sess->ops);
+	char **nicks = g_new0(char *, sess->ops);
 	multidata data;
 
 	data.nicks = nicks;
 	data.i = 0;
 	tree_foreach (sess->usertree, (tree_traverse_func *)mdeop_cb, &data);
 	send_channel_modes (sess, tbuf, nicks, 0, data.i, '-', 'o', 0);
-	free (nicks);
+	g_free (nicks);
 
 	return TRUE;
 }
@@ -1045,18 +1040,13 @@ GSList *menu_list = NULL;
 static void
 menu_free (menu_entry *me)
 {
-	free (me->path);
-	if (me->label)
-		free (me->label);
-	if (me->cmd)
-		free (me->cmd);
-	if (me->ucmd)
-		free (me->ucmd);
-	if (me->group)
-		free (me->group);
-	if (me->icon)
-		free (me->icon);
-	free (me);
+	g_free (me->path);
+	g_free (me->label);
+	g_free (me->cmd);
+	g_free (me->ucmd);
+	g_free (me->group);
+	g_free (me->icon);
+	g_free (me);
 }
 
 /* strings equal? but ignore underscores */
@@ -1115,9 +1105,9 @@ menu_del_children (char *path, char *label)
 	if (!label)
 		label = "";
 	if (path[0])
-		snprintf (buf, sizeof (buf), "%s/%s", path, label);
+		g_snprintf (buf, sizeof (buf), "%s/%s", path, label);
 	else
-		snprintf (buf, sizeof (buf), "%s", label);
+		g_snprintf (buf, sizeof (buf), "%s", label);
 
 	list = menu_list;
 	while (list)
@@ -1168,7 +1158,9 @@ menu_is_mainmenu_root (char *path, gint16 *offset)
 	{
 		if (!strncmp (path, menus[i] + 1, menus[i][0]))
 		{
-			*offset = menus[i][0] + 1;	/* number of bytes to offset the root */
+			*offset = menus[i][0];	/* number of bytes to offset the root */
+			if (path[*offset] != '\0')
+				*offset += 1;
 			return 0;	/* is not main menu */
 		}
 	}
@@ -1193,7 +1185,7 @@ menu_add (char *path, char *label, char *cmd, char *ucmd, int pos, int state, in
 		return;
 	}
 
-	me = malloc (sizeof (menu_entry));
+	me = g_new (menu_entry, 1);
 	me->pos = pos;
 	me->modifier = mod;
 	me->is_main = menu_is_mainmenu_root (path, &me->root_offset);
@@ -1201,31 +1193,26 @@ menu_add (char *path, char *label, char *cmd, char *ucmd, int pos, int state, in
 	me->markup = markup;
 	me->enable = enable;
 	me->key = key;
-	me->path = strdup (path);
+	me->path = g_strdup (path);
 	me->label = NULL;
 	me->cmd = NULL;
 	me->ucmd = NULL;
 	me->group = NULL;
 	me->icon = NULL;
 
-	if (label)
-		me->label = strdup (label);
-	if (cmd)
-		me->cmd = strdup (cmd);
-	if (ucmd)
-		me->ucmd = strdup (ucmd);
-	if (group)
-		me->group = strdup (group);
-	if (icon)
-		me->icon = strdup (icon);
+	me->label = g_strdup (label);
+	me->cmd = g_strdup (cmd);
+	me->ucmd = g_strdup (ucmd);
+	me->group = g_strdup (group);
+	me->icon = g_strdup (icon);
 
 	menu_list = g_slist_append (menu_list, me);
 	label = fe_menu_add (me);
 	if (label)
 	{
 		/* FE has given us a stripped label */
-		free (me->label);
-		me->label = strdup (label);
+		g_free (me->label);
+		me->label = g_strdup (label);
 		g_free (label); /* this is from pango */
 	}
 }
@@ -1321,7 +1308,7 @@ cmd_menu (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 	if (markup)
 	{
 		char *p;	/* to force pango closing tags through */
-		for (p = label; *p; p++)
+		for (p = label; p && *p; p++)
 			if (*p == 3)
 				*p = '/';
 	}
@@ -1454,7 +1441,7 @@ exec_check_process (struct session *sess)
 	{
 		close (sess->running_exec->myfd);
 		fe_input_remove (sess->running_exec->iotag);
-		free (sess->running_exec);
+		g_free (sess->running_exec);
 		sess->running_exec = NULL;
 	}
 }
@@ -1531,11 +1518,10 @@ cmd_execw (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 		return FALSE;
 	}
 	len = strlen(word_eol[2]);
-	temp = malloc(len + 2);
-	sprintf(temp, "%s\n", word_eol[2]);
+	temp = g_strconcat (word_eol[2], "\n", NULL);
 	PrintText(sess, temp);
 	write(sess->running_exec->myfd, temp, len + 1);
-	free(temp);
+	g_free(temp);
 
 	return TRUE;
 }
@@ -1559,7 +1545,7 @@ exec_handle_colors (char *buf, int len)
 	if (strchr (buf, 27) == 0)
 		return;
 
-	nbuf = malloc (len + 1);
+	nbuf = g_malloc (len + 1);
 
 	while (i < len)
 	{
@@ -1653,7 +1639,7 @@ norm:			nbuf[j] = buf[i];
 
 	nbuf[j] = 0;
 	memcpy (buf, nbuf, j + 1);
-	free (nbuf);
+	g_free (nbuf);
 }
 
 #ifndef HAVE_MEMRCHR
@@ -1665,7 +1651,7 @@ memrchr (const void *block, int c, size_t size)
 	for (p = (unsigned char *)block + size; p != block; p--)
 		if (*p == c)
 			return p;
-	return 0;
+	return NULL;
 }
 #endif
 
@@ -1679,14 +1665,14 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
 	len = s->buffill;
 	if (len) {
 		/* append new data to buffered incomplete line */
-		buf = malloc(len + 2050);
+		buf = g_malloc (len + 2050);
 		memcpy(buf, s->linebuf, len);
 		readpos = buf + len;
-		free(s->linebuf);
+		g_free (s->linebuf);
 		s->linebuf = NULL;
 	}
 	else
-		readpos = buf = malloc(2050);
+		readpos = buf = g_malloc (2050);
 
 	rd = read (sok, readpos, 2048);
 	if (rd < 1)
@@ -1707,12 +1693,12 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
 			else
 				PrintText (s->sess, buf);
 		}
-		free(buf);
+		g_free(buf);
 		waitpid (s->childpid, NULL, 0);
 		s->sess->running_exec = NULL;
 		fe_input_remove (s->iotag);
 		close (sok);
-		free (s);
+		g_free (s);
 		return TRUE;
 	}
 	len += rd;
@@ -1725,7 +1711,7 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
 		rest = buf;
 	if (*rest) {
 		s->buffill = len - (rest - buf); /* = strlen(rest) */
-		s->linebuf = malloc(s->buffill + 1);
+		s->linebuf = g_malloc (s->buffill + 1);
 		memcpy(s->linebuf, rest, s->buffill);
 		*rest = '\0';
 		len -= s->buffill; /* possibly 0 */
@@ -1741,7 +1727,7 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
 			PrintText (s->sess, buf);
 	}
 
-	free(buf);
+	g_free (buf);
 	return TRUE;
 }
 
@@ -1803,8 +1789,7 @@ cmd_exec (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 			return FALSE;
 		}
 #endif
-		s = (struct nbexec *) malloc (sizeof (struct nbexec));
-		memset(s, 0, sizeof(*s));
+		s = g_new0 (struct nbexec, 1);
 		s->myfd = fds[0];
 		s->tochannel = tochannel;
 		s->sess = sess;
@@ -1851,8 +1836,9 @@ cmd_exec (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 			PrintText (sess, "Error in fork(2)\n");
 			close(fds[0]);
 			close(fds[1]);
-			free (s);
-		} else
+			g_free (s);
+		}
+		else
 		{
 			/* Parent path */
 			close(fds[1]);
@@ -1940,12 +1926,12 @@ get_bool_cb (int val, getvalinfo *info)
 {
 	char buf[512];
 
-	snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
+	g_snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
 	if (is_session (info->sess))
 		handle_command (info->sess, buf, FALSE);
 
-	free (info->cmd);
-	free (info);
+	g_free (info->cmd);
+	g_free (info);
 }
 
 static int
@@ -1956,8 +1942,8 @@ cmd_getbool (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 	if (!word[4][0])
 		return FALSE;
 
-	info = malloc (sizeof (*info));
-	info->cmd = strdup (word[2]);
+	info = g_new (getvalinfo, 1);
+	info->cmd = g_strdup (word[2]);
 	info->sess = sess;
 
 	fe_get_bool (word[3], word_eol[4], get_bool_cb, info);
@@ -1972,13 +1958,13 @@ get_int_cb (int cancel, int val, getvalinfo *info)
 
 	if (!cancel)
 	{
-		snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
+		g_snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
 		if (is_session (info->sess))
 			handle_command (info->sess, buf, FALSE);
 	}
 
-	free (info->cmd);
-	free (info);
+	g_free (info->cmd);
+	g_free (info);
 }
 
 static int
@@ -1989,8 +1975,8 @@ cmd_getint (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 	if (!word[4][0])
 		return FALSE;
 
-	info = malloc (sizeof (*info));
-	info->cmd = strdup (word[3]);
+	info = g_new (getvalinfo, 1);
+	info->cmd = g_strdup (word[3]);
 	info->sess = sess;
 
 	fe_get_int (word[4], atoi (word[2]), get_int_cb, info);
@@ -2007,13 +1993,13 @@ get_file_cb (char *cmd, char *file)
       no args */
 	if (file)
 	{
-		snprintf (buf, sizeof (buf), "%s %s", cmd, file);
+		g_snprintf (buf, sizeof (buf), "%s %s", cmd, file);
 		handle_command (current_sess, buf, FALSE);
 	}
 	else
 	{
 		handle_command (current_sess, cmd, FALSE);
-		free (cmd);
+		g_free (cmd);
 	}
 }
 
@@ -2044,7 +2030,7 @@ cmd_getfile (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 		idx++;
 	}
 
-	fe_get_file (word[idx+1], word[idx+2], (void *)get_file_cb, strdup (word[idx]), flags);
+	fe_get_file (word[idx+1], word[idx+2], (void *)get_file_cb, g_strdup (word[idx]), flags);
 
 	return TRUE;
 }
@@ -2056,13 +2042,13 @@ get_str_cb (int cancel, char *val, getvalinfo *info)
 
 	if (!cancel)
 	{
-		snprintf (buf, sizeof (buf), "%s %s", info->cmd, val);
+		g_snprintf (buf, sizeof (buf), "%s %s", info->cmd, val);
 		if (is_session (info->sess))
 			handle_command (info->sess, buf, FALSE);
 	}
 
-	free (info->cmd);
-	free (info);
+	g_free (info->cmd);
+	g_free (info);
 }
 
 static int
@@ -2073,8 +2059,8 @@ cmd_getstr (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 	if (!word[4][0])
 		return FALSE;
 
-	info = malloc (sizeof (*info));
-	info->cmd = strdup (word[3]);
+	info = g_new (getvalinfo, 1);
+	info->cmd = g_strdup (word[3]);
 	info->sess = sess;
 
 	fe_get_str (word[4], word[2], get_str_cb, info);
@@ -2200,7 +2186,7 @@ cmd_help (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 	} else
 	{
 		struct popup *pop;
-		char *buf = malloc (4096);
+		char *buf = g_malloc (4096);
 		help_list hl;
 
 		hl.longfmt = longfmt;
@@ -2245,7 +2231,7 @@ cmd_help (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 		plugin_command_foreach (sess, &hl, (void *)show_help_line);
 		strcat (buf, "\n");
 		PrintText (sess, buf);
-		free (buf);
+		g_free (buf);
 
 		PrintTextf (sess, "\n%s\n\n", _("Type /HELP <command> for more information, or /HELP -l"));
 	}
@@ -2293,7 +2279,7 @@ cmd_ignore (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 			    strchr (mask, '*') == NULL)
 			{
 				mask = tbuf;
-				snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
+				g_snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
 			}
 
 			i = ignore_add (mask, type, TRUE);
@@ -2549,7 +2535,7 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 			PrintText (sess, errorstring (errno));
 			g_free (buf);
 		}
-		free (file);
+		g_free (file);
 		return TRUE;
 	}
 
@@ -2562,7 +2548,7 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 
 		file = expand_homedir (word[2]);
 		error = plugin_load (sess, file, arg);
-		free (file);
+		g_free (file);
 
 		if (error)
 			PrintText (sess, error);
@@ -2651,7 +2637,7 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 		return TRUE;
 	}
 
-	snprintf (tbuf, TBUFSIZE, "\001ACTION %s\001\r", act);
+	g_snprintf (tbuf, TBUFSIZE, "\001ACTION %s\001\r", act);
 	/* first try through DCC CHAT */
 	if (dcc_write_chat (sess->channel, tbuf))
 	{
@@ -2674,7 +2660,7 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 				if (*split_text)
 					offset += strlen(split_text);
 
-				g_free(split_text);
+				g_free (split_text);
 			}
 
 			sess->server->p_action (sess->server, sess->channel, act + offset);
@@ -2693,17 +2679,26 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 static int
 cmd_mode (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 {
-	/* +channel channels are dying, let those servers whine about modes.
-	 * return info about current channel if available and no info is given */
-	if ((*word[2] == '+') || (*word[2] == 0) || (!is_channel(sess->server, word[2]) &&
-				!(rfc_casecmp(sess->server->nick, word[2]) == 0)))
+	/* We allow omitting the target, so we have to figure it out:
+	 * - Can only use info from channels or dialogs
+	 * - Empty arg is always sess info
+	 * - Assume + is mode not channel
+	 * - We know valid channels and our nick
+	 * - We cannot easily know if other nick or valid mode (Need to store 004)
+	 */
+	if ((sess->type != SESS_CHANNEL && sess->type != SESS_DIALOG)
+	    || (!(*word[2] == '-' || *word[2] == '+' || *word[2] == '\0')
+	        && (is_channel (sess->server, word[2]) || !rfc_casecmp (sess->server->nick, word[2])))
+	   )
+	{
+		sess->server->p_mode (sess->server, word[2], word_eol[3]);
+	}
+	else
 	{
 		if(sess->channel[0] == 0)
 			return FALSE;
 		sess->server->p_mode (sess->server, sess->channel, word_eol[2]);
 	}
-	else
-		sess->server->p_mode (sess->server, word[2], word_eol[3]);
 	return TRUE;
 }
 
@@ -2721,7 +2716,7 @@ mop_cb (struct User *user, multidata *data)
 static int
 cmd_mop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 {
-	char **nicks = malloc (sizeof (char *) * (sess->total - sess->ops));
+	char **nicks = g_new0 (char *, sess->total - sess->ops);
 	multidata data;
 
 	data.nicks = nicks;
@@ -2729,7 +2724,7 @@ cmd_mop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 	tree_foreach (sess->usertree, (tree_traverse_func *)mop_cb, &data);
 	send_channel_modes (sess, tbuf, nicks, 0, data.i, '+', 'o', 0);
 
-	free (nicks);
+	g_free (nicks);
 
 	return TRUE;
 }
@@ -2780,7 +2775,7 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 					if (*split_text)
 						offset += strlen(split_text);
 
-					g_free(split_text);
+					g_free (split_text);
 				}
 				sess->server->p_message (sess->server, nick, msg + offset);
 				offset = 0;
@@ -2801,7 +2796,7 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 					if (*split_text)
 						offset += strlen(split_text);
 
-					g_free(split_text);
+					g_free (split_text);
 				}
 				inbound_chanmsg (newsess->server, NULL, newsess->channel,
 									  newsess->server->nick, msg + offset, TRUE, FALSE,
@@ -2895,7 +2890,7 @@ cmd_notice (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 			if (*split_text)
 				offset += strlen(split_text);
 			
-			g_free(split_text);
+			g_free (split_text);
 		}
 
 		sess->server->p_notice (sess->server, word[2], text + offset);
@@ -2991,7 +2986,7 @@ cmd_ping (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 
 	tim = make_ping_time ();
 
-	snprintf (timestring, sizeof (timestring), "%lu", tim);
+	g_snprintf (timestring, sizeof (timestring), "%lu", tim);
 	sess->server->p_ping (sess->server, to, timestring);
 
 	return TRUE;
@@ -3054,7 +3049,7 @@ cmd_query (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 				if (*split_text)
 					offset += strlen(split_text);
 
-				g_free(split_text);
+				g_free (split_text);
 			}
 			sess->server->p_message (sess->server, nick, msg + offset);
 			inbound_chanmsg (nick_sess->server, nick_sess, nick_sess->channel,
@@ -3231,9 +3226,9 @@ cmd_send (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 	if ((addr & 0xffff0000) == 0xc0a80000 ||	/* 192.168.x.x */
 		 (addr & 0xff000000) == 0x0a000000)		/* 10.x.x.x */
 		/* we got a private net address, let's PSEND or it'll fail */
-		snprintf (tbuf, 512, "DCC PSEND %s", word_eol[2]);
+		g_snprintf (tbuf, 512, "DCC PSEND %s", word_eol[2]);
 	else
-		snprintf (tbuf, 512, "DCC SEND %s", word_eol[2]);
+		g_snprintf (tbuf, 512, "DCC SEND %s", word_eol[2]);
 
 	handle_command (sess, tbuf, FALSE);
 
@@ -3418,8 +3413,9 @@ cmd_server (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 			safe_strcpy (serv->password, net->pass, sizeof (serv->password));
 			serv->loginmethod = net->logintype;
 		}
-		else /* Otherwise ensure no password is sent */
+		else /* Otherwise ensure no password is sent or SASL started */
 		{
+			serv->loginmethod = LOGIN_DEFAULT;
 			serv->password[0] = 0;
 		}
 	}
@@ -3484,12 +3480,6 @@ cmd_topic (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 static int
 cmd_tray (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 {
-	if (strcmp (word[2], "-b") == 0)
-	{
-		fe_tray_set_balloon (word[3], word[4][0] ? word[4] : NULL);
-		return TRUE;
-	}
-
 	if (strcmp (word[2], "-t") == 0)
 	{
 		fe_tray_set_tooltip (word[3][0] ? word[3] : NULL);
@@ -3533,7 +3523,7 @@ cmd_unignore (struct session *sess, char *tbuf, char *word[],
 		if (strchr (mask, '?') == NULL && strchr (mask, '*') == NULL)
 		{
 			mask = tbuf;
-			snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
+			g_snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
 		}
 		
 		if (ignore_del (mask, NULL))
@@ -3873,7 +3863,7 @@ const struct commands xc_cmds[] = {
 	 N_("ALLCHANL <cmd>, sends a command to all channels on the current server")},
 	{"ALLSERV", cmd_allservers, 0, 0, 1,
 	 N_("ALLSERV <cmd>, sends a command to all servers you're in")},
-	{"AWAY", cmd_away, 1, 0, 1, N_("AWAY [<reason>], sets you away")},
+	{"AWAY", cmd_away, 1, 0, 1, N_("AWAY [<reason>], sets you away (use /BACK to unset)")},
 	{"BACK", cmd_back, 1, 0, 1, N_("BACK, sets you back (not away)")},
 	{"BAN", cmd_ban, 1, 1, 1,
 	 N_("BAN <mask> [<bantype>], bans everyone matching the mask from the current channel. If they are already on the channel this doesn't kick them (needs chanop)")},
@@ -4096,7 +4086,7 @@ usercommand_show_help (session *sess, char *name)
 		pop = (struct popup *) list->data;
 		if (!g_ascii_strcasecmp (pop->name, name))
 		{
-			snprintf (buf, sizeof(buf), _("User Command for: %s\n"), pop->cmd);
+			g_snprintf (buf, sizeof(buf), _("User Command for: %s\n"), pop->cmd);
 			PrintText (sess, buf);
 
 			found = TRUE;
@@ -4123,7 +4113,7 @@ help (session *sess, char *tbuf, char *helpcmd, int quiet)
 	{
 		if (cmd->help)
 		{
-			snprintf (tbuf, TBUFSIZE, _("Usage: %s\n"), _(cmd->help));
+			g_snprintf (tbuf, TBUFSIZE, _("Usage: %s\n"), _(cmd->help));
 			PrintText (sess, tbuf);
 		} else
 		{
@@ -4145,7 +4135,7 @@ help (session *sess, char *tbuf, char *helpcmd, int quiet)
  * - this beast is used for UserCommands, UserlistButtons and CTCP replies   */
 
 int
-auto_insert (char *dest, int destlen, unsigned char *src, char *word[],
+auto_insert (char *dest, gsize destlen, unsigned char *src, char *word[],
 				 char *word_eol[], char *a, char *c, char *d, char *e, char *h,
 				 char *n, char *s, char *u)
 {
@@ -4217,7 +4207,7 @@ auto_insert (char *dest, int destlen, unsigned char *src, char *word[],
 				switch (src[0])
 				{
 				case '%':
-					if ((dest - orig) + 2 >= destlen)
+					if ((dest - orig) + 2u >= destlen)
 						return 2;
 					dest[0] = '%';
 					dest[1] = 0;
@@ -4252,7 +4242,7 @@ auto_insert (char *dest, int destlen, unsigned char *src, char *word[],
 				case 'y':
 					now = time (0);
 					tm_ptr = localtime (&now);
-					snprintf (buf, sizeof (buf), "%4d%02d%02d", 1900 +
+					g_snprintf (buf, sizeof (buf), "%4d%02d%02d", 1900 +
 								 tm_ptr->tm_year, 1 + tm_ptr->tm_mon, tm_ptr->tm_mday);
 					utf = buf;
 					break;
@@ -4311,81 +4301,78 @@ check_special_chars (char *cmd, int do_ascii) /* check for %X */
 	if (!len)
 		return;
 
-	buf = malloc (len + 1);
+	buf = g_malloc (len + 1);
 
-	if (buf)
+	while (cmd[j])
 	{
-		while (cmd[j])
+		switch (cmd[j])
 		{
-			switch (cmd[j])
+		case '%':
+			occur++;
+			if (	do_ascii &&
+					j + 3 < len &&
+					(isdigit ((unsigned char) cmd[j + 1]) && isdigit ((unsigned char) cmd[j + 2]) &&
+					isdigit ((unsigned char) cmd[j + 3])))
 			{
-			case '%':
-				occur++;
-				if (	do_ascii &&
-						j + 3 < len &&
-						(isdigit ((unsigned char) cmd[j + 1]) && isdigit ((unsigned char) cmd[j + 2]) &&
-						isdigit ((unsigned char) cmd[j + 3])))
+				tbuf[0] = cmd[j + 1];
+				tbuf[1] = cmd[j + 2];
+				tbuf[2] = cmd[j + 3];
+				tbuf[3] = 0;
+				buf[i] = atoi (tbuf);
+				utf = g_locale_to_utf8 (buf + i, 1, 0, &utf_len, 0);
+				if (utf)
 				{
-					tbuf[0] = cmd[j + 1];
-					tbuf[1] = cmd[j + 2];
-					tbuf[2] = cmd[j + 3];
-					tbuf[3] = 0;
-					buf[i] = atoi (tbuf);
-					utf = g_locale_to_utf8 (buf + i, 1, 0, &utf_len, 0);
-					if (utf)
-					{
-						memcpy (buf + i, utf, utf_len);
-						g_free (utf);
-						i += (utf_len - 1);
-					}
-					j += 3;
-				} else
+					memcpy (buf + i, utf, utf_len);
+					g_free (utf);
+					i += (utf_len - 1);
+				}
+				j += 3;
+			} else
+			{
+				switch (cmd[j + 1])
 				{
-					switch (cmd[j + 1])
-					{
-					case 'R':
-						buf[i] = '\026';
-						break;
-					case 'U':
-						buf[i] = '\037';
-						break;
-					case 'B':
-						buf[i] = '\002';
-						break;
-					case 'I':
-						buf[i] = '\035';
-						break;
-					case 'C':
-						buf[i] = '\003';
-						break;
-					case 'O':
-						buf[i] = '\017';
-						break;
-					case 'H':	/* CL: invisible text code */
-						buf[i] = HIDDEN_CHAR;
-						break;
-					case '%':
-						buf[i] = '%';
-						break;
-					default:
-						buf[i] = '%';
-						j--;
-						break;
-					}
-					j++;
+				case 'R':
+					buf[i] = '\026';
+					break;
+				case 'U':
+					buf[i] = '\037';
+					break;
+				case 'B':
+					buf[i] = '\002';
+					break;
+				case 'I':
+					buf[i] = '\035';
+					break;
+				case 'C':
+					buf[i] = '\003';
+					break;
+				case 'O':
+					buf[i] = '\017';
+					break;
+				case 'H':	/* CL: invisible text code */
+					buf[i] = HIDDEN_CHAR;
+					break;
+				case '%':
+					buf[i] = '%';
+					break;
+				default:
+					buf[i] = '%';
+					j--;
 					break;
-			default:
-					buf[i] = cmd[j];
 				}
+				j++;
+				break;
+		default:
+				buf[i] = cmd[j];
 			}
-			j++;
-			i++;
 		}
-		buf[i] = 0;
-		if (occur)
-			strcpy (cmd, buf);
-		free (buf);
+		j++;
+		i++;
 	}
+	buf[i] = 0;
+	if (occur)
+		strcpy (cmd, buf);
+	g_free (buf);
 }
 
 typedef struct
@@ -4408,7 +4395,7 @@ nick_comp_cb (struct User *user, nickdata *data)
 		lenu = strlen (user->nick);
 		if (lenu == data->len)
 		{
-			snprintf (data->tbuf, TBUFSIZE, "%s%s", user->nick, data->space);
+			g_snprintf (data->tbuf, TBUFSIZE, "%s%s", user->nick, data->space);
 			data->len = -1;
 			return FALSE;
 		} else if (lenu < data->bestlen)
@@ -4452,7 +4439,7 @@ perform_nick_completion (struct session *sess, char *cmd, char *tbuf)
 
 				if (data.best)
 				{
-					snprintf (tbuf, TBUFSIZE, "%s%s", data.best->nick, space - 1);
+					g_snprintf (tbuf, TBUFSIZE, "%s%s", data.best->nick, space - 1);
 					return;
 				}
 			}
@@ -4485,12 +4472,10 @@ handle_say (session *sess, char *text, int check_spch)
 	struct DCC *dcc;
 	char *word[PDIWORDS+1];
 	char *word_eol[PDIWORDS+1];
-	char pdibuf_static[1024];
-	char newcmd_static[1024];
-	char *pdibuf = pdibuf_static;
-	char *newcmd = newcmd_static;
+	char *pdibuf;
+	char *newcmd;
 	int len;
-	int newcmdlen = sizeof newcmd_static;
+	int newcmdlen;
 	message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT;
 
 	if (strcmp (sess->channel, "(lastlog)") == 0)
@@ -4500,11 +4485,9 @@ handle_say (session *sess, char *text, int check_spch)
 	}
 
 	len = strlen (text);
-	if (len >= sizeof pdibuf_static)
-		pdibuf = malloc (len + 1);
-
-	if (len + NICKLEN >= newcmdlen)
-		newcmd = malloc (newcmdlen = len + NICKLEN + 1);
+	pdibuf = g_malloc (len + 1);
+	newcmdlen = MAX(len + NICKLEN + 1, TBUFSIZE);
+	newcmd = g_malloc (newcmdlen);
 
 	if (check_spch && prefs.hex_input_perc_color)
 		check_special_chars (text, prefs.hex_input_perc_ascii);
@@ -4565,7 +4548,7 @@ handle_say (session *sess, char *text, int check_spch)
 			if (*split_text)
 				offset += strlen(split_text);
 			
-			g_free(split_text);
+			g_free (split_text);
 		}
 
 		inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick,
@@ -4577,11 +4560,9 @@ handle_say (session *sess, char *text, int check_spch)
 	}
 
 xit:
-	if (pdibuf != pdibuf_static)
-		free (pdibuf);
+	g_free (pdibuf);
 
-	if (newcmd != newcmd_static)
-		free (newcmd);
+	g_free (newcmd);
 }
 
 char *
@@ -4675,8 +4656,6 @@ handle_command (session *sess, char *cmd, int check_spch)
 	char *word_eol[PDIWORDS+1];
 	static int command_level = 0;
 	struct commands *int_cmd;
-	char pdibuf_static[1024];
-	char tbuf_static[TBUFSIZE];
 	char *pdibuf;
 	char *tbuf;
 	int len;
@@ -4691,23 +4670,8 @@ handle_command (session *sess, char *cmd, int check_spch)
 	/* anything below MUST DEC command_level before returning */
 
 	len = strlen (cmd);
-	if (len >= sizeof (pdibuf_static))
-	{
-		pdibuf = malloc (len + 1);
-	}
-	else
-	{
-		pdibuf = pdibuf_static;
-	}
-
-	if ((len * 2) >= sizeof (tbuf_static))
-	{
-		tbuf = malloc ((len * 2) + 1);
-	}
-	else
-	{
-		tbuf = tbuf_static;
-	}
+	pdibuf = g_malloc (len + 1);
+	tbuf = g_malloc (MAX(TBUFSIZE, (len * 2) + 1));
 
 	/* split the text into words and word_eol */
 	process_data_init (pdibuf, cmd, word, word_eol, TRUE, TRUE);
@@ -4786,13 +4750,13 @@ handle_command (session *sess, char *cmd, int check_spch)
 	}
 	else
 	{
-		/* unknown command, just send it to the server and hope */
 		if (!sess->server->connected)
 		{
-			PrintText (sess, _("Unknown Command. Try /help\n"));
+			PrintTextf (sess, _("Unknown Command %s. Try /help\n"), word[1]);
 		}
 		else
 		{
+			/* unknown command, just send it to the server and hope */
 			sess->server->p_raw (sess->server, cmd);
 		}
 	}
@@ -4800,15 +4764,8 @@ handle_command (session *sess, char *cmd, int check_spch)
 xit:
 	command_level--;
 
-	if (pdibuf != pdibuf_static)
-	{
-		free (pdibuf);
-	}
-
-	if (tbuf != tbuf_static)
-	{
-		free (tbuf);
-	}
+	g_free (pdibuf);
+	g_free (tbuf);
 
 	return ret;
 }