From d86fc7fcc14558821b55b8f84c1cbdfcb345adbf Mon Sep 17 00:00:00 2001 From: Tilghman Lesher <tilghman@meg.abyt.es> Date: Wed, 30 Jul 2008 15:30:18 +0000 Subject: [PATCH] Add %u and %g to the ASTERISK_PROMPT settings, for username and group, respectively. Also, take the opportunity to clean up the CLI prompt generation code. (closes issue #13175) Reported by: eliel Patches: cliprompt.patch uploaded by eliel (license 64) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@134353 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- doc/tex/cliprompt.tex | 6 +- main/asterisk.c | 150 +++++++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 79 deletions(-) diff --git a/doc/tex/cliprompt.tex b/doc/tex/cliprompt.tex index 42e6b4bd13..aaa2afb0e4 100644 --- a/doc/tex/cliprompt.tex +++ b/doc/tex/cliprompt.tex @@ -12,18 +12,18 @@ the current value by Asterisk: \item \%h - Full hostname \item \%H - Short hostname \item \%t - Time + \item \%u - Username + \item \%g - Groupname \item \%\% - Percent sign \item \%\# - '\#' if Asterisk is run in console mode, '$>$' if running as remote console \item \%Cn[;n] - Change terminal foreground (and optional background) color to specified A full list of colors may be found in \path{include/asterisk/term.h} \end{itemize} -On Linux systems, you may also use: +On systems which implement getloadavg(3), you may also use: \begin{itemize} \item \%l1 - Load average over past minute \item \%l2 - Load average over past 5 minutes \item \%l3 - Load average over past 15 minutes - \item \%l4 - Process fraction (processes running / total processes) - \item \%l5 - The most recently allocated pid \end{itemize} diff --git a/main/asterisk.c b/main/asterisk.c index 20dd36343f..ead10ca007 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -1991,25 +1991,34 @@ static int ast_el_read_char(EditLine *el, char *cp) return (0); } +static struct ast_str *prompt = NULL; + static char *cli_prompt(EditLine *el) { - static char prompt[200]; + char tmp[100]; char *pfmt; int color_used = 0; + static int cli_prompt_changes = 0; char term_code[20]; + struct passwd *pw; + struct group *gr; + + if (prompt == NULL) { + prompt = ast_str_create(100); + } else if (!cli_prompt_changes) { + return prompt->str; + } else { + ast_str_reset(prompt); + } if ((pfmt = getenv("ASTERISK_PROMPT"))) { - char *t = pfmt, *p = prompt; - memset(prompt, 0, sizeof(prompt)); - while (*t != '\0' && *p < sizeof(prompt)) { + char *t = pfmt; + struct timeval ts = ast_tvnow(); + while (*t != '\0') { if (*t == '%') { - char hostname[MAXHOSTNAMELEN]=""; - int i; - struct timeval ts = ast_tvnow(); + char hostname[MAXHOSTNAMELEN] = ""; + int i, which; struct ast_tm tm = { 0, }; -#ifdef linux - FILE *LOADAVG; -#endif int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK; t++; @@ -2017,10 +2026,10 @@ static char *cli_prompt(EditLine *el) case 'C': /* color */ t++; if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) { - strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); + ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code))); t += i - 1; } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) { - strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); + ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code))); t += i - 1; } @@ -2028,102 +2037,91 @@ static char *cli_prompt(EditLine *el) color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1; break; case 'd': /* date */ - if (ast_localtime(&ts, &tm, NULL)) - ast_strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm); + if (ast_localtime(&ts, &tm, NULL)) { + ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm); + ast_str_append(&prompt, 0, "%s", tmp); + cli_prompt_changes++; + } + break; + case 'g': /* group */ + if ((gr = getgrgid(getgid()))) { + ast_str_append(&prompt, 0, "%s", gr->gr_name); + } break; case 'h': /* hostname */ - if (!gethostname(hostname, sizeof(hostname) - 1)) - strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); - else - strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); + if (!gethostname(hostname, sizeof(hostname) - 1)) { + ast_str_append(&prompt, 0, "%s", hostname); + } else { + ast_str_append(&prompt, 0, "%s", "localhost"); + } break; case 'H': /* short hostname */ if (!gethostname(hostname, sizeof(hostname) - 1)) { - for (i = 0; i < sizeof(hostname); i++) { - if (hostname[i] == '.') { - hostname[i] = '\0'; - break; - } + char *dotptr; + if ((dotptr = strchr(hostname, '.'))) { + *dotptr = '\0'; } - strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); - } else - strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); + ast_str_append(&prompt, 0, "%s", hostname); + } else { + ast_str_append(&prompt, 0, "%s", "localhost"); + } break; -#ifdef linux +#ifdef HAVE_GETLOADAVG case 'l': /* load avg */ t++; - if ((LOADAVG = fopen("/proc/loadavg", "r"))) { - float avg1, avg2, avg3; - int actproc, totproc, npid, which; - fscanf(LOADAVG, "%f %f %f %d/%d %d", - &avg1, &avg2, &avg3, &actproc, &totproc, &npid); - if (sscanf(t, "%d", &which) == 1) { - switch (which) { - case 1: - snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1); - break; - case 2: - snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2); - break; - case 3: - snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3); - break; - case 4: - snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc); - break; - case 5: - snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid); - break; - } - } + if (sscanf(t, "%d", &which) == 1 && which > 0 && which <= 3) { + double list[3]; + getloadavg(list, 3); + ast_str_append(&prompt, 0, "%.2f", list[which - 1]); + cli_prompt_changes++; } break; #endif case 's': /* Asterisk system name (from asterisk.conf) */ - strncat(p, ast_config_AST_SYSTEM_NAME, sizeof(prompt) - strlen(prompt) - 1); + ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME); break; case 't': /* time */ - if (ast_localtime(&ts, &tm, NULL)) - ast_strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm); + if (ast_localtime(&ts, &tm, NULL)) { + ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm); + ast_str_append(&prompt, 0, "%s", tmp); + cli_prompt_changes++; + } + break; + case 'u': /* username */ + if ((pw = getpwuid(getuid()))) { + ast_str_append(&prompt, 0, "%s", pw->pw_name); + } break; case '#': /* process console or remote? */ - if (!ast_opt_remote) - strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1); - else - strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1); + ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#'); break; case '%': /* literal % */ - strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1); + ast_str_append(&prompt, 0, "%c", '%'); break; case '\0': /* % is last character - prevent bug */ t--; break; } - while (*p != '\0') - p++; t++; } else { - *p = *t; - p++; - t++; + if (prompt->used + 5 > prompt->len) { + ast_str_make_space(&prompt, prompt->len + 5); + } + prompt->str[prompt->used++] = *t++; + prompt->str[prompt->used] = '\0'; } } if (color_used) { /* Force colors back to normal at end */ - term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code)); - if (strlen(term_code) > sizeof(prompt) - strlen(prompt) - 1) { - ast_copy_string(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code) + 1); - } else { - /* This looks wrong, but we've already checked the length of term_code to ensure it's safe */ - strncat(p, term_code, sizeof(term_code)); - } + ast_str_append(&prompt, 0, "%s", term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code))); } - } else if (remotehostname) - snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname); - else - ast_copy_string(prompt, ASTERISK_PROMPT, sizeof(prompt)); + } else if (remotehostname) { + ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname); + } else { + ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT); + } - return(prompt); + return(prompt->str); } static char **ast_el_strtoarr(char *buf) -- GitLab