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