Home | History | Annotate | Download | only in lib
      1 #include <stdio.h>
      2 #include <stdarg.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <sys/socket.h>
      6 #include <sys/types.h>
      7 #include <linux/if.h>
      8 
      9 #include "color.h"
     10 
     11 enum color {
     12 	C_RED,
     13 	C_GREEN,
     14 	C_YELLOW,
     15 	C_BLUE,
     16 	C_MAGENTA,
     17 	C_CYAN,
     18 	C_WHITE,
     19 	C_BOLD_RED,
     20 	C_BOLD_GREEN,
     21 	C_BOLD_YELLOW,
     22 	C_BOLD_BLUE,
     23 	C_BOLD_MAGENTA,
     24 	C_BOLD_CYAN,
     25 	C_BOLD_WHITE,
     26 	C_CLEAR
     27 };
     28 
     29 static const char * const color_codes[] = {
     30 	"\e[31m",
     31 	"\e[32m",
     32 	"\e[33m",
     33 	"\e[34m",
     34 	"\e[35m",
     35 	"\e[36m",
     36 	"\e[37m",
     37 	"\e[1;31m",
     38 	"\e[1;32m",
     39 	"\e[1;33m",
     40 	"\e[1;34m",
     41 	"\e[1;35m",
     42 	"\e[1;36m",
     43 	"\e[1;37m",
     44 	"\e[0m",
     45 	NULL,
     46 };
     47 
     48 /* light background */
     49 static enum color attr_colors_light[] = {
     50 	C_CYAN,
     51 	C_YELLOW,
     52 	C_MAGENTA,
     53 	C_BLUE,
     54 	C_GREEN,
     55 	C_RED,
     56 	C_CLEAR,
     57 };
     58 
     59 /* dark background */
     60 static enum color attr_colors_dark[] = {
     61 	C_BOLD_CYAN,
     62 	C_BOLD_YELLOW,
     63 	C_BOLD_MAGENTA,
     64 	C_BOLD_BLUE,
     65 	C_BOLD_GREEN,
     66 	C_BOLD_RED,
     67 	C_CLEAR
     68 };
     69 
     70 static int is_dark_bg;
     71 static int color_is_enabled;
     72 
     73 void enable_color(void)
     74 {
     75 	color_is_enabled = 1;
     76 	set_color_palette();
     77 }
     78 
     79 void set_color_palette(void)
     80 {
     81 	char *p = getenv("COLORFGBG");
     82 
     83 	/*
     84 	 * COLORFGBG environment variable usually contains either two or three
     85 	 * values separated by semicolons; we want the last value in either case.
     86 	 * If this value is 0-6 or 8, background is dark.
     87 	 */
     88 	if (p && (p = strrchr(p, ';')) != NULL
     89 		&& ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
     90 		&& p[2] == '\0')
     91 		is_dark_bg = 1;
     92 }
     93 
     94 void check_if_color_enabled(void)
     95 {
     96 	if (color_is_enabled) {
     97 		fprintf(stderr, "Option \"-json\" conflicts with \"-color\".\n");
     98 		exit(1);
     99 	}
    100 }
    101 
    102 int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...)
    103 {
    104 	int ret = 0;
    105 	va_list args;
    106 
    107 	va_start(args, fmt);
    108 
    109 	if (!color_is_enabled || attr == COLOR_NONE) {
    110 		ret = vfprintf(fp, fmt, args);
    111 		goto end;
    112 	}
    113 
    114 	ret += fprintf(fp, "%s", color_codes[is_dark_bg ?
    115 		attr_colors_dark[attr] : attr_colors_light[attr]]);
    116 
    117 	ret += vfprintf(fp, fmt, args);
    118 	ret += fprintf(fp, "%s", color_codes[C_CLEAR]);
    119 
    120 end:
    121 	va_end(args);
    122 	return ret;
    123 }
    124 
    125 enum color_attr ifa_family_color(__u8 ifa_family)
    126 {
    127 	switch (ifa_family) {
    128 	case AF_INET:
    129 		return COLOR_INET;
    130 	case AF_INET6:
    131 		return COLOR_INET6;
    132 	default:
    133 		return COLOR_NONE;
    134 	}
    135 }
    136 
    137 enum color_attr oper_state_color(__u8 state)
    138 {
    139 	switch (state) {
    140 	case IF_OPER_UP:
    141 		return COLOR_OPERSTATE_UP;
    142 	case IF_OPER_DOWN:
    143 		return COLOR_OPERSTATE_DOWN;
    144 	default:
    145 		return COLOR_NONE;
    146 	}
    147 }
    148