xref: /onnv-gate/usr/src/cmd/avs/sdbc/sd_stats.c (revision 11576:b23c42c0c9d6)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
21*11576SSurya.Prakki@Sun.COM 
227836SJohn.Forte@Sun.COM /*
23*11576SSurya.Prakki@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
247836SJohn.Forte@Sun.COM  * Use is subject to license terms.
257836SJohn.Forte@Sun.COM  */
267836SJohn.Forte@Sun.COM 
277836SJohn.Forte@Sun.COM #include <stdio.h>
287836SJohn.Forte@Sun.COM #include <stdlib.h>
297836SJohn.Forte@Sun.COM #include <unistd.h>
307836SJohn.Forte@Sun.COM #include <strings.h>
317836SJohn.Forte@Sun.COM #include <curses.h>
327836SJohn.Forte@Sun.COM #include <signal.h>
337836SJohn.Forte@Sun.COM #include <fcntl.h>
347836SJohn.Forte@Sun.COM #include <locale.h>
357836SJohn.Forte@Sun.COM 
367836SJohn.Forte@Sun.COM #include <sys/types.h>
377836SJohn.Forte@Sun.COM #include <sys/time.h>
387836SJohn.Forte@Sun.COM #include <sys/nsctl/sdbc_ioctl.h>
397836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_u.h>
407836SJohn.Forte@Sun.COM #include <sys/nsctl/sd_bcache.h>
417836SJohn.Forte@Sun.COM #include <sys/nsctl/sd_conf.h>
427836SJohn.Forte@Sun.COM 
437836SJohn.Forte@Sun.COM extern void total_display(void);
447836SJohn.Forte@Sun.COM extern void display_cache(void);
457836SJohn.Forte@Sun.COM extern void wrefresh_file(WINDOW *, int);
467836SJohn.Forte@Sun.COM extern int is_dirty(void);
477836SJohn.Forte@Sun.COM extern int dual_stats(void);
487836SJohn.Forte@Sun.COM void checkbuf(int);
497836SJohn.Forte@Sun.COM void setup_ranges(char *);
507836SJohn.Forte@Sun.COM void prheading(int);
517836SJohn.Forte@Sun.COM extern int zero_nic(void);
527836SJohn.Forte@Sun.COM 
537836SJohn.Forte@Sun.COM #ifdef m88k
547836SJohn.Forte@Sun.COM #define	USEC_INIT()	usec_ptr = (unsigned int *)timer_init()
557836SJohn.Forte@Sun.COM #define	USEC_READ()	(*usec_ptr)
567836SJohn.Forte@Sun.COM #else /* !m88k */
577836SJohn.Forte@Sun.COM #define	USEC_INIT()	USEC_START()
587836SJohn.Forte@Sun.COM #include <sys/time.h>
597836SJohn.Forte@Sun.COM static struct timeval Usec_time;
607836SJohn.Forte@Sun.COM static int Usec_started = 0;
617836SJohn.Forte@Sun.COM 
627836SJohn.Forte@Sun.COM extern int higher(int);
637836SJohn.Forte@Sun.COM extern int is_dirty();
647836SJohn.Forte@Sun.COM extern int dual_stats();
657836SJohn.Forte@Sun.COM extern void total_display();
667836SJohn.Forte@Sun.COM extern void display_cache();
677836SJohn.Forte@Sun.COM extern void wrefresh_file(WINDOW *, int);
687836SJohn.Forte@Sun.COM void setup_ranges(char *);
697836SJohn.Forte@Sun.COM 
707836SJohn.Forte@Sun.COM void prheading(int);
717836SJohn.Forte@Sun.COM void checkbuf(int);
727836SJohn.Forte@Sun.COM void quit(int);
737836SJohn.Forte@Sun.COM void leave(int);
747836SJohn.Forte@Sun.COM #pragma does_not_return(quit, leave)
757836SJohn.Forte@Sun.COM 
767836SJohn.Forte@Sun.COM int sdbc_max_devices = 0;
777836SJohn.Forte@Sun.COM 
787836SJohn.Forte@Sun.COM static void
USEC_START()797836SJohn.Forte@Sun.COM USEC_START()
807836SJohn.Forte@Sun.COM {
817836SJohn.Forte@Sun.COM 	if (!Usec_started) {
827836SJohn.Forte@Sun.COM 		(void) gettimeofday(&Usec_time, NULL);
837836SJohn.Forte@Sun.COM 		Usec_started = 1;
847836SJohn.Forte@Sun.COM 	}
857836SJohn.Forte@Sun.COM }
867836SJohn.Forte@Sun.COM 
877836SJohn.Forte@Sun.COM static unsigned int
USEC_READ()887836SJohn.Forte@Sun.COM USEC_READ()
897836SJohn.Forte@Sun.COM {
907836SJohn.Forte@Sun.COM 	struct timeval tv;
917836SJohn.Forte@Sun.COM 	if (!Usec_started)
927836SJohn.Forte@Sun.COM 		USEC_START();
937836SJohn.Forte@Sun.COM 
947836SJohn.Forte@Sun.COM 	(void) gettimeofday(&tv, NULL);
957836SJohn.Forte@Sun.COM 	return (unsigned)((tv.tv_sec - Usec_time.tv_sec) * 1000000
967836SJohn.Forte@Sun.COM 	    + (tv.tv_usec - Usec_time.tv_usec));
977836SJohn.Forte@Sun.COM }
987836SJohn.Forte@Sun.COM #endif /* m88k */
997836SJohn.Forte@Sun.COM 
1007836SJohn.Forte@Sun.COM int		rev_flag = 0;		/* Reverse video flag */
1017836SJohn.Forte@Sun.COM int		bold_flg = 0;		/* Bold flag */
1027836SJohn.Forte@Sun.COM int		under_flg = 0;		/* Underline flag */
1037836SJohn.Forte@Sun.COM int		errflg = 0;		/* Error flag */
1047836SJohn.Forte@Sun.COM int		node_sw = 0;		/* Per node switch */
1057836SJohn.Forte@Sun.COM int 		toggle_total_sw = 0;
1067836SJohn.Forte@Sun.COM int		mirror_sw = 0;		/* Dual copy switch */
1077836SJohn.Forte@Sun.COM 
1087836SJohn.Forte@Sun.COM int		kmemfd;
1097836SJohn.Forte@Sun.COM int		delay = 1;			/* Display delay (seconds) */
1107836SJohn.Forte@Sun.COM 
1117836SJohn.Forte@Sun.COM time_t	*usec_ptr;
1127836SJohn.Forte@Sun.COM time_t	currtime = 0;
1137836SJohn.Forte@Sun.COM int		lasttime = 0;
1147836SJohn.Forte@Sun.COM int		Elapsed_Time = 0;
1157836SJohn.Forte@Sun.COM 
1167836SJohn.Forte@Sun.COM static char	*range;
1177836SJohn.Forte@Sun.COM static int	had_r_option = 0;
1187836SJohn.Forte@Sun.COM int		logfd = -1;		/* screen output logging */
1197836SJohn.Forte@Sun.COM extern 		int range_num;
1207836SJohn.Forte@Sun.COM extern		int screen;
1217836SJohn.Forte@Sun.COM extern 		int dual_screen;
1227836SJohn.Forte@Sun.COM int		*on_off;
1237836SJohn.Forte@Sun.COM int		*dual_on_off;
1247836SJohn.Forte@Sun.COM int		*updates_prev;
1257836SJohn.Forte@Sun.COM double		*rate_prev;
1267836SJohn.Forte@Sun.COM int		*samples;
1277836SJohn.Forte@Sun.COM _sd_stats_t	*cs_cur;
1287836SJohn.Forte@Sun.COM _sd_stats_t	*cs_prev;
1297836SJohn.Forte@Sun.COM _sd_stats_t	*cs_persec;
1307836SJohn.Forte@Sun.COM 
1317836SJohn.Forte@Sun.COM typedef struct {
1327836SJohn.Forte@Sun.COM 	int lb, ub;
1337836SJohn.Forte@Sun.COM } range_t;
1347836SJohn.Forte@Sun.COM 
1357836SJohn.Forte@Sun.COM extern range_t ranges[];
1367836SJohn.Forte@Sun.COM 
1377836SJohn.Forte@Sun.COM #ifdef lint
1387836SJohn.Forte@Sun.COM int
sd_stats_lintmain(int argc,char * argv[])1397836SJohn.Forte@Sun.COM sd_stats_lintmain(int argc, char *argv[])
1407836SJohn.Forte@Sun.COM #else
1417836SJohn.Forte@Sun.COM int
1427836SJohn.Forte@Sun.COM main(int argc, char *argv[])
1437836SJohn.Forte@Sun.COM #endif
1447836SJohn.Forte@Sun.COM {
1457836SJohn.Forte@Sun.COM 	spcs_s_info_t ustats;
1467836SJohn.Forte@Sun.COM 	struct timeval tout;
1477836SJohn.Forte@Sun.COM 	fd_set readfds;
1487836SJohn.Forte@Sun.COM 	char *errmessage, *ch;
1497836SJohn.Forte@Sun.COM 	int c, period, prev;
1507836SJohn.Forte@Sun.COM 	int count = 0, dflag = 0;
1517836SJohn.Forte@Sun.COM 	int fd = fileno(stdin);
1527836SJohn.Forte@Sun.COM 
1537836SJohn.Forte@Sun.COM 	errmessage = NULL;
1547836SJohn.Forte@Sun.COM 
1557836SJohn.Forte@Sun.COM 	if (strcmp(argv[0], "sd_stats") != 0)
1567836SJohn.Forte@Sun.COM 		errmessage = getenv("SD_STATS_USAGE");
1577836SJohn.Forte@Sun.COM 
1587836SJohn.Forte@Sun.COM 	if (errmessage == NULL)
1597836SJohn.Forte@Sun.COM 		errmessage = gettext("Usage: sd_stats [-Mz] "
1607836SJohn.Forte@Sun.COM 				"[-d delay_time] [-l logfile] [-r range]");
1617836SJohn.Forte@Sun.COM 
1627836SJohn.Forte@Sun.COM 	if (SDBC_IOCTL(SDBC_MAXFILES, &sdbc_max_devices,
1637836SJohn.Forte@Sun.COM 	    0, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
1647836SJohn.Forte@Sun.COM 		if (ustats) {  	/* if SPCS_S_ERROR */
1657836SJohn.Forte@Sun.COM 			spcs_s_report(ustats, stderr);
1667836SJohn.Forte@Sun.COM 			spcs_s_ufree(&ustats);
1677836SJohn.Forte@Sun.COM 		}
1687836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, gettext("cannot get maxfiles\n"));
1697836SJohn.Forte@Sun.COM 		exit(1);
1707836SJohn.Forte@Sun.COM 	}
1717836SJohn.Forte@Sun.COM 	on_off = calloc(sdbc_max_devices, sizeof (int));
1727836SJohn.Forte@Sun.COM 	dual_on_off = calloc(sdbc_max_devices, sizeof (int));
1737836SJohn.Forte@Sun.COM 	updates_prev = calloc(sdbc_max_devices, sizeof (int));
1747836SJohn.Forte@Sun.COM 	samples = calloc(sdbc_max_devices, sizeof (int));
1757836SJohn.Forte@Sun.COM 	rate_prev = calloc(sdbc_max_devices, sizeof (double));
1767836SJohn.Forte@Sun.COM 	cs_cur = malloc(sizeof (_sd_stats_t) +
1777836SJohn.Forte@Sun.COM 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
1787836SJohn.Forte@Sun.COM 	cs_prev = malloc(sizeof (_sd_stats_t) +
1797836SJohn.Forte@Sun.COM 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
1807836SJohn.Forte@Sun.COM 	cs_persec = malloc(sizeof (_sd_stats_t) +
1817836SJohn.Forte@Sun.COM 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
1827836SJohn.Forte@Sun.COM 	range = malloc(100);
1837836SJohn.Forte@Sun.COM 
1847836SJohn.Forte@Sun.COM 	if (!on_off || !dual_on_off || !updates_prev || !samples ||
1857836SJohn.Forte@Sun.COM 	    !rate_prev || !cs_cur || !cs_prev || !cs_persec || !range) {
1867836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, gettext("no free memory\n"));
1877836SJohn.Forte@Sun.COM 		exit(1);
1887836SJohn.Forte@Sun.COM 	}
1897836SJohn.Forte@Sun.COM 
1907836SJohn.Forte@Sun.COM 	*range = '\0';
1917836SJohn.Forte@Sun.COM 
1927836SJohn.Forte@Sun.COM 	while ((c = getopt(argc, argv, "DMzd:l:r:h")) != EOF) {
1937836SJohn.Forte@Sun.COM 
1947836SJohn.Forte@Sun.COM 		prev = c;
1957836SJohn.Forte@Sun.COM 		switch (c) {
1967836SJohn.Forte@Sun.COM 
1977836SJohn.Forte@Sun.COM 		case 'd':
1987836SJohn.Forte@Sun.COM 			delay = atoi(optarg);
1997836SJohn.Forte@Sun.COM 			ch = optarg;
2007836SJohn.Forte@Sun.COM 			while (*ch != '\0') {
2017836SJohn.Forte@Sun.COM 				if (!isdigit(*ch))
2027836SJohn.Forte@Sun.COM 					errflg++;
2037836SJohn.Forte@Sun.COM 				ch++;
2047836SJohn.Forte@Sun.COM 			}
2057836SJohn.Forte@Sun.COM 			break;
2067836SJohn.Forte@Sun.COM 
2077836SJohn.Forte@Sun.COM 		case 'l':
2087836SJohn.Forte@Sun.COM 			logfd = open(optarg, O_CREAT|O_WRONLY|O_TRUNC, 0644);
2097836SJohn.Forte@Sun.COM 			break;
2107836SJohn.Forte@Sun.COM 
2117836SJohn.Forte@Sun.COM 		case 'r':
2127836SJohn.Forte@Sun.COM 			ch = optarg;
2137836SJohn.Forte@Sun.COM 			while (*ch != '\0') {
2147836SJohn.Forte@Sun.COM 				if ((!isdigit(*ch)) && (*ch != ',') &&
2157836SJohn.Forte@Sun.COM 				    (*ch != ':'))
2167836SJohn.Forte@Sun.COM 					errflg++;
2177836SJohn.Forte@Sun.COM 				ch++;
2187836SJohn.Forte@Sun.COM 			}
2197836SJohn.Forte@Sun.COM 			if (errflg)
2207836SJohn.Forte@Sun.COM 				break;
2217836SJohn.Forte@Sun.COM 
2227836SJohn.Forte@Sun.COM 			range = realloc((char *)range,
2237836SJohn.Forte@Sun.COM 					(strlen(range) + strlen(optarg) + 1)
2247836SJohn.Forte@Sun.COM 					* sizeof (char));
2257836SJohn.Forte@Sun.COM 
2267836SJohn.Forte@Sun.COM 			if (had_r_option)
2277836SJohn.Forte@Sun.COM 				(void) strcat(range, ",");
2287836SJohn.Forte@Sun.COM 			(void) strcat(range, optarg);
2297836SJohn.Forte@Sun.COM 			had_r_option = 1;
2307836SJohn.Forte@Sun.COM 			break;
2317836SJohn.Forte@Sun.COM 
2327836SJohn.Forte@Sun.COM 		case 'z':
2337836SJohn.Forte@Sun.COM 			if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0,
2347836SJohn.Forte@Sun.COM 					&ustats) == SPCS_S_ERROR) {
2357836SJohn.Forte@Sun.COM 				if (ustats) {
2367836SJohn.Forte@Sun.COM 					spcs_s_report(ustats, stderr);
2377836SJohn.Forte@Sun.COM 					spcs_s_ufree(&ustats);
2387836SJohn.Forte@Sun.COM 				}
2397836SJohn.Forte@Sun.COM 			}
2407836SJohn.Forte@Sun.COM 
2417836SJohn.Forte@Sun.COM 			break;
2427836SJohn.Forte@Sun.COM 
2437836SJohn.Forte@Sun.COM 		case 'D':
2447836SJohn.Forte@Sun.COM 			dflag = 1;
2457836SJohn.Forte@Sun.COM 			break;
2467836SJohn.Forte@Sun.COM 
2477836SJohn.Forte@Sun.COM 		case 'M':
2487836SJohn.Forte@Sun.COM 			mirror_sw = 1;
2497836SJohn.Forte@Sun.COM 			break;
2507836SJohn.Forte@Sun.COM 
2517836SJohn.Forte@Sun.COM 		case 'h':
2527836SJohn.Forte@Sun.COM 		case '?':
2537836SJohn.Forte@Sun.COM 		default :
2547836SJohn.Forte@Sun.COM 			errflg++;
2557836SJohn.Forte@Sun.COM 			break;
2567836SJohn.Forte@Sun.COM 		}
2577836SJohn.Forte@Sun.COM 	}
2587836SJohn.Forte@Sun.COM 
2597836SJohn.Forte@Sun.COM 	if (errflg) {
2607836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s\n", errmessage);
2617836SJohn.Forte@Sun.COM 		exit(1);
2627836SJohn.Forte@Sun.COM 	} else if (!prev) {
2637836SJohn.Forte@Sun.COM 		if (argc > 1) {
2647836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s\n", errmessage);
2657836SJohn.Forte@Sun.COM 			exit(1);
2667836SJohn.Forte@Sun.COM 		}
2677836SJohn.Forte@Sun.COM 	}
2687836SJohn.Forte@Sun.COM 
2697836SJohn.Forte@Sun.COM 	if (dflag) {
2707836SJohn.Forte@Sun.COM 		exit(is_dirty());
2717836SJohn.Forte@Sun.COM 	}
2727836SJohn.Forte@Sun.COM 
2737836SJohn.Forte@Sun.COM 
2747836SJohn.Forte@Sun.COM 	/*
2757836SJohn.Forte@Sun.COM 	 * A few curses routines to setup screen and tty interface
2767836SJohn.Forte@Sun.COM 	 */
2777836SJohn.Forte@Sun.COM 	(void) initscr();
2787836SJohn.Forte@Sun.COM 	(void) cbreak();
2797836SJohn.Forte@Sun.COM 	(void) noecho();
2807836SJohn.Forte@Sun.COM 	(void) nonl();
2817836SJohn.Forte@Sun.COM 	(void) erase();
2827836SJohn.Forte@Sun.COM 	(void) clear();
2837836SJohn.Forte@Sun.COM 	(void) refresh();
2847836SJohn.Forte@Sun.COM 
2857836SJohn.Forte@Sun.COM 	setup_ranges(range);
2867836SJohn.Forte@Sun.COM 
2877836SJohn.Forte@Sun.COM 	/*
2887836SJohn.Forte@Sun.COM 	 * Set signal handle
2897836SJohn.Forte@Sun.COM 	 */
290*11576SSurya.Prakki@Sun.COM 	(void) sigset(SIGPIPE, leave);
291*11576SSurya.Prakki@Sun.COM 	(void) sigset(SIGINT, leave);
292*11576SSurya.Prakki@Sun.COM 	(void) sigset(SIGQUIT, leave);
293*11576SSurya.Prakki@Sun.COM 	(void) signal(SIGFPE, leave);
294*11576SSurya.Prakki@Sun.COM 	(void) signal(SIGSEGV, leave);
2957836SJohn.Forte@Sun.COM 
2967836SJohn.Forte@Sun.COM 	USEC_INIT();
2977836SJohn.Forte@Sun.COM 	currtime = USEC_READ();
2987836SJohn.Forte@Sun.COM 
2997836SJohn.Forte@Sun.COM 	/*
3007836SJohn.Forte@Sun.COM 	 * Wait one second before reading the new values
3017836SJohn.Forte@Sun.COM 	 */
3027836SJohn.Forte@Sun.COM 	(void) sleep(1);
3037836SJohn.Forte@Sun.COM 
3047836SJohn.Forte@Sun.COM 	/*CONSTCOND*/
3057836SJohn.Forte@Sun.COM 	while (1) {
3067836SJohn.Forte@Sun.COM 
3077836SJohn.Forte@Sun.COM 		lasttime = currtime;
3087836SJohn.Forte@Sun.COM 		currtime = USEC_READ();
3097836SJohn.Forte@Sun.COM 
3107836SJohn.Forte@Sun.COM 		/*
3117836SJohn.Forte@Sun.COM 		 * If less that 1 second, force it to one second
3127836SJohn.Forte@Sun.COM 		 */
3137836SJohn.Forte@Sun.COM 		if ((period = (currtime - lasttime) / 1000000) <= 0)
3147836SJohn.Forte@Sun.COM 			period = 1;
3157836SJohn.Forte@Sun.COM 
3167836SJohn.Forte@Sun.COM 		/*
3177836SJohn.Forte@Sun.COM 		 * Calculate new per/period values for statistics
3187836SJohn.Forte@Sun.COM 		 */
3197836SJohn.Forte@Sun.COM 		Elapsed_Time += period;
3207836SJohn.Forte@Sun.COM 
3217836SJohn.Forte@Sun.COM 		/*
3227836SJohn.Forte@Sun.COM 		 * Display new statistics
3237836SJohn.Forte@Sun.COM 		 */
3247836SJohn.Forte@Sun.COM 		prheading(++count);
3257836SJohn.Forte@Sun.COM 
3267836SJohn.Forte@Sun.COM 		if (mirror_sw) {
3277836SJohn.Forte@Sun.COM 			if (dual_stats() < 0)
3287836SJohn.Forte@Sun.COM 				mirror_sw = 0;
3297836SJohn.Forte@Sun.COM 		} else if (toggle_total_sw)
3307836SJohn.Forte@Sun.COM 			total_display();
3317836SJohn.Forte@Sun.COM 		else
3327836SJohn.Forte@Sun.COM 			display_cache();
3337836SJohn.Forte@Sun.COM 
3347836SJohn.Forte@Sun.COM 		(void) move(0, 0);
3357836SJohn.Forte@Sun.COM 		(void) refresh();
3367836SJohn.Forte@Sun.COM 		if (logfd > -1) wrefresh_file(stdscr, logfd);
3377836SJohn.Forte@Sun.COM 
3387836SJohn.Forte@Sun.COM 		FD_ZERO(&readfds);
3397836SJohn.Forte@Sun.COM 		FD_SET(fd, &readfds);
3407836SJohn.Forte@Sun.COM 		tout.tv_sec = delay;
3417836SJohn.Forte@Sun.COM 		for (;;) {
3427836SJohn.Forte@Sun.COM 			tout.tv_usec = 0;
3437836SJohn.Forte@Sun.COM 			if (select(fd + 1, &readfds, (fd_set *)0, (fd_set *)0,
3447836SJohn.Forte@Sun.COM 				&tout) <= 0)
3457836SJohn.Forte@Sun.COM 				break;
3467836SJohn.Forte@Sun.COM 			if ((c = getch()) == EOF) {
3477836SJohn.Forte@Sun.COM 				(void) sleep(delay);
3487836SJohn.Forte@Sun.COM 				break;
3497836SJohn.Forte@Sun.COM 			}
3507836SJohn.Forte@Sun.COM 			checkbuf(c);
3517836SJohn.Forte@Sun.COM 			tout.tv_sec = 0;
3527836SJohn.Forte@Sun.COM 		}
3537836SJohn.Forte@Sun.COM 		(void) erase();
3547836SJohn.Forte@Sun.COM 	}
3557836SJohn.Forte@Sun.COM #pragma error_messages(off, E_STATEMENT_NOT_REACHED)
3567836SJohn.Forte@Sun.COM 	return (0);
3577836SJohn.Forte@Sun.COM #pragma error_messages(default, E_STATEMENT_NOT_REACHED)
3587836SJohn.Forte@Sun.COM }
3597836SJohn.Forte@Sun.COM 
3607836SJohn.Forte@Sun.COM void
checkbuf(int c)3617836SJohn.Forte@Sun.COM checkbuf(int c)
3627836SJohn.Forte@Sun.COM {
3637836SJohn.Forte@Sun.COM 	spcs_s_info_t ustats;
3647836SJohn.Forte@Sun.COM 
3657836SJohn.Forte@Sun.COM 	switch (c) {
3667836SJohn.Forte@Sun.COM 	case 'b' : /* ctrl b or b --  scroll backward */
3677836SJohn.Forte@Sun.COM 	case  2  :
3687836SJohn.Forte@Sun.COM 		{
3697836SJohn.Forte@Sun.COM 		if (mirror_sw == 1) {
3707836SJohn.Forte@Sun.COM 			if (dual_screen > 0)
3717836SJohn.Forte@Sun.COM 				dual_screen--;
3727836SJohn.Forte@Sun.COM 			break;
3737836SJohn.Forte@Sun.COM 		}
3747836SJohn.Forte@Sun.COM 		if (screen > 0)
3757836SJohn.Forte@Sun.COM 			screen--;
3767836SJohn.Forte@Sun.COM 		break;
3777836SJohn.Forte@Sun.COM 		}
3787836SJohn.Forte@Sun.COM 
3797836SJohn.Forte@Sun.COM 	case 'f' : /* ctrl f or f -- scroll forward */
3807836SJohn.Forte@Sun.COM 	case  6  :
3817836SJohn.Forte@Sun.COM 		{
3827836SJohn.Forte@Sun.COM 		if (mirror_sw == 1) {
3837836SJohn.Forte@Sun.COM 			dual_screen++;
3847836SJohn.Forte@Sun.COM 			break;
3857836SJohn.Forte@Sun.COM 		}
3867836SJohn.Forte@Sun.COM 		screen++;
3877836SJohn.Forte@Sun.COM 		break;
3887836SJohn.Forte@Sun.COM 		}
3897836SJohn.Forte@Sun.COM 
3907836SJohn.Forte@Sun.COM 	case 't':
3917836SJohn.Forte@Sun.COM 	case 'T':
3927836SJohn.Forte@Sun.COM 		if (mirror_sw == 1)
3937836SJohn.Forte@Sun.COM 			mirror_sw = 0;
3947836SJohn.Forte@Sun.COM 
3957836SJohn.Forte@Sun.COM 		toggle_total_sw ^= 1;
3967836SJohn.Forte@Sun.COM 		break;
3977836SJohn.Forte@Sun.COM 
3987836SJohn.Forte@Sun.COM 	case '-':
3997836SJohn.Forte@Sun.COM 	case KEY_DOWN:
4007836SJohn.Forte@Sun.COM 		if (delay > 1) {
4017836SJohn.Forte@Sun.COM 			--delay;
4027836SJohn.Forte@Sun.COM 		} else {
4037836SJohn.Forte@Sun.COM 			(void) beep();
4047836SJohn.Forte@Sun.COM 		}
4057836SJohn.Forte@Sun.COM 		break;
4067836SJohn.Forte@Sun.COM 
4077836SJohn.Forte@Sun.COM 	case '+':
4087836SJohn.Forte@Sun.COM 	case KEY_UP:
4097836SJohn.Forte@Sun.COM 		delay++;
4107836SJohn.Forte@Sun.COM 		break;
4117836SJohn.Forte@Sun.COM 
4127836SJohn.Forte@Sun.COM 	case 'C':
4137836SJohn.Forte@Sun.COM 	case 0xc:
4147836SJohn.Forte@Sun.COM 		(void) clearok(stdscr, TRUE);
4157836SJohn.Forte@Sun.COM 		break;
4167836SJohn.Forte@Sun.COM 
4177836SJohn.Forte@Sun.COM 	case 'B':
4187836SJohn.Forte@Sun.COM 		if (bold_flg) {
4197836SJohn.Forte@Sun.COM 			bold_flg = 0;
4207836SJohn.Forte@Sun.COM 			(void) attroff(A_BOLD);
4217836SJohn.Forte@Sun.COM 		} else {
4227836SJohn.Forte@Sun.COM 			bold_flg = 1;
4237836SJohn.Forte@Sun.COM 			(void) attron(A_BOLD);
4247836SJohn.Forte@Sun.COM 		}
4257836SJohn.Forte@Sun.COM 		break;
4267836SJohn.Forte@Sun.COM 
4277836SJohn.Forte@Sun.COM 	case 'R':
4287836SJohn.Forte@Sun.COM 		if (rev_flag) {
4297836SJohn.Forte@Sun.COM 			rev_flag = 0;
4307836SJohn.Forte@Sun.COM 			(void) attroff(A_REVERSE);
4317836SJohn.Forte@Sun.COM 		} else {
4327836SJohn.Forte@Sun.COM 			rev_flag = 1;
4337836SJohn.Forte@Sun.COM 			(void) attron(A_REVERSE);
4347836SJohn.Forte@Sun.COM 		}
4357836SJohn.Forte@Sun.COM 		break;
4367836SJohn.Forte@Sun.COM 
4377836SJohn.Forte@Sun.COM 	case 'z':
4387836SJohn.Forte@Sun.COM 		if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0,
439*11576SSurya.Prakki@Sun.COM 		    &ustats) == SPCS_S_ERROR) {
4407836SJohn.Forte@Sun.COM 			if (ustats) {
4417836SJohn.Forte@Sun.COM 				spcs_s_report(ustats, stderr);
4427836SJohn.Forte@Sun.COM 				spcs_s_ufree(&ustats);
4437836SJohn.Forte@Sun.COM 			}
4447836SJohn.Forte@Sun.COM 		}
4457836SJohn.Forte@Sun.COM 		break;
4467836SJohn.Forte@Sun.COM 
4477836SJohn.Forte@Sun.COM 	case 'm':
4487836SJohn.Forte@Sun.COM 	case 'M':
4497836SJohn.Forte@Sun.COM 		mirror_sw = mirror_sw ? 0 : 1;
4507836SJohn.Forte@Sun.COM 		(void) clear();
4517836SJohn.Forte@Sun.COM 		break;
4527836SJohn.Forte@Sun.COM 	}
4537836SJohn.Forte@Sun.COM }
4547836SJohn.Forte@Sun.COM 
4557836SJohn.Forte@Sun.COM void
prheading(int count)4567836SJohn.Forte@Sun.COM prheading(int count)
4577836SJohn.Forte@Sun.COM {
4587836SJohn.Forte@Sun.COM 	time_t	tim;
4597836SJohn.Forte@Sun.COM 
4607836SJohn.Forte@Sun.COM 	/*
4617836SJohn.Forte@Sun.COM 	 * Print sample count in upper left corner
4627836SJohn.Forte@Sun.COM 	 */
4637836SJohn.Forte@Sun.COM 	(void) mvprintw(0,  0, "SAMPLE %-8d", count);
4647836SJohn.Forte@Sun.COM 
4657836SJohn.Forte@Sun.COM 	/*
4667836SJohn.Forte@Sun.COM 	 * Get time and print it in upper right corner
4677836SJohn.Forte@Sun.COM 	 */
4687836SJohn.Forte@Sun.COM 	tim = time((time_t *)0);
4697836SJohn.Forte@Sun.COM 	(void) mvprintw(0, 79 - 10, "%-8.8s\n", &(ctime(&tim)[11]));
4707836SJohn.Forte@Sun.COM }
4717836SJohn.Forte@Sun.COM 
4727836SJohn.Forte@Sun.COM /*ARGSUSED*/
4737836SJohn.Forte@Sun.COM void
leave(int status)4747836SJohn.Forte@Sun.COM leave(int status)
4757836SJohn.Forte@Sun.COM {
476*11576SSurya.Prakki@Sun.COM 	(void) sigignore(SIGPIPE);
477*11576SSurya.Prakki@Sun.COM 	(void) sigignore(SIGALRM);
4787836SJohn.Forte@Sun.COM 	/* clear(); */
4797836SJohn.Forte@Sun.COM 	(void) move(LINES, 0);
4807836SJohn.Forte@Sun.COM 	(void) refresh();
4817836SJohn.Forte@Sun.COM 	if (logfd > -1) wrefresh_file(stdscr, logfd);
4827836SJohn.Forte@Sun.COM 	quit(0);
4837836SJohn.Forte@Sun.COM }
4847836SJohn.Forte@Sun.COM 
4857836SJohn.Forte@Sun.COM void
quit(int status)4867836SJohn.Forte@Sun.COM quit(int status)
4877836SJohn.Forte@Sun.COM {
4887836SJohn.Forte@Sun.COM 	(void) resetterm();
4897836SJohn.Forte@Sun.COM 	(void) endwin();
4907836SJohn.Forte@Sun.COM 	exit(status);
4917836SJohn.Forte@Sun.COM }
4927836SJohn.Forte@Sun.COM 
4937836SJohn.Forte@Sun.COM void
setup_ranges(char * range)4947836SJohn.Forte@Sun.COM setup_ranges(char *range)
4957836SJohn.Forte@Sun.COM {
4967836SJohn.Forte@Sun.COM 	int ndx;
4977836SJohn.Forte@Sun.COM 	char chr1;
4987836SJohn.Forte@Sun.COM 	char prev_chr = '\0';
4997836SJohn.Forte@Sun.COM 	int got_colon = 0;
5007836SJohn.Forte@Sun.COM 	int after_got_colon = 0;
5017836SJohn.Forte@Sun.COM 	int got_comma = 0;
5027836SJohn.Forte@Sun.COM 	int after_got_comma = 0;
5037836SJohn.Forte@Sun.COM 	int number = 0;
5047836SJohn.Forte@Sun.COM 	int prev_num = 0;
5057836SJohn.Forte@Sun.COM 
5067836SJohn.Forte@Sun.COM 	if (range == NULL || (strlen(range) == 0)) {
5077836SJohn.Forte@Sun.COM 		ranges[range_num].lb = 0;
5087836SJohn.Forte@Sun.COM 		ranges[range_num].ub = sdbc_max_devices - 1;
5097836SJohn.Forte@Sun.COM 		return;
5107836SJohn.Forte@Sun.COM 	} else {
5117836SJohn.Forte@Sun.COM 		ndx = 0;
5127836SJohn.Forte@Sun.COM 		got_comma = 0;
5137836SJohn.Forte@Sun.COM 		got_colon = 0;
5147836SJohn.Forte@Sun.COM 		while ((chr1 = (range[ndx++])) != '\0') {
5157836SJohn.Forte@Sun.COM 			switch (chr1) {
5167836SJohn.Forte@Sun.COM 			case '0':
5177836SJohn.Forte@Sun.COM 			case '1':
5187836SJohn.Forte@Sun.COM 			case '2':
5197836SJohn.Forte@Sun.COM 			case '3':
5207836SJohn.Forte@Sun.COM 			case '4':
5217836SJohn.Forte@Sun.COM 			case '5':
5227836SJohn.Forte@Sun.COM 			case '6':
5237836SJohn.Forte@Sun.COM 			case '7':
5247836SJohn.Forte@Sun.COM 			case '8':
5257836SJohn.Forte@Sun.COM 			case '9':
5267836SJohn.Forte@Sun.COM 				number = number*10 + (chr1 - '0');
5277836SJohn.Forte@Sun.COM 				break;
5287836SJohn.Forte@Sun.COM 			case ':':
5297836SJohn.Forte@Sun.COM 				got_colon = 1;
5307836SJohn.Forte@Sun.COM 				break;
5317836SJohn.Forte@Sun.COM 			case ',':
5327836SJohn.Forte@Sun.COM 				got_comma = 1;
5337836SJohn.Forte@Sun.COM 				break;
5347836SJohn.Forte@Sun.COM 			default: /* ignore any unknown characters */
5357836SJohn.Forte@Sun.COM 				break;
5367836SJohn.Forte@Sun.COM 			}	/* switch */
5377836SJohn.Forte@Sun.COM 			if (got_comma && after_got_colon) {
5387836SJohn.Forte@Sun.COM 				after_got_colon = 0;
5397836SJohn.Forte@Sun.COM 				got_comma = 0;
5407836SJohn.Forte@Sun.COM 				if (number >= sdbc_max_devices)
5417836SJohn.Forte@Sun.COM 					number = sdbc_max_devices - 1;
5427836SJohn.Forte@Sun.COM 				ranges[range_num].lb = prev_num;
5437836SJohn.Forte@Sun.COM 				ranges[range_num].ub = number;
5447836SJohn.Forte@Sun.COM 				if (range_num == 99) break;
5457836SJohn.Forte@Sun.COM 				range_num++;
5467836SJohn.Forte@Sun.COM 				number = 0;
5477836SJohn.Forte@Sun.COM 			} else if (got_colon && after_got_comma) {
5487836SJohn.Forte@Sun.COM 				got_colon = 0;
5497836SJohn.Forte@Sun.COM 				after_got_colon = 1;
5507836SJohn.Forte@Sun.COM 				after_got_comma = 0;
5517836SJohn.Forte@Sun.COM 				if (number >= sdbc_max_devices)
5527836SJohn.Forte@Sun.COM 					number = sdbc_max_devices - 1;
5537836SJohn.Forte@Sun.COM 				prev_num = number;
5547836SJohn.Forte@Sun.COM 				number = 0;
5557836SJohn.Forte@Sun.COM 			} else if (got_colon) {
5567836SJohn.Forte@Sun.COM 				got_colon = 0;
5577836SJohn.Forte@Sun.COM 				after_got_colon = 1;
5587836SJohn.Forte@Sun.COM 				if ((prev_chr != '\0') && (prev_chr != ':')) {
5597836SJohn.Forte@Sun.COM 					if (number >= sdbc_max_devices)
5607836SJohn.Forte@Sun.COM 						number = sdbc_max_devices - 1;
5617836SJohn.Forte@Sun.COM 					prev_num = number;
5627836SJohn.Forte@Sun.COM 					number = 0;
5637836SJohn.Forte@Sun.COM 				}
5647836SJohn.Forte@Sun.COM 			} else if (got_comma) {
5657836SJohn.Forte@Sun.COM 				got_comma = 0;
5667836SJohn.Forte@Sun.COM 				after_got_comma = 1;
5677836SJohn.Forte@Sun.COM 				after_got_colon = 0;
5687836SJohn.Forte@Sun.COM 				if (number >= sdbc_max_devices)
5697836SJohn.Forte@Sun.COM 					number = sdbc_max_devices -1;
5707836SJohn.Forte@Sun.COM 				if ((prev_chr != '\0') && (prev_chr != ',')) {
5717836SJohn.Forte@Sun.COM 					ranges[range_num].lb = number;
5727836SJohn.Forte@Sun.COM 					ranges[range_num].ub = number;
5737836SJohn.Forte@Sun.COM 					if (range_num == 99) break;
5747836SJohn.Forte@Sun.COM 						range_num++;
5757836SJohn.Forte@Sun.COM 				}
5767836SJohn.Forte@Sun.COM 				number = 0;
5777836SJohn.Forte@Sun.COM 			}	/* if */
5787836SJohn.Forte@Sun.COM 			prev_chr = chr1;
5797836SJohn.Forte@Sun.COM 		}		/* while */
5807836SJohn.Forte@Sun.COM 		if (number >= sdbc_max_devices)
5817836SJohn.Forte@Sun.COM 			number = sdbc_max_devices - 1;
5827836SJohn.Forte@Sun.COM 		if (after_got_colon) {
5837836SJohn.Forte@Sun.COM 			ranges[range_num].lb = prev_num;
5847836SJohn.Forte@Sun.COM 			ranges[range_num].ub = number;
5857836SJohn.Forte@Sun.COM 		} else {
5867836SJohn.Forte@Sun.COM 			if ((after_got_comma) && (prev_chr == ','))
5877836SJohn.Forte@Sun.COM 				range_num--;
5887836SJohn.Forte@Sun.COM 			else {
5897836SJohn.Forte@Sun.COM 				ranges[range_num].lb = number;
5907836SJohn.Forte@Sun.COM 				ranges[range_num].ub = number;
5917836SJohn.Forte@Sun.COM 			}
5927836SJohn.Forte@Sun.COM 		}
5937836SJohn.Forte@Sun.COM 	}
5947836SJohn.Forte@Sun.COM }
595