diff --git a/apps/app_queue.c b/apps/app_queue.c
index f02ed44070a5b093ea29477569bba0c9df9c527a..6e410002ae27f07fe40028e2c4afd11f445122b4 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -105,6 +105,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/callerid.h"
 #include "asterisk/cel.h"
 #include "asterisk/data.h"
+#include "asterisk/term.h"
 
 /* Define, to debug reference counts on queues, without debugging reference counts on queue members */
 /* #define REF_DEBUG_ONLY_QUEUES */
@@ -8312,11 +8313,14 @@ static char *__queues_show(struct mansession *s, int fd, int argc, const char *
 
 				ast_str_append(&out, 0, " (ringinuse %s)", mem->ringinuse ? "enabled" : "disabled");
 
-				ast_str_append(&out, 0, "%s%s%s (%s)",
-					mem->dynamic ? " (dynamic)" : "",
-					mem->realtime ? " (realtime)" : "",
-					mem->paused ? " (paused)" : "",
-					ast_devstate2str(mem->status));
+				ast_str_append(&out, 0, "%s%s%s%s%s%s%s%s%s (%s%s%s)",
+					mem->dynamic ? ast_term_color(COLOR_CYAN, COLOR_BLACK) : "", mem->dynamic ? " (dynamic)" : "", ast_term_reset(),
+					mem->realtime ? ast_term_color(COLOR_MAGENTA, COLOR_BLACK) : "", mem->realtime ? " (realtime)" : "", ast_term_reset(),
+					mem->paused ? ast_term_color(COLOR_BROWN, COLOR_BLACK) : "", mem->paused ? " (paused)" : "", ast_term_reset(),
+					ast_term_color(
+						mem->status == AST_DEVICE_UNAVAILABLE || mem->status == AST_DEVICE_UNKNOWN ?
+							COLOR_RED : COLOR_GREEN, COLOR_BLACK),
+						ast_devstate2str(mem->status), ast_term_reset());
 				if (mem->calls) {
 					ast_str_append(&out, 0, " has taken %d calls (last was %ld secs ago)",
 						mem->calls, (long) (time(NULL) - mem->lastcall));
diff --git a/include/asterisk/term.h b/include/asterisk/term.h
index bbdc7531983a803edce49f8f2850d4f8472cdfb4..18d743b76078e15a6df5ad48ca536cc13140927e 100644
--- a/include/asterisk/term.h
+++ b/include/asterisk/term.h
@@ -29,7 +29,7 @@ extern "C" {
 
 #define ESC 0x1b
 
-/*! \name Terminal Attributes 
+/*! \name Terminal Attributes
 */
 /*@{ */
 #define ATTR_RESET	0
@@ -44,17 +44,17 @@ extern "C" {
 /*! \name Terminal Colors
 */
 /*@{ */
-#define COLOR_BLACK 	30
-#define COLOR_GRAY  	(30 | 128)
-#define COLOR_RED	31
-#define COLOR_BRRED	(31 | 128)
-#define COLOR_GREEN	32
-#define COLOR_BRGREEN	(32 | 128)
-#define COLOR_BROWN	33
-#define COLOR_YELLOW	(33 | 128)
-#define COLOR_BLUE	34
-#define COLOR_BRBLUE	(34 | 128)
-#define COLOR_MAGENTA	35
+#define COLOR_BLACK     30
+#define COLOR_GRAY      (30 | 128)
+#define COLOR_RED       31
+#define COLOR_BRRED     (31 | 128)
+#define COLOR_GREEN     32
+#define COLOR_BRGREEN   (32 | 128)
+#define COLOR_BROWN     33
+#define COLOR_YELLOW    (33 | 128)
+#define COLOR_BLUE      34
+#define COLOR_BRBLUE    (34 | 128)
+#define COLOR_MAGENTA   35
 #define COLOR_BRMAGENTA (35 | 128)
 #define COLOR_CYAN      36
 #define COLOR_BRCYAN    (36 | 128)
@@ -62,10 +62,27 @@ extern "C" {
 #define COLOR_BRWHITE   (37 | 128)
 /*@} */
 
+/*! \brief Shortcut macros for coloring a set of text
+ */
+#define COLORIZE_FMT	"%s%s%s"
+#define COLORIZE(fg, bg, str)	ast_term_color(fg,bg),str,ast_term_reset()
 /*! \brief Maximum number of characters needed for a color escape sequence,
  *         plus a null char */
-#define AST_TERM_MAX_ESCAPE_CHARS   23
+#define AST_TERM_MAX_ESCAPE_CHARS   12
+#define AST_TERM_MAX_ROTATING_BUFFERS	15
 
+/*! \brief Colorize a specified string by adding terminal color codes
+ *
+ * \param outbuf Result buffer
+ * \param inbuf Starting string
+ * \param fgcolor Foreground color, specified as one of the constants in include/asterisk/term.h.  Use '0' if the want the normal terminal foreground color.
+ * \param bgcolor Background color, specified as one of the constants in include/asterisk/term.h.  Use '0' if you want the normal terminal background color.
+ * \param maxout Maximum size of outbuf
+ *
+ * \return outbuf
+ *
+ * \deprecated Due to the necessity of pre-sizing a result buffer, new code should avoid using this function in preference to ast_term_color_code() or ast_term_color().
+ */
 char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout);
 
 /*!
@@ -80,6 +97,22 @@ char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int
  */
 int ast_term_color_code(struct ast_str **str, int fgcolor, int bgcolor);
 
+/*!
+ * \brief Return a color sequence string
+ * \param fgcolor foreground color
+ * \param bgcolor background color
+ * \note This function may be called up to 15 times within the arguments to a single function without the danger of overwriting a common buffer.
+ *
+ * \return A color sequence string, or the empty string, on error
+ */
+const char *ast_term_color(int fgcolor, int bgcolor);
+
+/*!
+ * \brief Returns the terminal reset code
+ * \return String which, when sent to the screen, resets the terminal colors
+ */
+const char *ast_term_reset(void);
+
 /*!
  * \brief Write a color sequence to a string
  *
@@ -87,22 +120,30 @@ int ast_term_color_code(struct ast_str **str, int fgcolor, int bgcolor);
  * \param fgcolor foreground color
  * \param bgcolor background color
  * \param maxout maximum number of characters to write
+ * \deprecated You should use ast_term_color_code or ast_term_color, instead.
  *
  * \return outbuf
  */
 char *term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout);
 
+/*!
+ * \brief Remove colorings from a specified string
+ * \param outbuf the location to write to
+ * \param inbuf the original string
+ * \param maxout the available size of outbuf
+ * \return outbuf
+ */
 char *term_strip(char *outbuf, const char *inbuf, int maxout);
 
 void term_filter_escapes(char *line);
 
 char *term_prompt(char *outbuf, const char *inbuf, int maxout);
 
-char *term_prep(void);
+const char *term_prep(void);
 
-char *term_end(void);
+const char *term_end(void);
 
-char *term_quit(void);
+const char *term_quit(void);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }
diff --git a/main/asterisk.c b/main/asterisk.c
index f7b62613aaa3ee9e3cda02bb89922ac921d32da2..243321dda3594ddfac3ee41a79a493d8a050daa6 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -2571,7 +2571,6 @@ static char *cli_prompt(EditLine *editline)
 	char *pfmt;
 	int color_used = 0;
 	static int cli_prompt_changes = 0;
-	char term_code[20];
 	struct passwd *pw;
 	struct group *gr;
 
@@ -2598,10 +2597,10 @@ static char *cli_prompt(EditLine *editline)
 				case 'C': /* color */
 					t++;
 					if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
-						ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
+						ast_term_color_code(&prompt, fgcolor, bgcolor);
 						t += i - 1;
 					} else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
-						ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
+						ast_term_color_code(&prompt, fgcolor, 0);
 						t += i - 1;
 					}
 
