fs_cli: implement configurable prompt, input, and output coloring

In .fs_cli_conf, set:

  prompt-color => blue
  input-text-color => red
  output-text-color => yellow
This commit is contained in:
Travis Cross 2011-09-22 20:32:16 +00:00
parent a79f1f4202
commit c7ec19d6f0

View File

@ -57,14 +57,18 @@ typedef struct {
const char *console_fnkeys[12]; const char *console_fnkeys[12];
char loglevel[128]; char loglevel[128];
int quiet; int quiet;
char prompt_color[12];
char input_text_color[12];
char output_text_color[12];
} cli_profile_t; } cli_profile_t;
static int warn_stop = 0; static int warn_stop = 0;
static int connected = 0; static int connected = 0;
static int allow_ctl_c = 0; static int allow_ctl_c = 0;
static char prompt_str[512] = ""; static char prompt_str[512] = "";
static char *prompt_color = ESL_SEQ_DEFAULT_COLOR; static char prompt_color[12] = ESL_SEQ_DEFAULT_COLOR;
static char *text_color = ESL_SEQ_DEFAULT_COLOR; static char input_text_color[12] = ESL_SEQ_DEFAULT_COLOR;
static char output_text_color[12] = ESL_SEQ_DEFAULT_COLOR;
static cli_profile_t profiles[128] = {{{0}}}; static cli_profile_t profiles[128] = {{{0}}};
static cli_profile_t internal_profile = {{ 0 }}; static cli_profile_t internal_profile = {{ 0 }};
static int pcount = 0; static int pcount = 0;
@ -578,6 +582,17 @@ static void redisplay(void)
return; return;
} }
static int output_printf(const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap, fmt);
printf("%s", output_text_color);
r = vprintf(fmt, ap);
va_end(ap);
return r;
}
static void *msg_thread_run(esl_thread_t *me, void *obj) static void *msg_thread_run(esl_thread_t *me, void *obj)
{ {
esl_handle_t *handle = (esl_handle_t *) obj; esl_handle_t *handle = (esl_handle_t *) obj;
@ -609,7 +624,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
#ifndef WIN32 #ifndef WIN32
if (aok) { if (aok) {
clear_line(); clear_line();
printf("%s%s%s", colors[level], handle->last_event->body, ESL_SEQ_DEFAULT_COLOR); printf("%s%s", colors[level], handle->last_event->body);
redisplay(); redisplay();
} }
#else #else
@ -627,7 +642,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
esl_event_serialize(handle->last_ievent, &s, ESL_FALSE); esl_event_serialize(handle->last_ievent, &s, ESL_FALSE);
if (aok) { if (aok) {
clear_line(); clear_line();
printf("RECV EVENT\n%s\n", s); output_printf("RECV EVENT\n%s\n", s);
redisplay(); redisplay();
} }
free(s); free(s);
@ -637,9 +652,9 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
} }
if (aok && !known) { if (aok && !known) {
char *s; char *s;
printf("INCOMING DATA [%s]\n%s\n", type, handle->last_event->body ? handle->last_event->body : ""); output_printf("INCOMING DATA [%s]\n%s\n", type, handle->last_event->body ? handle->last_event->body : "");
esl_event_serialize(handle->last_event, &s, ESL_FALSE); esl_event_serialize(handle->last_event, &s, ESL_FALSE);
printf("RECV EVENT\n%s\n", s); output_printf("RECV EVENT\n%s\n", s);
redisplay(); redisplay();
free(s); free(s);
} }
@ -648,7 +663,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
if (warn_stop) { if (warn_stop) {
if (aok) { if (aok) {
clear_line(); clear_line();
printf("Type control-D or /exit or /quit or /bye to exit.\n\n"); output_printf("Type control-D or /exit or /quit or /bye to exit.\n\n");
redisplay(); redisplay();
} }
warn_stop = 0; warn_stop = 0;
@ -677,7 +692,7 @@ static int process_command(esl_handle_t *handle, const char *cmd)
while (*cmd == ' ') cmd++; while (*cmd == ' ') cmd++;
if ((*cmd == '/' && cmd++) || !strncasecmp(cmd, "...", 3)) { if ((*cmd == '/' && cmd++) || !strncasecmp(cmd, "...", 3)) {
if (!strcasecmp(cmd, "help")) { if (!strcasecmp(cmd, "help")) {
printf("%s", cli_usage); output_printf("%s", cli_usage);
goto end; goto end;
} }
if (!strcasecmp(cmd, "exit") || if (!strcasecmp(cmd, "exit") ||
@ -697,7 +712,7 @@ static int process_command(esl_handle_t *handle, const char *cmd)
} else { } else {
esl_safe_free(filter_uuid); esl_safe_free(filter_uuid);
} }
printf("UUID filtering %s\n", filter_uuid ? "enabled" : "disabled"); output_printf("UUID filtering %s\n", filter_uuid ? "enabled" : "disabled");
} else if (!strncasecmp(cmd, "event", 5) || } else if (!strncasecmp(cmd, "event", 5) ||
!strncasecmp(cmd, "noevents", 8) || !strncasecmp(cmd, "noevents", 8) ||
!strncasecmp(cmd, "nixevent", 8) || !strncasecmp(cmd, "nixevent", 8) ||
@ -711,26 +726,26 @@ static int process_command(esl_handle_t *handle, const char *cmd)
int tmp_debug = atoi(cmd+6); int tmp_debug = atoi(cmd+6);
if (tmp_debug > -1 && tmp_debug < 8) { if (tmp_debug > -1 && tmp_debug < 8) {
esl_global_set_default_logger(tmp_debug); esl_global_set_default_logger(tmp_debug);
printf("fs_cli debug level set to %d\n", tmp_debug); output_printf("fs_cli debug level set to %d\n", tmp_debug);
} else { } else {
printf("fs_cli debug level must be 0 - 7\n"); output_printf("fs_cli debug level must be 0 - 7\n");
} }
} else { } else {
printf("Unknown command [%s]\n", cmd); output_printf("Unknown command [%s]\n", cmd);
} }
} else { } else {
char cmd_str[1024] = ""; char cmd_str[1024] = "";
const char *err = NULL; const char *err = NULL;
snprintf(cmd_str, sizeof(cmd_str), "api %s\nconsole_execute: true\n\n", cmd); snprintf(cmd_str, sizeof(cmd_str), "api %s\nconsole_execute: true\n\n", cmd);
if (esl_send_recv(handle, cmd_str)) { if (esl_send_recv(handle, cmd_str)) {
printf("Socket interrupted, bye!\n"); output_printf("Socket interrupted, bye!\n");
return -1; return -1;
} }
if (handle->last_sr_event) { if (handle->last_sr_event) {
if (handle->last_sr_event->body) { if (handle->last_sr_event->body) {
printf("%s\n", handle->last_sr_event->body); output_printf("%s\n", handle->last_sr_event->body);
} else if ((err = esl_event_get_header(handle->last_sr_event, "reply-text")) && !strncasecmp(err, "-err", 3)) { } else if ((err = esl_event_get_header(handle->last_sr_event, "reply-text")) && !strncasecmp(err, "-err", 3)) {
printf("Error: %s!\n", err + 4); output_printf("Error: %s!\n", err + 4);
} }
} }
} }
@ -811,7 +826,7 @@ static const char *banner =
"\n" "\n"
"Type /help <enter> to see a list of commands\n\n\n"; "Type /help <enter> to see a list of commands\n\n\n";
static void print_banner(FILE *stream) { fprintf(stream,banner); } static void print_banner(FILE *stream) { fprintf(stream, "%s%s", output_text_color, banner); }
static void set_fn_keys(cli_profile_t *profile) static void set_fn_keys(cli_profile_t *profile)
{ {
@ -927,6 +942,33 @@ static unsigned char complete(EditLine *el, int ch)
} }
#endif #endif
struct color_map_el {
char name[32];
char seq[12];
};
struct color_map_el color_map[] = {
{"black", ESL_SEQ_FBLACK}, {"bold-black", ESL_SEQ_BBLACK},
{"red", ESL_SEQ_FRED}, {"bold-red", ESL_SEQ_BRED},
{"green", ESL_SEQ_FGREEN}, {"bold-green", ESL_SEQ_BGREEN},
{"yellow", ESL_SEQ_FYELLOW}, {"bold-yellow", ESL_SEQ_BYELLOW},
{"blue", ESL_SEQ_FBLUE}, {"bold-blue", ESL_SEQ_BBLUE},
{"magenta", ESL_SEQ_FMAGEN}, {"bold-magenta", ESL_SEQ_BMAGEN},
{"cyan", ESL_SEQ_FCYAN}, {"bold-cyan", ESL_SEQ_BCYAN},
{"white", ESL_SEQ_FWHITE}, {"bold-white", ESL_SEQ_BWHITE},
{{0}}};
static const char* match_color(const char *s) {
struct color_map_el *map = color_map;
while (map->name) {
if (!(strcasecmp(s, map->name))) {
return map->seq;
}
map++;
}
return ESL_SEQ_DEFAULT_COLOR;
}
static void read_config(const char *dft_cfile, const char *cfile) { static void read_config(const char *dft_cfile, const char *cfile) {
esl_config_t cfg; esl_config_t cfg;
if (esl_config_open_file(&cfg, cfile) || if (esl_config_open_file(&cfg, cfile) ||
@ -941,6 +983,9 @@ static void read_config(const char *dft_cfile, const char *cfile) {
esl_set_string(profiles[pcount].pass, "ClueCon"); esl_set_string(profiles[pcount].pass, "ClueCon");
profiles[pcount].port = 8021; profiles[pcount].port = 8021;
set_fn_keys(&profiles[pcount]); set_fn_keys(&profiles[pcount]);
esl_set_string(profiles[pcount].prompt_color, prompt_color);
esl_set_string(profiles[pcount].input_text_color, input_text_color);
esl_set_string(profiles[pcount].output_text_color, output_text_color);
esl_log(ESL_LOG_DEBUG, "Found Profile [%s]\n", profiles[pcount].name); esl_log(ESL_LOG_DEBUG, "Found Profile [%s]\n", profiles[pcount].name);
pcount++; pcount++;
} }
@ -964,6 +1009,12 @@ static void read_config(const char *dft_cfile, const char *cfile) {
esl_set_string(profiles[pcount-1].loglevel, val); esl_set_string(profiles[pcount-1].loglevel, val);
} else if(!strcasecmp(var, "quiet")) { } else if(!strcasecmp(var, "quiet")) {
profiles[pcount-1].quiet = esl_true(val); profiles[pcount-1].quiet = esl_true(val);
} else if(!strcasecmp(var, "prompt-color")) {
esl_set_string(profiles[pcount-1].prompt_color, match_color(val));
} else if(!strcasecmp(var, "input-text-color")) {
esl_set_string(profiles[pcount-1].input_text_color, match_color(val));
} else if(!strcasecmp(var, "output-text-color")) {
esl_set_string(profiles[pcount-1].output_text_color, match_color(val));
} else if (!strncasecmp(var, "key_F", 5)) { } else if (!strncasecmp(var, "key_F", 5)) {
char *key = var + 5; char *key = var + 5;
if (key) { if (key) {
@ -1034,6 +1085,9 @@ int main(int argc, char *argv[])
strncpy(internal_profile.name, "internal", sizeof(internal_profile.name)); strncpy(internal_profile.name, "internal", sizeof(internal_profile.name));
internal_profile.port = 8021; internal_profile.port = 8021;
set_fn_keys(&internal_profile); set_fn_keys(&internal_profile);
esl_set_string(internal_profile.prompt_color, prompt_color);
esl_set_string(internal_profile.input_text_color, input_text_color);
esl_set_string(internal_profile.output_text_color, output_text_color);
if (home) { if (home) {
snprintf(hfile, sizeof(hfile), "%s/.fs_cli_history", home); snprintf(hfile, sizeof(hfile), "%s/.fs_cli_history", home);
snprintf(cfile, sizeof(cfile), "%s/.fs_cli_conf", home); snprintf(cfile, sizeof(cfile), "%s/.fs_cli_conf", home);
@ -1146,14 +1200,17 @@ int main(int argc, char *argv[])
profile->quiet = 0; profile->quiet = 0;
} }
esl_log(ESL_LOG_DEBUG, "Using profile %s [%s]\n", profile->name, profile->host); esl_log(ESL_LOG_DEBUG, "Using profile %s [%s]\n", profile->name, profile->host);
esl_set_string(prompt_color, profile->prompt_color);
esl_set_string(input_text_color, profile->input_text_color);
esl_set_string(output_text_color, profile->output_text_color);
if (argv_host) { if (argv_host) {
if (argv_port && profile->port != 8021) { if (argv_port && profile->port != 8021) {
snprintf(prompt_str, sizeof(prompt_str), "%sfreeswitch@%s:%u@%s> %s", prompt_color, profile->host, profile->port, profile->name, text_color); snprintf(prompt_str, sizeof(prompt_str), "%sfreeswitch@%s:%u@%s> %s", prompt_color, profile->host, profile->port, profile->name, input_text_color);
} else { } else {
snprintf(prompt_str, sizeof(prompt_str), "%sfreeswitch@%s@%s> %s", prompt_color, profile->host, profile->name, text_color); snprintf(prompt_str, sizeof(prompt_str), "%sfreeswitch@%s@%s> %s", prompt_color, profile->host, profile->name, input_text_color);
} }
} else { } else {
snprintf(prompt_str, sizeof(prompt_str), "%sfreeswitch@%s> %s", prompt_color, profile->name, text_color); snprintf(prompt_str, sizeof(prompt_str), "%sfreeswitch@%s> %s", prompt_color, profile->name, input_text_color);
} }
connect: connect:
connected = 0; connected = 0;
@ -1269,7 +1326,7 @@ int main(int argc, char *argv[])
} }
print_banner(stdout); print_banner(stdout);
esl_log(ESL_LOG_INFO, "FS CLI Ready.\nenter /help for a list of commands.\n"); esl_log(ESL_LOG_INFO, "FS CLI Ready.\nenter /help for a list of commands.\n");
printf("%s\n", handle.last_sr_reply); output_printf("%s\n", handle.last_sr_reply);
while (running > 0) { while (running > 0) {
int r; int r;
#ifdef HAVE_EDITLINE #ifdef HAVE_EDITLINE