xref: /titanic_52/usr/src/cmd/avs/sdbc/sd_stats.c (revision 570de38f63910201fdd77246630b7aa8f9dc5661)
1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21*570de38fSSurya Prakki 
22fcf3ce44SJohn Forte /*
23*570de38fSSurya Prakki  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24fcf3ce44SJohn Forte  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27fcf3ce44SJohn Forte #include <stdio.h>
28fcf3ce44SJohn Forte #include <stdlib.h>
29fcf3ce44SJohn Forte #include <unistd.h>
30fcf3ce44SJohn Forte #include <strings.h>
31fcf3ce44SJohn Forte #include <curses.h>
32fcf3ce44SJohn Forte #include <signal.h>
33fcf3ce44SJohn Forte #include <fcntl.h>
34fcf3ce44SJohn Forte #include <locale.h>
35fcf3ce44SJohn Forte 
36fcf3ce44SJohn Forte #include <sys/types.h>
37fcf3ce44SJohn Forte #include <sys/time.h>
38fcf3ce44SJohn Forte #include <sys/nsctl/sdbc_ioctl.h>
39fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h>
40fcf3ce44SJohn Forte #include <sys/nsctl/sd_bcache.h>
41fcf3ce44SJohn Forte #include <sys/nsctl/sd_conf.h>
42fcf3ce44SJohn Forte 
43fcf3ce44SJohn Forte extern void total_display(void);
44fcf3ce44SJohn Forte extern void display_cache(void);
45fcf3ce44SJohn Forte extern void wrefresh_file(WINDOW *, int);
46fcf3ce44SJohn Forte extern int is_dirty(void);
47fcf3ce44SJohn Forte extern int dual_stats(void);
48fcf3ce44SJohn Forte void checkbuf(int);
49fcf3ce44SJohn Forte void setup_ranges(char *);
50fcf3ce44SJohn Forte void prheading(int);
51fcf3ce44SJohn Forte extern int zero_nic(void);
52fcf3ce44SJohn Forte 
53fcf3ce44SJohn Forte #ifdef m88k
54fcf3ce44SJohn Forte #define	USEC_INIT()	usec_ptr = (unsigned int *)timer_init()
55fcf3ce44SJohn Forte #define	USEC_READ()	(*usec_ptr)
56fcf3ce44SJohn Forte #else /* !m88k */
57fcf3ce44SJohn Forte #define	USEC_INIT()	USEC_START()
58fcf3ce44SJohn Forte #include <sys/time.h>
59fcf3ce44SJohn Forte static struct timeval Usec_time;
60fcf3ce44SJohn Forte static int Usec_started = 0;
61fcf3ce44SJohn Forte 
62fcf3ce44SJohn Forte extern int higher(int);
63fcf3ce44SJohn Forte extern int is_dirty();
64fcf3ce44SJohn Forte extern int dual_stats();
65fcf3ce44SJohn Forte extern void total_display();
66fcf3ce44SJohn Forte extern void display_cache();
67fcf3ce44SJohn Forte extern void wrefresh_file(WINDOW *, int);
68fcf3ce44SJohn Forte void setup_ranges(char *);
69fcf3ce44SJohn Forte 
70fcf3ce44SJohn Forte void prheading(int);
71fcf3ce44SJohn Forte void checkbuf(int);
72fcf3ce44SJohn Forte void quit(int);
73fcf3ce44SJohn Forte void leave(int);
74fcf3ce44SJohn Forte #pragma does_not_return(quit, leave)
75fcf3ce44SJohn Forte 
76fcf3ce44SJohn Forte int sdbc_max_devices = 0;
77fcf3ce44SJohn Forte 
78fcf3ce44SJohn Forte static void
79fcf3ce44SJohn Forte USEC_START()
80fcf3ce44SJohn Forte {
81fcf3ce44SJohn Forte 	if (!Usec_started) {
82fcf3ce44SJohn Forte 		(void) gettimeofday(&Usec_time, NULL);
83fcf3ce44SJohn Forte 		Usec_started = 1;
84fcf3ce44SJohn Forte 	}
85fcf3ce44SJohn Forte }
86fcf3ce44SJohn Forte 
87fcf3ce44SJohn Forte static unsigned int
88fcf3ce44SJohn Forte USEC_READ()
89fcf3ce44SJohn Forte {
90fcf3ce44SJohn Forte 	struct timeval tv;
91fcf3ce44SJohn Forte 	if (!Usec_started)
92fcf3ce44SJohn Forte 		USEC_START();
93fcf3ce44SJohn Forte 
94fcf3ce44SJohn Forte 	(void) gettimeofday(&tv, NULL);
95fcf3ce44SJohn Forte 	return (unsigned)((tv.tv_sec - Usec_time.tv_sec) * 1000000
96fcf3ce44SJohn Forte 	    + (tv.tv_usec - Usec_time.tv_usec));
97fcf3ce44SJohn Forte }
98fcf3ce44SJohn Forte #endif /* m88k */
99fcf3ce44SJohn Forte 
100fcf3ce44SJohn Forte int		rev_flag = 0;		/* Reverse video flag */
101fcf3ce44SJohn Forte int		bold_flg = 0;		/* Bold flag */
102fcf3ce44SJohn Forte int		under_flg = 0;		/* Underline flag */
103fcf3ce44SJohn Forte int		errflg = 0;		/* Error flag */
104fcf3ce44SJohn Forte int		node_sw = 0;		/* Per node switch */
105fcf3ce44SJohn Forte int 		toggle_total_sw = 0;
106fcf3ce44SJohn Forte int		mirror_sw = 0;		/* Dual copy switch */
107fcf3ce44SJohn Forte 
108fcf3ce44SJohn Forte int		kmemfd;
109fcf3ce44SJohn Forte int		delay = 1;			/* Display delay (seconds) */
110fcf3ce44SJohn Forte 
111fcf3ce44SJohn Forte time_t	*usec_ptr;
112fcf3ce44SJohn Forte time_t	currtime = 0;
113fcf3ce44SJohn Forte int		lasttime = 0;
114fcf3ce44SJohn Forte int		Elapsed_Time = 0;
115fcf3ce44SJohn Forte 
116fcf3ce44SJohn Forte static char	*range;
117fcf3ce44SJohn Forte static int	had_r_option = 0;
118fcf3ce44SJohn Forte int		logfd = -1;		/* screen output logging */
119fcf3ce44SJohn Forte extern 		int range_num;
120fcf3ce44SJohn Forte extern		int screen;
121fcf3ce44SJohn Forte extern 		int dual_screen;
122fcf3ce44SJohn Forte int		*on_off;
123fcf3ce44SJohn Forte int		*dual_on_off;
124fcf3ce44SJohn Forte int		*updates_prev;
125fcf3ce44SJohn Forte double		*rate_prev;
126fcf3ce44SJohn Forte int		*samples;
127fcf3ce44SJohn Forte _sd_stats_t	*cs_cur;
128fcf3ce44SJohn Forte _sd_stats_t	*cs_prev;
129fcf3ce44SJohn Forte _sd_stats_t	*cs_persec;
130fcf3ce44SJohn Forte 
131fcf3ce44SJohn Forte typedef struct {
132fcf3ce44SJohn Forte 	int lb, ub;
133fcf3ce44SJohn Forte } range_t;
134fcf3ce44SJohn Forte 
135fcf3ce44SJohn Forte extern range_t ranges[];
136fcf3ce44SJohn Forte 
137fcf3ce44SJohn Forte #ifdef lint
138fcf3ce44SJohn Forte int
139fcf3ce44SJohn Forte sd_stats_lintmain(int argc, char *argv[])
140fcf3ce44SJohn Forte #else
141fcf3ce44SJohn Forte int
142fcf3ce44SJohn Forte main(int argc, char *argv[])
143fcf3ce44SJohn Forte #endif
144fcf3ce44SJohn Forte {
145fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
146fcf3ce44SJohn Forte 	struct timeval tout;
147fcf3ce44SJohn Forte 	fd_set readfds;
148fcf3ce44SJohn Forte 	char *errmessage, *ch;
149fcf3ce44SJohn Forte 	int c, period, prev;
150fcf3ce44SJohn Forte 	int count = 0, dflag = 0;
151fcf3ce44SJohn Forte 	int fd = fileno(stdin);
152fcf3ce44SJohn Forte 
153fcf3ce44SJohn Forte 	errmessage = NULL;
154fcf3ce44SJohn Forte 
155fcf3ce44SJohn Forte 	if (strcmp(argv[0], "sd_stats") != 0)
156fcf3ce44SJohn Forte 		errmessage = getenv("SD_STATS_USAGE");
157fcf3ce44SJohn Forte 
158fcf3ce44SJohn Forte 	if (errmessage == NULL)
159fcf3ce44SJohn Forte 		errmessage = gettext("Usage: sd_stats [-Mz] "
160fcf3ce44SJohn Forte 				"[-d delay_time] [-l logfile] [-r range]");
161fcf3ce44SJohn Forte 
162fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_MAXFILES, &sdbc_max_devices,
163fcf3ce44SJohn Forte 	    0, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
164fcf3ce44SJohn Forte 		if (ustats) {  	/* if SPCS_S_ERROR */
165fcf3ce44SJohn Forte 			spcs_s_report(ustats, stderr);
166fcf3ce44SJohn Forte 			spcs_s_ufree(&ustats);
167fcf3ce44SJohn Forte 		}
168fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("cannot get maxfiles\n"));
169fcf3ce44SJohn Forte 		exit(1);
170fcf3ce44SJohn Forte 	}
171fcf3ce44SJohn Forte 	on_off = calloc(sdbc_max_devices, sizeof (int));
172fcf3ce44SJohn Forte 	dual_on_off = calloc(sdbc_max_devices, sizeof (int));
173fcf3ce44SJohn Forte 	updates_prev = calloc(sdbc_max_devices, sizeof (int));
174fcf3ce44SJohn Forte 	samples = calloc(sdbc_max_devices, sizeof (int));
175fcf3ce44SJohn Forte 	rate_prev = calloc(sdbc_max_devices, sizeof (double));
176fcf3ce44SJohn Forte 	cs_cur = malloc(sizeof (_sd_stats_t) +
177fcf3ce44SJohn Forte 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
178fcf3ce44SJohn Forte 	cs_prev = malloc(sizeof (_sd_stats_t) +
179fcf3ce44SJohn Forte 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
180fcf3ce44SJohn Forte 	cs_persec = malloc(sizeof (_sd_stats_t) +
181fcf3ce44SJohn Forte 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
182fcf3ce44SJohn Forte 	range = malloc(100);
183fcf3ce44SJohn Forte 
184fcf3ce44SJohn Forte 	if (!on_off || !dual_on_off || !updates_prev || !samples ||
185fcf3ce44SJohn Forte 	    !rate_prev || !cs_cur || !cs_prev || !cs_persec || !range) {
186fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("no free memory\n"));
187fcf3ce44SJohn Forte 		exit(1);
188fcf3ce44SJohn Forte 	}
189fcf3ce44SJohn Forte 
190fcf3ce44SJohn Forte 	*range = '\0';
191fcf3ce44SJohn Forte 
192fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv, "DMzd:l:r:h")) != EOF) {
193fcf3ce44SJohn Forte 
194fcf3ce44SJohn Forte 		prev = c;
195fcf3ce44SJohn Forte 		switch (c) {
196fcf3ce44SJohn Forte 
197fcf3ce44SJohn Forte 		case 'd':
198fcf3ce44SJohn Forte 			delay = atoi(optarg);
199fcf3ce44SJohn Forte 			ch = optarg;
200fcf3ce44SJohn Forte 			while (*ch != '\0') {
201fcf3ce44SJohn Forte 				if (!isdigit(*ch))
202fcf3ce44SJohn Forte 					errflg++;
203fcf3ce44SJohn Forte 				ch++;
204fcf3ce44SJohn Forte 			}
205fcf3ce44SJohn Forte 			break;
206fcf3ce44SJohn Forte 
207fcf3ce44SJohn Forte 		case 'l':
208fcf3ce44SJohn Forte 			logfd = open(optarg, O_CREAT|O_WRONLY|O_TRUNC, 0644);
209fcf3ce44SJohn Forte 			break;
210fcf3ce44SJohn Forte 
211fcf3ce44SJohn Forte 		case 'r':
212fcf3ce44SJohn Forte 			ch = optarg;
213fcf3ce44SJohn Forte 			while (*ch != '\0') {
214fcf3ce44SJohn Forte 				if ((!isdigit(*ch)) && (*ch != ',') &&
215fcf3ce44SJohn Forte 				    (*ch != ':'))
216fcf3ce44SJohn Forte 					errflg++;
217fcf3ce44SJohn Forte 				ch++;
218fcf3ce44SJohn Forte 			}
219fcf3ce44SJohn Forte 			if (errflg)
220fcf3ce44SJohn Forte 				break;
221fcf3ce44SJohn Forte 
222fcf3ce44SJohn Forte 			range = realloc((char *)range,
223fcf3ce44SJohn Forte 					(strlen(range) + strlen(optarg) + 1)
224fcf3ce44SJohn Forte 					* sizeof (char));
225fcf3ce44SJohn Forte 
226fcf3ce44SJohn Forte 			if (had_r_option)
227fcf3ce44SJohn Forte 				(void) strcat(range, ",");
228fcf3ce44SJohn Forte 			(void) strcat(range, optarg);
229fcf3ce44SJohn Forte 			had_r_option = 1;
230fcf3ce44SJohn Forte 			break;
231fcf3ce44SJohn Forte 
232fcf3ce44SJohn Forte 		case 'z':
233fcf3ce44SJohn Forte 			if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0,
234fcf3ce44SJohn Forte 					&ustats) == SPCS_S_ERROR) {
235fcf3ce44SJohn Forte 				if (ustats) {
236fcf3ce44SJohn Forte 					spcs_s_report(ustats, stderr);
237fcf3ce44SJohn Forte 					spcs_s_ufree(&ustats);
238fcf3ce44SJohn Forte 				}
239fcf3ce44SJohn Forte 			}
240fcf3ce44SJohn Forte 
241fcf3ce44SJohn Forte 			break;
242fcf3ce44SJohn Forte 
243fcf3ce44SJohn Forte 		case 'D':
244fcf3ce44SJohn Forte 			dflag = 1;
245fcf3ce44SJohn Forte 			break;
246fcf3ce44SJohn Forte 
247fcf3ce44SJohn Forte 		case 'M':
248fcf3ce44SJohn Forte 			mirror_sw = 1;
249fcf3ce44SJohn Forte 			break;
250fcf3ce44SJohn Forte 
251fcf3ce44SJohn Forte 		case 'h':
252fcf3ce44SJohn Forte 		case '?':
253fcf3ce44SJohn Forte 		default :
254fcf3ce44SJohn Forte 			errflg++;
255fcf3ce44SJohn Forte 			break;
256fcf3ce44SJohn Forte 		}
257fcf3ce44SJohn Forte 	}
258fcf3ce44SJohn Forte 
259fcf3ce44SJohn Forte 	if (errflg) {
260fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n", errmessage);
261fcf3ce44SJohn Forte 		exit(1);
262fcf3ce44SJohn Forte 	} else if (!prev) {
263fcf3ce44SJohn Forte 		if (argc > 1) {
264fcf3ce44SJohn Forte 			(void) fprintf(stderr, "%s\n", errmessage);
265fcf3ce44SJohn Forte 			exit(1);
266fcf3ce44SJohn Forte 		}
267fcf3ce44SJohn Forte 	}
268fcf3ce44SJohn Forte 
269fcf3ce44SJohn Forte 	if (dflag) {
270fcf3ce44SJohn Forte 		exit(is_dirty());
271fcf3ce44SJohn Forte 	}
272fcf3ce44SJohn Forte 
273fcf3ce44SJohn Forte 
274fcf3ce44SJohn Forte 	/*
275fcf3ce44SJohn Forte 	 * A few curses routines to setup screen and tty interface
276fcf3ce44SJohn Forte 	 */
277fcf3ce44SJohn Forte 	(void) initscr();
278fcf3ce44SJohn Forte 	(void) cbreak();
279fcf3ce44SJohn Forte 	(void) noecho();
280fcf3ce44SJohn Forte 	(void) nonl();
281fcf3ce44SJohn Forte 	(void) erase();
282fcf3ce44SJohn Forte 	(void) clear();
283fcf3ce44SJohn Forte 	(void) refresh();
284fcf3ce44SJohn Forte 
285fcf3ce44SJohn Forte 	setup_ranges(range);
286fcf3ce44SJohn Forte 
287fcf3ce44SJohn Forte 	/*
288fcf3ce44SJohn Forte 	 * Set signal handle
289fcf3ce44SJohn Forte 	 */
290*570de38fSSurya Prakki 	(void) sigset(SIGPIPE, leave);
291*570de38fSSurya Prakki 	(void) sigset(SIGINT, leave);
292*570de38fSSurya Prakki 	(void) sigset(SIGQUIT, leave);
293*570de38fSSurya Prakki 	(void) signal(SIGFPE, leave);
294*570de38fSSurya Prakki 	(void) signal(SIGSEGV, leave);
295fcf3ce44SJohn Forte 
296fcf3ce44SJohn Forte 	USEC_INIT();
297fcf3ce44SJohn Forte 	currtime = USEC_READ();
298fcf3ce44SJohn Forte 
299fcf3ce44SJohn Forte 	/*
300fcf3ce44SJohn Forte 	 * Wait one second before reading the new values
301fcf3ce44SJohn Forte 	 */
302fcf3ce44SJohn Forte 	(void) sleep(1);
303fcf3ce44SJohn Forte 
304fcf3ce44SJohn Forte 	/*CONSTCOND*/
305fcf3ce44SJohn Forte 	while (1) {
306fcf3ce44SJohn Forte 
307fcf3ce44SJohn Forte 		lasttime = currtime;
308fcf3ce44SJohn Forte 		currtime = USEC_READ();
309fcf3ce44SJohn Forte 
310fcf3ce44SJohn Forte 		/*
311fcf3ce44SJohn Forte 		 * If less that 1 second, force it to one second
312fcf3ce44SJohn Forte 		 */
313fcf3ce44SJohn Forte 		if ((period = (currtime - lasttime) / 1000000) <= 0)
314fcf3ce44SJohn Forte 			period = 1;
315fcf3ce44SJohn Forte 
316fcf3ce44SJohn Forte 		/*
317fcf3ce44SJohn Forte 		 * Calculate new per/period values for statistics
318fcf3ce44SJohn Forte 		 */
319fcf3ce44SJohn Forte 		Elapsed_Time += period;
320fcf3ce44SJohn Forte 
321fcf3ce44SJohn Forte 		/*
322fcf3ce44SJohn Forte 		 * Display new statistics
323fcf3ce44SJohn Forte 		 */
324fcf3ce44SJohn Forte 		prheading(++count);
325fcf3ce44SJohn Forte 
326fcf3ce44SJohn Forte 		if (mirror_sw) {
327fcf3ce44SJohn Forte 			if (dual_stats() < 0)
328fcf3ce44SJohn Forte 				mirror_sw = 0;
329fcf3ce44SJohn Forte 		} else if (toggle_total_sw)
330fcf3ce44SJohn Forte 			total_display();
331fcf3ce44SJohn Forte 		else
332fcf3ce44SJohn Forte 			display_cache();
333fcf3ce44SJohn Forte 
334fcf3ce44SJohn Forte 		(void) move(0, 0);
335fcf3ce44SJohn Forte 		(void) refresh();
336fcf3ce44SJohn Forte 		if (logfd > -1) wrefresh_file(stdscr, logfd);
337fcf3ce44SJohn Forte 
338fcf3ce44SJohn Forte 		FD_ZERO(&readfds);
339fcf3ce44SJohn Forte 		FD_SET(fd, &readfds);
340fcf3ce44SJohn Forte 		tout.tv_sec = delay;
341fcf3ce44SJohn Forte 		for (;;) {
342fcf3ce44SJohn Forte 			tout.tv_usec = 0;
343fcf3ce44SJohn Forte 			if (select(fd + 1, &readfds, (fd_set *)0, (fd_set *)0,
344fcf3ce44SJohn Forte 				&tout) <= 0)
345fcf3ce44SJohn Forte 				break;
346fcf3ce44SJohn Forte 			if ((c = getch()) == EOF) {
347fcf3ce44SJohn Forte 				(void) sleep(delay);
348fcf3ce44SJohn Forte 				break;
349fcf3ce44SJohn Forte 			}
350fcf3ce44SJohn Forte 			checkbuf(c);
351fcf3ce44SJohn Forte 			tout.tv_sec = 0;
352fcf3ce44SJohn Forte 		}
353fcf3ce44SJohn Forte 		(void) erase();
354fcf3ce44SJohn Forte 	}
355fcf3ce44SJohn Forte #pragma error_messages(off, E_STATEMENT_NOT_REACHED)
356fcf3ce44SJohn Forte 	return (0);
357fcf3ce44SJohn Forte #pragma error_messages(default, E_STATEMENT_NOT_REACHED)
358fcf3ce44SJohn Forte }
359fcf3ce44SJohn Forte 
360fcf3ce44SJohn Forte void
361fcf3ce44SJohn Forte checkbuf(int c)
362fcf3ce44SJohn Forte {
363fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
364fcf3ce44SJohn Forte 
365fcf3ce44SJohn Forte 	switch (c) {
366fcf3ce44SJohn Forte 	case 'b' : /* ctrl b or b --  scroll backward */
367fcf3ce44SJohn Forte 	case  2  :
368fcf3ce44SJohn Forte 		{
369fcf3ce44SJohn Forte 		if (mirror_sw == 1) {
370fcf3ce44SJohn Forte 			if (dual_screen > 0)
371fcf3ce44SJohn Forte 				dual_screen--;
372fcf3ce44SJohn Forte 			break;
373fcf3ce44SJohn Forte 		}
374fcf3ce44SJohn Forte 		if (screen > 0)
375fcf3ce44SJohn Forte 			screen--;
376fcf3ce44SJohn Forte 		break;
377fcf3ce44SJohn Forte 		}
378fcf3ce44SJohn Forte 
379fcf3ce44SJohn Forte 	case 'f' : /* ctrl f or f -- scroll forward */
380fcf3ce44SJohn Forte 	case  6  :
381fcf3ce44SJohn Forte 		{
382fcf3ce44SJohn Forte 		if (mirror_sw == 1) {
383fcf3ce44SJohn Forte 			dual_screen++;
384fcf3ce44SJohn Forte 			break;
385fcf3ce44SJohn Forte 		}
386fcf3ce44SJohn Forte 		screen++;
387fcf3ce44SJohn Forte 		break;
388fcf3ce44SJohn Forte 		}
389fcf3ce44SJohn Forte 
390fcf3ce44SJohn Forte 	case 't':
391fcf3ce44SJohn Forte 	case 'T':
392fcf3ce44SJohn Forte 		if (mirror_sw == 1)
393fcf3ce44SJohn Forte 			mirror_sw = 0;
394fcf3ce44SJohn Forte 
395fcf3ce44SJohn Forte 		toggle_total_sw ^= 1;
396fcf3ce44SJohn Forte 		break;
397fcf3ce44SJohn Forte 
398fcf3ce44SJohn Forte 	case '-':
399fcf3ce44SJohn Forte 	case KEY_DOWN:
400fcf3ce44SJohn Forte 		if (delay > 1) {
401fcf3ce44SJohn Forte 			--delay;
402fcf3ce44SJohn Forte 		} else {
403fcf3ce44SJohn Forte 			(void) beep();
404fcf3ce44SJohn Forte 		}
405fcf3ce44SJohn Forte 		break;
406fcf3ce44SJohn Forte 
407fcf3ce44SJohn Forte 	case '+':
408fcf3ce44SJohn Forte 	case KEY_UP:
409fcf3ce44SJohn Forte 		delay++;
410fcf3ce44SJohn Forte 		break;
411fcf3ce44SJohn Forte 
412fcf3ce44SJohn Forte 	case 'C':
413fcf3ce44SJohn Forte 	case 0xc:
414fcf3ce44SJohn Forte 		(void) clearok(stdscr, TRUE);
415fcf3ce44SJohn Forte 		break;
416fcf3ce44SJohn Forte 
417fcf3ce44SJohn Forte 	case 'B':
418fcf3ce44SJohn Forte 		if (bold_flg) {
419fcf3ce44SJohn Forte 			bold_flg = 0;
420fcf3ce44SJohn Forte 			(void) attroff(A_BOLD);
421fcf3ce44SJohn Forte 		} else {
422fcf3ce44SJohn Forte 			bold_flg = 1;
423fcf3ce44SJohn Forte 			(void) attron(A_BOLD);
424fcf3ce44SJohn Forte 		}
425fcf3ce44SJohn Forte 		break;
426fcf3ce44SJohn Forte 
427fcf3ce44SJohn Forte 	case 'R':
428fcf3ce44SJohn Forte 		if (rev_flag) {
429fcf3ce44SJohn Forte 			rev_flag = 0;
430fcf3ce44SJohn Forte 			(void) attroff(A_REVERSE);
431fcf3ce44SJohn Forte 		} else {
432fcf3ce44SJohn Forte 			rev_flag = 1;
433fcf3ce44SJohn Forte 			(void) attron(A_REVERSE);
434fcf3ce44SJohn Forte 		}
435fcf3ce44SJohn Forte 		break;
436fcf3ce44SJohn Forte 
437fcf3ce44SJohn Forte 	case 'z':
438fcf3ce44SJohn Forte 		if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0,
439fcf3ce44SJohn Forte 		    &ustats) == SPCS_S_ERROR) {
440fcf3ce44SJohn Forte 			if (ustats) {
441fcf3ce44SJohn Forte 				spcs_s_report(ustats, stderr);
442fcf3ce44SJohn Forte 				spcs_s_ufree(&ustats);
443fcf3ce44SJohn Forte 			}
444fcf3ce44SJohn Forte 		}
445fcf3ce44SJohn Forte 		break;
446fcf3ce44SJohn Forte 
447fcf3ce44SJohn Forte 	case 'm':
448fcf3ce44SJohn Forte 	case 'M':
449fcf3ce44SJohn Forte 		mirror_sw = mirror_sw ? 0 : 1;
450fcf3ce44SJohn Forte 		(void) clear();
451fcf3ce44SJohn Forte 		break;
452fcf3ce44SJohn Forte 	}
453fcf3ce44SJohn Forte }
454fcf3ce44SJohn Forte 
455fcf3ce44SJohn Forte void
456fcf3ce44SJohn Forte prheading(int count)
457fcf3ce44SJohn Forte {
458fcf3ce44SJohn Forte 	time_t	tim;
459fcf3ce44SJohn Forte 
460fcf3ce44SJohn Forte 	/*
461fcf3ce44SJohn Forte 	 * Print sample count in upper left corner
462fcf3ce44SJohn Forte 	 */
463fcf3ce44SJohn Forte 	(void) mvprintw(0,  0, "SAMPLE %-8d", count);
464fcf3ce44SJohn Forte 
465fcf3ce44SJohn Forte 	/*
466fcf3ce44SJohn Forte 	 * Get time and print it in upper right corner
467fcf3ce44SJohn Forte 	 */
468fcf3ce44SJohn Forte 	tim = time((time_t *)0);
469fcf3ce44SJohn Forte 	(void) mvprintw(0, 79 - 10, "%-8.8s\n", &(ctime(&tim)[11]));
470fcf3ce44SJohn Forte }
471fcf3ce44SJohn Forte 
472fcf3ce44SJohn Forte /*ARGSUSED*/
473fcf3ce44SJohn Forte void
474fcf3ce44SJohn Forte leave(int status)
475fcf3ce44SJohn Forte {
476*570de38fSSurya Prakki 	(void) sigignore(SIGPIPE);
477*570de38fSSurya Prakki 	(void) sigignore(SIGALRM);
478fcf3ce44SJohn Forte 	/* clear(); */
479fcf3ce44SJohn Forte 	(void) move(LINES, 0);
480fcf3ce44SJohn Forte 	(void) refresh();
481fcf3ce44SJohn Forte 	if (logfd > -1) wrefresh_file(stdscr, logfd);
482fcf3ce44SJohn Forte 	quit(0);
483fcf3ce44SJohn Forte }
484fcf3ce44SJohn Forte 
485fcf3ce44SJohn Forte void
486fcf3ce44SJohn Forte quit(int status)
487fcf3ce44SJohn Forte {
488fcf3ce44SJohn Forte 	(void) resetterm();
489fcf3ce44SJohn Forte 	(void) endwin();
490fcf3ce44SJohn Forte 	exit(status);
491fcf3ce44SJohn Forte }
492fcf3ce44SJohn Forte 
493fcf3ce44SJohn Forte void
494fcf3ce44SJohn Forte setup_ranges(char *range)
495fcf3ce44SJohn Forte {
496fcf3ce44SJohn Forte 	int ndx;
497fcf3ce44SJohn Forte 	char chr1;
498fcf3ce44SJohn Forte 	char prev_chr = '\0';
499fcf3ce44SJohn Forte 	int got_colon = 0;
500fcf3ce44SJohn Forte 	int after_got_colon = 0;
501fcf3ce44SJohn Forte 	int got_comma = 0;
502fcf3ce44SJohn Forte 	int after_got_comma = 0;
503fcf3ce44SJohn Forte 	int number = 0;
504fcf3ce44SJohn Forte 	int prev_num = 0;
505fcf3ce44SJohn Forte 
506fcf3ce44SJohn Forte 	if (range == NULL || (strlen(range) == 0)) {
507fcf3ce44SJohn Forte 		ranges[range_num].lb = 0;
508fcf3ce44SJohn Forte 		ranges[range_num].ub = sdbc_max_devices - 1;
509fcf3ce44SJohn Forte 		return;
510fcf3ce44SJohn Forte 	} else {
511fcf3ce44SJohn Forte 		ndx = 0;
512fcf3ce44SJohn Forte 		got_comma = 0;
513fcf3ce44SJohn Forte 		got_colon = 0;
514fcf3ce44SJohn Forte 		while ((chr1 = (range[ndx++])) != '\0') {
515fcf3ce44SJohn Forte 			switch (chr1) {
516fcf3ce44SJohn Forte 			case '0':
517fcf3ce44SJohn Forte 			case '1':
518fcf3ce44SJohn Forte 			case '2':
519fcf3ce44SJohn Forte 			case '3':
520fcf3ce44SJohn Forte 			case '4':
521fcf3ce44SJohn Forte 			case '5':
522fcf3ce44SJohn Forte 			case '6':
523fcf3ce44SJohn Forte 			case '7':
524fcf3ce44SJohn Forte 			case '8':
525fcf3ce44SJohn Forte 			case '9':
526fcf3ce44SJohn Forte 				number = number*10 + (chr1 - '0');
527fcf3ce44SJohn Forte 				break;
528fcf3ce44SJohn Forte 			case ':':
529fcf3ce44SJohn Forte 				got_colon = 1;
530fcf3ce44SJohn Forte 				break;
531fcf3ce44SJohn Forte 			case ',':
532fcf3ce44SJohn Forte 				got_comma = 1;
533fcf3ce44SJohn Forte 				break;
534fcf3ce44SJohn Forte 			default: /* ignore any unknown characters */
535fcf3ce44SJohn Forte 				break;
536fcf3ce44SJohn Forte 			}	/* switch */
537fcf3ce44SJohn Forte 			if (got_comma && after_got_colon) {
538fcf3ce44SJohn Forte 				after_got_colon = 0;
539fcf3ce44SJohn Forte 				got_comma = 0;
540fcf3ce44SJohn Forte 				if (number >= sdbc_max_devices)
541fcf3ce44SJohn Forte 					number = sdbc_max_devices - 1;
542fcf3ce44SJohn Forte 				ranges[range_num].lb = prev_num;
543fcf3ce44SJohn Forte 				ranges[range_num].ub = number;
544fcf3ce44SJohn Forte 				if (range_num == 99) break;
545fcf3ce44SJohn Forte 				range_num++;
546fcf3ce44SJohn Forte 				number = 0;
547fcf3ce44SJohn Forte 			} else if (got_colon && after_got_comma) {
548fcf3ce44SJohn Forte 				got_colon = 0;
549fcf3ce44SJohn Forte 				after_got_colon = 1;
550fcf3ce44SJohn Forte 				after_got_comma = 0;
551fcf3ce44SJohn Forte 				if (number >= sdbc_max_devices)
552fcf3ce44SJohn Forte 					number = sdbc_max_devices - 1;
553fcf3ce44SJohn Forte 				prev_num = number;
554fcf3ce44SJohn Forte 				number = 0;
555fcf3ce44SJohn Forte 			} else if (got_colon) {
556fcf3ce44SJohn Forte 				got_colon = 0;
557fcf3ce44SJohn Forte 				after_got_colon = 1;
558fcf3ce44SJohn Forte 				if ((prev_chr != '\0') && (prev_chr != ':')) {
559fcf3ce44SJohn Forte 					if (number >= sdbc_max_devices)
560fcf3ce44SJohn Forte 						number = sdbc_max_devices - 1;
561fcf3ce44SJohn Forte 					prev_num = number;
562fcf3ce44SJohn Forte 					number = 0;
563fcf3ce44SJohn Forte 				}
564fcf3ce44SJohn Forte 			} else if (got_comma) {
565fcf3ce44SJohn Forte 				got_comma = 0;
566fcf3ce44SJohn Forte 				after_got_comma = 1;
567fcf3ce44SJohn Forte 				after_got_colon = 0;
568fcf3ce44SJohn Forte 				if (number >= sdbc_max_devices)
569fcf3ce44SJohn Forte 					number = sdbc_max_devices -1;
570fcf3ce44SJohn Forte 				if ((prev_chr != '\0') && (prev_chr != ',')) {
571fcf3ce44SJohn Forte 					ranges[range_num].lb = number;
572fcf3ce44SJohn Forte 					ranges[range_num].ub = number;
573fcf3ce44SJohn Forte 					if (range_num == 99) break;
574fcf3ce44SJohn Forte 						range_num++;
575fcf3ce44SJohn Forte 				}
576fcf3ce44SJohn Forte 				number = 0;
577fcf3ce44SJohn Forte 			}	/* if */
578fcf3ce44SJohn Forte 			prev_chr = chr1;
579fcf3ce44SJohn Forte 		}		/* while */
580fcf3ce44SJohn Forte 		if (number >= sdbc_max_devices)
581fcf3ce44SJohn Forte 			number = sdbc_max_devices - 1;
582fcf3ce44SJohn Forte 		if (after_got_colon) {
583fcf3ce44SJohn Forte 			ranges[range_num].lb = prev_num;
584fcf3ce44SJohn Forte 			ranges[range_num].ub = number;
585fcf3ce44SJohn Forte 		} else {
586fcf3ce44SJohn Forte 			if ((after_got_comma) && (prev_chr == ','))
587fcf3ce44SJohn Forte 				range_num--;
588fcf3ce44SJohn Forte 			else {
589fcf3ce44SJohn Forte 				ranges[range_num].lb = number;
590fcf3ce44SJohn Forte 				ranges[range_num].ub = number;
591fcf3ce44SJohn Forte 			}
592fcf3ce44SJohn Forte 		}
593fcf3ce44SJohn Forte 	}
594fcf3ce44SJohn Forte }
595