@@ -2681,7 +2680,7 @@ static char *cli_prompt(EditLine *editline)
 		}
 		if (color_used) {
 			/* Force colors back to normal at end */
-			ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
+			ast_term_color_code(&prompt, 0, 0);
 		}
 	} else if (remotehostname) {
 		ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
@@ -3586,7 +3585,6 @@ int main(int argc, char *argv[])
 	int c;
 	char filename[80] = "";
 	char hostname[MAXHOSTNAMELEN] = "";
-	char tmp[80];
 	char * xarg = NULL;
 	int x;
 	FILE *f;
@@ -4284,7 +4282,7 @@ int main(int argc, char *argv[])
 
 	/* We might have the option of showing a console, but for now just
 	   do nothing... */
-	ast_verb(0, "%s\n", term_color(tmp, "Asterisk Ready.", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
+	ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRWHITE, COLOR_BLACK, "Asterisk Ready."));
 	if (ast_opt_no_fork) {
 		consolethread = pthread_self();
 	}
diff --git a/main/data.c b/main/data.c
index 44ba390ad258b7573f7edb0406e912e0d494c2d7..b7bedf25464290f1bf4d51b53221819bd3f23b34 100644
--- a/main/data.c
+++ b/main/data.c
@@ -2797,7 +2797,7 @@ static void data_result_print_cli_node(int fd, const struct ast_data *node, uint
 
 	ast_free(tabs);
 
-	ast_term_color_code(&output, COLOR_WHITE, 0);
+	ast_term_color_code(&output, 0, 0);
 
 	ast_cli(fd, "%s", ast_str_buffer(output));
 
@@ -2840,19 +2840,7 @@ static void __data_result_print_cli(int fd, const struct ast_data *root, uint32_
  */
 static void data_result_print_cli(int fd, const struct ast_data *root)
 {
-	struct ast_str *output;
-
-	/* print the initial node. */
-	output = ast_str_create(30);
-	if (!output) {
-		return;
-	}
-
-	ast_term_color_code(&output, data_result_get_color(root->type), 0);
-	ast_str_append(&output, 0, "%s\n", root->name);
-	ast_term_color_code(&output, COLOR_WHITE, 0);
-	ast_cli(fd, "%s", ast_str_buffer(output));
-	ast_free(output);
+	ast_cli(fd, COLORIZE_FMT "\n", COLORIZE(data_result_get_color(root->type), 0, root->name));
 
 	__data_result_print_cli(fd, root, 0);
 
diff --git a/main/logger.c b/main/logger.c
index 656117ce54439d9e01f2c3c1c345ab623d3befe7..97a79ecf28249799e1776340e5020a25813608d3 100644
--- a/main/logger.c
+++ b/main/logger.c
@@ -1082,7 +1082,6 @@ static void logger_print_normal(struct logmsg *logmsg)
 			/* Console channels */
 			} else if (chan->type == LOGTYPE_CONSOLE && (chan->logmask & (1 << logmsg->level))) {
 				char linestr[128];
-				char tmp1[80], tmp2[80], tmp3[80], tmp4[80];
 
 				/* If the level is verbose, then skip it */
 				if (logmsg->level == __LOG_VERBOSE)
@@ -1091,14 +1090,14 @@ static void logger_print_normal(struct logmsg *logmsg)
 				/* Turn the numerical line number into a string */
 				snprintf(linestr, sizeof(linestr), "%d", logmsg->line);
 				/* Build string to print out */
-				snprintf(buf, sizeof(buf), "[%s] %s[%d]%s: %s:%s %s: %s",
+				snprintf(buf, sizeof(buf), "[%s] " COLORIZE_FMT "[%d]%s: " COLORIZE_FMT ":" COLORIZE_FMT " " COLORIZE_FMT ": %s",
 					 logmsg->date,
-					 term_color(tmp1, logmsg->level_name, colors[logmsg->level], 0, sizeof(tmp1)),
+					 COLORIZE(colors[logmsg->level], 0, logmsg->level_name),
 					 logmsg->lwp,
 					 call_identifier_str,
-					 term_color(tmp2, logmsg->file, COLOR_BRWHITE, 0, sizeof(tmp2)),
-					 term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
-					 term_color(tmp4, logmsg->function, COLOR_BRWHITE, 0, sizeof(tmp4)),
+					 COLORIZE(COLOR_BRWHITE, 0, logmsg->file),
+					 COLORIZE(COLOR_BRWHITE, 0, linestr),
+					 COLORIZE(COLOR_BRWHITE, 0, logmsg->function),
 					 logmsg->message);
 				/* Print out */
 				ast_console_puts_mutable(buf, logmsg->level);
diff --git a/main/manager.c b/main/manager.c
index 5ef315bd20215247d2da4cbd4d9d4f6a2589bd67..0543ee6fb3234d22d3d8aa61db38eb94214cba63 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -1635,7 +1635,7 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
 	term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
 	term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
 	term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
-	term_color(privilege_title, "[Privilege]\n", COLOR_MAGENTA, 0,40);
+	term_color(privilege_title, "[Privilege]\n", COLOR_MAGENTA, 0, 40);
 #endif
 
 	AST_RWLIST_RDLOCK(&actions);
diff --git a/main/pbx.c b/main/pbx.c
index 1c58973c722726978aaff8bc6e3368ceeb67aab7..bf95ccbe247faa0029c0171ee5eebdee90831adb 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -4041,7 +4041,6 @@ static int acf_retrieve_docs(struct ast_custom_function *acf)
 int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
 {
 	struct ast_custom_function *cur;
-	char tmps[80];
 
 	if (!acf) {
 		return -1;
@@ -4079,7 +4078,7 @@ int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_m
 
 	AST_RWLIST_UNLOCK(&acf_root);
 
-	ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps)));
+	ast_verb(2, "Registered custom function '" COLORIZE_FMT "'\n", COLORIZE(COLOR_BRCYAN, 0, acf->name));
 
 	return 0;
 }
@@ -4694,12 +4693,11 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
 #endif
 			ast_debug(1, "Launching '%s'\n", app->name);
 			{
-				char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
-				ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n",
+				ast_verb(3, "Executing [%s@%s:%d] " COLORIZE_FMT "(\"" COLORIZE_FMT "\", \"" COLORIZE_FMT "\") %s\n",
 					exten, context, priority,
-					term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
-					term_color(tmp2, ast_channel_name(c), COLOR_BRMAGENTA, 0, sizeof(tmp2)),
-					term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)),
+					COLORIZE(COLOR_BRCYAN, 0, app->name),
+					COLORIZE(COLOR_BRMAGENTA, 0, ast_channel_name(c)),
+					COLORIZE(COLOR_BRMAGENTA, 0, passdata),
 					"in new stack");
 			}
 			/*** DOCUMENTATION
@@ -7127,7 +7125,6 @@ int ast_register_application2(const char *app, int (*execute)(struct ast_channel
 {
 	struct ast_app *tmp;
 	struct ast_app *cur;
-	char tmps[80];
 	int length;
 #ifdef AST_XML_DOCS
 	char *tmpxml;
@@ -7206,7 +7203,7 @@ int ast_register_application2(const char *app, int (*execute)(struct ast_channel
 	if (!cur)
 		AST_RWLIST_INSERT_TAIL(&apps, tmp, list);
 
-	ast_verb(2, "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
+	ast_verb(2, "Registered application '" COLORIZE_FMT "'\n", COLORIZE(COLOR_BRCYAN, 0, tmp->name));
 
 	AST_RWLIST_UNLOCK(&apps);
 
@@ -7248,74 +7245,67 @@ void ast_unregister_switch(struct ast_switch *sw)
 
 static void print_app_docs(struct ast_app *aa, int fd)
 {
-	/* Maximum number of characters added by terminal coloring is 22 */
-	char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40], stxtitle[40], argtitle[40];
-	char seealsotitle[40];
-	char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL, *syntax = NULL, *arguments = NULL;
-	char *seealso = NULL;
-	int syntax_size, synopsis_size, description_size, arguments_size, seealso_size;
-
-	snprintf(info, sizeof(info), "\n  -= Info about application '%s' =- \n\n", aa->name);
-	term_color(infotitle, info, COLOR_MAGENTA, 0, sizeof(infotitle));
-
-	term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
-	term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
-	term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
-	term_color(argtitle, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
-	term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, 40);
-
 #ifdef AST_XML_DOCS
