"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "trafshow-3.1/color.c" of archive trafshow-3.1.tgz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /*
    2  *	Copyright (c) 1993-1997 JSC Rinet, Novosibirsk, Russia
    3  *
    4  * Redistribution and use in source forms, with and without modification,
    5  * are permitted provided that this entire comment appears intact.
    6  * Redistribution in binary form may occur without any restrictions.
    7  *
    8  * THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND.
    9  */
   10 
   11 /* color.c -- trafshow color support */
   12 
   13 #ifdef	HAVE_CONFIG_H
   14 #include <config.h>
   15 #endif
   16 
   17 #ifdef	HAVE_HAS_COLORS
   18 
   19 #ifdef	HAVE_SLCURSES
   20 #include <slcurses.h>
   21 #endif
   22 #ifdef	HAVE_NCURSES
   23 #include <ncurses.h>
   24 #endif
   25 #ifdef	HAVE_CURSES
   26 #include <curses.h>
   27 #endif
   28 
   29 #include <sys/types.h>
   30 #include <netinet/in.h>
   31 #include <arpa/inet.h>
   32 #include <stdio.h>
   33 #include <stdlib.h>
   34 #include <string.h>
   35 #include <pwd.h>
   36 #include <unistd.h>
   37 #include <ctype.h>
   38 #include <netdb.h>
   39 
   40 #include "trafshow.h"
   41 
   42 #ifndef	INADDR_NONE
   43 #define	INADDR_NONE	0xffffffff
   44 #endif
   45 
   46 static struct m_entry *color_mask = NULL;
   47 static int n_masks = 0;
   48 static int n_pairs = 0;
   49 static char *rc_file;
   50 static int rc_line;
   51 
   52 /* The SLcurses can't handle blink attribute as ncurses; so hack it */
   53 #ifdef	HAVE_SLCURSES
   54 #ifdef	A_BOLD
   55 #undef	A_BOLD
   56 #endif
   57 #define	A_BOLD		SLTT_BOLD_MASK
   58 #ifdef	A_BLINK
   59 #undef	A_BLINK
   60 #endif
   61 #define	A_BLINK		SLTT_BLINK_MASK
   62 
   63 static void
   64 slang_init_pair(pair, fc, bc, at)
   65 	short pair, fc, bc;
   66 	int at;
   67 {
   68 	SLtt_set_color_object(pair, ((fc | (bc << 8)) << 8) | at);
   69 }
   70 
   71 static int
   72 slang_pair_content(pair, fc, bc)
   73 	short pair, *fc, *bc;
   74 {
   75 	int attr;
   76 	SLtt_Char_Type at;
   77 
   78 	at = SLtt_get_color_object(pair);
   79 	attr = at & (A_BOLD | A_BLINK);
   80 	at &= ~(A_BOLD | A_BLINK);
   81 	at >>= 8;
   82 	*fc = at & 0xff;
   83 	*bc = (at >> 8) & 0xff;
   84 
   85 	return attr;
   86 }
   87 #endif	/* HAVE_SLCURSES */
   88 
   89 static short
   90 findpair(f, b, a)
   91 	short f, b;
   92 	int a;
   93 {
   94 	int i, a1;
   95 	short f1, b1;
   96 	struct m_entry *m;
   97 
   98 	for (m = color_mask, i = 0; m != NULL && i < n_masks-1; m++, i++) {
   99 #ifdef	HAVE_SLCURSES
  100 		a1 = slang_pair_content(m->pair, &f1, &b1);
  101 		if (f == f1 && b == b1 && a == a1) return m->pair;
  102 #else
  103 		pair_content(m->pair, &f1, &b1);
  104 		if (f == f1 && b == b1) return m->pair;
  105 #endif
  106 	}
  107 	return 0;
  108 }
  109 
  110 static void
  111 addcolormask(s, m)
  112 	char *s;
  113 	struct m_entry *m;
  114 {
  115 	int i, attr = 0;
  116 	short fc, bc;
  117 	char f[100], *b;
  118 	static short fc_def = COLOR_WHITE, bc_def = COLOR_BLACK;
  119 	static char *ctab[8] = { "black", "red", "green", "yellow",
  120 				"blue",	"magenta", "cyan", "white" };
  121 
  122 	if ((b = strchr(strcpy(f, s), ':')) != NULL) *b++ = '\0';
  123 
  124 	if (*f) {
  125 		for (i = 0; i < 8; i++)
  126 			if (!strcasecmp(ctab[i], f)) break;
  127 		if (i < 8) fc = i;
  128 		else {
  129 			fc = atoi(f);
  130 			if (fc < 1 || fc > COLORS)
  131 				error(0, "%s: line %d: Unknown color `%s'", rc_file, rc_line, f);
  132 		}
  133 		if (isupper(*f)) attr |= A_BOLD;
  134 	} else fc = fc_def;
  135 
  136 	if (b && *b) {
  137 		for (i = 0; i < 8; i++)
  138 			if (!strcasecmp(ctab[i], b)) break;
  139 		if (i < 8) bc = i;
  140 		else {
  141 			bc = atoi(b);
  142 			if (bc < 1 || bc > COLORS)
  143 				error(0, "%s: line %d: Unknown color `%s'",
  144 				      rc_file, rc_line, b);
  145 		}
  146 		if (isupper(*b)) attr |= A_BLINK;
  147 	} else bc = bc_def;
  148 
  149 	if (m != NULL) {
  150 		if ((color_mask = realloc(color_mask, ++n_masks * sizeof(struct m_entry))) == NULL)
  151 			error(1, "addcolormask: realloc");
  152 		if ((m->pair = findpair(fc, bc, attr)) == 0) {
  153 			if (++n_pairs < COLOR_PAIRS-1)
  154 #ifdef	HAVE_SLCURSES
  155 				slang_init_pair(n_pairs, fc, bc, attr);
  156 #else
  157 				init_pair(n_pairs, fc, bc);
  158 #endif
  159 			else	error(0, "%s: line %d: Max %d color-pairs can be used",
  160 				      rc_file, rc_line, COLOR_PAIRS-1);
  161 			m->pair = n_pairs;
  162 		}
  163 		m->attr = attr;
  164 		memcpy(color_mask + (n_masks-1), m, sizeof(struct m_entry));
  165 	} else {	/* default colors */
  166 #ifdef	HAVE_SLCURSES
  167 		slang_init_pair(0, fc, bc, attr);
  168 #else
  169 #ifdef	HAVE_BKGD
  170 		init_pair(COLOR_PAIRS-1, fc, bc);
  171 		bkgd(COLOR_PAIR(COLOR_PAIRS-1) | attr);
  172 #elif	HAVE_WBKGD
  173 		init_pair(COLOR_PAIRS-1, fc, bc);
  174 		wbkgd(stdscr, COLOR_PAIR(COLOR_PAIRS-1) | attr);
  175 #else /* assume the color-pair 0 is background for whole screen */
  176 		init_pair(0, fc, bc);
  177 #endif
  178 #endif
  179 		fc_def = fc;
  180 		bc_def = bc;
  181 	}
  182 }
  183 
  184 static u_int32_t
  185 addr_mask(addr)
  186 	u_int32_t addr;
  187 {
  188 	register u_int32_t m = INADDR_BROADCAST;
  189 
  190 	if (addr) {
  191 		while ((addr & IN_CLASSA_NET) == 0)
  192 			addr <<= IN_CLASSC_NSHIFT, m >>= IN_CLASSC_NSHIFT;
  193 	} else m = INADDR_ANY;
  194 	return m;
  195 }
  196 
  197 /*
  198  * Left justify 'addr' and return its resulting network mask.
  199  */
  200 static u_int32_t
  201 net_mask(addr)
  202 	u_int32_t *addr;
  203 {
  204 	register u_int32_t m = INADDR_BROADCAST;
  205 
  206 	if (*addr)
  207 		while ((*addr & 0xff000000) == 0)
  208 			*addr <<= 8, m <<= 8;
  209 	return m;
  210 }
  211 
  212 static int
  213 isany(s)
  214 	char *s;
  215 {
  216 	return (!strcmp(s, "*") || !strcasecmp(s, "any") || !strcasecmp(s, "all"));
  217 }
  218 
  219 static u_int32_t
  220 str2addr(str, mask)
  221 	char *str;
  222 	u_int32_t *mask;
  223 {
  224 	struct in_addr in;
  225 	struct netent *np;
  226 	struct hostent *hp;
  227 
  228 	if ((in.s_addr = inet_network(str)) != INADDR_NONE) {
  229 		net_mask(&in.s_addr);
  230 		in.s_addr = htonl(in.s_addr);
  231 		*mask = addr_mask(in.s_addr);
  232 		return in.s_addr;
  233 	}
  234 	if (isany(str)) {
  235 		*mask = INADDR_ANY;
  236 		return INADDR_ANY;
  237 	}
  238 	if ((np = getnetbyname(str)) != NULL) {
  239 		in.s_addr = np->n_net;
  240 		*mask = htonl(net_mask(&in.s_addr));
  241 		return htonl(in.s_addr);
  242 	}
  243 	if ((hp = gethostbyname(str)) != NULL) {
  244 		in.s_addr = *(u_int32_t *)*hp->h_addr_list;
  245 		*mask = addr_mask(in.s_addr);
  246 		return in.s_addr;
  247 	}
  248 	error(0, "%s: line %d: Unknown host or network `%s'",
  249 	      rc_file, rc_line, str);
  250 
  251 	/* NOTREACHED */
  252 	return 0;
  253 }
  254 
  255 static u_short
  256 str2port(str, proto)
  257 	char *str, *proto;
  258 {
  259 	u_short port;
  260 	struct servent *sp;
  261 
  262 	if ((port = atoi(str)) < 1) {
  263 		if (isany(str)) return (u_short)0;
  264 		if ((sp = getservbyname(str, proto)) != NULL)
  265 			port = ntohs(sp->s_port);
  266 		else {
  267 			if (proto)
  268 				error(0, "%s: line %d: Unknown port `%s' protocol `%s'",
  269 				      rc_file, rc_line, str, proto);
  270 			else	error(0, "%s: line %d: Unknown port `%s'",
  271 				      rc_file, rc_line, str);
  272 		}
  273 	}
  274 	return port;
  275 }
  276 
  277 static u_int32_t
  278 parsehostport(s, mask, port, proto)
  279 	char *s, *proto;
  280 	u_int32_t *mask;
  281 	u_short *port;
  282 {
  283 	u_int32_t addr;
  284 	char h[100], *m, *p;
  285 
  286 	if ((p = strchr(strcpy(h, s), ':')) != NULL) *p++ = '\0';
  287 	if ((m = strchr(h, '/')) != NULL) *m++ = '\0';
  288 	addr = str2addr(h, mask);
  289 	if (m) {
  290 		if (strchr(m, '.') == NULL) {	/* mean number of bits */
  291 			int i, n = atoi(m);
  292 			*mask = 0;
  293 			for (i = 0; i < n; i++) {
  294 				*mask >>= 1;
  295 				*mask |= 0x80000000L;
  296 			}
  297 			*mask = htonl(*mask);
  298 		} else *mask = inet_addr(m);
  299 	}
  300 	*port = (u_short)0;
  301 	if (p) *port = str2port(p, proto);
  302 	return addr;
  303 }
  304 
  305 static char *
  306 str2proto(str, proto)
  307 	char *str;
  308 	u_short *proto;
  309 {
  310 	short num;
  311 
  312 	if (isany(str)) {
  313 		*proto = (u_short)0;
  314 		return NULL;
  315 	}
  316 	if ((num = getprotonum(str)) == -1)
  317 		error(0, "%s: line %d: Unknown protocol `%s'",
  318 		      rc_file, rc_line, str);
  319 
  320 	*proto = num;
  321 	return getprotoname(*proto);
  322 }
  323 
  324 int
  325 init_colormask()
  326 {
  327 	FILE *fp;
  328 	int ns;
  329 	struct m_entry m;
  330 	struct passwd *pw;
  331 	char *p, buf[1024];
  332 	char s1[100], s2[100], s3[100], s4[100];
  333 	extern char *program_name;
  334 
  335 	if ((pw = getpwuid(getuid())) == NULL)
  336 		error(1, "init_color_mask: getpwuid");
  337 	(void) sprintf(buf, "%s/.%s", pw->pw_dir, program_name);
  338 	if ((fp = fopen(buf, "r")) == NULL) {
  339 		(void) strcpy(buf, "/etc/");
  340 		(void) strcat(buf, program_name);
  341 		if ((fp = fopen(buf, "r")) == NULL) return 0;
  342 	}
  343 	if ((rc_file = (char *)malloc(strlen(buf)+1)) == NULL)
  344 		error(1, "init_color_mask: malloc");
  345 	(void)strcpy(rc_file, buf);
  346 	rc_line = 0;
  347 	while (fgets(buf, sizeof(buf), fp) != NULL) {
  348 		rc_line++;
  349 		if (buf[0] == '\n' || buf[0] == '#') continue;
  350 		if ((p = strchr(buf, '#')) != NULL) {
  351 			*p++ = '\n';
  352 			*p = '\0';
  353 		}
  354 		memset(&m, 0, sizeof(struct m_entry));
  355 		ns = sscanf(buf, "%s %s %s %s\n", s1, s2, s3, s4);
  356 		if (ns == 2) {
  357 			if (strcasecmp(s1, "default")) {
  358 				if ((p = strchr(s1, '/')) != NULL) {
  359 					*p++ = '\0';
  360 					m.dport = str2port(s1, str2proto(p, &m.proto));
  361 				} else	m.dport = str2port(s1, NULL);
  362 				addcolormask(s2, &m);
  363 				m.sport = m.dport;
  364 				m.dport = 0;
  365 				addcolormask(s2, &m);
  366 			} else addcolormask(s2, NULL);
  367 		} else if (ns == 4) {
  368 			p = str2proto(s3, &m.proto);
  369 			m.src.s_addr = parsehostport(s1, &m.sm.s_addr, &m.sport, p);
  370 			m.dst.s_addr = parsehostport(s2, &m.dm.s_addr, &m.dport, p);
  371 			addcolormask(s4, &m);
  372 		} else error(0, "%s: line %d: Bad format", rc_file, rc_line);
  373 	}
  374 	fclose(fp);
  375 #ifdef	DEBUG
  376 	error(0, "n_masks=%d, n_pairs=%d", n_masks, n_pairs);
  377 #endif
  378 	return n_masks;
  379 }
  380 
  381 int
  382 color_on(e)
  383 	register struct t_entry *e;
  384 {
  385 	int i;
  386 	register struct m_entry *m;
  387 
  388 	for (m = color_mask, i = 0; m != NULL, i < n_masks; m++, i++) {
  389 		if ((e->src.s_addr & m->sm.s_addr) ^ m->src.s_addr)
  390 			continue;
  391 		if ((e->dst.s_addr & m->dm.s_addr) ^ m->dst.s_addr)
  392 			continue;
  393 		if (m->proto && e->proto != m->proto)
  394 			continue;
  395 		if (m->sport && e->sport != m->sport)
  396 			continue;
  397 		if (m->dport && e->dport != m->dport)
  398 			continue;
  399 #ifdef	HAVE_SLCURSES
  400 		attron(COLOR_PAIR(m->pair));
  401 #else
  402 		attron(COLOR_PAIR(m->pair) | m->attr);
  403 #endif
  404 		return TRUE;
  405 	}
  406 	return FALSE;
  407 }
  408 
  409 #endif	/* HAVE_HAS_COLORS */