00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 369001 $")
00033
00034 #include "asterisk/_private.h"
00035 #include <sys/time.h>
00036 #include <signal.h>
00037 #include <sys/stat.h>
00038 #include <fcntl.h>
00039
00040 #include "asterisk/term.h"
00041 #include "asterisk/lock.h"
00042 #include "asterisk/utils.h"
00043
00044 static int vt100compat;
00045
00046 static char prepdata[80] = "";
00047 static char enddata[80] = "";
00048 static char quitdata[80] = "";
00049
00050 static const char * const termpath[] = {
00051 "/usr/share/terminfo",
00052 "/usr/local/share/misc/terminfo",
00053 "/usr/lib/terminfo",
00054 NULL
00055 };
00056
00057 static int opposite(int color)
00058 {
00059 int lookup[] = {
00060 COLOR_BLACK,
00061 COLOR_MAGENTA,
00062 COLOR_GREEN,
00063 COLOR_BROWN,
00064 COLOR_CYAN,
00065 COLOR_RED,
00066 COLOR_BLUE,
00067 COLOR_BLACK };
00068 return color ? lookup[color - 30] : 0;
00069 }
00070
00071
00072 static short convshort(char *s)
00073 {
00074 register int a, b;
00075
00076 a = (int) s[0] & 0377;
00077 b = (int) s[1] & 0377;
00078
00079 if (a == 0377 && b == 0377)
00080 return -1;
00081 if (a == 0376 && b == 0377)
00082 return -2;
00083
00084 return a + b * 256;
00085 }
00086
00087 int ast_term_init(void)
00088 {
00089 char *term = getenv("TERM");
00090 char termfile[256] = "";
00091 char buffer[512] = "";
00092 int termfd = -1, parseokay = 0, i;
00093
00094 if (ast_opt_no_color) {
00095 return 0;
00096 }
00097
00098 if (!ast_opt_console) {
00099
00100 vt100compat = 1;
00101 goto end;
00102 }
00103
00104 if (!term) {
00105 return 0;
00106 }
00107
00108 for (i = 0;; i++) {
00109 if (termpath[i] == NULL) {
00110 break;
00111 }
00112 snprintf(termfile, sizeof(termfile), "%s/%c/%s", termpath[i], *term, term);
00113 termfd = open(termfile, O_RDONLY);
00114 if (termfd > -1) {
00115 break;
00116 }
00117 }
00118 if (termfd > -1) {
00119 int actsize = read(termfd, buffer, sizeof(buffer) - 1);
00120 short sz_names = convshort(buffer + 2);
00121 short sz_bools = convshort(buffer + 4);
00122 short n_nums = convshort(buffer + 6);
00123
00124
00125
00126
00127 if (sz_names + sz_bools + n_nums < actsize) {
00128
00129
00130 short max_colors = convshort(buffer + 12 + sz_names + sz_bools + 13 * 2);
00131 if (max_colors > 0) {
00132 vt100compat = 1;
00133 }
00134 parseokay = 1;
00135 }
00136 close(termfd);
00137 }
00138
00139 if (!parseokay) {
00140
00141
00142
00143
00144
00145 if (!strcmp(term, "linux")) {
00146 vt100compat = 1;
00147 } else if (!strcmp(term, "xterm")) {
00148 vt100compat = 1;
00149 } else if (!strcmp(term, "xterm-color")) {
00150 vt100compat = 1;
00151 } else if (!strcmp(term, "xterm-256color")) {
00152 vt100compat = 1;
00153 } else if (!strncmp(term, "Eterm", 5)) {
00154
00155 vt100compat = 1;
00156 } else if (!strcmp(term, "vt100")) {
00157 vt100compat = 1;
00158 } else if (!strncmp(term, "crt", 3)) {
00159
00160 vt100compat = 1;
00161 }
00162 }
00163
00164 end:
00165 if (vt100compat) {
00166
00167 if (ast_opt_light_background) {
00168 snprintf(prepdata, sizeof(prepdata), "%c[%dm", ESC, COLOR_BROWN);
00169 snprintf(enddata, sizeof(enddata), "%c[%dm", ESC, COLOR_BLACK);
00170 snprintf(quitdata, sizeof(quitdata), "%c[0m", ESC);
00171 } else if (ast_opt_force_black_background) {
00172 snprintf(prepdata, sizeof(prepdata), "%c[%d;%d;%dm", ESC, ATTR_BRIGHT, COLOR_BROWN, COLOR_BLACK + 10);
00173 snprintf(enddata, sizeof(enddata), "%c[%d;%d;%dm", ESC, ATTR_RESET, COLOR_WHITE, COLOR_BLACK + 10);
00174 snprintf(quitdata, sizeof(quitdata), "%c[0m", ESC);
00175 } else {
00176 snprintf(prepdata, sizeof(prepdata), "%c[%d;%dm", ESC, ATTR_BRIGHT, COLOR_BROWN);
00177 snprintf(enddata, sizeof(enddata), "%c[%d;%dm", ESC, ATTR_RESET, COLOR_WHITE);
00178 snprintf(quitdata, sizeof(quitdata), "%c[0m", ESC);
00179 }
00180 }
00181 return 0;
00182 }
00183
00184 char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
00185 {
00186 int attr = 0;
00187
00188 if (!vt100compat) {
00189 ast_copy_string(outbuf, inbuf, maxout);
00190 return outbuf;
00191 }
00192 if (!fgcolor) {
00193 ast_copy_string(outbuf, inbuf, maxout);
00194 return outbuf;
00195 }
00196
00197 if (fgcolor & 128) {
00198 attr = ast_opt_light_background ? 0 : ATTR_BRIGHT;
00199 fgcolor &= ~128;
00200 }
00201
00202 if (bgcolor) {
00203 bgcolor &= ~128;
00204 }
00205
00206 if (ast_opt_light_background) {
00207 fgcolor = opposite(fgcolor);
00208 }
00209
00210 if (ast_opt_force_black_background) {
00211 snprintf(outbuf, maxout, "%c[%d;%d;%dm%s%c[%d;%dm", ESC, attr, fgcolor, bgcolor + 10, inbuf, ESC, COLOR_WHITE, COLOR_BLACK + 10);
00212 } else {
00213 snprintf(outbuf, maxout, "%c[%d;%dm%s%c[0m", ESC, attr, fgcolor, inbuf, ESC);
00214 }
00215 return outbuf;
00216 }
00217
00218 static void check_fgcolor(int *fgcolor, int *attr)
00219 {
00220 if (*fgcolor & 128) {
00221 *attr = ast_opt_light_background ? 0 : ATTR_BRIGHT;
00222 *fgcolor &= ~128;
00223 }
00224
00225 if (ast_opt_light_background) {
00226 *fgcolor = opposite(*fgcolor);
00227 }
00228 }
00229
00230 static void check_bgcolor(int *bgcolor)
00231 {
00232 if (*bgcolor) {
00233 *bgcolor &= ~128;
00234 }
00235 }
00236
00237 static int check_colors_allowed(int fgcolor)
00238 {
00239 return (!vt100compat || !fgcolor) ? 0 : 1;
00240 }
00241
00242 int ast_term_color_code(struct ast_str **str, int fgcolor, int bgcolor)
00243 {
00244 int attr = 0;
00245
00246 if (!check_colors_allowed(fgcolor)) {
00247 return -1;
00248 }
00249
00250 check_fgcolor(&fgcolor, &attr);
00251 check_bgcolor(&bgcolor);
00252
00253 if (ast_opt_force_black_background) {
00254 ast_str_append(str, 0, "%c[%d;%d;%dm", ESC, attr, fgcolor, COLOR_BLACK + 10);
00255 } else if (bgcolor) {
00256 ast_str_append(str, 0, "%c[%d;%d;%dm", ESC, attr, fgcolor, bgcolor + 10);
00257 } else {
00258 ast_str_append(str, 0, "%c[%d;%dm", ESC, attr, fgcolor);
00259 }
00260
00261 return 0;
00262 }
00263
00264 char *term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout)
00265 {
00266 int attr = 0;
00267
00268 if (!check_colors_allowed(fgcolor)) {
00269 *outbuf = '\0';
00270 return outbuf;
00271 }
00272
00273 check_fgcolor(&fgcolor, &attr);
00274 check_bgcolor(&bgcolor);
00275
00276 if (ast_opt_force_black_background) {
00277 snprintf(outbuf, maxout, "%c[%d;%d;%dm", ESC, attr, fgcolor, COLOR_BLACK + 10);
00278 } else if (bgcolor) {
00279 snprintf(outbuf, maxout, "%c[%d;%d;%dm", ESC, attr, fgcolor, bgcolor + 10);
00280 } else {
00281 snprintf(outbuf, maxout, "%c[%d;%dm", ESC, attr, fgcolor);
00282 }
00283
00284 return outbuf;
00285 }
00286
00287 char *term_strip(char *outbuf, const char *inbuf, int maxout)
00288 {
00289 char *outbuf_ptr = outbuf;
00290 const char *inbuf_ptr = inbuf;
00291
00292 while (outbuf_ptr < outbuf + maxout) {
00293 switch (*inbuf_ptr) {
00294 case ESC:
00295 while (*inbuf_ptr && (*inbuf_ptr != 'm'))
00296 inbuf_ptr++;
00297 break;
00298 default:
00299 *outbuf_ptr = *inbuf_ptr;
00300 outbuf_ptr++;
00301 }
00302 if (! *inbuf_ptr)
00303 break;
00304 inbuf_ptr++;
00305 }
00306 return outbuf;
00307 }
00308
00309 char *term_prompt(char *outbuf, const char *inbuf, int maxout)
00310 {
00311 if (!vt100compat) {
00312 ast_copy_string(outbuf, inbuf, maxout);
00313 return outbuf;
00314 }
00315 if (ast_opt_force_black_background) {
00316 snprintf(outbuf, maxout, "%c[%d;%dm%c%c[%d;%dm%s",
00317 ESC, COLOR_BLUE, COLOR_BLACK + 10,
00318 inbuf[0],
00319 ESC, COLOR_WHITE, COLOR_BLACK + 10,
00320 inbuf + 1);
00321 } else if (ast_opt_light_background) {
00322 snprintf(outbuf, maxout, "%c[%d;0m%c%c[%d;0m%s",
00323 ESC, COLOR_BLUE,
00324 inbuf[0],
00325 ESC, COLOR_BLACK,
00326 inbuf + 1);
00327 } else {
00328 snprintf(outbuf, maxout, "%c[%d;%d;0m%c%c[%d;%d;0m%s",
00329 ESC, ATTR_BRIGHT, COLOR_BLUE,
00330 inbuf[0],
00331 ESC, 0, COLOR_WHITE,
00332 inbuf + 1);
00333 }
00334 return outbuf;
00335 }
00336
00337
00338 void term_filter_escapes(char *line)
00339 {
00340 int i;
00341 int len = strlen(line);
00342
00343 for (i = 0; i < len; i++) {
00344 if (line[i] != ESC)
00345 continue;
00346 if ((i < (len - 2)) &&
00347 (line[i + 1] == 0x5B)) {
00348 switch (line[i + 2]) {
00349 case 0x30:
00350 case 0x31:
00351 case 0x33:
00352 continue;
00353 }
00354 }
00355
00356 line[i] = ' ';
00357 }
00358 }
00359
00360 char *term_prep(void)
00361 {
00362 return prepdata;
00363 }
00364
00365 char *term_end(void)
00366 {
00367 return enddata;
00368 }
00369
00370 char *term_quit(void)
00371 {
00372 return quitdata;
00373 }