+	char *synopsis = NULL, *description = NULL, *arguments = NULL, *seealso = NULL;
 	if (aa->docsrc == AST_XML_DOC) {
+		synopsis = ast_xmldoc_printable(S_OR(aa->synopsis, "Not available"), 1);
 		description = ast_xmldoc_printable(S_OR(aa->description, "Not available"), 1);
 		arguments = ast_xmldoc_printable(S_OR(aa->arguments, "Not available"), 1);
-		synopsis = ast_xmldoc_printable(S_OR(aa->synopsis, "Not available"), 1);
 		seealso = ast_xmldoc_printable(S_OR(aa->seealso, "Not available"), 1);
-
 		if (!synopsis || !description || !arguments || !seealso) {
-			goto return_cleanup;
-		}
+			goto free_docs;
+		}
+		ast_cli(fd, "\n"
+			"%s  -= Info about application '%s' =- %s\n\n"
+			COLORIZE_FMT "\n"
+			"%s\n\n"
+			COLORIZE_FMT "\n"
+			"%s\n\n"
+			COLORIZE_FMT "\n"
+			"%s%s%s\n\n"
+			COLORIZE_FMT "\n"
+			"%s\n\n"
+			COLORIZE_FMT "\n"
+			"%s\n",
+			ast_term_color(COLOR_MAGENTA, 0), aa->name, ast_term_reset(),
+			COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
+			COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
+			COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"),
+				ast_term_color(COLOR_CYAN, 0), S_OR(aa->syntax, "Not available"), ast_term_reset(),
+			COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
+			COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso);
+free_docs:
+		ast_free(synopsis);
+		ast_free(description);
+		ast_free(arguments);
+		ast_free(seealso);
 	} else
 #endif
 	{
-		synopsis_size = strlen(S_OR(aa->synopsis, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
-		synopsis = ast_malloc(synopsis_size);
-
-		description_size = strlen(S_OR(aa->description, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
-		description = ast_malloc(description_size);
-
-		arguments_size = strlen(S_OR(aa->arguments, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
-		arguments = ast_malloc(arguments_size);
-
-		seealso_size = strlen(S_OR(aa->seealso, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
-		seealso = ast_malloc(seealso_size);
-
-		if (!synopsis || !description || !arguments || !seealso) {
-			goto return_cleanup;
-		}
-
-		term_color(synopsis, S_OR(aa->synopsis, "Not available"), COLOR_CYAN, 0, synopsis_size);
-		term_color(description, S_OR(aa->description, "Not available"),	COLOR_CYAN, 0, description_size);
-		term_color(arguments, S_OR(aa->arguments, "Not available"), COLOR_CYAN, 0, arguments_size);
-		term_color(seealso, S_OR(aa->seealso, "Not available"), COLOR_CYAN, 0, seealso_size);
-	}
-
-	/* Handle the syntax the same for both XML and raw docs */
-	syntax_size = strlen(S_OR(aa->syntax, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
-	if (!(syntax = ast_malloc(syntax_size))) {
-		goto return_cleanup;
+		ast_cli(fd, "\n"
+			"%s  -= Info about application '%s' =- %s\n\n"
+			COLORIZE_FMT "\n"
+			COLORIZE_FMT "\n\n"
+			COLORIZE_FMT "\n"
+			COLORIZE_FMT "\n\n"
+			COLORIZE_FMT "\n"
+			COLORIZE_FMT "\n\n"
+			COLORIZE_FMT "\n"
+			COLORIZE_FMT "\n\n"
+			COLORIZE_FMT "\n"
+			COLORIZE_FMT "\n",
+			ast_term_color(COLOR_MAGENTA, 0), aa->name, ast_term_reset(),
+			COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"),
+			COLORIZE(COLOR_CYAN, 0, S_OR(aa->synopsis, "Not available")),
+			COLORIZE(COLOR_MAGENTA, 0, "[Description]"),
+			COLORIZE(COLOR_CYAN, 0, S_OR(aa->description, "Not available")),
+			COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"),
+			COLORIZE(COLOR_CYAN, 0, S_OR(aa->syntax, "Not available")),
+			COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"),
+			COLORIZE(COLOR_CYAN, 0, S_OR(aa->arguments, "Not available")),
+			COLORIZE(COLOR_MAGENTA, 0, "[See Also]"),
+			COLORIZE(COLOR_CYAN, 0, S_OR(aa->seealso, "Not available")));
 	}
-	term_color(syntax, S_OR(aa->syntax, "Not available"), COLOR_CYAN, 0, syntax_size);
-
-	ast_cli(fd, "%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n",
-			infotitle, syntitle, synopsis, destitle, description,
-			stxtitle, syntax, argtitle, arguments, seealsotitle, seealso);
-
-return_cleanup:
-	ast_free(description);
-	ast_free(arguments);
-	ast_free(synopsis);
-	ast_free(seealso);
-	ast_free(syntax);
 }
 
 /*
diff --git a/main/term.c b/main/term.c
index 132b7fa0cce9d39541e01a1787163029b09c9d66..2e28032a79f1d3d4bf545c524f3ba876d2d26687 100644
--- a/main/term.c
+++ b/main/term.c
@@ -40,6 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/term.h"
 #include "asterisk/lock.h"
 #include "asterisk/utils.h"
+#include "asterisk/threadstorage.h"
 
 static int vt100compat;
 
@@ -54,6 +55,13 @@ static const char * const termpath[] = {
 	NULL
 	};
 
+AST_THREADSTORAGE(commonbuf);
+
+struct commonbuf {
+	short which;
+	char buffer[AST_TERM_MAX_ROTATING_BUFFERS][AST_TERM_MAX_ESCAPE_CHARS];
+};
+
 static int opposite(int color)
 {
 	int lookup[] = {
@@ -217,11 +225,11 @@ char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int
 
 static void check_fgcolor(int *fgcolor, int *attr)
 {
+	*attr = ast_opt_light_background ? 0 : ATTR_BRIGHT;
 	if (*fgcolor & 128) {
-		*attr = ast_opt_light_background ? 0 : ATTR_BRIGHT;
 		*fgcolor &= ~128;
 	}
-	
+
 	if (ast_opt_light_background) {
 		*fgcolor = opposite(*fgcolor);
 	}
@@ -249,7 +257,7 @@ int ast_term_color_code(struct ast_str **str, int fgcolor, int bgcolor)
 
 	check_fgcolor(&fgcolor, &attr);
 	check_bgcolor(&bgcolor);
-	
+
 	if (ast_opt_force_black_background) {
 		ast_str_append(str, 0, "%c[%d;%d;%dm", ESC, attr, fgcolor, COLOR_BLACK + 10);
 	} else if (bgcolor) {
@@ -284,6 +292,32 @@ char *term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout)
 	return outbuf;
 }
 
+const char *ast_term_color(int fgcolor, int bgcolor)
+{
+	struct commonbuf *cb = ast_threadstorage_get(&commonbuf, sizeof(*cb));
+	char *buf;
+
+	if (!cb) {
+		return "";
+	}
+	buf = cb->buffer[cb->which++];
+	if (cb->which == AST_TERM_MAX_ROTATING_BUFFERS) {
+		cb->which = 0;
+	}
+
+	return term_color_code(buf, fgcolor, bgcolor, AST_TERM_MAX_ESCAPE_CHARS);
+}
+
+const char *ast_term_reset(void)
+{
+	if (ast_opt_force_black_background) {
+		static const char reset[] = { ESC, '[', COLOR_BLACK + 10, 'm', 0 };
+		return reset;
+	} else {
+		return quitdata;
+	}
+}
+
 char *term_strip(char *outbuf, const char *inbuf, int maxout)
 {
 	char *outbuf_ptr = outbuf;
@@ -313,22 +347,22 @@ char *term_prompt(char *outbuf, const char *inbuf, int maxout)
 		return outbuf;
 	}
 	if (ast_opt_force_black_background) {
-		snprintf(outbuf, maxout, "%c[%d;%dm%c%c[%d;%dm%s",
-			ESC, COLOR_BLUE, COLOR_BLACK + 10,
+		snprintf(outbuf, maxout, "%c[%d;%d;%dm%c%c[%d;%dm%s",
+			ESC, ATTR_BRIGHT, COLOR_BLUE, COLOR_BLACK + 10,
 			inbuf[0],
 			ESC, COLOR_WHITE, COLOR_BLACK + 10,
 			inbuf + 1);
 	} else if (ast_opt_light_background) {
-		snprintf(outbuf, maxout, "%c[%d;0m%c%c[%d;0m%s",
+		snprintf(outbuf, maxout, "%c[%d;0m%c%c[0m%s",
 			ESC, COLOR_BLUE,
 			inbuf[0],
-			ESC, COLOR_BLACK,
+			ESC,
 			inbuf + 1);
 	} else {
-		snprintf(outbuf, maxout, "%c[%d;%d;0m%c%c[%d;%d;0m%s",
+		snprintf(outbuf, maxout, "%c[%d;%d;0m%c%c[0m%s",
 			ESC, ATTR_BRIGHT, COLOR_BLUE,
 			inbuf[0],
-			ESC, 0, COLOR_WHITE,
+			ESC,
 			inbuf + 1);
 	}
 	return outbuf;
@@ -357,17 +391,17 @@ void term_filter_escapes(char *line)
 	}
 }
 
-char *term_prep(void)
+const char *term_prep(void)
 {
 	return prepdata;
 }
 
-char *term_end(void)
+const char *term_end(void)
 {
 	return enddata;
 }
 
-char *term_quit(void)
+const char *term_quit(void)
 {
 	return quitdata;
 }