1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
/* SPDX-License-Identifier: GPL-2.0 */
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/if.h>
#include "color.h"
#include "utils.h"
static void set_color_palette(void);
enum color {
C_RED,
C_GREEN,
C_YELLOW,
C_BLUE,
C_MAGENTA,
C_CYAN,
C_WHITE,
C_BOLD_RED,
C_BOLD_GREEN,
C_BOLD_YELLOW,
C_BOLD_BLUE,
C_BOLD_MAGENTA,
C_BOLD_CYAN,
C_BOLD_WHITE,
C_CLEAR
};
static const char * const color_codes[] = {
"\e[31m",
"\e[32m",
"\e[33m",
"\e[34m",
"\e[35m",
"\e[36m",
"\e[37m",
"\e[1;31m",
"\e[1;32m",
"\e[1;33m",
"\e[1;34m",
"\e[1;35m",
"\e[1;36m",
"\e[1;37m",
"\e[0m",
NULL,
};
/* light background */
static enum color attr_colors_light[] = {
C_CYAN,
C_YELLOW,
C_MAGENTA,
C_BLUE,
C_GREEN,
C_RED,
C_CLEAR,
};
/* dark background */
static enum color attr_colors_dark[] = {
C_BOLD_CYAN,
C_BOLD_YELLOW,
C_BOLD_MAGENTA,
C_BOLD_BLUE,
C_BOLD_GREEN,
C_BOLD_RED,
C_CLEAR
};
static int is_dark_bg;
static int color_is_enabled;
static void enable_color(void)
{
color_is_enabled = 1;
set_color_palette();
}
bool check_enable_color(int color, int json)
{
if (json || color == COLOR_OPT_NEVER)
return false;
if (color == COLOR_OPT_ALWAYS || isatty(fileno(stdout))) {
enable_color();
return true;
}
return false;
}
bool matches_color(const char *arg, int *val)
{
char *dup, *p;
if (!val)
return false;
dup = strdupa(arg);
p = strchrnul(dup, '=');
if (*p)
*(p++) = '\0';
if (matches(dup, "-color"))
return false;
if (*p == '\0' || !strcmp(p, "always"))
*val = COLOR_OPT_ALWAYS;
else if (!strcmp(p, "auto"))
*val = COLOR_OPT_AUTO;
else if (!strcmp(p, "never"))
*val = COLOR_OPT_NEVER;
else
return false;
return true;
}
static void set_color_palette(void)
{
char *p = getenv("COLORFGBG");
/*
* COLORFGBG environment variable usually contains either two or three
* values separated by semicolons; we want the last value in either case.
* If this value is 0-6 or 8, background is dark.
*/
if (p && (p = strrchr(p, ';')) != NULL
&& ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
&& p[2] == '\0')
is_dark_bg = 1;
}
__attribute__((format(printf, 3, 4)))
int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...)
{
int ret = 0;
va_list args;
va_start(args, fmt);
if (!color_is_enabled || attr == COLOR_NONE) {
ret = vfprintf(fp, fmt, args);
goto end;
}
ret += fprintf(fp, "%s", color_codes[is_dark_bg ?
attr_colors_dark[attr] : attr_colors_light[attr]]);
ret += vfprintf(fp, fmt, args);
ret += fprintf(fp, "%s", color_codes[C_CLEAR]);
end:
va_end(args);
return ret;
}
enum color_attr ifa_family_color(__u8 ifa_family)
{
switch (ifa_family) {
case AF_INET:
return COLOR_INET;
case AF_INET6:
return COLOR_INET6;
default:
return COLOR_NONE;
}
}
enum color_attr oper_state_color(__u8 state)
{
switch (state) {
case IF_OPER_UP:
return COLOR_OPERSTATE_UP;
case IF_OPER_DOWN:
return COLOR_OPERSTATE_DOWN;
default:
return COLOR_NONE;
}
}
|