xref: /titanic_51/usr/src/cmd/format/io.c (revision f1bf06561684fdb7e38b282b7a4508d35a50985b)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5b519f838Sbz211116  * Common Development and Distribution License (the "License").
6b519f838Sbz211116  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
2265908c77Syu, larry liu - Sun Microsystems - Beijing China  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*f1bf0656SHans Rosenfeld  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * This file contains I/O related functions.
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate #include "global.h"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <stdlib.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <signal.h>
367c478bd9Sstevel@tonic-gate #include <ctype.h>
377c478bd9Sstevel@tonic-gate #include <stdarg.h>
387c478bd9Sstevel@tonic-gate #include <sys/tty.h>
397c478bd9Sstevel@tonic-gate #include <sys/termio.h>
407c478bd9Sstevel@tonic-gate #include <sys/termios.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include "startup.h"
437c478bd9Sstevel@tonic-gate #include "misc.h"
447c478bd9Sstevel@tonic-gate #include "menu_partition.h"
457c478bd9Sstevel@tonic-gate #include "param.h"
467c478bd9Sstevel@tonic-gate #include "menu.h"
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate extern int	data_lineno;
507c478bd9Sstevel@tonic-gate extern char	*space2str();
517c478bd9Sstevel@tonic-gate extern long	strtol();
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate  * This variable is used to determine whether a token is present in the pipe
557c478bd9Sstevel@tonic-gate  * already.
567c478bd9Sstevel@tonic-gate  */
577c478bd9Sstevel@tonic-gate static	char	token_present = 0;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate  * This variable always gives us access to the most recent token type
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate int	last_token_type = 0;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #ifdef	__STDC__
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate  * Prototypes for ANSI C compilers
677c478bd9Sstevel@tonic-gate  */
687c478bd9Sstevel@tonic-gate static int	sup_get_token(char *);
697c478bd9Sstevel@tonic-gate static void	pushchar(int c);
707c478bd9Sstevel@tonic-gate static int	checkeof(void);
717c478bd9Sstevel@tonic-gate static void	flushline(void);
727c478bd9Sstevel@tonic-gate static int	strcnt(char *s1, char *s2);
73342440ecSPrasad Singamsetty static int	getbn(char *str, diskaddr_t *iptr);
747c478bd9Sstevel@tonic-gate static void	print_input_choices(int type, u_ioparam_t *param);
757c478bd9Sstevel@tonic-gate static int	slist_widest_str(slist_t *slist);
767c478bd9Sstevel@tonic-gate static void	ljust_print(char *str, int width);
777c478bd9Sstevel@tonic-gate static int	sup_inputchar(void);
787c478bd9Sstevel@tonic-gate static void	sup_pushchar(int c);
797c478bd9Sstevel@tonic-gate static int	geti64(char *str, uint64_t *iptr, uint64_t *wild);
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate #else	/* __STDC__ */
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate  * Prototypes for non-ANSI C compilers
847c478bd9Sstevel@tonic-gate  */
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate static int	sup_get_token();
877c478bd9Sstevel@tonic-gate static void	pushchar(int c);
887c478bd9Sstevel@tonic-gate static int	checkeof(void);
897c478bd9Sstevel@tonic-gate static void	flushline(void);
907c478bd9Sstevel@tonic-gate static int	strcnt(char *s1, char *s2);
91342440ecSPrasad Singamsetty static int	getbn(char *str, diskaddr_t *iptr);
927c478bd9Sstevel@tonic-gate static void	print_input_choices(int type, u_ioparam_t *param);
937c478bd9Sstevel@tonic-gate static int	slist_widest_str(slist_t *slist);
947c478bd9Sstevel@tonic-gate static void	ljust_print(char *str, int width);
957c478bd9Sstevel@tonic-gate static int	sup_inputchar(void);
967c478bd9Sstevel@tonic-gate static void	sup_pushchar(int c);
977c478bd9Sstevel@tonic-gate static int	geti64(char *str, uint64_t *iptr, uint64_t *wild);
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate #endif	/* __STDC__ */
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate /*
1037c478bd9Sstevel@tonic-gate  * This routine pushes the given character back onto the input stream.
1047c478bd9Sstevel@tonic-gate  */
1057c478bd9Sstevel@tonic-gate static void
1067c478bd9Sstevel@tonic-gate pushchar(c)
1077c478bd9Sstevel@tonic-gate 	int	c;
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	(void) ungetc(c, stdin);
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate /*
1137c478bd9Sstevel@tonic-gate  * This routine checks the input stream for an eof condition.
1147c478bd9Sstevel@tonic-gate  */
1157c478bd9Sstevel@tonic-gate static int
1167c478bd9Sstevel@tonic-gate checkeof()
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate 	return (feof(stdin));
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate /*
1227c478bd9Sstevel@tonic-gate  * This routine gets the next token off the input stream.  A token is
1237c478bd9Sstevel@tonic-gate  * basically any consecutive non-white characters.
1247c478bd9Sstevel@tonic-gate  */
1257c478bd9Sstevel@tonic-gate char *
1267c478bd9Sstevel@tonic-gate gettoken(inbuf)
1277c478bd9Sstevel@tonic-gate 	char	*inbuf;
1287c478bd9Sstevel@tonic-gate {
1297c478bd9Sstevel@tonic-gate 	char	*ptr = inbuf;
1307c478bd9Sstevel@tonic-gate 	int	c, quoted = 0;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate retoke:
1337c478bd9Sstevel@tonic-gate 	/*
1347c478bd9Sstevel@tonic-gate 	 * Remove any leading white-space.
1357c478bd9Sstevel@tonic-gate 	 */
1367c478bd9Sstevel@tonic-gate 	while ((isspace(c = getchar())) && (c != '\n'))
1377c478bd9Sstevel@tonic-gate 		;
1387c478bd9Sstevel@tonic-gate 	/*
1397c478bd9Sstevel@tonic-gate 	 * If we are at the beginning of a line and hit the comment character,
1407c478bd9Sstevel@tonic-gate 	 * flush the line and start again.
1417c478bd9Sstevel@tonic-gate 	 */
1427c478bd9Sstevel@tonic-gate 	if (!token_present && c == COMMENT_CHAR) {
1437c478bd9Sstevel@tonic-gate 		token_present = 1;
1447c478bd9Sstevel@tonic-gate 		flushline();
1457c478bd9Sstevel@tonic-gate 		goto retoke;
1467c478bd9Sstevel@tonic-gate 	}
1477c478bd9Sstevel@tonic-gate 	/*
1487c478bd9Sstevel@tonic-gate 	 * Loop on each character until we hit unquoted white-space.
1497c478bd9Sstevel@tonic-gate 	 */
1507c478bd9Sstevel@tonic-gate 	while (!isspace(c) || quoted && (c != '\n')) {
1517c478bd9Sstevel@tonic-gate 		/*
1527c478bd9Sstevel@tonic-gate 		 * If we hit eof, get out.
1537c478bd9Sstevel@tonic-gate 		 */
1547c478bd9Sstevel@tonic-gate 		if (checkeof())
1557c478bd9Sstevel@tonic-gate 			return (NULL);
1567c478bd9Sstevel@tonic-gate 		/*
1577c478bd9Sstevel@tonic-gate 		 * If we hit a double quote, change the state of quotedness.
1587c478bd9Sstevel@tonic-gate 		 */
1597c478bd9Sstevel@tonic-gate 		if (c == '"')
1607c478bd9Sstevel@tonic-gate 			quoted = !quoted;
1617c478bd9Sstevel@tonic-gate 		/*
1627c478bd9Sstevel@tonic-gate 		 * If there's room in the buffer, add the character to the end.
1637c478bd9Sstevel@tonic-gate 		 */
1647c478bd9Sstevel@tonic-gate 		else if (ptr - inbuf < TOKEN_SIZE)
1657c478bd9Sstevel@tonic-gate 			*ptr++ = (char)c;
1667c478bd9Sstevel@tonic-gate 		/*
1677c478bd9Sstevel@tonic-gate 		 * Get the next character.
1687c478bd9Sstevel@tonic-gate 		 */
1697c478bd9Sstevel@tonic-gate 		c = getchar();
1707c478bd9Sstevel@tonic-gate 	}
1717c478bd9Sstevel@tonic-gate 	/*
1727c478bd9Sstevel@tonic-gate 	 * Null terminate the token.
1737c478bd9Sstevel@tonic-gate 	 */
1747c478bd9Sstevel@tonic-gate 	*ptr = '\0';
1757c478bd9Sstevel@tonic-gate 	/*
1767c478bd9Sstevel@tonic-gate 	 * Peel off white-space still in the pipe.
1777c478bd9Sstevel@tonic-gate 	 */
1787c478bd9Sstevel@tonic-gate 	while (isspace(c) && (c != '\n'))
1797c478bd9Sstevel@tonic-gate 		c = getchar();
1807c478bd9Sstevel@tonic-gate 	/*
1817c478bd9Sstevel@tonic-gate 	 * If we hit another token, push it back and set state.
1827c478bd9Sstevel@tonic-gate 	 */
1837c478bd9Sstevel@tonic-gate 	if (c != '\n') {
1847c478bd9Sstevel@tonic-gate 		pushchar(c);
1857c478bd9Sstevel@tonic-gate 		token_present = 1;
1867c478bd9Sstevel@tonic-gate 	} else
1877c478bd9Sstevel@tonic-gate 		token_present = 0;
1887c478bd9Sstevel@tonic-gate 	/*
1897c478bd9Sstevel@tonic-gate 	 * Return the token.
1907c478bd9Sstevel@tonic-gate 	 */
1917c478bd9Sstevel@tonic-gate 	return (inbuf);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate /*
1957c478bd9Sstevel@tonic-gate  * This routine removes the leading and trailing spaces from a token.
1967c478bd9Sstevel@tonic-gate  */
1977c478bd9Sstevel@tonic-gate void
1987c478bd9Sstevel@tonic-gate clean_token(cleantoken, token)
1997c478bd9Sstevel@tonic-gate 	char	*cleantoken, *token;
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate 	char	*ptr;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	/*
2047c478bd9Sstevel@tonic-gate 	 * Strip off leading white-space.
2057c478bd9Sstevel@tonic-gate 	 */
2067c478bd9Sstevel@tonic-gate 	for (ptr = token; isspace(*ptr); ptr++)
2077c478bd9Sstevel@tonic-gate 		;
2087c478bd9Sstevel@tonic-gate 	/*
2097c478bd9Sstevel@tonic-gate 	 * Copy it into the clean buffer.
2107c478bd9Sstevel@tonic-gate 	 */
2117c478bd9Sstevel@tonic-gate 	(void) strcpy(cleantoken, ptr);
2127c478bd9Sstevel@tonic-gate 	/*
2137c478bd9Sstevel@tonic-gate 	 * Strip off trailing white-space.
2147c478bd9Sstevel@tonic-gate 	 */
2157c478bd9Sstevel@tonic-gate 	for (ptr = cleantoken + strlen(cleantoken) - 1;
2167c478bd9Sstevel@tonic-gate 		isspace(*ptr) && (ptr >= cleantoken); ptr--) {
2177c478bd9Sstevel@tonic-gate 		*ptr = '\0';
2187c478bd9Sstevel@tonic-gate 	}
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate /*
2227c478bd9Sstevel@tonic-gate  * This routine checks if a token is already present on the input line
2237c478bd9Sstevel@tonic-gate  */
2247c478bd9Sstevel@tonic-gate int
2257c478bd9Sstevel@tonic-gate istokenpresent()
2267c478bd9Sstevel@tonic-gate {
2277c478bd9Sstevel@tonic-gate 	return (token_present);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate /*
2317c478bd9Sstevel@tonic-gate  * This routine flushes the rest of an input line if there is known
2327c478bd9Sstevel@tonic-gate  * to be data in it.  The flush has to be qualified because the newline
2337c478bd9Sstevel@tonic-gate  * may have already been swallowed by the last gettoken.
2347c478bd9Sstevel@tonic-gate  */
2357c478bd9Sstevel@tonic-gate static void
2367c478bd9Sstevel@tonic-gate flushline()
2377c478bd9Sstevel@tonic-gate {
2387c478bd9Sstevel@tonic-gate 	if (token_present) {
2397c478bd9Sstevel@tonic-gate 		/*
2407c478bd9Sstevel@tonic-gate 		 * Flush the pipe to eol or eof.
2417c478bd9Sstevel@tonic-gate 		 */
2427c478bd9Sstevel@tonic-gate 		while ((getchar() != '\n') && !checkeof())
2437c478bd9Sstevel@tonic-gate 			;
2447c478bd9Sstevel@tonic-gate 		/*
2457c478bd9Sstevel@tonic-gate 		 * Mark the pipe empty.
2467c478bd9Sstevel@tonic-gate 		 */
2477c478bd9Sstevel@tonic-gate 		token_present = 0;
2487c478bd9Sstevel@tonic-gate 	}
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate /*
2527c478bd9Sstevel@tonic-gate  * This routine returns the number of characters that are identical
2537c478bd9Sstevel@tonic-gate  * between s1 and s2, stopping as soon as a mismatch is found.
2547c478bd9Sstevel@tonic-gate  */
2557c478bd9Sstevel@tonic-gate static int
2567c478bd9Sstevel@tonic-gate strcnt(s1, s2)
2577c478bd9Sstevel@tonic-gate 	char	*s1, *s2;
2587c478bd9Sstevel@tonic-gate {
2597c478bd9Sstevel@tonic-gate 	int	i = 0;
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	while ((*s1 != '\0') && (*s1++ == *s2++))
2627c478bd9Sstevel@tonic-gate 		i++;
2637c478bd9Sstevel@tonic-gate 	return (i);
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate /*
2677c478bd9Sstevel@tonic-gate  * This routine converts the given token into an integer.  The token
2687c478bd9Sstevel@tonic-gate  * must convert cleanly into an integer with no unknown characters.
2697c478bd9Sstevel@tonic-gate  * If the token is the wildcard string, and the wildcard parameter
2707c478bd9Sstevel@tonic-gate  * is present, the wildcard value will be returned.
2717c478bd9Sstevel@tonic-gate  */
2727c478bd9Sstevel@tonic-gate int
2737c478bd9Sstevel@tonic-gate geti(str, iptr, wild)
2747c478bd9Sstevel@tonic-gate 	char	*str;
2757c478bd9Sstevel@tonic-gate 	int	*iptr, *wild;
2767c478bd9Sstevel@tonic-gate {
2777c478bd9Sstevel@tonic-gate 	char	*str2;
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	/*
2807c478bd9Sstevel@tonic-gate 	 * If there's a wildcard value and the string is wild, return the
2817c478bd9Sstevel@tonic-gate 	 * wildcard value.
2827c478bd9Sstevel@tonic-gate 	 */
2837c478bd9Sstevel@tonic-gate 	if (wild != NULL && strcmp(str, WILD_STRING) == 0)
2847c478bd9Sstevel@tonic-gate 		*iptr = *wild;
2857c478bd9Sstevel@tonic-gate 	else {
2867c478bd9Sstevel@tonic-gate 		/*
2877c478bd9Sstevel@tonic-gate 		 * Conver the string to an integer.
2887c478bd9Sstevel@tonic-gate 		 */
2897c478bd9Sstevel@tonic-gate 		*iptr = (int)strtol(str, &str2, 0);
2907c478bd9Sstevel@tonic-gate 		/*
2917c478bd9Sstevel@tonic-gate 		 * If any characters didn't convert, it's an error.
2927c478bd9Sstevel@tonic-gate 		 */
2937c478bd9Sstevel@tonic-gate 		if (*str2 != '\0') {
2947c478bd9Sstevel@tonic-gate 			err_print("`%s' is not an integer.\n", str);
2957c478bd9Sstevel@tonic-gate 			return (-1);
2967c478bd9Sstevel@tonic-gate 		}
2977c478bd9Sstevel@tonic-gate 	}
2987c478bd9Sstevel@tonic-gate 	return (0);
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate /*
3027c478bd9Sstevel@tonic-gate  * This routine converts the given token into a long long.  The token
3037c478bd9Sstevel@tonic-gate  * must convert cleanly into a 64-bit integer with no unknown characters.
3047c478bd9Sstevel@tonic-gate  * If the token is the wildcard string, and the wildcard parameter
3057c478bd9Sstevel@tonic-gate  * is present, the wildcard value will be returned.
3067c478bd9Sstevel@tonic-gate  */
3077c478bd9Sstevel@tonic-gate static int
3087c478bd9Sstevel@tonic-gate geti64(str, iptr, wild)
3097c478bd9Sstevel@tonic-gate 	char		*str;
3107c478bd9Sstevel@tonic-gate 	uint64_t	*iptr, *wild;
3117c478bd9Sstevel@tonic-gate {
3127c478bd9Sstevel@tonic-gate 	char	*str2;
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 	/*
3157c478bd9Sstevel@tonic-gate 	 * If there's a wildcard value and the string is wild, return the
3167c478bd9Sstevel@tonic-gate 	 * wildcard value.
3177c478bd9Sstevel@tonic-gate 	 */
3187c478bd9Sstevel@tonic-gate 	if ((wild != NULL) && (strcmp(str, WILD_STRING)) == 0) {
3197c478bd9Sstevel@tonic-gate 		*iptr = *wild;
3207c478bd9Sstevel@tonic-gate 	} else {
3217c478bd9Sstevel@tonic-gate 		/*
3227c478bd9Sstevel@tonic-gate 		 * Conver the string to an integer.
3237c478bd9Sstevel@tonic-gate 		 */
3247c478bd9Sstevel@tonic-gate 		*iptr = (uint64_t)strtoll(str, &str2, 0);
3257c478bd9Sstevel@tonic-gate 		/*
3267c478bd9Sstevel@tonic-gate 		 * If any characters didn't convert, it's an error.
3277c478bd9Sstevel@tonic-gate 		 */
3287c478bd9Sstevel@tonic-gate 		if (*str2 != '\0') {
3297c478bd9Sstevel@tonic-gate 			err_print("`%s' is not an integer.\n", str);
3307c478bd9Sstevel@tonic-gate 			return (-1);
3317c478bd9Sstevel@tonic-gate 		}
3327c478bd9Sstevel@tonic-gate 	}
3337c478bd9Sstevel@tonic-gate 	return (0);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate /*
3377c478bd9Sstevel@tonic-gate  * This routine converts the given string into a block number on the
3387c478bd9Sstevel@tonic-gate  * current disk.  The format of a block number is either a self-based
3397c478bd9Sstevel@tonic-gate  * number, or a series of self-based numbers separated by slashes.
3407c478bd9Sstevel@tonic-gate  * Any number preceeding the first slash is considered a cylinder value.
3417c478bd9Sstevel@tonic-gate  * Any number succeeding the first slash but preceeding the second is
3427c478bd9Sstevel@tonic-gate  * considered a head value.  Any number succeeding the second slash is
3437c478bd9Sstevel@tonic-gate  * considered a sector value.  Any of these numbers can be wildcarded
3447c478bd9Sstevel@tonic-gate  * to the highest possible legal value.
3457c478bd9Sstevel@tonic-gate  */
3467c478bd9Sstevel@tonic-gate static int
3477c478bd9Sstevel@tonic-gate getbn(str, iptr)
3487c478bd9Sstevel@tonic-gate 	char	*str;
349342440ecSPrasad Singamsetty 	diskaddr_t	*iptr;
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate 	char	*cptr, *hptr, *sptr;
352342440ecSPrasad Singamsetty 	int	cyl, head, sect;
353342440ecSPrasad Singamsetty 	int	wild;
354342440ecSPrasad Singamsetty 	diskaddr_t	wild64;
3557c478bd9Sstevel@tonic-gate 	TOKEN	buf;
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 	/*
3587c478bd9Sstevel@tonic-gate 	 * Set cylinder pointer to beginning of string.
3597c478bd9Sstevel@tonic-gate 	 */
3607c478bd9Sstevel@tonic-gate 	cptr = str;
3617c478bd9Sstevel@tonic-gate 	/*
3627c478bd9Sstevel@tonic-gate 	 * Look for the first slash.
3637c478bd9Sstevel@tonic-gate 	 */
3647c478bd9Sstevel@tonic-gate 	while ((*str != '\0') && (*str != '/'))
3657c478bd9Sstevel@tonic-gate 		str++;
3667c478bd9Sstevel@tonic-gate 	/*
3677c478bd9Sstevel@tonic-gate 	 * If there wasn't one, convert string to an integer and return it.
3687c478bd9Sstevel@tonic-gate 	 */
3697c478bd9Sstevel@tonic-gate 	if (*str == '\0') {
370342440ecSPrasad Singamsetty 		wild64 = physsects() - 1;
371342440ecSPrasad Singamsetty 		if (geti64(cptr, iptr, &wild64))
3727c478bd9Sstevel@tonic-gate 			return (-1);
3737c478bd9Sstevel@tonic-gate 		return (0);
3747c478bd9Sstevel@tonic-gate 	}
3757c478bd9Sstevel@tonic-gate 	/*
3767c478bd9Sstevel@tonic-gate 	 * Null out the slash and set head pointer just beyond it.
3777c478bd9Sstevel@tonic-gate 	 */
3787c478bd9Sstevel@tonic-gate 	*str++ = '\0';
3797c478bd9Sstevel@tonic-gate 	hptr = str;
3807c478bd9Sstevel@tonic-gate 	/*
3817c478bd9Sstevel@tonic-gate 	 * Look for the second slash.
3827c478bd9Sstevel@tonic-gate 	 */
3837c478bd9Sstevel@tonic-gate 	while ((*str != '\0') && (*str != '/'))
3847c478bd9Sstevel@tonic-gate 		str++;
3857c478bd9Sstevel@tonic-gate 	/*
3867c478bd9Sstevel@tonic-gate 	 * If there wasn't one, sector pointer points to a .
3877c478bd9Sstevel@tonic-gate 	 */
3887c478bd9Sstevel@tonic-gate 	if (*str == '\0')
3897c478bd9Sstevel@tonic-gate 		sptr = str;
3907c478bd9Sstevel@tonic-gate 	/*
3917c478bd9Sstevel@tonic-gate 	 * If there was, null it out and set sector point just beyond it.
3927c478bd9Sstevel@tonic-gate 	 */
3937c478bd9Sstevel@tonic-gate 	else {
3947c478bd9Sstevel@tonic-gate 		*str++ = '\0';
3957c478bd9Sstevel@tonic-gate 		sptr = str;
3967c478bd9Sstevel@tonic-gate 	}
3977c478bd9Sstevel@tonic-gate 	/*
3987c478bd9Sstevel@tonic-gate 	 * Convert the cylinder part to an integer and store it.
3997c478bd9Sstevel@tonic-gate 	 */
4007c478bd9Sstevel@tonic-gate 	clean_token(buf, cptr);
4017c478bd9Sstevel@tonic-gate 	wild = ncyl + acyl - 1;
4027c478bd9Sstevel@tonic-gate 	if (geti(buf, &cyl, &wild))
4037c478bd9Sstevel@tonic-gate 		return (-1);
4047c478bd9Sstevel@tonic-gate 	if ((cyl < 0) || (cyl >= (ncyl + acyl))) {
4057c478bd9Sstevel@tonic-gate 		err_print("`%d' is out of range.\n", cyl);
4067c478bd9Sstevel@tonic-gate 		return (-1);
4077c478bd9Sstevel@tonic-gate 	}
4087c478bd9Sstevel@tonic-gate 	/*
4097c478bd9Sstevel@tonic-gate 	 * Convert the head part to an integer and store it.
4107c478bd9Sstevel@tonic-gate 	 */
4117c478bd9Sstevel@tonic-gate 	clean_token(buf, hptr);
4127c478bd9Sstevel@tonic-gate 	wild = nhead - 1;
4137c478bd9Sstevel@tonic-gate 	if (geti(buf, &head, &wild))
4147c478bd9Sstevel@tonic-gate 		return (-1);
4157c478bd9Sstevel@tonic-gate 	if ((head < 0) || (head >= nhead)) {
4167c478bd9Sstevel@tonic-gate 		err_print("`%d' is out of range.\n", head);
4177c478bd9Sstevel@tonic-gate 		return (-1);
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 	/*
4207c478bd9Sstevel@tonic-gate 	 * Convert the sector part to an integer and store it.
4217c478bd9Sstevel@tonic-gate 	 */
4227c478bd9Sstevel@tonic-gate 	clean_token(buf, sptr);
4237c478bd9Sstevel@tonic-gate 	wild = sectors(head) - 1;
4247c478bd9Sstevel@tonic-gate 	if (geti(buf, &sect, &wild))
4257c478bd9Sstevel@tonic-gate 		return (-1);
4267c478bd9Sstevel@tonic-gate 	if ((sect < 0) || (sect >= sectors(head))) {
4277c478bd9Sstevel@tonic-gate 		err_print("`%d' is out of range.\n", sect);
4287c478bd9Sstevel@tonic-gate 		return (-1);
4297c478bd9Sstevel@tonic-gate 	}
4307c478bd9Sstevel@tonic-gate 	/*
4317c478bd9Sstevel@tonic-gate 	 * Combine the pieces into a block number and return it.
4327c478bd9Sstevel@tonic-gate 	 */
4337c478bd9Sstevel@tonic-gate 	*iptr = chs2bn(cyl, head, sect);
4347c478bd9Sstevel@tonic-gate 	return (0);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate  * This routine is the basis for all input into the program.  It
4397c478bd9Sstevel@tonic-gate  * understands the semantics of a set of input types, and provides
4407c478bd9Sstevel@tonic-gate  * consistent error messages for all input.  It allows for default
4417c478bd9Sstevel@tonic-gate  * values and prompt strings.
4427c478bd9Sstevel@tonic-gate  */
4437c478bd9Sstevel@tonic-gate uint64_t
4447c478bd9Sstevel@tonic-gate input(type, promptstr, delim, param, deflt, cmdflag)
4457c478bd9Sstevel@tonic-gate 	int		type;
4467c478bd9Sstevel@tonic-gate 	char		*promptstr;
4477c478bd9Sstevel@tonic-gate 	int		delim;
4487c478bd9Sstevel@tonic-gate 	u_ioparam_t	*param;
4497c478bd9Sstevel@tonic-gate 	int		*deflt;
4507c478bd9Sstevel@tonic-gate 	int		cmdflag;
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate 	int		interactive, help, i, length, index, tied;
453342440ecSPrasad Singamsetty 	blkaddr_t	bn;
4547c478bd9Sstevel@tonic-gate 	diskaddr_t	bn64;
4557c478bd9Sstevel@tonic-gate 	char		**str, **strings;
4567c478bd9Sstevel@tonic-gate 	TOKEN		token, cleantoken;
4577c478bd9Sstevel@tonic-gate 	TOKEN		token2, cleantoken2;
458f1c60556Spr131582 	char		*arg;
4597c478bd9Sstevel@tonic-gate 	struct		bounds *bounds;
4607c478bd9Sstevel@tonic-gate 	char		*s;
4617c478bd9Sstevel@tonic-gate 	int		value;
4627c478bd9Sstevel@tonic-gate 	int		cyls, cylno;
4637c478bd9Sstevel@tonic-gate 	uint64_t	blokno;
4647c478bd9Sstevel@tonic-gate 	float		nmegs;
4657c478bd9Sstevel@tonic-gate 	float		ngigs;
4667c478bd9Sstevel@tonic-gate 	char		shell_argv[MAXPATHLEN];
4677c478bd9Sstevel@tonic-gate 	part_deflt_t	*part_deflt;
4687c478bd9Sstevel@tonic-gate 	efi_deflt_t	*efi_deflt;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	/*
4717c478bd9Sstevel@tonic-gate 	 * Optional integer input has been added as a hack.
4727c478bd9Sstevel@tonic-gate 	 * Function result is 1 if user typed anything.
4737c478bd9Sstevel@tonic-gate 	 * Whatever they typed is returned in *deflt.
4747c478bd9Sstevel@tonic-gate 	 * This permits us to distinguish between "no value",
4757c478bd9Sstevel@tonic-gate 	 * and actually entering in some value, for instance.
4767c478bd9Sstevel@tonic-gate 	 */
4777c478bd9Sstevel@tonic-gate 	if (type == FIO_OPINT) {
4787c478bd9Sstevel@tonic-gate 		assert(deflt != NULL);
4797c478bd9Sstevel@tonic-gate 	}
4807c478bd9Sstevel@tonic-gate reprompt:
4817c478bd9Sstevel@tonic-gate 	help = interactive = 0;
4827c478bd9Sstevel@tonic-gate 	/*
4837c478bd9Sstevel@tonic-gate 	 * If we are inputting a command, flush any current input in the pipe.
4847c478bd9Sstevel@tonic-gate 	 */
4857c478bd9Sstevel@tonic-gate 	if (cmdflag == CMD_INPUT)
4867c478bd9Sstevel@tonic-gate 		flushline();
4877c478bd9Sstevel@tonic-gate 	/*
4887c478bd9Sstevel@tonic-gate 	 * Note whether the token is already present.
4897c478bd9Sstevel@tonic-gate 	 */
4907c478bd9Sstevel@tonic-gate 	if (!token_present)
4917c478bd9Sstevel@tonic-gate 		interactive = 1;
4927c478bd9Sstevel@tonic-gate 	/*
4937c478bd9Sstevel@tonic-gate 	 * Print the prompt.
4947c478bd9Sstevel@tonic-gate 	 */
4957c478bd9Sstevel@tonic-gate 	fmt_print(promptstr);
4967c478bd9Sstevel@tonic-gate 	/*
4977c478bd9Sstevel@tonic-gate 	 * If there is a default value, print it in a format appropriate
4987c478bd9Sstevel@tonic-gate 	 * for the input type.
4997c478bd9Sstevel@tonic-gate 	 */
5007c478bd9Sstevel@tonic-gate 	if (deflt != NULL) {
5017c478bd9Sstevel@tonic-gate 		switch (type) {
5027c478bd9Sstevel@tonic-gate 		case FIO_BN:
503342440ecSPrasad Singamsetty #if !defined(lint)	/* caller has aligned the pointer specifying FIO_BN */
504342440ecSPrasad Singamsetty 			fmt_print("[%llu, ", *(diskaddr_t *)deflt);
505342440ecSPrasad Singamsetty 			pr_dblock(fmt_print, *(diskaddr_t *)deflt);
5067c478bd9Sstevel@tonic-gate 			fmt_print("]");
507342440ecSPrasad Singamsetty #endif
5087c478bd9Sstevel@tonic-gate 			break;
5097c478bd9Sstevel@tonic-gate 		case FIO_INT:
5107c478bd9Sstevel@tonic-gate 			fmt_print("[%d]", *deflt);
5117c478bd9Sstevel@tonic-gate 			break;
5127c478bd9Sstevel@tonic-gate 		case FIO_INT64:
5137c478bd9Sstevel@tonic-gate #if defined(lint)
5147c478bd9Sstevel@tonic-gate 			/* caller is longlong aligned specifying FIO_INT64 */
5157c478bd9Sstevel@tonic-gate 			efi_deflt = NULL;
5167c478bd9Sstevel@tonic-gate #else
5177c478bd9Sstevel@tonic-gate 			efi_deflt = (efi_deflt_t *)deflt;
5187c478bd9Sstevel@tonic-gate #endif
5197c478bd9Sstevel@tonic-gate 			fmt_print("[%llu]", efi_deflt->start_sector);
5207c478bd9Sstevel@tonic-gate 			break;
5217c478bd9Sstevel@tonic-gate 		case FIO_CSTR:
5227c478bd9Sstevel@tonic-gate 		case FIO_MSTR:
5237c478bd9Sstevel@tonic-gate 			strings = (char **)param->io_charlist;
5247c478bd9Sstevel@tonic-gate 			for (i = 0, str = strings; i < *deflt; i++, str++)
5257c478bd9Sstevel@tonic-gate 				;
5267c478bd9Sstevel@tonic-gate 			fmt_print("[%s]", *str);
5277c478bd9Sstevel@tonic-gate 			break;
5287c478bd9Sstevel@tonic-gate 		case FIO_OSTR:
5297c478bd9Sstevel@tonic-gate 			fmt_print("[\"%s\"]", (char *)deflt);
5307c478bd9Sstevel@tonic-gate 			break;
5317c478bd9Sstevel@tonic-gate 		case FIO_SLIST:
5327c478bd9Sstevel@tonic-gate 			/*
5337c478bd9Sstevel@tonic-gate 			 * Search for a string matching the default
5347c478bd9Sstevel@tonic-gate 			 * value.  If found, use it.  Otherwise
5357c478bd9Sstevel@tonic-gate 			 * assume the default value is actually
5367c478bd9Sstevel@tonic-gate 			 * an illegal choice, and default to
5377c478bd9Sstevel@tonic-gate 			 * the first item in the list.
5387c478bd9Sstevel@tonic-gate 			 */
5397c478bd9Sstevel@tonic-gate 			s = find_string(param->io_slist, *deflt);
5407c478bd9Sstevel@tonic-gate 			if (s == (char *)NULL) {
5417c478bd9Sstevel@tonic-gate 				s = (param->io_slist)->str;
5427c478bd9Sstevel@tonic-gate 			}
5437c478bd9Sstevel@tonic-gate 			fmt_print("[%s]", s);
5447c478bd9Sstevel@tonic-gate 			break;
5457c478bd9Sstevel@tonic-gate 		case FIO_CYL:
5467c478bd9Sstevel@tonic-gate 			/*
5477c478bd9Sstevel@tonic-gate 			 * Old-style partition size input, used to
5487c478bd9Sstevel@tonic-gate 			 * modify complete partition tables
5497c478bd9Sstevel@tonic-gate 			 */
550342440ecSPrasad Singamsetty 			blokno = *(blkaddr32_t *)deflt;
551342440ecSPrasad Singamsetty 			fmt_print("[%llub, %uc, %1.2fmb, %1.2fgb]", blokno,
552342440ecSPrasad Singamsetty 			    bn2c(blokno), bn2mb(blokno), bn2gb(blokno));
5537c478bd9Sstevel@tonic-gate 			break;
5547c478bd9Sstevel@tonic-gate 		case FIO_ECYL:
5557c478bd9Sstevel@tonic-gate 			/*
5567c478bd9Sstevel@tonic-gate 			 * set up pointer to partition defaults
5577c478bd9Sstevel@tonic-gate 			 * structure
5587c478bd9Sstevel@tonic-gate 			 */
5597c478bd9Sstevel@tonic-gate 			part_deflt = (part_deflt_t *)deflt;
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate 			/*
5627c478bd9Sstevel@tonic-gate 			 * Build print format specifier.  We use the
5637c478bd9Sstevel@tonic-gate 			 * starting cylinder number which was entered
5647c478bd9Sstevel@tonic-gate 			 * before this call to input(), in case the
5657c478bd9Sstevel@tonic-gate 			 * user has changed it from the value in the
5667c478bd9Sstevel@tonic-gate 			 * cur_parts->pinfo_map[].dkl_cylno
5677c478bd9Sstevel@tonic-gate 			 * field for the current parition
5687c478bd9Sstevel@tonic-gate 			 */
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 			/*
5717c478bd9Sstevel@tonic-gate 			 * Determine the proper default end cylinder:
5727c478bd9Sstevel@tonic-gate 			 * Start Cyl	Default Size	End Cylinder
5737c478bd9Sstevel@tonic-gate 			 *	0		0	0
5747c478bd9Sstevel@tonic-gate 			 *	>0		0	Start Cyl
5757c478bd9Sstevel@tonic-gate 			 *	0		>0	Default Size
5767c478bd9Sstevel@tonic-gate 			 *				(Cyls) - 1
5777c478bd9Sstevel@tonic-gate 			 *	>0		>0	(Start +
5787c478bd9Sstevel@tonic-gate 			 *				Default Size
5797c478bd9Sstevel@tonic-gate 			 *				(Cyls)) -1
5807c478bd9Sstevel@tonic-gate 			 */
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 			if (part_deflt->deflt_size == 0) {
5837c478bd9Sstevel@tonic-gate 				cylno = part_deflt->start_cyl;
5847c478bd9Sstevel@tonic-gate 			} else if (part_deflt->start_cyl == 0) {
585342440ecSPrasad Singamsetty 				cylno = bn2c(part_deflt->deflt_size) - 1;
5867c478bd9Sstevel@tonic-gate 			} else {
5877c478bd9Sstevel@tonic-gate 				cylno = (bn2c(part_deflt->deflt_size) +
5887c478bd9Sstevel@tonic-gate 					    part_deflt->start_cyl) - 1;
5897c478bd9Sstevel@tonic-gate 			}
5907c478bd9Sstevel@tonic-gate 
591342440ecSPrasad Singamsetty 			fmt_print("[%ub, %uc, %de, %1.2fmb, %1.2fgb]",
5927c478bd9Sstevel@tonic-gate 			    part_deflt->deflt_size,
5937c478bd9Sstevel@tonic-gate 			    bn2c(part_deflt->deflt_size),
5947c478bd9Sstevel@tonic-gate 			    cylno,
5957c478bd9Sstevel@tonic-gate 			    bn2mb(part_deflt->deflt_size),
5967c478bd9Sstevel@tonic-gate 			    bn2gb(part_deflt->deflt_size));
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate 			break;
5997c478bd9Sstevel@tonic-gate 		case FIO_EFI:
6007c478bd9Sstevel@tonic-gate #if defined(lint)
6017c478bd9Sstevel@tonic-gate 			/* caller is longlong aligned when specifying FIO_EFI */
6027c478bd9Sstevel@tonic-gate 			efi_deflt = NULL;
6037c478bd9Sstevel@tonic-gate #else
6047c478bd9Sstevel@tonic-gate 			efi_deflt = (efi_deflt_t *)deflt;
6057c478bd9Sstevel@tonic-gate #endif
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 			fmt_print("[%llub, %llue, %llumb, %llugb, %llutb]",
6087c478bd9Sstevel@tonic-gate 			    efi_deflt->end_sector,
6097c478bd9Sstevel@tonic-gate 			    efi_deflt->start_sector + efi_deflt->end_sector - 1,
61065908c77Syu, larry liu - Sun Microsystems - Beijing China 			    (efi_deflt->end_sector * cur_blksz) /
6117c478bd9Sstevel@tonic-gate 				(1024 * 1024),
61265908c77Syu, larry liu - Sun Microsystems - Beijing China 			    (efi_deflt->end_sector * cur_blksz) /
6137c478bd9Sstevel@tonic-gate 				(1024 * 1024 * 1024),
61465908c77Syu, larry liu - Sun Microsystems - Beijing China 			    (efi_deflt->end_sector * cur_blksz) /
6157c478bd9Sstevel@tonic-gate 				((uint64_t)1024 * 1024 * 1024 * 1024));
6167c478bd9Sstevel@tonic-gate 			break;
6177c478bd9Sstevel@tonic-gate 		case FIO_OPINT:
6187c478bd9Sstevel@tonic-gate 			/* no default value for optional input type */
6197c478bd9Sstevel@tonic-gate 			fmt_print("[default]");
6207c478bd9Sstevel@tonic-gate 			break;
6217c478bd9Sstevel@tonic-gate 		default:
6227c478bd9Sstevel@tonic-gate 			err_print("Error: unknown input type.\n");
6237c478bd9Sstevel@tonic-gate 			fullabort();
6247c478bd9Sstevel@tonic-gate 		}
6257c478bd9Sstevel@tonic-gate 	}
6267c478bd9Sstevel@tonic-gate 	/*
6277c478bd9Sstevel@tonic-gate 	 * Print the delimiter character.
6287c478bd9Sstevel@tonic-gate 	 */
6297c478bd9Sstevel@tonic-gate 	fmt_print("%c ", delim);
6307c478bd9Sstevel@tonic-gate 	/*
6317c478bd9Sstevel@tonic-gate 	 * Get the token.  If we hit eof, exit the program gracefully.
6327c478bd9Sstevel@tonic-gate 	 */
6337c478bd9Sstevel@tonic-gate 	if (gettoken(token) == NULL)
6347c478bd9Sstevel@tonic-gate 		fullabort();
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	/*
6377c478bd9Sstevel@tonic-gate 	 * check if the user has issued (!) , escape to shell
6387c478bd9Sstevel@tonic-gate 	 */
6397c478bd9Sstevel@tonic-gate 	if ((cmdflag == CMD_INPUT) && (token[0] == '!')) {
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 	    /* get the list of arguments to shell command */
642f1c60556Spr131582 		(void) memset(shell_argv, 0, sizeof (shell_argv));
643f1c60556Spr131582 
644f1c60556Spr131582 		/* initialize to the first token... */
645f1c60556Spr131582 		arg = &token[1];
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 		/*
648f1c60556Spr131582 		 * ... and then collect all tokens until the end of
649f1c60556Spr131582 		 * the line as arguments
6507c478bd9Sstevel@tonic-gate 		 */
651f1c60556Spr131582 		do {
652f1c60556Spr131582 			/* skip empty tokens. */
653f1c60556Spr131582 			if (*arg == '\0')
654f1c60556Spr131582 				continue;
655f1c60556Spr131582 			/*
656f1c60556Spr131582 			 * If either of the following two strlcat()
657f1c60556Spr131582 			 * operations overflows, report an error and
658f1c60556Spr131582 			 * exit gracefully.
659f1c60556Spr131582 			 */
660f1c60556Spr131582 			if ((strlcat(shell_argv, arg, sizeof (shell_argv)) >=
661f1c60556Spr131582 				sizeof (shell_argv)) ||
662f1c60556Spr131582 			    (strlcat(shell_argv, " ", sizeof (shell_argv)) >=
663f1c60556Spr131582 				sizeof (shell_argv))) {
664f1c60556Spr131582 				err_print("Error: Command line too long.\n");
665f1c60556Spr131582 				fullabort();
6667c478bd9Sstevel@tonic-gate 			}
667f1c60556Spr131582 		} while (token_present && (arg = gettoken(token)) != NULL);
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 		/* execute the shell command */
670f1c60556Spr131582 		(void) execute_shell(shell_argv, sizeof (shell_argv));
6717c478bd9Sstevel@tonic-gate 		redisplay_menu_list((char **)param->io_charlist);
6727c478bd9Sstevel@tonic-gate 		if (interactive) {
6737c478bd9Sstevel@tonic-gate 			goto reprompt;
6747c478bd9Sstevel@tonic-gate 		}
6757c478bd9Sstevel@tonic-gate 	}
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 	/*
6787c478bd9Sstevel@tonic-gate 	 * Certain commands accept up to two tokens
6797c478bd9Sstevel@tonic-gate 	 * Unfortunately, this is kind of a hack.
6807c478bd9Sstevel@tonic-gate 	 */
6817c478bd9Sstevel@tonic-gate 	token2[0] = 0;
6827c478bd9Sstevel@tonic-gate 	cleantoken2[0] = 0;
6837c478bd9Sstevel@tonic-gate 	if (type == FIO_CYL || type == FIO_ECYL) {
6847c478bd9Sstevel@tonic-gate 		if (token_present) {
6857c478bd9Sstevel@tonic-gate 			if (gettoken(token2) == NULL)
6867c478bd9Sstevel@tonic-gate 				fullabort();
6877c478bd9Sstevel@tonic-gate 			clean_token(cleantoken2, token2);
6887c478bd9Sstevel@tonic-gate 		}
6897c478bd9Sstevel@tonic-gate 	}
6907c478bd9Sstevel@tonic-gate 	/*
6917c478bd9Sstevel@tonic-gate 	 * Echo the token back to the user if it was in the pipe or we
6927c478bd9Sstevel@tonic-gate 	 * are running out of a command file.
6937c478bd9Sstevel@tonic-gate 	 */
6947c478bd9Sstevel@tonic-gate 	if (!interactive || option_f) {
6957c478bd9Sstevel@tonic-gate 		if (token2[0] == 0) {
6967c478bd9Sstevel@tonic-gate 			fmt_print("%s\n", token);
6977c478bd9Sstevel@tonic-gate 		} else {
6987c478bd9Sstevel@tonic-gate 			fmt_print("%s %s\n", token, token2);
6997c478bd9Sstevel@tonic-gate 		}
7007c478bd9Sstevel@tonic-gate 	}
7017c478bd9Sstevel@tonic-gate 	/*
7027c478bd9Sstevel@tonic-gate 	 * If we are logging, echo the token to the log file.  The else
7037c478bd9Sstevel@tonic-gate 	 * is necessary here because the above printf will also put the
7047c478bd9Sstevel@tonic-gate 	 * token in the log file.
7057c478bd9Sstevel@tonic-gate 	 */
7067c478bd9Sstevel@tonic-gate 	else if (log_file) {
7077c478bd9Sstevel@tonic-gate 		log_print("%s %s\n", token, token2);
7087c478bd9Sstevel@tonic-gate 	}
7097c478bd9Sstevel@tonic-gate 	/*
7107c478bd9Sstevel@tonic-gate 	 * If the token was not in the pipe and it wasn't a command, flush
7117c478bd9Sstevel@tonic-gate 	 * the rest of the line to keep things in sync.
7127c478bd9Sstevel@tonic-gate 	 */
7137c478bd9Sstevel@tonic-gate 	if (interactive && cmdflag != CMD_INPUT)
7147c478bd9Sstevel@tonic-gate 		flushline();
7157c478bd9Sstevel@tonic-gate 	/*
7167c478bd9Sstevel@tonic-gate 	 * Scrub off the white-space.
7177c478bd9Sstevel@tonic-gate 	 */
7187c478bd9Sstevel@tonic-gate 	clean_token(cleantoken, token);
7197c478bd9Sstevel@tonic-gate 	/*
7207c478bd9Sstevel@tonic-gate 	 * If the input was a blank line and we weren't prompting
7217c478bd9Sstevel@tonic-gate 	 * specifically for a blank line...
7227c478bd9Sstevel@tonic-gate 	 */
7237c478bd9Sstevel@tonic-gate 	if ((strcmp(cleantoken, "") == 0) && (type != FIO_BLNK)) {
7247c478bd9Sstevel@tonic-gate 		/*
7257c478bd9Sstevel@tonic-gate 		 * If there's a default, return it.
7267c478bd9Sstevel@tonic-gate 		 */
7277c478bd9Sstevel@tonic-gate 		if (deflt != NULL) {
7287c478bd9Sstevel@tonic-gate 			if (type == FIO_OSTR) {
7297c478bd9Sstevel@tonic-gate 				/*
7307c478bd9Sstevel@tonic-gate 				 * Duplicate and return the default string
7317c478bd9Sstevel@tonic-gate 				 */
7327c478bd9Sstevel@tonic-gate 				return ((int)alloc_string((char *)deflt));
7337c478bd9Sstevel@tonic-gate 			} else if (type == FIO_SLIST) {
7347c478bd9Sstevel@tonic-gate 				/*
7357c478bd9Sstevel@tonic-gate 				 * If we can find a match for the default
7367c478bd9Sstevel@tonic-gate 				 * value in the list, return the default
7377c478bd9Sstevel@tonic-gate 				 * value.  If there's no match for the
7387c478bd9Sstevel@tonic-gate 				 * default value, it's an illegal
7397c478bd9Sstevel@tonic-gate 				 * choice.  Return the first value in
7407c478bd9Sstevel@tonic-gate 				 * the list.
7417c478bd9Sstevel@tonic-gate 				 */
7427c478bd9Sstevel@tonic-gate 				s = find_string(param->io_slist, *deflt);
7437c478bd9Sstevel@tonic-gate 				if ((cur_label == L_TYPE_EFI) &&
7447c478bd9Sstevel@tonic-gate 				    (s == (char *)NULL)) {
7457c478bd9Sstevel@tonic-gate 					return (*deflt);
7467c478bd9Sstevel@tonic-gate 				}
7477c478bd9Sstevel@tonic-gate 				if (s == (char *)NULL) {
7487c478bd9Sstevel@tonic-gate 					return ((param->io_slist)->value);
7497c478bd9Sstevel@tonic-gate 				} else {
7507c478bd9Sstevel@tonic-gate 					return (*deflt);
7517c478bd9Sstevel@tonic-gate 				}
7527c478bd9Sstevel@tonic-gate 			} else if (type == FIO_OPINT) {
7537c478bd9Sstevel@tonic-gate 				/*
7547c478bd9Sstevel@tonic-gate 				 * The user didn't enter anything
7557c478bd9Sstevel@tonic-gate 				 */
7567c478bd9Sstevel@tonic-gate 				return (0);
7577c478bd9Sstevel@tonic-gate 			} else if (type == FIO_ECYL) {
7587c478bd9Sstevel@tonic-gate 				return (part_deflt->deflt_size);
7597c478bd9Sstevel@tonic-gate 			} else if (type == FIO_INT64) {
7607c478bd9Sstevel@tonic-gate 				return (efi_deflt->start_sector);
7617c478bd9Sstevel@tonic-gate 			} else if (type == FIO_EFI) {
7627c478bd9Sstevel@tonic-gate 				return (efi_deflt->end_sector);
7637c478bd9Sstevel@tonic-gate 			} else {
7647c478bd9Sstevel@tonic-gate 				return (*deflt);
7657c478bd9Sstevel@tonic-gate 			}
7667c478bd9Sstevel@tonic-gate 		}
7677c478bd9Sstevel@tonic-gate 		/*
7687c478bd9Sstevel@tonic-gate 		 * If the blank was not in the pipe, just reprompt.
7697c478bd9Sstevel@tonic-gate 		 */
7707c478bd9Sstevel@tonic-gate 		if (interactive) {
7717c478bd9Sstevel@tonic-gate 			goto reprompt;
7727c478bd9Sstevel@tonic-gate 		}
7737c478bd9Sstevel@tonic-gate 		/*
7747c478bd9Sstevel@tonic-gate 		 * If the blank was in the pipe, it's an error.
7757c478bd9Sstevel@tonic-gate 		 */
7767c478bd9Sstevel@tonic-gate 		err_print("No default for this entry.\n");
7777c478bd9Sstevel@tonic-gate 		cmdabort(SIGINT);
7787c478bd9Sstevel@tonic-gate 	}
7797c478bd9Sstevel@tonic-gate 	/*
7807c478bd9Sstevel@tonic-gate 	 * If token is a '?' or a 'h', it is a request for help.
7817c478bd9Sstevel@tonic-gate 	 */
7827c478bd9Sstevel@tonic-gate 	if ((strcmp(cleantoken, "?") == 0) ||
7837c478bd9Sstevel@tonic-gate 		(strcmp(cleantoken, "h") == 0) ||
7847c478bd9Sstevel@tonic-gate 			(strcmp(cleantoken, "help") == 0)) {
7857c478bd9Sstevel@tonic-gate 		help = 1;
7867c478bd9Sstevel@tonic-gate 	}
7877c478bd9Sstevel@tonic-gate 	/*
7887c478bd9Sstevel@tonic-gate 	 * Switch on the type of input expected.
7897c478bd9Sstevel@tonic-gate 	 */
7907c478bd9Sstevel@tonic-gate 	switch (type) {
7917c478bd9Sstevel@tonic-gate 	/*
7927c478bd9Sstevel@tonic-gate 	 * Expecting a disk block number.
7937c478bd9Sstevel@tonic-gate 	 */
7947c478bd9Sstevel@tonic-gate 	case FIO_BN:
7957c478bd9Sstevel@tonic-gate 		/*
7967c478bd9Sstevel@tonic-gate 		 * Parameter is the bounds of legal block numbers.
7977c478bd9Sstevel@tonic-gate 		 */
7987c478bd9Sstevel@tonic-gate 		bounds = (struct bounds *)&param->io_bounds;
7997c478bd9Sstevel@tonic-gate 		/*
8007c478bd9Sstevel@tonic-gate 		 * Print help message if required.
8017c478bd9Sstevel@tonic-gate 		 */
8027c478bd9Sstevel@tonic-gate 		if (help) {
8037c478bd9Sstevel@tonic-gate 			fmt_print("Expecting a block number from %llu (",
8047c478bd9Sstevel@tonic-gate 			    bounds->lower);
8057c478bd9Sstevel@tonic-gate 			pr_dblock(fmt_print, bounds->lower);
8067c478bd9Sstevel@tonic-gate 			fmt_print(") to %llu (", bounds->upper);
8077c478bd9Sstevel@tonic-gate 			pr_dblock(fmt_print, bounds->upper);
8087c478bd9Sstevel@tonic-gate 			fmt_print(")\n");
8097c478bd9Sstevel@tonic-gate 			break;
8107c478bd9Sstevel@tonic-gate 		}
8117c478bd9Sstevel@tonic-gate 		/*
8127c478bd9Sstevel@tonic-gate 		 * Convert token to a disk block number.
8137c478bd9Sstevel@tonic-gate 		 */
8147c478bd9Sstevel@tonic-gate 		if (cur_label == L_TYPE_EFI) {
8157c478bd9Sstevel@tonic-gate 		    if (geti64(cleantoken, (uint64_t *)&bn64,
8167c478bd9Sstevel@tonic-gate 			(uint64_t *)NULL))
8177c478bd9Sstevel@tonic-gate 			    break;
8187c478bd9Sstevel@tonic-gate 		} else {
819342440ecSPrasad Singamsetty 		    if (getbn(cleantoken, &bn64))
8207c478bd9Sstevel@tonic-gate 			break;
8217c478bd9Sstevel@tonic-gate 		}
822342440ecSPrasad Singamsetty 		/*
823342440ecSPrasad Singamsetty 		 * Check to be sure it is within the legal bounds.
824342440ecSPrasad Singamsetty 		 */
8257c478bd9Sstevel@tonic-gate 		if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) {
8267c478bd9Sstevel@tonic-gate 			err_print("`");
8277c478bd9Sstevel@tonic-gate 			pr_dblock(err_print, bn64);
8287c478bd9Sstevel@tonic-gate 			err_print("' is out of range.\n");
8297c478bd9Sstevel@tonic-gate 			break;
8307c478bd9Sstevel@tonic-gate 		}
831342440ecSPrasad Singamsetty 		/*
832342440ecSPrasad Singamsetty 		 * It's ok, return it.
833342440ecSPrasad Singamsetty 		 */
8347c478bd9Sstevel@tonic-gate 		return (bn64);
8357c478bd9Sstevel@tonic-gate 	/*
8367c478bd9Sstevel@tonic-gate 	 * Expecting an integer.
8377c478bd9Sstevel@tonic-gate 	 */
8387c478bd9Sstevel@tonic-gate 	case FIO_INT:
8397c478bd9Sstevel@tonic-gate 		/*
8407c478bd9Sstevel@tonic-gate 		 * Parameter is the bounds of legal integers.
8417c478bd9Sstevel@tonic-gate 		 */
8427c478bd9Sstevel@tonic-gate 		bounds = (struct bounds *)&param->io_bounds;
8437c478bd9Sstevel@tonic-gate 		/*
8447c478bd9Sstevel@tonic-gate 		 * Print help message if required.
8457c478bd9Sstevel@tonic-gate 		 */
8467c478bd9Sstevel@tonic-gate 		if (help) {
8477c478bd9Sstevel@tonic-gate 			fmt_print("Expecting an integer from %llu",
8487c478bd9Sstevel@tonic-gate 			    bounds->lower);
8497c478bd9Sstevel@tonic-gate 			fmt_print(" to %llu\n", bounds->upper);
8507c478bd9Sstevel@tonic-gate 			break;
8517c478bd9Sstevel@tonic-gate 		}
8527c478bd9Sstevel@tonic-gate 		/*
8537c478bd9Sstevel@tonic-gate 		 * Convert the token into an integer.
8547c478bd9Sstevel@tonic-gate 		 */
8557c478bd9Sstevel@tonic-gate 		if (geti(cleantoken, (int *)&bn, (int *)NULL))
8567c478bd9Sstevel@tonic-gate 			break;
8577c478bd9Sstevel@tonic-gate 		/*
8587c478bd9Sstevel@tonic-gate 		 * Check to be sure it is within the legal bounds.
8597c478bd9Sstevel@tonic-gate 		 */
8607c478bd9Sstevel@tonic-gate 		if ((bn < bounds->lower) || (bn > bounds->upper)) {
861342440ecSPrasad Singamsetty 			err_print("`%lu' is out of range.\n", bn);
8627c478bd9Sstevel@tonic-gate 			break;
8637c478bd9Sstevel@tonic-gate 		}
8647c478bd9Sstevel@tonic-gate 		/*
8657c478bd9Sstevel@tonic-gate 		 * If it's ok, return it.
8667c478bd9Sstevel@tonic-gate 		 */
8677c478bd9Sstevel@tonic-gate 		return (bn);
8687c478bd9Sstevel@tonic-gate 	case FIO_INT64:
8697c478bd9Sstevel@tonic-gate 		/*
8707c478bd9Sstevel@tonic-gate 		 * Parameter is the bounds of legal integers.
8717c478bd9Sstevel@tonic-gate 		 */
8727c478bd9Sstevel@tonic-gate 		bounds = (struct bounds *)&param->io_bounds;
8737c478bd9Sstevel@tonic-gate 		/*
8747c478bd9Sstevel@tonic-gate 		 * Print help message if required.
8757c478bd9Sstevel@tonic-gate 		 */
8767c478bd9Sstevel@tonic-gate 		if (help) {
8777c478bd9Sstevel@tonic-gate 			fmt_print("Expecting an integer from %llu",
8787c478bd9Sstevel@tonic-gate 			    bounds->lower);
8797c478bd9Sstevel@tonic-gate 			fmt_print(" to %llu\n", bounds->upper);
8807c478bd9Sstevel@tonic-gate 			break;
8817c478bd9Sstevel@tonic-gate 		}
8827c478bd9Sstevel@tonic-gate 		/*
8837c478bd9Sstevel@tonic-gate 		 * Convert the token into an integer.
8847c478bd9Sstevel@tonic-gate 		 */
8857c478bd9Sstevel@tonic-gate 		if (geti64(cleantoken, (uint64_t *)&bn64, (uint64_t *)NULL)) {
8867c478bd9Sstevel@tonic-gate 			break;
8877c478bd9Sstevel@tonic-gate 		}
8887c478bd9Sstevel@tonic-gate 		/*
8897c478bd9Sstevel@tonic-gate 		 * Check to be sure it is within the legal bounds.
8907c478bd9Sstevel@tonic-gate 		 */
8917c478bd9Sstevel@tonic-gate 		if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) {
8927c478bd9Sstevel@tonic-gate 			err_print("`%llu' is out of range.\n", bn64);
8937c478bd9Sstevel@tonic-gate 			break;
8947c478bd9Sstevel@tonic-gate 		}
8957c478bd9Sstevel@tonic-gate 		/*
8967c478bd9Sstevel@tonic-gate 		 * If it's ok, return it.
8977c478bd9Sstevel@tonic-gate 		 */
8987c478bd9Sstevel@tonic-gate 		return (bn64);
8997c478bd9Sstevel@tonic-gate 	/*
9007c478bd9Sstevel@tonic-gate 	 * Expecting an integer, or no input.
9017c478bd9Sstevel@tonic-gate 	 */
9027c478bd9Sstevel@tonic-gate 	case FIO_OPINT:
9037c478bd9Sstevel@tonic-gate 		/*
9047c478bd9Sstevel@tonic-gate 		 * Parameter is the bounds of legal integers.
9057c478bd9Sstevel@tonic-gate 		 */
9067c478bd9Sstevel@tonic-gate 		bounds = (struct bounds *)&param->io_bounds;
9077c478bd9Sstevel@tonic-gate 		/*
9087c478bd9Sstevel@tonic-gate 		 * Print help message if required.
9097c478bd9Sstevel@tonic-gate 		 */
9107c478bd9Sstevel@tonic-gate 		if (help) {
9117c478bd9Sstevel@tonic-gate 			fmt_print("Expecting an integer from %llu",
9127c478bd9Sstevel@tonic-gate 			    bounds->lower);
9137c478bd9Sstevel@tonic-gate 			fmt_print(" to %llu, or no input\n", bounds->upper);
9147c478bd9Sstevel@tonic-gate 			break;
9157c478bd9Sstevel@tonic-gate 		}
9167c478bd9Sstevel@tonic-gate 		/*
9177c478bd9Sstevel@tonic-gate 		 * Convert the token into an integer.
9187c478bd9Sstevel@tonic-gate 		 */
9197c478bd9Sstevel@tonic-gate 		if (geti(cleantoken, (int *)&bn, (int *)NULL))
9207c478bd9Sstevel@tonic-gate 			break;
9217c478bd9Sstevel@tonic-gate 		/*
9227c478bd9Sstevel@tonic-gate 		 * Check to be sure it is within the legal bounds.
9237c478bd9Sstevel@tonic-gate 		 */
9247c478bd9Sstevel@tonic-gate 		if ((bn < bounds->lower) || (bn > bounds->upper)) {
925342440ecSPrasad Singamsetty 			err_print("`%lu' is out of range.\n", bn);
9267c478bd9Sstevel@tonic-gate 			break;
9277c478bd9Sstevel@tonic-gate 		}
9287c478bd9Sstevel@tonic-gate 		/*
9297c478bd9Sstevel@tonic-gate 		 * For optional case, return 1 indicating that
9307c478bd9Sstevel@tonic-gate 		 * the user actually did enter something.
9317c478bd9Sstevel@tonic-gate 		 */
932342440ecSPrasad Singamsetty 		if (!deflt)
9337c478bd9Sstevel@tonic-gate 			*deflt = bn;
9347c478bd9Sstevel@tonic-gate 		return (1);
9357c478bd9Sstevel@tonic-gate 	/*
9367c478bd9Sstevel@tonic-gate 	 * Expecting a closed string.  This means that the input
9377c478bd9Sstevel@tonic-gate 	 * string must exactly match one of the strings passed in
9387c478bd9Sstevel@tonic-gate 	 * as the parameter.
9397c478bd9Sstevel@tonic-gate 	 */
9407c478bd9Sstevel@tonic-gate 	case FIO_CSTR:
9417c478bd9Sstevel@tonic-gate 		/*
9427c478bd9Sstevel@tonic-gate 		 * The parameter is a null terminated array of character
9437c478bd9Sstevel@tonic-gate 		 * pointers, each one pointing to a legal input string.
9447c478bd9Sstevel@tonic-gate 		 */
9457c478bd9Sstevel@tonic-gate 		strings = (char **)param->io_charlist;
9467c478bd9Sstevel@tonic-gate 		/*
9477c478bd9Sstevel@tonic-gate 		 * Walk through the legal strings, seeing if any of them
9487c478bd9Sstevel@tonic-gate 		 * match the token.  If a match is made, return the index
9497c478bd9Sstevel@tonic-gate 		 * of the string that was matched.
9507c478bd9Sstevel@tonic-gate 		 */
9517c478bd9Sstevel@tonic-gate 		for (str = strings; *str != NULL; str++)
9527c478bd9Sstevel@tonic-gate 			if (strcmp(cleantoken, *str) == 0)
9537c478bd9Sstevel@tonic-gate 				return (str - strings);
9547c478bd9Sstevel@tonic-gate 		/*
9557c478bd9Sstevel@tonic-gate 		 * Print help message if required.
9567c478bd9Sstevel@tonic-gate 		 */
9577c478bd9Sstevel@tonic-gate 		if (help) {
9587c478bd9Sstevel@tonic-gate 			print_input_choices(type, param);
9597c478bd9Sstevel@tonic-gate 		} else {
9607c478bd9Sstevel@tonic-gate 			err_print("`%s' is not expected.\n", cleantoken);
9617c478bd9Sstevel@tonic-gate 		}
9627c478bd9Sstevel@tonic-gate 		break;
9637c478bd9Sstevel@tonic-gate 	/*
9647c478bd9Sstevel@tonic-gate 	 * Expecting a matched string.  This means that the input
9657c478bd9Sstevel@tonic-gate 	 * string must either match one of the strings passed in,
9667c478bd9Sstevel@tonic-gate 	 * or be a unique abbreviation of one of them.
9677c478bd9Sstevel@tonic-gate 	 */
9687c478bd9Sstevel@tonic-gate 	case FIO_MSTR:
9697c478bd9Sstevel@tonic-gate 		/*
9707c478bd9Sstevel@tonic-gate 		 * The parameter is a null terminated array of character
9717c478bd9Sstevel@tonic-gate 		 * pointers, each one pointing to a legal input string.
9727c478bd9Sstevel@tonic-gate 		 */
9737c478bd9Sstevel@tonic-gate 		strings = (char **)param->io_charlist;
9747c478bd9Sstevel@tonic-gate 		length = index = tied = 0;
9757c478bd9Sstevel@tonic-gate 		/*
9767c478bd9Sstevel@tonic-gate 		 * Loop through the legal input strings.
9777c478bd9Sstevel@tonic-gate 		 */
9787c478bd9Sstevel@tonic-gate 		for (str = strings; *str != NULL; str++) {
9797c478bd9Sstevel@tonic-gate 			/*
9807c478bd9Sstevel@tonic-gate 			 * See how many characters of the token match
9817c478bd9Sstevel@tonic-gate 			 * this legal string.
9827c478bd9Sstevel@tonic-gate 			 */
9837c478bd9Sstevel@tonic-gate 			i = strcnt(cleantoken, *str);
9847c478bd9Sstevel@tonic-gate 			/*
9857c478bd9Sstevel@tonic-gate 			 * If it's not the whole token, then it's not a match.
9867c478bd9Sstevel@tonic-gate 			 */
9877c478bd9Sstevel@tonic-gate 			if ((uint_t)i < strlen(cleantoken))
9887c478bd9Sstevel@tonic-gate 				continue;
9897c478bd9Sstevel@tonic-gate 			/*
9907c478bd9Sstevel@tonic-gate 			 * If it ties with another input, remember that.
9917c478bd9Sstevel@tonic-gate 			 */
9927c478bd9Sstevel@tonic-gate 			if (i == length)
9937c478bd9Sstevel@tonic-gate 				tied = 1;
9947c478bd9Sstevel@tonic-gate 			/*
9957c478bd9Sstevel@tonic-gate 			 * If it matches the most so far, record that.
9967c478bd9Sstevel@tonic-gate 			 */
9977c478bd9Sstevel@tonic-gate 			if (i > length) {
9987c478bd9Sstevel@tonic-gate 				index = str - strings;
9997c478bd9Sstevel@tonic-gate 				tied = 0;
10007c478bd9Sstevel@tonic-gate 				length = i;
10017c478bd9Sstevel@tonic-gate 			}
10027c478bd9Sstevel@tonic-gate 		}
10037c478bd9Sstevel@tonic-gate 		/*
10047c478bd9Sstevel@tonic-gate 		 * Print help message if required.
10057c478bd9Sstevel@tonic-gate 		 */
10067c478bd9Sstevel@tonic-gate 		if (length == 0) {
10077c478bd9Sstevel@tonic-gate 			if (help) {
10087c478bd9Sstevel@tonic-gate 				print_input_choices(type, param);
10097c478bd9Sstevel@tonic-gate 			} else {
10107c478bd9Sstevel@tonic-gate 				err_print("`%s' is not expected.\n",
10117c478bd9Sstevel@tonic-gate 				    cleantoken);
10127c478bd9Sstevel@tonic-gate 			}
10137c478bd9Sstevel@tonic-gate 			break;
10147c478bd9Sstevel@tonic-gate 		}
10157c478bd9Sstevel@tonic-gate 		/*
10167c478bd9Sstevel@tonic-gate 		 * If the abbreviation was non-unique, it's an error.
10177c478bd9Sstevel@tonic-gate 		 */
10187c478bd9Sstevel@tonic-gate 		if (tied) {
10197c478bd9Sstevel@tonic-gate 			err_print("`%s' is ambiguous.\n", cleantoken);
10207c478bd9Sstevel@tonic-gate 			break;
10217c478bd9Sstevel@tonic-gate 		}
10227c478bd9Sstevel@tonic-gate 		/*
10237c478bd9Sstevel@tonic-gate 		 * We matched one.  Return the index of the string we matched.
10247c478bd9Sstevel@tonic-gate 		 */
10257c478bd9Sstevel@tonic-gate 		return (index);
10267c478bd9Sstevel@tonic-gate 	/*
10277c478bd9Sstevel@tonic-gate 	 * Expecting an open string.  This means that any string is legal.
10287c478bd9Sstevel@tonic-gate 	 */
10297c478bd9Sstevel@tonic-gate 	case FIO_OSTR:
10307c478bd9Sstevel@tonic-gate 		/*
10317c478bd9Sstevel@tonic-gate 		 * Print a help message if required.
10327c478bd9Sstevel@tonic-gate 		 */
10337c478bd9Sstevel@tonic-gate 		if (help) {
10347c478bd9Sstevel@tonic-gate 			fmt_print("Expecting a string\n");
10357c478bd9Sstevel@tonic-gate 			break;
10367c478bd9Sstevel@tonic-gate 		}
10377c478bd9Sstevel@tonic-gate 		/*
10387c478bd9Sstevel@tonic-gate 		 * alloc a copy of the string and return it
10397c478bd9Sstevel@tonic-gate 		 */
10407c478bd9Sstevel@tonic-gate 		return ((int)alloc_string(token));
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 	/*
10437c478bd9Sstevel@tonic-gate 	 * Expecting a blank line.
10447c478bd9Sstevel@tonic-gate 	 */
10457c478bd9Sstevel@tonic-gate 	case FIO_BLNK:
10467c478bd9Sstevel@tonic-gate 		/*
10477c478bd9Sstevel@tonic-gate 		 * We are always in non-echo mode when we are inputting
10487c478bd9Sstevel@tonic-gate 		 * this type.  We echo the newline as a carriage return
10497c478bd9Sstevel@tonic-gate 		 * only so the prompt string will be covered over.
10507c478bd9Sstevel@tonic-gate 		 */
10517c478bd9Sstevel@tonic-gate 		nolog_print("\015");
10527c478bd9Sstevel@tonic-gate 		/*
10537c478bd9Sstevel@tonic-gate 		 * If we are logging, send a newline to the log file.
10547c478bd9Sstevel@tonic-gate 		 */
10557c478bd9Sstevel@tonic-gate 		if (log_file)
10567c478bd9Sstevel@tonic-gate 			log_print("\n");
10577c478bd9Sstevel@tonic-gate 		/*
10587c478bd9Sstevel@tonic-gate 		 * There is no value returned for this type.
10597c478bd9Sstevel@tonic-gate 		 */
10607c478bd9Sstevel@tonic-gate 		return (0);
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate 	/*
10637c478bd9Sstevel@tonic-gate 	 * Expecting one of the entries in a string list.
10647c478bd9Sstevel@tonic-gate 	 * Accept unique abbreviations.
10657c478bd9Sstevel@tonic-gate 	 * Return the value associated with the matched string.
10667c478bd9Sstevel@tonic-gate 	 */
10677c478bd9Sstevel@tonic-gate 	case FIO_SLIST:
10687c478bd9Sstevel@tonic-gate 		i = find_value((slist_t *)param->io_slist,
10697c478bd9Sstevel@tonic-gate 			cleantoken, &value);
10707c478bd9Sstevel@tonic-gate 		if (i == 1) {
10717c478bd9Sstevel@tonic-gate 			return (value);
10727c478bd9Sstevel@tonic-gate 		} else {
10737c478bd9Sstevel@tonic-gate 			/*
10747c478bd9Sstevel@tonic-gate 			 * Print help message if required.
10757c478bd9Sstevel@tonic-gate 			 */
10767c478bd9Sstevel@tonic-gate 
10777c478bd9Sstevel@tonic-gate 			if (help) {
10787c478bd9Sstevel@tonic-gate 				print_input_choices(type, param);
10797c478bd9Sstevel@tonic-gate 			} else {
10807c478bd9Sstevel@tonic-gate 				if (i == 0)
10817c478bd9Sstevel@tonic-gate 					err_print("`%s' not expected.\n",
10827c478bd9Sstevel@tonic-gate 					    cleantoken);
10837c478bd9Sstevel@tonic-gate 				else
10847c478bd9Sstevel@tonic-gate 					err_print("`%s' is ambiguous.\n",
10857c478bd9Sstevel@tonic-gate 					    cleantoken);
10867c478bd9Sstevel@tonic-gate 			}
10877c478bd9Sstevel@tonic-gate 		}
10887c478bd9Sstevel@tonic-gate 		break;
10897c478bd9Sstevel@tonic-gate 
10907c478bd9Sstevel@tonic-gate 	/*
10917c478bd9Sstevel@tonic-gate 	 * Cylinder size input when modifying a complete partition map
10927c478bd9Sstevel@tonic-gate 	 */
10937c478bd9Sstevel@tonic-gate 	case FIO_CYL:
10947c478bd9Sstevel@tonic-gate 		/*
10957c478bd9Sstevel@tonic-gate 		 * Parameter is the bounds of legal block numbers.
10967c478bd9Sstevel@tonic-gate 		 */
10977c478bd9Sstevel@tonic-gate 		bounds = (struct bounds *)&param->io_bounds;
10987c478bd9Sstevel@tonic-gate 		assert(bounds->lower == 0);
10997c478bd9Sstevel@tonic-gate 		/*
11007c478bd9Sstevel@tonic-gate 		 * Print help message if required.
11017c478bd9Sstevel@tonic-gate 		 */
11027c478bd9Sstevel@tonic-gate 		if (help) {
11037c478bd9Sstevel@tonic-gate 			fmt_print("Expecting up to %llu blocks,",
11047c478bd9Sstevel@tonic-gate 			    bounds->upper);
1105342440ecSPrasad Singamsetty 			fmt_print(" %u cylinders, ", bn2c(bounds->upper));
11067c478bd9Sstevel@tonic-gate 			fmt_print(" %1.2f megabytes, ", bn2mb(bounds->upper));
11077c478bd9Sstevel@tonic-gate 			fmt_print("or %1.2f gigabytes\n", bn2gb(bounds->upper));
11087c478bd9Sstevel@tonic-gate 			break;
11097c478bd9Sstevel@tonic-gate 		}
11107c478bd9Sstevel@tonic-gate 		/*
11117c478bd9Sstevel@tonic-gate 		 * Parse the first token: try to find 'b', 'c' or 'm'
11127c478bd9Sstevel@tonic-gate 		 */
11137c478bd9Sstevel@tonic-gate 		s = cleantoken;
11147c478bd9Sstevel@tonic-gate 		while (*s && (isdigit(*s) || (*s == '.') || (*s == '$'))) {
11157c478bd9Sstevel@tonic-gate 			s++;
11167c478bd9Sstevel@tonic-gate 		}
11177c478bd9Sstevel@tonic-gate 		/*
11187c478bd9Sstevel@tonic-gate 		 * If we found a conversion specifier, second token is unused
11197c478bd9Sstevel@tonic-gate 		 * Otherwise, the second token should supply it.
11207c478bd9Sstevel@tonic-gate 		 */
11217c478bd9Sstevel@tonic-gate 		if (*s != 0) {
11227c478bd9Sstevel@tonic-gate 			value = *s;
11237c478bd9Sstevel@tonic-gate 			*s = 0;
11247c478bd9Sstevel@tonic-gate 		} else {
11257c478bd9Sstevel@tonic-gate 			value = cleantoken2[0];
11267c478bd9Sstevel@tonic-gate 		}
11277c478bd9Sstevel@tonic-gate 		/*
11287c478bd9Sstevel@tonic-gate 		 * If the token is the wild card, simply supply the max
11297c478bd9Sstevel@tonic-gate 		 * This order allows the user to specify the maximum in
11307c478bd9Sstevel@tonic-gate 		 * either blocks/cyls/megabytes - a convenient fiction.
11317c478bd9Sstevel@tonic-gate 		 */
11327c478bd9Sstevel@tonic-gate 		if (strcmp(cleantoken, WILD_STRING) == 0) {
11337c478bd9Sstevel@tonic-gate 			return (bounds->upper);
11347c478bd9Sstevel@tonic-gate 		}
11357c478bd9Sstevel@tonic-gate 		/*
11367c478bd9Sstevel@tonic-gate 		 * Allow the user to specify zero with no units,
11377c478bd9Sstevel@tonic-gate 		 * by just defaulting to cylinders.
11387c478bd9Sstevel@tonic-gate 		 */
11397c478bd9Sstevel@tonic-gate 		if (strcmp(cleantoken, "0") == 0) {
11407c478bd9Sstevel@tonic-gate 			value = 'c';
11417c478bd9Sstevel@tonic-gate 		}
11427c478bd9Sstevel@tonic-gate 		/*
11437c478bd9Sstevel@tonic-gate 		 * If there's a decimal point, but no unit specification,
11447c478bd9Sstevel@tonic-gate 		 * let's assume megabytes.
11457c478bd9Sstevel@tonic-gate 		 */
11467c478bd9Sstevel@tonic-gate 		if ((value == 0) && (strchr(cleantoken, '.') != NULL)) {
11477c478bd9Sstevel@tonic-gate 			value = 'm';
11487c478bd9Sstevel@tonic-gate 		}
11497c478bd9Sstevel@tonic-gate 		/*
11507c478bd9Sstevel@tonic-gate 		 * Handle each unit type we support
11517c478bd9Sstevel@tonic-gate 		 */
11527c478bd9Sstevel@tonic-gate 		switch (value) {
11537c478bd9Sstevel@tonic-gate 		case 'b':
11547c478bd9Sstevel@tonic-gate 			/*
11557c478bd9Sstevel@tonic-gate 			 * Convert token to a disk block number.
11567c478bd9Sstevel@tonic-gate 			 */
1157342440ecSPrasad Singamsetty 			if (geti64(cleantoken, &bn64, &bounds->upper))
11587c478bd9Sstevel@tonic-gate 				break;
11597c478bd9Sstevel@tonic-gate 			/*
11607c478bd9Sstevel@tonic-gate 			 * Check to be sure it is within the legal bounds.
11617c478bd9Sstevel@tonic-gate 			 */
1162342440ecSPrasad Singamsetty 			if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) {
11637c478bd9Sstevel@tonic-gate 				err_print(
1164342440ecSPrasad Singamsetty 				    "`%llub' is out of the range %llu "
1165342440ecSPrasad Singamsetty 				    "to %llu\n",
1166342440ecSPrasad Singamsetty 				    bn64, bounds->lower, bounds->upper);
11677c478bd9Sstevel@tonic-gate 				break;
11687c478bd9Sstevel@tonic-gate 			}
11697c478bd9Sstevel@tonic-gate 			/*
11707c478bd9Sstevel@tonic-gate 			 * Verify the block lies on a cylinder boundary
11717c478bd9Sstevel@tonic-gate 			 */
1172342440ecSPrasad Singamsetty 			if ((bn64 % spc()) != 0) {
11737c478bd9Sstevel@tonic-gate 				err_print(
1174342440ecSPrasad Singamsetty 				    "partition size must be a multiple of "
1175342440ecSPrasad Singamsetty 				    "%u blocks to lie on a cylinder boundary\n",
11767c478bd9Sstevel@tonic-gate 				    spc());
11777c478bd9Sstevel@tonic-gate 				err_print(
1178342440ecSPrasad Singamsetty 				    "%llu blocks is approximately %u cylinders,"
1179342440ecSPrasad Singamsetty 				    " %1.2f megabytes or %1.2f gigabytes\n",
1180342440ecSPrasad Singamsetty 				    bn64, bn2c(bn64), bn2mb(bn64), bn2gb(bn64));
11817c478bd9Sstevel@tonic-gate 				break;
11827c478bd9Sstevel@tonic-gate 			}
1183342440ecSPrasad Singamsetty 			return (bn64);
11847c478bd9Sstevel@tonic-gate 		case 'c':
11857c478bd9Sstevel@tonic-gate 			/*
11867c478bd9Sstevel@tonic-gate 			 * Convert token from a number of cylinders to
11877c478bd9Sstevel@tonic-gate 			 * a number of blocks.
11887c478bd9Sstevel@tonic-gate 			 */
11897c478bd9Sstevel@tonic-gate 			i = bn2c(bounds->upper);
11907c478bd9Sstevel@tonic-gate 			if (geti(cleantoken, &cyls, &i))
11917c478bd9Sstevel@tonic-gate 				break;
11927c478bd9Sstevel@tonic-gate 			/*
11937c478bd9Sstevel@tonic-gate 			 * Check the bounds - cyls is number of cylinders
11947c478bd9Sstevel@tonic-gate 			 */
11957c478bd9Sstevel@tonic-gate 			if (cyls > (bounds->upper/spc())) {
11967c478bd9Sstevel@tonic-gate 				err_print("`%dc' is out of range\n", cyls);
11977c478bd9Sstevel@tonic-gate 				break;
11987c478bd9Sstevel@tonic-gate 			}
11997c478bd9Sstevel@tonic-gate 			/*
12007c478bd9Sstevel@tonic-gate 			 * Convert cylinders to blocks and return
12017c478bd9Sstevel@tonic-gate 			 */
12027c478bd9Sstevel@tonic-gate 			return (cyls * spc());
12037c478bd9Sstevel@tonic-gate 		case 'm':
12047c478bd9Sstevel@tonic-gate 			/*
12057c478bd9Sstevel@tonic-gate 			 * Convert token from megabytes to a block number.
12067c478bd9Sstevel@tonic-gate 			 */
1207b519f838Sbz211116 			if (sscanf(cleantoken, "%f2", &nmegs) != 1) {
12087c478bd9Sstevel@tonic-gate 				err_print("`%s' is not recognized\n",
12097c478bd9Sstevel@tonic-gate 				    cleantoken);
12107c478bd9Sstevel@tonic-gate 				break;
12117c478bd9Sstevel@tonic-gate 			}
12127c478bd9Sstevel@tonic-gate 			/*
12137c478bd9Sstevel@tonic-gate 			 * Check the bounds
12147c478bd9Sstevel@tonic-gate 			 */
12157c478bd9Sstevel@tonic-gate 			if (nmegs > bn2mb(bounds->upper)) {
12167c478bd9Sstevel@tonic-gate 				err_print("`%1.2fmb' is out of range\n", nmegs);
12177c478bd9Sstevel@tonic-gate 				break;
12187c478bd9Sstevel@tonic-gate 			}
12197c478bd9Sstevel@tonic-gate 			/*
12207c478bd9Sstevel@tonic-gate 			 * Convert to blocks
12217c478bd9Sstevel@tonic-gate 			 */
1222342440ecSPrasad Singamsetty 			bn64 = mb2bn(nmegs);
12237c478bd9Sstevel@tonic-gate 			/*
12247c478bd9Sstevel@tonic-gate 			 * Round value up to nearest cylinder
12257c478bd9Sstevel@tonic-gate 			 */
12267c478bd9Sstevel@tonic-gate 			i = spc();
1227342440ecSPrasad Singamsetty 			bn64 = ((bn64 + (i-1)) / i) * i;
1228342440ecSPrasad Singamsetty 			return (bn64);
12297c478bd9Sstevel@tonic-gate 		case 'g':
12307c478bd9Sstevel@tonic-gate 			/*
12317c478bd9Sstevel@tonic-gate 			 * Convert token from gigabytes to a block number.
12327c478bd9Sstevel@tonic-gate 			 */
1233b519f838Sbz211116 			if (sscanf(cleantoken, "%f2", &ngigs) != 1) {
12347c478bd9Sstevel@tonic-gate 				err_print("`%s' is not recognized\n",
12357c478bd9Sstevel@tonic-gate 				    cleantoken);
12367c478bd9Sstevel@tonic-gate 				break;
12377c478bd9Sstevel@tonic-gate 			}
12387c478bd9Sstevel@tonic-gate 			/*
12397c478bd9Sstevel@tonic-gate 			 * Check the bounds
12407c478bd9Sstevel@tonic-gate 			 */
12417c478bd9Sstevel@tonic-gate 			if (ngigs > bn2gb(bounds->upper)) {
12427c478bd9Sstevel@tonic-gate 				err_print("`%1.2fgb' is out of range\n", ngigs);
12437c478bd9Sstevel@tonic-gate 				break;
12447c478bd9Sstevel@tonic-gate 			}
12457c478bd9Sstevel@tonic-gate 			/*
12467c478bd9Sstevel@tonic-gate 			 * Convert to blocks
12477c478bd9Sstevel@tonic-gate 			 */
1248342440ecSPrasad Singamsetty 			bn64 = gb2bn(ngigs);
12497c478bd9Sstevel@tonic-gate 			/*
12507c478bd9Sstevel@tonic-gate 			 * Round value up to nearest cylinder
12517c478bd9Sstevel@tonic-gate 			 */
12527c478bd9Sstevel@tonic-gate 			i = spc();
1253342440ecSPrasad Singamsetty 			bn64 = ((bn64 + (i-1)) / i) * i;
1254342440ecSPrasad Singamsetty 			return (bn64);
12557c478bd9Sstevel@tonic-gate 		default:
12567c478bd9Sstevel@tonic-gate 			err_print(
12577c478bd9Sstevel@tonic-gate "Please specify units in either b(blocks), c(cylinders), m(megabytes) \
12587c478bd9Sstevel@tonic-gate or g(gigabytes)\n");
12597c478bd9Sstevel@tonic-gate 			break;
12607c478bd9Sstevel@tonic-gate 		}
12617c478bd9Sstevel@tonic-gate 		break;
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate 	case FIO_ECYL:
12647c478bd9Sstevel@tonic-gate 		/*
12657c478bd9Sstevel@tonic-gate 		 * Parameter is the bounds of legal block numbers.
12667c478bd9Sstevel@tonic-gate 		 */
12677c478bd9Sstevel@tonic-gate 		bounds = (struct bounds *)&param->io_bounds;
12687c478bd9Sstevel@tonic-gate 		assert(bounds->lower == 0);
12697c478bd9Sstevel@tonic-gate 
12707c478bd9Sstevel@tonic-gate 		/*
12717c478bd9Sstevel@tonic-gate 		 * Print help message if required.
12727c478bd9Sstevel@tonic-gate 		 */
12737c478bd9Sstevel@tonic-gate 		if (help) {
12747c478bd9Sstevel@tonic-gate 			fmt_print("Expecting up to %llu blocks,",
12757c478bd9Sstevel@tonic-gate 			    bounds->upper);
1276342440ecSPrasad Singamsetty 			fmt_print(" %u cylinders, ",
12777c478bd9Sstevel@tonic-gate 			    bn2c(bounds->upper));
1278342440ecSPrasad Singamsetty 			fmt_print(" %u end cylinder, ",
1279342440ecSPrasad Singamsetty 			    (uint_t)(bounds->upper / spc()));
12807c478bd9Sstevel@tonic-gate 			fmt_print(" %1.2f megabytes, ",
12817c478bd9Sstevel@tonic-gate 			    bn2mb(bounds->upper));
12827c478bd9Sstevel@tonic-gate 			fmt_print("or %1.2f gigabytes\n",
12837c478bd9Sstevel@tonic-gate 			    bn2gb(bounds->upper));
12847c478bd9Sstevel@tonic-gate 			break;
12857c478bd9Sstevel@tonic-gate 		}
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 		/*
12887c478bd9Sstevel@tonic-gate 		 * Parse the first token: try to find 'b', 'c', 'e'
12897c478bd9Sstevel@tonic-gate 		 * or 'm'
12907c478bd9Sstevel@tonic-gate 		 */
12917c478bd9Sstevel@tonic-gate 		s = cleantoken;
12927c478bd9Sstevel@tonic-gate 		while (*s && (isdigit(*s) || (*s == '.') || (*s == '$'))) {
12937c478bd9Sstevel@tonic-gate 			s++;
12947c478bd9Sstevel@tonic-gate 		}
12957c478bd9Sstevel@tonic-gate 
12967c478bd9Sstevel@tonic-gate 		/*
12977c478bd9Sstevel@tonic-gate 		 * If we found a conversion specifier, second token is
12987c478bd9Sstevel@tonic-gate 		 * unused Otherwise, the second token should supply it.
12997c478bd9Sstevel@tonic-gate 		 */
13007c478bd9Sstevel@tonic-gate 		if (*s != 0) {
13017c478bd9Sstevel@tonic-gate 			value = *s;
13027c478bd9Sstevel@tonic-gate 			*s = 0;
13037c478bd9Sstevel@tonic-gate 		} else {
13047c478bd9Sstevel@tonic-gate 			value = cleantoken2[0];
13057c478bd9Sstevel@tonic-gate 		}
13067c478bd9Sstevel@tonic-gate 
13077c478bd9Sstevel@tonic-gate 		/*
13087c478bd9Sstevel@tonic-gate 		 * If the token is the wild card, simply supply the max
13097c478bd9Sstevel@tonic-gate 		 * This order allows the user to specify the maximum in
13107c478bd9Sstevel@tonic-gate 		 * either blocks/cyls/megabytes - a convenient fiction.
13117c478bd9Sstevel@tonic-gate 		 */
13127c478bd9Sstevel@tonic-gate 		if (strcmp(cleantoken, WILD_STRING) == 0) {
13137c478bd9Sstevel@tonic-gate 			return (bounds->upper);
13147c478bd9Sstevel@tonic-gate 		}
13157c478bd9Sstevel@tonic-gate 
13167c478bd9Sstevel@tonic-gate 		/*
13177c478bd9Sstevel@tonic-gate 		 * Allow the user to specify zero with no units,
13187c478bd9Sstevel@tonic-gate 		 * by just defaulting to cylinders.
13197c478bd9Sstevel@tonic-gate 		 */
13207c478bd9Sstevel@tonic-gate 
13217c478bd9Sstevel@tonic-gate 		if (value != 'e' && strcmp(cleantoken, "0") == 0) {
13227c478bd9Sstevel@tonic-gate 			value = 'c';
13237c478bd9Sstevel@tonic-gate 		}
13247c478bd9Sstevel@tonic-gate 
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 		/*
13277c478bd9Sstevel@tonic-gate 		 * If there's a decimal point, but no unit
13287c478bd9Sstevel@tonic-gate 		 * specification, let's assume megabytes.
13297c478bd9Sstevel@tonic-gate 		 */
13307c478bd9Sstevel@tonic-gate 		if ((value == 0) && (strchr(cleantoken, '.') != NULL)) {
13317c478bd9Sstevel@tonic-gate 			value = 'm';
13327c478bd9Sstevel@tonic-gate 		}
13337c478bd9Sstevel@tonic-gate 
13347c478bd9Sstevel@tonic-gate 		/*
13357c478bd9Sstevel@tonic-gate 		 * Handle each unit type we support
13367c478bd9Sstevel@tonic-gate 		 */
13377c478bd9Sstevel@tonic-gate 		switch (value) {
13387c478bd9Sstevel@tonic-gate 		case 'b':
13397c478bd9Sstevel@tonic-gate 			/*
13407c478bd9Sstevel@tonic-gate 			 * Convert token to a disk block number.
13417c478bd9Sstevel@tonic-gate 			 */
1342342440ecSPrasad Singamsetty 			if (geti64(cleantoken, &bn64, &bounds->upper))
13437c478bd9Sstevel@tonic-gate 				break;
13447c478bd9Sstevel@tonic-gate 			/*
13457c478bd9Sstevel@tonic-gate 			 * Check to be sure it is within the
13467c478bd9Sstevel@tonic-gate 			 * legal bounds.
13477c478bd9Sstevel@tonic-gate 			 */
1348342440ecSPrasad Singamsetty 			if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) {
13497c478bd9Sstevel@tonic-gate 				err_print(
1350342440ecSPrasad Singamsetty "`%llub' is out of the range %llu to %llu\n",
1351342440ecSPrasad Singamsetty 				    bn64, bounds->lower, bounds->upper);
13527c478bd9Sstevel@tonic-gate 				break;
13537c478bd9Sstevel@tonic-gate 			}
13547c478bd9Sstevel@tonic-gate 
13557c478bd9Sstevel@tonic-gate 			/*
13567c478bd9Sstevel@tonic-gate 			 * Verify the block lies on a cylinder
13577c478bd9Sstevel@tonic-gate 			 * boundary
13587c478bd9Sstevel@tonic-gate 			 */
1359342440ecSPrasad Singamsetty 			if ((bn64 % spc()) != 0) {
13607c478bd9Sstevel@tonic-gate 				err_print(
1361342440ecSPrasad Singamsetty 				    "partition size must be a multiple of %u "
1362342440ecSPrasad Singamsetty 				    "blocks to lie on a cylinder boundary\n",
13637c478bd9Sstevel@tonic-gate 				    spc());
13647c478bd9Sstevel@tonic-gate 				err_print(
1365342440ecSPrasad Singamsetty 				    "%llu blocks is approximately %u cylinders,"
1366342440ecSPrasad Singamsetty 				    " %1.2f megabytes or %1.2f gigabytes\n",
1367342440ecSPrasad Singamsetty 				    bn64, bn2c(bn64), bn2mb(bn64), bn2gb(bn64));
13687c478bd9Sstevel@tonic-gate 				break;
13697c478bd9Sstevel@tonic-gate 			}
13707c478bd9Sstevel@tonic-gate 
1371342440ecSPrasad Singamsetty 			return (bn64);
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate 		case 'e':
13747c478bd9Sstevel@tonic-gate 			/*
13757c478bd9Sstevel@tonic-gate 			 * Token is ending cylinder
13767c478bd9Sstevel@tonic-gate 			 */
13777c478bd9Sstevel@tonic-gate 
13787c478bd9Sstevel@tonic-gate 			/* convert token to integer */
13797c478bd9Sstevel@tonic-gate 			if (geti(cleantoken, &cylno, (int *)NULL)) {
13807c478bd9Sstevel@tonic-gate 				break;
13817c478bd9Sstevel@tonic-gate 			}
13827c478bd9Sstevel@tonic-gate 
13837c478bd9Sstevel@tonic-gate 			/*
13847c478bd9Sstevel@tonic-gate 			 * check that input cylno isn't before the current
13857c478bd9Sstevel@tonic-gate 			 * starting cylinder number.  Note that we are NOT
13867c478bd9Sstevel@tonic-gate 			 * using the starting cylinder from
13877c478bd9Sstevel@tonic-gate 			 * cur_parts->pinfo_map[].dkl_cylno!
13887c478bd9Sstevel@tonic-gate 			 */
13897c478bd9Sstevel@tonic-gate 			if (cylno < part_deflt->start_cyl) {
13907c478bd9Sstevel@tonic-gate 				err_print(
1391342440ecSPrasad Singamsetty "End cylinder must fall on or after start cylinder %u\n",
13927c478bd9Sstevel@tonic-gate 				    part_deflt->start_cyl);
13937c478bd9Sstevel@tonic-gate 				break;
13947c478bd9Sstevel@tonic-gate 			}
13957c478bd9Sstevel@tonic-gate 
13967c478bd9Sstevel@tonic-gate 			/*
13977c478bd9Sstevel@tonic-gate 			 * calculate cylinder number of upper boundary, and
13987c478bd9Sstevel@tonic-gate 			 * verify that our input is within range
13997c478bd9Sstevel@tonic-gate 			 */
14007c478bd9Sstevel@tonic-gate 			i = (bn2c(bounds->upper) + part_deflt->start_cyl - 1);
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate 			if (cylno > i) {
14037c478bd9Sstevel@tonic-gate 				err_print(
14047c478bd9Sstevel@tonic-gate "End cylinder %d is beyond max cylinder %d\n",
14057c478bd9Sstevel@tonic-gate 				    cylno, i);
14067c478bd9Sstevel@tonic-gate 				break;
14077c478bd9Sstevel@tonic-gate 			}
14087c478bd9Sstevel@tonic-gate 
14097c478bd9Sstevel@tonic-gate 			/*
14107c478bd9Sstevel@tonic-gate 			 * calculate number of cylinders based on input
14117c478bd9Sstevel@tonic-gate 			 */
14127c478bd9Sstevel@tonic-gate 			cyls = ((cylno - part_deflt->start_cyl) + 1);
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate 			return (cyls * spc());
14157c478bd9Sstevel@tonic-gate 
14167c478bd9Sstevel@tonic-gate 		case 'c':
14177c478bd9Sstevel@tonic-gate 			/*
14187c478bd9Sstevel@tonic-gate 			 * Convert token from a number of
14197c478bd9Sstevel@tonic-gate 			 * cylinders to a number of blocks.
14207c478bd9Sstevel@tonic-gate 			 */
14217c478bd9Sstevel@tonic-gate 			i = bn2c(bounds->upper);
14227c478bd9Sstevel@tonic-gate 			if (geti(cleantoken, &cyls, &i))
14237c478bd9Sstevel@tonic-gate 				break;
14247c478bd9Sstevel@tonic-gate 
14257c478bd9Sstevel@tonic-gate 			/*
14267c478bd9Sstevel@tonic-gate 			 * Check the bounds - cyls is number of
14277c478bd9Sstevel@tonic-gate 			 * cylinders
14287c478bd9Sstevel@tonic-gate 			 */
14297c478bd9Sstevel@tonic-gate 			if (cyls > (bounds->upper/spc())) {
14307c478bd9Sstevel@tonic-gate 				err_print("`%dc' is out of range\n", cyls);
14317c478bd9Sstevel@tonic-gate 				break;
14327c478bd9Sstevel@tonic-gate 			}
14337c478bd9Sstevel@tonic-gate 
14347c478bd9Sstevel@tonic-gate 			/*
14357c478bd9Sstevel@tonic-gate 			 * Convert cylinders to blocks and
14367c478bd9Sstevel@tonic-gate 			 * return
14377c478bd9Sstevel@tonic-gate 			 */
14387c478bd9Sstevel@tonic-gate 			return (cyls * spc());
14397c478bd9Sstevel@tonic-gate 
14407c478bd9Sstevel@tonic-gate 		case 'm':
14417c478bd9Sstevel@tonic-gate 			/*
14427c478bd9Sstevel@tonic-gate 			 * Convert token from megabytes to a
14437c478bd9Sstevel@tonic-gate 			 * block number.
14447c478bd9Sstevel@tonic-gate 			 */
1445b519f838Sbz211116 			if (sscanf(cleantoken, "%f2", &nmegs) != 1) {
14467c478bd9Sstevel@tonic-gate 				err_print("`%s' is not recognized\n",
14477c478bd9Sstevel@tonic-gate 				    cleantoken);
14487c478bd9Sstevel@tonic-gate 				break;
14497c478bd9Sstevel@tonic-gate 			}
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate 			/*
14527c478bd9Sstevel@tonic-gate 			 * Check the bounds
14537c478bd9Sstevel@tonic-gate 			 */
14547c478bd9Sstevel@tonic-gate 			if (nmegs > bn2mb(bounds->upper)) {
14557c478bd9Sstevel@tonic-gate 				err_print("`%1.2fmb' is out of range\n", nmegs);
14567c478bd9Sstevel@tonic-gate 				break;
14577c478bd9Sstevel@tonic-gate 			}
14587c478bd9Sstevel@tonic-gate 
14597c478bd9Sstevel@tonic-gate 			/*
14607c478bd9Sstevel@tonic-gate 			 * Convert to blocks
14617c478bd9Sstevel@tonic-gate 			 */
1462342440ecSPrasad Singamsetty 			bn64 = mb2bn(nmegs);
14637c478bd9Sstevel@tonic-gate 
14647c478bd9Sstevel@tonic-gate 			/*
14657c478bd9Sstevel@tonic-gate 			 * Round value up to nearest cylinder
14667c478bd9Sstevel@tonic-gate 			 */
14677c478bd9Sstevel@tonic-gate 			i = spc();
1468342440ecSPrasad Singamsetty 			bn64 = ((bn64 + (i-1)) / i) * i;
1469342440ecSPrasad Singamsetty 			return (bn64);
14707c478bd9Sstevel@tonic-gate 
14717c478bd9Sstevel@tonic-gate 		case 'g':
14727c478bd9Sstevel@tonic-gate 			/*
14737c478bd9Sstevel@tonic-gate 			 * Convert token from gigabytes to a
14747c478bd9Sstevel@tonic-gate 			 * block number.
14757c478bd9Sstevel@tonic-gate 			 */
1476b519f838Sbz211116 			if (sscanf(cleantoken, "%f2", &ngigs) != 1) {
14777c478bd9Sstevel@tonic-gate 				err_print("`%s' is not recognized\n",
14787c478bd9Sstevel@tonic-gate 				    cleantoken);
14797c478bd9Sstevel@tonic-gate 				break;
14807c478bd9Sstevel@tonic-gate 			}
14817c478bd9Sstevel@tonic-gate 
14827c478bd9Sstevel@tonic-gate 			/*
14837c478bd9Sstevel@tonic-gate 			 * Check the bounds
14847c478bd9Sstevel@tonic-gate 			 */
14857c478bd9Sstevel@tonic-gate 			if (ngigs > bn2gb(bounds->upper)) {
14867c478bd9Sstevel@tonic-gate 				err_print("`%1.2fgb' is out of range\n", ngigs);
14877c478bd9Sstevel@tonic-gate 				break;
14887c478bd9Sstevel@tonic-gate 			}
14897c478bd9Sstevel@tonic-gate 
14907c478bd9Sstevel@tonic-gate 			/*
14917c478bd9Sstevel@tonic-gate 			 * Convert to blocks
14927c478bd9Sstevel@tonic-gate 			 */
1493342440ecSPrasad Singamsetty 			bn64 = gb2bn(ngigs);
14947c478bd9Sstevel@tonic-gate 
14957c478bd9Sstevel@tonic-gate 			/*
14967c478bd9Sstevel@tonic-gate 			 * Round value up to nearest cylinder
14977c478bd9Sstevel@tonic-gate 			 */
14987c478bd9Sstevel@tonic-gate 			i = spc();
1499342440ecSPrasad Singamsetty 			bn64 = ((bn64 + (i-1)) / i) * i;
1500342440ecSPrasad Singamsetty 			return (bn64);
15017c478bd9Sstevel@tonic-gate 
15027c478bd9Sstevel@tonic-gate 		default:
15037c478bd9Sstevel@tonic-gate 			err_print(
15047c478bd9Sstevel@tonic-gate "Please specify units in either b(blocks), c(cylinders), e(end cylinder),\n");
15057c478bd9Sstevel@tonic-gate 			err_print("m(megabytes) or g(gigabytes)\n");
15067c478bd9Sstevel@tonic-gate 			break;
15077c478bd9Sstevel@tonic-gate 		}
15087c478bd9Sstevel@tonic-gate 		break;
15097c478bd9Sstevel@tonic-gate 	case FIO_EFI:
15107c478bd9Sstevel@tonic-gate 		/*
15117c478bd9Sstevel@tonic-gate 		 * Parameter is the bounds of legal block numbers.
15127c478bd9Sstevel@tonic-gate 		 */
15137c478bd9Sstevel@tonic-gate 		bounds = (struct bounds *)&param->io_bounds;
15147c478bd9Sstevel@tonic-gate 
15157c478bd9Sstevel@tonic-gate 		/*
15167c478bd9Sstevel@tonic-gate 		 * Print help message if required.
15177c478bd9Sstevel@tonic-gate 		 */
15187c478bd9Sstevel@tonic-gate 		if (help) {
15197c478bd9Sstevel@tonic-gate 			fmt_print("Expecting up to %llu sectors,",
15207c478bd9Sstevel@tonic-gate 			    cur_parts->etoc->efi_last_u_lba);
15217c478bd9Sstevel@tonic-gate 			fmt_print("or %llu megabytes,",
152265908c77Syu, larry liu - Sun Microsystems - Beijing China 			    (cur_parts->etoc->efi_last_u_lba * cur_blksz)/
15237c478bd9Sstevel@tonic-gate 				(1024 * 1024));
15247c478bd9Sstevel@tonic-gate 			fmt_print("or %llu gigabytes\n",
152565908c77Syu, larry liu - Sun Microsystems - Beijing China 			    (cur_parts->etoc->efi_last_u_lba * cur_blksz)/
15267c478bd9Sstevel@tonic-gate 				(1024 * 1024 * 1024));
15277c478bd9Sstevel@tonic-gate 			fmt_print("or %llu terabytes\n",
152865908c77Syu, larry liu - Sun Microsystems - Beijing China 			    (cur_parts->etoc->efi_last_u_lba * cur_blksz)/
15297c478bd9Sstevel@tonic-gate 				((uint64_t)1024 * 1024 * 1024 * 1024));
15307c478bd9Sstevel@tonic-gate 			break;
15317c478bd9Sstevel@tonic-gate 		}
15327c478bd9Sstevel@tonic-gate 
15337c478bd9Sstevel@tonic-gate 		/*
15347c478bd9Sstevel@tonic-gate 		 * Parse the first token: try to find 'b', 'c', 'e'
15357c478bd9Sstevel@tonic-gate 		 * or 'm'
15367c478bd9Sstevel@tonic-gate 		 */
15377c478bd9Sstevel@tonic-gate 		s = cleantoken;
15387c478bd9Sstevel@tonic-gate 		while (*s && (isdigit(*s) || (*s == '.') || (*s == '$'))) {
15397c478bd9Sstevel@tonic-gate 			s++;
15407c478bd9Sstevel@tonic-gate 		}
15417c478bd9Sstevel@tonic-gate 
15427c478bd9Sstevel@tonic-gate 		/*
15437c478bd9Sstevel@tonic-gate 		 * If we found a conversion specifier, second token is
15447c478bd9Sstevel@tonic-gate 		 * unused Otherwise, the second token should supply it.
15457c478bd9Sstevel@tonic-gate 		 */
15467c478bd9Sstevel@tonic-gate 		if (*s != 0) {
15477c478bd9Sstevel@tonic-gate 			value = *s;
15487c478bd9Sstevel@tonic-gate 			*s = 0;
15497c478bd9Sstevel@tonic-gate 		} else {
15507c478bd9Sstevel@tonic-gate 			value = cleantoken2[0];
15517c478bd9Sstevel@tonic-gate 		}
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 		/*
15547c478bd9Sstevel@tonic-gate 		 * If the token is the wild card, simply supply the max
15557c478bd9Sstevel@tonic-gate 		 * This order allows the user to specify the maximum in
15567c478bd9Sstevel@tonic-gate 		 * either blocks/cyls/megabytes - a convenient fiction.
15577c478bd9Sstevel@tonic-gate 		 */
15587c478bd9Sstevel@tonic-gate 		if (strcmp(cleantoken, WILD_STRING) == 0) {
15597c478bd9Sstevel@tonic-gate 			return (bounds->upper - EFI_MIN_RESV_SIZE -
15607c478bd9Sstevel@tonic-gate 			    efi_deflt->start_sector);
15617c478bd9Sstevel@tonic-gate 		}
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate 		/*
15647c478bd9Sstevel@tonic-gate 		 * Allow the user to specify zero with no units,
15657c478bd9Sstevel@tonic-gate 		 * by just defaulting to sectors.
15667c478bd9Sstevel@tonic-gate 		 */
15677c478bd9Sstevel@tonic-gate 
15687c478bd9Sstevel@tonic-gate 		if (value != 'e' && strcmp(cleantoken, "0") == 0) {
15697c478bd9Sstevel@tonic-gate 			value = 'm';
15707c478bd9Sstevel@tonic-gate 		}
15717c478bd9Sstevel@tonic-gate 
15727c478bd9Sstevel@tonic-gate 
15737c478bd9Sstevel@tonic-gate 		/*
15747c478bd9Sstevel@tonic-gate 		 * If there's a decimal point, but no unit
15757c478bd9Sstevel@tonic-gate 		 * specification, let's assume megabytes.
15767c478bd9Sstevel@tonic-gate 		 */
15777c478bd9Sstevel@tonic-gate 		if ((value == 0) && (strchr(cleantoken, '.') != NULL)) {
15787c478bd9Sstevel@tonic-gate 			value = 'm';
15797c478bd9Sstevel@tonic-gate 		}
15807c478bd9Sstevel@tonic-gate 
15817c478bd9Sstevel@tonic-gate 		/*
15827c478bd9Sstevel@tonic-gate 		 * Handle each unit type we support
15837c478bd9Sstevel@tonic-gate 		 */
15847c478bd9Sstevel@tonic-gate 		switch (value) {
15857c478bd9Sstevel@tonic-gate 		case 'b':
15867c478bd9Sstevel@tonic-gate 			/*
15877c478bd9Sstevel@tonic-gate 			 * Token is number of blocks
15887c478bd9Sstevel@tonic-gate 			 */
15897c478bd9Sstevel@tonic-gate 			if (geti64(cleantoken, &blokno, (uint64_t *)NULL)) {
15907c478bd9Sstevel@tonic-gate 			    break;
15917c478bd9Sstevel@tonic-gate 			}
15927c478bd9Sstevel@tonic-gate 			if (blokno > bounds->upper) {
15937c478bd9Sstevel@tonic-gate 			    err_print(
15947c478bd9Sstevel@tonic-gate "Number of blocks must be less that the total available blocks.\n");
15957c478bd9Sstevel@tonic-gate 			    break;
15967c478bd9Sstevel@tonic-gate 			}
15977c478bd9Sstevel@tonic-gate 			return (blokno);
15987c478bd9Sstevel@tonic-gate 
15997c478bd9Sstevel@tonic-gate 		case 'e':
16007c478bd9Sstevel@tonic-gate 			/*
16017c478bd9Sstevel@tonic-gate 			 * Token is ending block number
16027c478bd9Sstevel@tonic-gate 			 */
16037c478bd9Sstevel@tonic-gate 
16047c478bd9Sstevel@tonic-gate 			/* convert token to integer */
16057c478bd9Sstevel@tonic-gate 			if (geti64(cleantoken, &blokno, (uint64_t *)NULL)) {
16067c478bd9Sstevel@tonic-gate 				break;
16077c478bd9Sstevel@tonic-gate 			}
16087c478bd9Sstevel@tonic-gate 
16097c478bd9Sstevel@tonic-gate 			/*
16107c478bd9Sstevel@tonic-gate 			 * Some sanity check
16117c478bd9Sstevel@tonic-gate 			 */
16127c478bd9Sstevel@tonic-gate 			if (blokno < efi_deflt->start_sector) {
16137c478bd9Sstevel@tonic-gate 				err_print(
16147c478bd9Sstevel@tonic-gate "End Sector must fall on or after start sector %llu\n",
16157c478bd9Sstevel@tonic-gate 				    efi_deflt->start_sector);
16167c478bd9Sstevel@tonic-gate 				break;
16177c478bd9Sstevel@tonic-gate 			}
16187c478bd9Sstevel@tonic-gate 
16197c478bd9Sstevel@tonic-gate 			/*
16207c478bd9Sstevel@tonic-gate 			 * verify that our input is within range
16217c478bd9Sstevel@tonic-gate 			 */
16227c478bd9Sstevel@tonic-gate 			if (blokno > cur_parts->etoc->efi_last_u_lba) {
16237c478bd9Sstevel@tonic-gate 				err_print(
16247c478bd9Sstevel@tonic-gate "End Sector %llu is beyond max Sector %llu\n",
16257c478bd9Sstevel@tonic-gate 				    blokno, cur_parts->etoc->efi_last_u_lba);
16267c478bd9Sstevel@tonic-gate 				break;
16277c478bd9Sstevel@tonic-gate 			}
16287c478bd9Sstevel@tonic-gate 
16297c478bd9Sstevel@tonic-gate 			/*
16307c478bd9Sstevel@tonic-gate 			 * calculate number of blocks based on input
16317c478bd9Sstevel@tonic-gate 			 */
16327c478bd9Sstevel@tonic-gate 
16337c478bd9Sstevel@tonic-gate 			return (blokno - efi_deflt->start_sector + 1);
16347c478bd9Sstevel@tonic-gate 
16357c478bd9Sstevel@tonic-gate 		case 'm':
16367c478bd9Sstevel@tonic-gate 			/*
16377c478bd9Sstevel@tonic-gate 			 * Convert token from megabytes to a
16387c478bd9Sstevel@tonic-gate 			 * block number.
16397c478bd9Sstevel@tonic-gate 			 */
1640b519f838Sbz211116 			if (sscanf(cleantoken, "%f2", &nmegs) != 1) {
16417c478bd9Sstevel@tonic-gate 				err_print("`%s' is not recognized\n",
16427c478bd9Sstevel@tonic-gate 				    cleantoken);
16437c478bd9Sstevel@tonic-gate 				break;
16447c478bd9Sstevel@tonic-gate 			}
16457c478bd9Sstevel@tonic-gate 
16467c478bd9Sstevel@tonic-gate 			/*
16477c478bd9Sstevel@tonic-gate 			 * Check the bounds
16487c478bd9Sstevel@tonic-gate 			 */
16497c478bd9Sstevel@tonic-gate 			if (nmegs > bn2mb(bounds->upper - bounds->lower)) {
16507c478bd9Sstevel@tonic-gate 				err_print("`%1.2fmb' is out of range\n", nmegs);
16517c478bd9Sstevel@tonic-gate 				break;
16527c478bd9Sstevel@tonic-gate 			}
16537c478bd9Sstevel@tonic-gate 
16547c478bd9Sstevel@tonic-gate 			return (mb2bn(nmegs));
16557c478bd9Sstevel@tonic-gate 
16567c478bd9Sstevel@tonic-gate 		case 'g':
1657b519f838Sbz211116 			if (sscanf(cleantoken, "%f2", &nmegs) != 1) {
16587c478bd9Sstevel@tonic-gate 				err_print("`%s' is not recognized\n",
16597c478bd9Sstevel@tonic-gate 				    cleantoken);
16607c478bd9Sstevel@tonic-gate 				break;
16617c478bd9Sstevel@tonic-gate 			}
16627c478bd9Sstevel@tonic-gate 			if (nmegs > bn2gb(bounds->upper - bounds->lower)) {
16637c478bd9Sstevel@tonic-gate 				err_print("`%1.2fgb' is out of range\n", nmegs);
16647c478bd9Sstevel@tonic-gate 				break;
16657c478bd9Sstevel@tonic-gate 			}
16667c478bd9Sstevel@tonic-gate 
16677c478bd9Sstevel@tonic-gate 			return (gb2bn(nmegs));
16687c478bd9Sstevel@tonic-gate 
16697c478bd9Sstevel@tonic-gate 		case 't':
1670b519f838Sbz211116 			if (sscanf(cleantoken, "%f2", &nmegs) != 1) {
16717c478bd9Sstevel@tonic-gate 				err_print("`%s' is not recognized\n",
16727c478bd9Sstevel@tonic-gate 				    cleantoken);
16737c478bd9Sstevel@tonic-gate 				break;
16747c478bd9Sstevel@tonic-gate 			}
16757c478bd9Sstevel@tonic-gate 			if (nmegs > bn2tb(bounds->upper - bounds->lower)) {
16767c478bd9Sstevel@tonic-gate 				err_print("`%1.2ftb' is out of range\n", nmegs);
16777c478bd9Sstevel@tonic-gate 				break;
16787c478bd9Sstevel@tonic-gate 			}
16797c478bd9Sstevel@tonic-gate 			return (uint64_t)((float)nmegs * 1024.0 *
168065908c77Syu, larry liu - Sun Microsystems - Beijing China 				1024.0 * 1024.0 * 1024.0 / cur_blksz);
16817c478bd9Sstevel@tonic-gate 
16827c478bd9Sstevel@tonic-gate 		default:
16837c478bd9Sstevel@tonic-gate 			err_print(
16847c478bd9Sstevel@tonic-gate "Please specify units in either b(number of blocks), e(end sector),\n");
16857c478bd9Sstevel@tonic-gate 			err_print(" g(gigabytes), m(megabytes)");
16867c478bd9Sstevel@tonic-gate 			err_print(" or t(terabytes)\n");
16877c478bd9Sstevel@tonic-gate 			break;
16887c478bd9Sstevel@tonic-gate 		}
16897c478bd9Sstevel@tonic-gate 		break;
16907c478bd9Sstevel@tonic-gate 
16917c478bd9Sstevel@tonic-gate 	/*
16927c478bd9Sstevel@tonic-gate 	 * If we don't recognize the input type, it's bad news.
16937c478bd9Sstevel@tonic-gate 	 */
16947c478bd9Sstevel@tonic-gate 	default:
16957c478bd9Sstevel@tonic-gate 		err_print("Error: unknown input type.\n");
16967c478bd9Sstevel@tonic-gate 		fullabort();
16977c478bd9Sstevel@tonic-gate 	}
16987c478bd9Sstevel@tonic-gate 	/*
16997c478bd9Sstevel@tonic-gate 	 * If we get here, it's because some error kept us from accepting
17007c478bd9Sstevel@tonic-gate 	 * the token.  If we are running out of a command file, gracefully
17017c478bd9Sstevel@tonic-gate 	 * leave the program.  If we are interacting with the user, simply
17027c478bd9Sstevel@tonic-gate 	 * reprompt.  If the token was in the pipe, abort the current command.
17037c478bd9Sstevel@tonic-gate 	 */
17047c478bd9Sstevel@tonic-gate 	if (option_f)
17057c478bd9Sstevel@tonic-gate 		fullabort();
17067c478bd9Sstevel@tonic-gate 	else if (interactive)
17077c478bd9Sstevel@tonic-gate 		goto reprompt;
17087c478bd9Sstevel@tonic-gate 	else
17097c478bd9Sstevel@tonic-gate 		cmdabort(SIGINT);
17107c478bd9Sstevel@tonic-gate 	/*
17117c478bd9Sstevel@tonic-gate 	 * Never actually reached.
17127c478bd9Sstevel@tonic-gate 	 */
17137c478bd9Sstevel@tonic-gate 	return (-1);
17147c478bd9Sstevel@tonic-gate }
17157c478bd9Sstevel@tonic-gate 
17167c478bd9Sstevel@tonic-gate /*
17177c478bd9Sstevel@tonic-gate  * Print input choices
17187c478bd9Sstevel@tonic-gate  */
17197c478bd9Sstevel@tonic-gate static void
17207c478bd9Sstevel@tonic-gate print_input_choices(type, param)
17217c478bd9Sstevel@tonic-gate 	int		type;
17227c478bd9Sstevel@tonic-gate 	u_ioparam_t	*param;
17237c478bd9Sstevel@tonic-gate {
17247c478bd9Sstevel@tonic-gate 	char		**sp;
17257c478bd9Sstevel@tonic-gate 	slist_t		*lp;
17267c478bd9Sstevel@tonic-gate 	int		width;
17277c478bd9Sstevel@tonic-gate 	int		col;
17287c478bd9Sstevel@tonic-gate 	int		ncols;
17297c478bd9Sstevel@tonic-gate 
17307c478bd9Sstevel@tonic-gate 	switch (type) {
17317c478bd9Sstevel@tonic-gate 	case FIO_CSTR:
17327c478bd9Sstevel@tonic-gate 		fmt_print("Expecting one of the following:\n");
17337c478bd9Sstevel@tonic-gate 		goto common;
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate 	case FIO_MSTR:
17367c478bd9Sstevel@tonic-gate 		fmt_print("Expecting one of the following: ");
17377c478bd9Sstevel@tonic-gate 		fmt_print("(abbreviations ok):\n");
17387c478bd9Sstevel@tonic-gate common:
17397c478bd9Sstevel@tonic-gate 		for (sp = (char **)param->io_charlist; *sp != NULL; sp++) {
17407c478bd9Sstevel@tonic-gate 			fmt_print("\t%s\n", *sp);
17417c478bd9Sstevel@tonic-gate 		}
17427c478bd9Sstevel@tonic-gate 		break;
17437c478bd9Sstevel@tonic-gate 
17447c478bd9Sstevel@tonic-gate 	case FIO_SLIST:
17457c478bd9Sstevel@tonic-gate 		fmt_print("Expecting one of the following: ");
17467c478bd9Sstevel@tonic-gate 		fmt_print("(abbreviations ok):\n");
17477c478bd9Sstevel@tonic-gate 		/*
17487c478bd9Sstevel@tonic-gate 		 * Figure out the width of the widest string
17497c478bd9Sstevel@tonic-gate 		 */
17507c478bd9Sstevel@tonic-gate 		width = slist_widest_str((slist_t *)param->io_slist);
17517c478bd9Sstevel@tonic-gate 		width += 4;
17527c478bd9Sstevel@tonic-gate 		/*
17537c478bd9Sstevel@tonic-gate 		 * If the help messages are empty, print the
17547c478bd9Sstevel@tonic-gate 		 * possible choices in left-justified columns
17557c478bd9Sstevel@tonic-gate 		 */
17567c478bd9Sstevel@tonic-gate 		lp = (slist_t *)param->io_slist;
17577c478bd9Sstevel@tonic-gate 		if (*lp->help == 0) {
17587c478bd9Sstevel@tonic-gate 			col = 0;
17597c478bd9Sstevel@tonic-gate 			ncols = 60 / width;
17607c478bd9Sstevel@tonic-gate 			for (; lp->str != NULL; lp++) {
17617c478bd9Sstevel@tonic-gate 				if (col == 0)
17627c478bd9Sstevel@tonic-gate 					fmt_print("\t");
17637c478bd9Sstevel@tonic-gate 				ljust_print(lp->str,
17647c478bd9Sstevel@tonic-gate 				    (++col == ncols) ? 0 : width);
17657c478bd9Sstevel@tonic-gate 				if (col == ncols) {
17667c478bd9Sstevel@tonic-gate 					col = 0;
17677c478bd9Sstevel@tonic-gate 					fmt_print("\n");
17687c478bd9Sstevel@tonic-gate 				}
17697c478bd9Sstevel@tonic-gate 			}
17707c478bd9Sstevel@tonic-gate 			if (col != 0)
17717c478bd9Sstevel@tonic-gate 				fmt_print("\n");
17727c478bd9Sstevel@tonic-gate 		} else {
17737c478bd9Sstevel@tonic-gate 			/*
17747c478bd9Sstevel@tonic-gate 			 * With help messages, print each choice,
17757c478bd9Sstevel@tonic-gate 			 * and help message, on its own line.
17767c478bd9Sstevel@tonic-gate 			 */
17777c478bd9Sstevel@tonic-gate 			for (; lp->str != NULL; lp++) {
17787c478bd9Sstevel@tonic-gate 				fmt_print("\t");
17797c478bd9Sstevel@tonic-gate 				ljust_print(lp->str, width);
17807c478bd9Sstevel@tonic-gate 				fmt_print("- %s\n", lp->help);
17817c478bd9Sstevel@tonic-gate 			}
17827c478bd9Sstevel@tonic-gate 		}
17837c478bd9Sstevel@tonic-gate 		break;
17847c478bd9Sstevel@tonic-gate 
17857c478bd9Sstevel@tonic-gate 	default:
17867c478bd9Sstevel@tonic-gate 		err_print("Error: unknown input type.\n");
17877c478bd9Sstevel@tonic-gate 		fullabort();
17887c478bd9Sstevel@tonic-gate 	}
17897c478bd9Sstevel@tonic-gate 
17907c478bd9Sstevel@tonic-gate 	fmt_print("\n");
17917c478bd9Sstevel@tonic-gate }
17927c478bd9Sstevel@tonic-gate 
17937c478bd9Sstevel@tonic-gate 
17947c478bd9Sstevel@tonic-gate /*
17957c478bd9Sstevel@tonic-gate  * Search a string list for a particular string.
17967c478bd9Sstevel@tonic-gate  * Use minimum recognition, to accept unique abbreviations
17977c478bd9Sstevel@tonic-gate  * Return the number of possible matches found.
17987c478bd9Sstevel@tonic-gate  * If only one match was found, return the arbitrary value
17997c478bd9Sstevel@tonic-gate  * associated with the matched string in match_value.
18007c478bd9Sstevel@tonic-gate  */
18017c478bd9Sstevel@tonic-gate int
18027c478bd9Sstevel@tonic-gate find_value(slist, match_str, match_value)
18037c478bd9Sstevel@tonic-gate 	slist_t		*slist;
18047c478bd9Sstevel@tonic-gate 	char		*match_str;
18057c478bd9Sstevel@tonic-gate 	int		*match_value;
18067c478bd9Sstevel@tonic-gate {
18077c478bd9Sstevel@tonic-gate 	int		i;
18087c478bd9Sstevel@tonic-gate 	int		nmatches;
18097c478bd9Sstevel@tonic-gate 	int		length;
18107c478bd9Sstevel@tonic-gate 	int		match_length;
18117c478bd9Sstevel@tonic-gate 
18127c478bd9Sstevel@tonic-gate 	nmatches = 0;
18137c478bd9Sstevel@tonic-gate 	length = 0;
18147c478bd9Sstevel@tonic-gate 
18157c478bd9Sstevel@tonic-gate 	match_length = strlen(match_str);
18167c478bd9Sstevel@tonic-gate 
18177c478bd9Sstevel@tonic-gate 	for (; slist->str != NULL; slist++) {
18187c478bd9Sstevel@tonic-gate 		/*
18197c478bd9Sstevel@tonic-gate 		 * See how many characters of the token match
18207c478bd9Sstevel@tonic-gate 		 */
18217c478bd9Sstevel@tonic-gate 		i = strcnt(match_str, slist->str);
18227c478bd9Sstevel@tonic-gate 		/*
18237c478bd9Sstevel@tonic-gate 		 * If it's not the whole token, then it's not a match.
18247c478bd9Sstevel@tonic-gate 		 */
18257c478bd9Sstevel@tonic-gate 		if (i  < match_length)
18267c478bd9Sstevel@tonic-gate 			continue;
18277c478bd9Sstevel@tonic-gate 		/*
18287c478bd9Sstevel@tonic-gate 		 * If it ties with another input, remember that.
18297c478bd9Sstevel@tonic-gate 		 */
18307c478bd9Sstevel@tonic-gate 		if (i == length)
18317c478bd9Sstevel@tonic-gate 			nmatches++;
18327c478bd9Sstevel@tonic-gate 		/*
18337c478bd9Sstevel@tonic-gate 		 * If it matches the most so far, record that.
18347c478bd9Sstevel@tonic-gate 		 */
18357c478bd9Sstevel@tonic-gate 		if (i > length) {
18367c478bd9Sstevel@tonic-gate 			*match_value = slist->value;
18377c478bd9Sstevel@tonic-gate 			nmatches = 1;
18387c478bd9Sstevel@tonic-gate 			length = i;
18397c478bd9Sstevel@tonic-gate 		}
18407c478bd9Sstevel@tonic-gate 	}
18417c478bd9Sstevel@tonic-gate 
18427c478bd9Sstevel@tonic-gate 	return (nmatches);
18437c478bd9Sstevel@tonic-gate }
18447c478bd9Sstevel@tonic-gate 
18457c478bd9Sstevel@tonic-gate /*
18467c478bd9Sstevel@tonic-gate  * Search a string list for a particular value.
18477c478bd9Sstevel@tonic-gate  * Return the string associated with that value.
18487c478bd9Sstevel@tonic-gate  */
18497c478bd9Sstevel@tonic-gate char *
18507c478bd9Sstevel@tonic-gate find_string(slist, match_value)
18517c478bd9Sstevel@tonic-gate 	slist_t		*slist;
18527c478bd9Sstevel@tonic-gate 	int		match_value;
18537c478bd9Sstevel@tonic-gate {
18547c478bd9Sstevel@tonic-gate 	for (; slist->str != NULL; slist++) {
18557c478bd9Sstevel@tonic-gate 		if (slist->value == match_value) {
18567c478bd9Sstevel@tonic-gate 			return (slist->str);
18577c478bd9Sstevel@tonic-gate 		}
18587c478bd9Sstevel@tonic-gate 	}
18597c478bd9Sstevel@tonic-gate 
18607c478bd9Sstevel@tonic-gate 	return ((char *)NULL);
18617c478bd9Sstevel@tonic-gate }
18627c478bd9Sstevel@tonic-gate 
18637c478bd9Sstevel@tonic-gate /*
18647c478bd9Sstevel@tonic-gate  * Return the width of the widest string in an slist
18657c478bd9Sstevel@tonic-gate  */
18667c478bd9Sstevel@tonic-gate static int
18677c478bd9Sstevel@tonic-gate slist_widest_str(slist)
18687c478bd9Sstevel@tonic-gate 	slist_t	*slist;
18697c478bd9Sstevel@tonic-gate {
18707c478bd9Sstevel@tonic-gate 	int	i;
18717c478bd9Sstevel@tonic-gate 	int	width;
18727c478bd9Sstevel@tonic-gate 
18737c478bd9Sstevel@tonic-gate 	width = 0;
18747c478bd9Sstevel@tonic-gate 	for (; slist->str != NULL; slist++) {
18757c478bd9Sstevel@tonic-gate 		if ((i = strlen(slist->str)) > width)
18767c478bd9Sstevel@tonic-gate 			width = i;
18777c478bd9Sstevel@tonic-gate 	}
18787c478bd9Sstevel@tonic-gate 
18797c478bd9Sstevel@tonic-gate 	return (width);
18807c478bd9Sstevel@tonic-gate }
18817c478bd9Sstevel@tonic-gate 
18827c478bd9Sstevel@tonic-gate /*
18837c478bd9Sstevel@tonic-gate  * Print a string left-justified to a fixed width.
18847c478bd9Sstevel@tonic-gate  */
18857c478bd9Sstevel@tonic-gate static void
18867c478bd9Sstevel@tonic-gate ljust_print(str, width)
18877c478bd9Sstevel@tonic-gate 	char	*str;
18887c478bd9Sstevel@tonic-gate 	int	width;
18897c478bd9Sstevel@tonic-gate {
18907c478bd9Sstevel@tonic-gate 	int	i;
18917c478bd9Sstevel@tonic-gate 
18927c478bd9Sstevel@tonic-gate 	fmt_print("%s", str);
18937c478bd9Sstevel@tonic-gate 	for (i = width - strlen(str); i > 0; i--) {
18947c478bd9Sstevel@tonic-gate 		fmt_print(" ");
18957c478bd9Sstevel@tonic-gate 	}
18967c478bd9Sstevel@tonic-gate }
18977c478bd9Sstevel@tonic-gate 
18987c478bd9Sstevel@tonic-gate /*
18997c478bd9Sstevel@tonic-gate  * This routine is a modified version of printf.  It handles the cases
19007c478bd9Sstevel@tonic-gate  * of silent mode and logging; other than that it is identical to the
19017c478bd9Sstevel@tonic-gate  * library version.
19027c478bd9Sstevel@tonic-gate  */
19037c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
19047c478bd9Sstevel@tonic-gate void
19057c478bd9Sstevel@tonic-gate fmt_print(char *format, ...)
19067c478bd9Sstevel@tonic-gate {
19077c478bd9Sstevel@tonic-gate 	va_list ap;
19087c478bd9Sstevel@tonic-gate 
19097c478bd9Sstevel@tonic-gate 	va_start(ap, format);
19107c478bd9Sstevel@tonic-gate 
19117c478bd9Sstevel@tonic-gate 	/*
19127c478bd9Sstevel@tonic-gate 	 * If we are running silent, skip it.
19137c478bd9Sstevel@tonic-gate 	 */
19147c478bd9Sstevel@tonic-gate 	if (option_s == 0) {
19157c478bd9Sstevel@tonic-gate 		/*
19167c478bd9Sstevel@tonic-gate 		 * Do the print to standard out.
19177c478bd9Sstevel@tonic-gate 		 */
19187c478bd9Sstevel@tonic-gate 		if (need_newline) {
19197c478bd9Sstevel@tonic-gate 			(void) printf("\n");
19207c478bd9Sstevel@tonic-gate 		}
19217c478bd9Sstevel@tonic-gate 		(void) vprintf(format, ap);
19227c478bd9Sstevel@tonic-gate 		/*
19237c478bd9Sstevel@tonic-gate 		 * If we are logging, also print to the log file.
19247c478bd9Sstevel@tonic-gate 		 */
19257c478bd9Sstevel@tonic-gate 		if (log_file) {
19267c478bd9Sstevel@tonic-gate 			if (need_newline) {
19277c478bd9Sstevel@tonic-gate 				(void) fprintf(log_file, "\n");
19287c478bd9Sstevel@tonic-gate 			}
19297c478bd9Sstevel@tonic-gate 			(void) vfprintf(log_file, format, ap);
19307c478bd9Sstevel@tonic-gate 			(void) fflush(log_file);
19317c478bd9Sstevel@tonic-gate 		}
19327c478bd9Sstevel@tonic-gate 	}
19337c478bd9Sstevel@tonic-gate 
19347c478bd9Sstevel@tonic-gate 	need_newline = 0;
19357c478bd9Sstevel@tonic-gate 
19367c478bd9Sstevel@tonic-gate 	va_end(ap);
19377c478bd9Sstevel@tonic-gate }
19387c478bd9Sstevel@tonic-gate 
19397c478bd9Sstevel@tonic-gate /*
19407c478bd9Sstevel@tonic-gate  * This routine is a modified version of printf.  It handles the cases
19417c478bd9Sstevel@tonic-gate  * of silent mode; other than that it is identical to the
19427c478bd9Sstevel@tonic-gate  * library version.  It differs from the above printf in that it does
19437c478bd9Sstevel@tonic-gate  * not print the message to a log file.
19447c478bd9Sstevel@tonic-gate  */
19457c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
19467c478bd9Sstevel@tonic-gate void
19477c478bd9Sstevel@tonic-gate nolog_print(char *format, ...)
19487c478bd9Sstevel@tonic-gate {
19497c478bd9Sstevel@tonic-gate 	va_list ap;
19507c478bd9Sstevel@tonic-gate 
19517c478bd9Sstevel@tonic-gate 	va_start(ap, format);
19527c478bd9Sstevel@tonic-gate 
19537c478bd9Sstevel@tonic-gate 	/*
19547c478bd9Sstevel@tonic-gate 	 * If we are running silent, skip it.
19557c478bd9Sstevel@tonic-gate 	 */
19567c478bd9Sstevel@tonic-gate 	if (option_s == 0) {
19577c478bd9Sstevel@tonic-gate 		/*
19587c478bd9Sstevel@tonic-gate 		 * Do the print to standard out.
19597c478bd9Sstevel@tonic-gate 		 */
19607c478bd9Sstevel@tonic-gate 		if (need_newline) {
19617c478bd9Sstevel@tonic-gate 			(void) printf("\n");
19627c478bd9Sstevel@tonic-gate 		}
19637c478bd9Sstevel@tonic-gate 		(void) vprintf(format, ap);
19647c478bd9Sstevel@tonic-gate 	}
19657c478bd9Sstevel@tonic-gate 
19667c478bd9Sstevel@tonic-gate 	va_end(ap);
19677c478bd9Sstevel@tonic-gate 
19687c478bd9Sstevel@tonic-gate 	need_newline = 0;
19697c478bd9Sstevel@tonic-gate }
19707c478bd9Sstevel@tonic-gate 
19717c478bd9Sstevel@tonic-gate /*
19727c478bd9Sstevel@tonic-gate  * This routine is a modified version of printf.  It handles the cases
19737c478bd9Sstevel@tonic-gate  * of silent mode, and only prints the message to the log file, not
19747c478bd9Sstevel@tonic-gate  * stdout.  Other than that is identical to the library version.
19757c478bd9Sstevel@tonic-gate  */
19767c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
19777c478bd9Sstevel@tonic-gate void
19787c478bd9Sstevel@tonic-gate log_print(char *format, ...)
19797c478bd9Sstevel@tonic-gate {
19807c478bd9Sstevel@tonic-gate 	va_list ap;
19817c478bd9Sstevel@tonic-gate 
19827c478bd9Sstevel@tonic-gate 	va_start(ap, format);
19837c478bd9Sstevel@tonic-gate 
19847c478bd9Sstevel@tonic-gate 	/*
19857c478bd9Sstevel@tonic-gate 	 * If we are running silent, skip it.
19867c478bd9Sstevel@tonic-gate 	 */
19877c478bd9Sstevel@tonic-gate 	if (option_s == 0) {
19887c478bd9Sstevel@tonic-gate 		/*
19897c478bd9Sstevel@tonic-gate 		 * Do the print to the log file.
19907c478bd9Sstevel@tonic-gate 		 */
19917c478bd9Sstevel@tonic-gate 		if (need_newline) {
19927c478bd9Sstevel@tonic-gate 			(void) fprintf(log_file, "\n");
19937c478bd9Sstevel@tonic-gate 		}
19947c478bd9Sstevel@tonic-gate 		(void) vfprintf(log_file, format, ap);
19957c478bd9Sstevel@tonic-gate 		(void) fflush(log_file);
19967c478bd9Sstevel@tonic-gate 	}
19977c478bd9Sstevel@tonic-gate 
19987c478bd9Sstevel@tonic-gate 	va_end(ap);
19997c478bd9Sstevel@tonic-gate 
20007c478bd9Sstevel@tonic-gate 	need_newline = 0;
20017c478bd9Sstevel@tonic-gate }
20027c478bd9Sstevel@tonic-gate 
20037c478bd9Sstevel@tonic-gate /*
20047c478bd9Sstevel@tonic-gate  * This routine is a modified version of printf.  It prints the message
20057c478bd9Sstevel@tonic-gate  * to stderr, and to the log file is appropriate.
20067c478bd9Sstevel@tonic-gate  * Other than that is identical to the library version.
20077c478bd9Sstevel@tonic-gate  */
20087c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
20097c478bd9Sstevel@tonic-gate void
20107c478bd9Sstevel@tonic-gate err_print(char *format, ...)
20117c478bd9Sstevel@tonic-gate {
20127c478bd9Sstevel@tonic-gate 	va_list ap;
20137c478bd9Sstevel@tonic-gate 
20147c478bd9Sstevel@tonic-gate 	va_start(ap, format);
20157c478bd9Sstevel@tonic-gate 
20167c478bd9Sstevel@tonic-gate 	/*
20177c478bd9Sstevel@tonic-gate 	 * Flush anything pending to stdout
20187c478bd9Sstevel@tonic-gate 	 */
20197c478bd9Sstevel@tonic-gate 	if (need_newline) {
20207c478bd9Sstevel@tonic-gate 		(void) printf("\n");
20217c478bd9Sstevel@tonic-gate 	}
20227c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
20237c478bd9Sstevel@tonic-gate 	/*
20247c478bd9Sstevel@tonic-gate 	 * Do the print to stderr.
20257c478bd9Sstevel@tonic-gate 	 */
20267c478bd9Sstevel@tonic-gate 	(void) vfprintf(stderr, format, ap);
20277c478bd9Sstevel@tonic-gate 	/*
20287c478bd9Sstevel@tonic-gate 	 * If we are logging, also print to the log file.
20297c478bd9Sstevel@tonic-gate 	 */
20307c478bd9Sstevel@tonic-gate 	if (log_file) {
20317c478bd9Sstevel@tonic-gate 		if (need_newline) {
20327c478bd9Sstevel@tonic-gate 			(void) fprintf(log_file, "\n");
20337c478bd9Sstevel@tonic-gate 		}
20347c478bd9Sstevel@tonic-gate 		(void) vfprintf(log_file, format, ap);
20357c478bd9Sstevel@tonic-gate 		(void) fflush(log_file);
20367c478bd9Sstevel@tonic-gate 	}
20377c478bd9Sstevel@tonic-gate 	va_end(ap);
20387c478bd9Sstevel@tonic-gate 
20397c478bd9Sstevel@tonic-gate 	need_newline = 0;
20407c478bd9Sstevel@tonic-gate }
20417c478bd9Sstevel@tonic-gate 
20427c478bd9Sstevel@tonic-gate /*
20437c478bd9Sstevel@tonic-gate  * Print a number of characters from a buffer.  The buffer
20447c478bd9Sstevel@tonic-gate  * does not need to be null-terminated.  Since the data
20457c478bd9Sstevel@tonic-gate  * may be coming from a device, we cannot be sure the
20467c478bd9Sstevel@tonic-gate  * data is not crud, so be rather defensive.
20477c478bd9Sstevel@tonic-gate  */
20487c478bd9Sstevel@tonic-gate void
20497c478bd9Sstevel@tonic-gate print_buf(buf, nbytes)
20507c478bd9Sstevel@tonic-gate 	char	*buf;
20517c478bd9Sstevel@tonic-gate 	int	nbytes;
20527c478bd9Sstevel@tonic-gate {
20537c478bd9Sstevel@tonic-gate 	int	c;
20547c478bd9Sstevel@tonic-gate 
20557c478bd9Sstevel@tonic-gate 	while (nbytes-- > 0) {
20567c478bd9Sstevel@tonic-gate 		c = *buf++;
20577c478bd9Sstevel@tonic-gate 		if (isascii(c) && isprint(c)) {
20587c478bd9Sstevel@tonic-gate 			fmt_print("%c", c);
20597c478bd9Sstevel@tonic-gate 		} else
20607c478bd9Sstevel@tonic-gate 			break;
20617c478bd9Sstevel@tonic-gate 	}
20627c478bd9Sstevel@tonic-gate }
20637c478bd9Sstevel@tonic-gate 
20647c478bd9Sstevel@tonic-gate #ifdef	not
20657c478bd9Sstevel@tonic-gate /*
20667c478bd9Sstevel@tonic-gate  * This routine prints out a message describing the given ctlr.
20677c478bd9Sstevel@tonic-gate  * The message is identical to the one printed by the kernel during
20687c478bd9Sstevel@tonic-gate  * booting.
20697c478bd9Sstevel@tonic-gate  */
20707c478bd9Sstevel@tonic-gate void
20717c478bd9Sstevel@tonic-gate pr_ctlrline(ctlr)
20727c478bd9Sstevel@tonic-gate 	register struct ctlr_info *ctlr;
20737c478bd9Sstevel@tonic-gate {
20747c478bd9Sstevel@tonic-gate 
20757c478bd9Sstevel@tonic-gate 	fmt_print("           %s%d at %s 0x%x ",
20767c478bd9Sstevel@tonic-gate 		ctlr->ctlr_cname, ctlr->ctlr_num,
20777c478bd9Sstevel@tonic-gate 		space2str(ctlr->ctlr_space), ctlr->ctlr_addr);
20787c478bd9Sstevel@tonic-gate 	if (ctlr->ctlr_vec != 0)
20797c478bd9Sstevel@tonic-gate 		fmt_print("vec 0x%x ", ctlr->ctlr_vec);
20807c478bd9Sstevel@tonic-gate 	else
20817c478bd9Sstevel@tonic-gate 		fmt_print("pri %d ", ctlr->ctlr_prio);
20827c478bd9Sstevel@tonic-gate 	fmt_print("\n");
20837c478bd9Sstevel@tonic-gate }
20847c478bd9Sstevel@tonic-gate #endif /* not */
20857c478bd9Sstevel@tonic-gate 
20867c478bd9Sstevel@tonic-gate /*
20877c478bd9Sstevel@tonic-gate  * This routine prints out a message describing the given disk.
20887c478bd9Sstevel@tonic-gate  * The message is identical to the one printed by the kernel during
20897c478bd9Sstevel@tonic-gate  * booting.
20907c478bd9Sstevel@tonic-gate  */
20917c478bd9Sstevel@tonic-gate void
20927c478bd9Sstevel@tonic-gate pr_diskline(disk, num)
20937c478bd9Sstevel@tonic-gate 	register struct disk_info *disk;
20947c478bd9Sstevel@tonic-gate 	int	num;
20957c478bd9Sstevel@tonic-gate {
20967c478bd9Sstevel@tonic-gate 	struct	ctlr_info *ctlr = disk->disk_ctlr;
20977c478bd9Sstevel@tonic-gate 	struct	disk_type *type = disk->disk_type;
20987c478bd9Sstevel@tonic-gate 
20997c478bd9Sstevel@tonic-gate 	fmt_print("    %4d. %s ", num, disk->disk_name);
21007c478bd9Sstevel@tonic-gate 	if ((type != NULL) && (disk->label_type == L_TYPE_SOLARIS)) {
2101342440ecSPrasad Singamsetty 		fmt_print("<%s cyl %u alt %u hd %u sec %u>",
21027c478bd9Sstevel@tonic-gate 			type->dtype_asciilabel, type->dtype_ncyl,
21037c478bd9Sstevel@tonic-gate 			type->dtype_acyl, type->dtype_nhead,
21047c478bd9Sstevel@tonic-gate 			type->dtype_nsect);
21057c478bd9Sstevel@tonic-gate 	} else if ((type != NULL) && (disk->label_type == L_TYPE_EFI)) {
210665908c77Syu, larry liu - Sun Microsystems - Beijing China 		cur_blksz = disk->disk_lbasize;
21077c478bd9Sstevel@tonic-gate 		print_efi_string(type->vendor, type->product,
21087c478bd9Sstevel@tonic-gate 			type->revision, type->capacity);
21097c478bd9Sstevel@tonic-gate 	} else if (disk->disk_flags & DSK_RESERVED) {
21107c478bd9Sstevel@tonic-gate 		fmt_print("<drive not available: reserved>");
21117c478bd9Sstevel@tonic-gate 	} else if (disk->disk_flags & DSK_UNAVAILABLE) {
21127c478bd9Sstevel@tonic-gate 		fmt_print("<drive not available>");
21137c478bd9Sstevel@tonic-gate 	} else {
21147c478bd9Sstevel@tonic-gate 		fmt_print("<drive type unknown>");
21157c478bd9Sstevel@tonic-gate 	}
21167c478bd9Sstevel@tonic-gate 	if (chk_volname(disk)) {
21177c478bd9Sstevel@tonic-gate 		fmt_print("  ");
21187c478bd9Sstevel@tonic-gate 		print_volname(disk);
21197c478bd9Sstevel@tonic-gate 	}
21207c478bd9Sstevel@tonic-gate 	fmt_print("\n");
21217c478bd9Sstevel@tonic-gate 
21227c478bd9Sstevel@tonic-gate 	if (disk->devfs_name != NULL) {
21237c478bd9Sstevel@tonic-gate 		fmt_print("          %s\n", disk->devfs_name);
21247c478bd9Sstevel@tonic-gate 	} else {
21257c478bd9Sstevel@tonic-gate 		fmt_print("          %s%d at %s%d slave %d\n",
21267c478bd9Sstevel@tonic-gate 			ctlr->ctlr_dname, disk->disk_dkinfo.dki_unit,
21277c478bd9Sstevel@tonic-gate 			ctlr->ctlr_cname, ctlr->ctlr_num,
21287c478bd9Sstevel@tonic-gate 			disk->disk_dkinfo.dki_slave);
21297c478bd9Sstevel@tonic-gate 	}
21307c478bd9Sstevel@tonic-gate 
21317c478bd9Sstevel@tonic-gate #ifdef	OLD
21327c478bd9Sstevel@tonic-gate 	fmt_print("    %4d. %s at %s%d slave %d", num, disk->disk_name,
21337c478bd9Sstevel@tonic-gate 	    ctlr->ctlr_cname, ctlr->ctlr_num, disk->disk_dkinfo.dki_slave);
21347c478bd9Sstevel@tonic-gate 	if (chk_volname(disk)) {
21357c478bd9Sstevel@tonic-gate 		fmt_print(": ");
21367c478bd9Sstevel@tonic-gate 		print_volname(disk);
21377c478bd9Sstevel@tonic-gate 	}
21387c478bd9Sstevel@tonic-gate 	fmt_print("\n");
21397c478bd9Sstevel@tonic-gate 	if (type != NULL) {
21407c478bd9Sstevel@tonic-gate 		fmt_print(
2141342440ecSPrasad Singamsetty "           %s%d: <%s cyl %u alt %u hd %u sec %u>\n",
21427c478bd9Sstevel@tonic-gate 		    ctlr->ctlr_dname, disk->disk_dkinfo.dki_unit,
21437c478bd9Sstevel@tonic-gate 		    type->dtype_asciilabel, type->dtype_ncyl,
21447c478bd9Sstevel@tonic-gate 		    type->dtype_acyl, type->dtype_nhead,
21457c478bd9Sstevel@tonic-gate 		    type->dtype_nsect);
21467c478bd9Sstevel@tonic-gate 	} else {
21477c478bd9Sstevel@tonic-gate 		fmt_print("           %s%d: <drive type unknown>\n",
21487c478bd9Sstevel@tonic-gate 		    ctlr->ctlr_dname, disk->disk_dkinfo.dki_unit);
21497c478bd9Sstevel@tonic-gate 	}
21507c478bd9Sstevel@tonic-gate #endif /* OLD */
21517c478bd9Sstevel@tonic-gate }
21527c478bd9Sstevel@tonic-gate 
21537c478bd9Sstevel@tonic-gate /*
21547c478bd9Sstevel@tonic-gate  * This routine prints out a given disk block number in cylinder/head/sector
21557c478bd9Sstevel@tonic-gate  * format.  It uses the printing routine passed in to do the actual output.
21567c478bd9Sstevel@tonic-gate  */
21577c478bd9Sstevel@tonic-gate void
21587c478bd9Sstevel@tonic-gate pr_dblock(void (*func)(char *, ...), diskaddr_t bn)
21597c478bd9Sstevel@tonic-gate {
21607c478bd9Sstevel@tonic-gate 	if (cur_label == L_TYPE_SOLARIS) {
2161342440ecSPrasad Singamsetty 		(*func)("%u/%u/%u", bn2c(bn),
2162342440ecSPrasad Singamsetty 		    bn2h(bn), bn2s(bn));
21637c478bd9Sstevel@tonic-gate 	} else {
21647c478bd9Sstevel@tonic-gate 		(*func)("%llu", bn);
21657c478bd9Sstevel@tonic-gate 	}
21667c478bd9Sstevel@tonic-gate }
21677c478bd9Sstevel@tonic-gate 
21687c478bd9Sstevel@tonic-gate /*
21697c478bd9Sstevel@tonic-gate  * This routine inputs a character from the data file.  It understands
21707c478bd9Sstevel@tonic-gate  * the use of '\' to prevent interpretation of a newline.  It also keeps
21717c478bd9Sstevel@tonic-gate  * track of the current line in the data file via a global variable.
21727c478bd9Sstevel@tonic-gate  */
21737c478bd9Sstevel@tonic-gate static int
21747c478bd9Sstevel@tonic-gate sup_inputchar()
21757c478bd9Sstevel@tonic-gate {
21767c478bd9Sstevel@tonic-gate 	int	c;
21777c478bd9Sstevel@tonic-gate 
21787c478bd9Sstevel@tonic-gate 	/*
21797c478bd9Sstevel@tonic-gate 	 * Input the character.
21807c478bd9Sstevel@tonic-gate 	 */
21817c478bd9Sstevel@tonic-gate 	c = getc(data_file);
21827c478bd9Sstevel@tonic-gate 	/*
21837c478bd9Sstevel@tonic-gate 	 * If it's not a backslash, return it.
21847c478bd9Sstevel@tonic-gate 	 */
21857c478bd9Sstevel@tonic-gate 	if (c != '\\')
21867c478bd9Sstevel@tonic-gate 		return (c);
21877c478bd9Sstevel@tonic-gate 	/*
21887c478bd9Sstevel@tonic-gate 	 * It was a backslash.  Get the next character.
21897c478bd9Sstevel@tonic-gate 	 */
21907c478bd9Sstevel@tonic-gate 	c = getc(data_file);
21917c478bd9Sstevel@tonic-gate 	/*
21927c478bd9Sstevel@tonic-gate 	 * If it was a newline, update the line counter and get the next
21937c478bd9Sstevel@tonic-gate 	 * character.
21947c478bd9Sstevel@tonic-gate 	 */
21957c478bd9Sstevel@tonic-gate 	if (c == '\n') {
21967c478bd9Sstevel@tonic-gate 		data_lineno++;
21977c478bd9Sstevel@tonic-gate 		c = getc(data_file);
21987c478bd9Sstevel@tonic-gate 	}
21997c478bd9Sstevel@tonic-gate 	/*
22007c478bd9Sstevel@tonic-gate 	 * Return the character.
22017c478bd9Sstevel@tonic-gate 	 */
22027c478bd9Sstevel@tonic-gate 	return (c);
22037c478bd9Sstevel@tonic-gate }
22047c478bd9Sstevel@tonic-gate 
22057c478bd9Sstevel@tonic-gate /*
22067c478bd9Sstevel@tonic-gate  * This routine pushes a character back onto the input pipe for the data file.
22077c478bd9Sstevel@tonic-gate  */
22087c478bd9Sstevel@tonic-gate static void
22097c478bd9Sstevel@tonic-gate sup_pushchar(c)
22107c478bd9Sstevel@tonic-gate 	int	c;
22117c478bd9Sstevel@tonic-gate {
22127c478bd9Sstevel@tonic-gate 	(void) ungetc(c, data_file);
22137c478bd9Sstevel@tonic-gate }
22147c478bd9Sstevel@tonic-gate 
22157c478bd9Sstevel@tonic-gate /*
22167c478bd9Sstevel@tonic-gate  * Variables to support pushing back tokens
22177c478bd9Sstevel@tonic-gate  */
22187c478bd9Sstevel@tonic-gate static  int	have_pushed_token = 0;
22197c478bd9Sstevel@tonic-gate static  TOKEN	pushed_buf;
22207c478bd9Sstevel@tonic-gate static  int	pushed_token;
22217c478bd9Sstevel@tonic-gate 
22227c478bd9Sstevel@tonic-gate /*
22237c478bd9Sstevel@tonic-gate  * This routine inputs a token from the data file.  A token is a series
22247c478bd9Sstevel@tonic-gate  * of contiguous non-white characters or a recognized special delimiter
22257c478bd9Sstevel@tonic-gate  * character.  Use of the wrapper lets us always have the value of the
22267c478bd9Sstevel@tonic-gate  * last token around, which is useful for error recovery.
22277c478bd9Sstevel@tonic-gate  */
22287c478bd9Sstevel@tonic-gate int
22297c478bd9Sstevel@tonic-gate sup_gettoken(buf)
22307c478bd9Sstevel@tonic-gate 	char	*buf;
22317c478bd9Sstevel@tonic-gate {
22327c478bd9Sstevel@tonic-gate 	last_token_type = sup_get_token(buf);
22337c478bd9Sstevel@tonic-gate 	return (last_token_type);
22347c478bd9Sstevel@tonic-gate }
22357c478bd9Sstevel@tonic-gate 
22367c478bd9Sstevel@tonic-gate static int
22377c478bd9Sstevel@tonic-gate sup_get_token(buf)
22387c478bd9Sstevel@tonic-gate 	char	*buf;
22397c478bd9Sstevel@tonic-gate {
22407c478bd9Sstevel@tonic-gate 	char	*ptr = buf;
22417c478bd9Sstevel@tonic-gate 	int	c, quoted = 0;
22427c478bd9Sstevel@tonic-gate 
22437c478bd9Sstevel@tonic-gate 	/*
22447c478bd9Sstevel@tonic-gate 	 * First check for presence of push-backed token.
22457c478bd9Sstevel@tonic-gate 	 * If so, return it.
22467c478bd9Sstevel@tonic-gate 	 */
22477c478bd9Sstevel@tonic-gate 	if (have_pushed_token) {
22487c478bd9Sstevel@tonic-gate 		have_pushed_token = 0;
22497c478bd9Sstevel@tonic-gate 		bcopy(pushed_buf, buf, TOKEN_SIZE+1);
22507c478bd9Sstevel@tonic-gate 		return (pushed_token);
22517c478bd9Sstevel@tonic-gate 	}
22527c478bd9Sstevel@tonic-gate 	/*
22537c478bd9Sstevel@tonic-gate 	 * Zero out the returned token buffer
22547c478bd9Sstevel@tonic-gate 	 */
22557c478bd9Sstevel@tonic-gate 	bzero(buf, TOKEN_SIZE + 1);
22567c478bd9Sstevel@tonic-gate 	/*
22577c478bd9Sstevel@tonic-gate 	 * Strip off leading white-space.
22587c478bd9Sstevel@tonic-gate 	 */
22597c478bd9Sstevel@tonic-gate 	while ((isspace(c = sup_inputchar())) && (c != '\n'))
22607c478bd9Sstevel@tonic-gate 		;
22617c478bd9Sstevel@tonic-gate 	/*
22627c478bd9Sstevel@tonic-gate 	 * Read in characters until we hit unquoted white-space.
22637c478bd9Sstevel@tonic-gate 	 */
22647c478bd9Sstevel@tonic-gate 	for (; !isspace(c) || quoted; c = sup_inputchar()) {
22657c478bd9Sstevel@tonic-gate 		/*
22667c478bd9Sstevel@tonic-gate 		 * If we hit eof, that's a token.
22677c478bd9Sstevel@tonic-gate 		 */
22687c478bd9Sstevel@tonic-gate 		if (feof(data_file))
22697c478bd9Sstevel@tonic-gate 			return (SUP_EOF);
22707c478bd9Sstevel@tonic-gate 		/*
22717c478bd9Sstevel@tonic-gate 		 * If we hit a double quote, change the state of quoting.
22727c478bd9Sstevel@tonic-gate 		 */
22737c478bd9Sstevel@tonic-gate 		if (c == '"') {
22747c478bd9Sstevel@tonic-gate 			quoted = !quoted;
22757c478bd9Sstevel@tonic-gate 			continue;
22767c478bd9Sstevel@tonic-gate 		}
22777c478bd9Sstevel@tonic-gate 		/*
22787c478bd9Sstevel@tonic-gate 		 * If we hit a newline, that delimits a token.
22797c478bd9Sstevel@tonic-gate 		 */
22807c478bd9Sstevel@tonic-gate 		if (c == '\n')
22817c478bd9Sstevel@tonic-gate 			break;
22827c478bd9Sstevel@tonic-gate 		/*
22837c478bd9Sstevel@tonic-gate 		 * If we hit any nonquoted special delimiters, that delimits
22847c478bd9Sstevel@tonic-gate 		 * a token.
22857c478bd9Sstevel@tonic-gate 		 */
22867c478bd9Sstevel@tonic-gate 		if (!quoted && (c == '=' || c == ',' || c == ':' ||
22877c478bd9Sstevel@tonic-gate 			c == '#' || c == '|' || c == '&' || c == '~'))
22887c478bd9Sstevel@tonic-gate 			break;
22897c478bd9Sstevel@tonic-gate 		/*
22907c478bd9Sstevel@tonic-gate 		 * Store the character if there's room left.
22917c478bd9Sstevel@tonic-gate 		 */
22927c478bd9Sstevel@tonic-gate 		if (ptr - buf < TOKEN_SIZE)
22937c478bd9Sstevel@tonic-gate 			*ptr++ = (char)c;
22947c478bd9Sstevel@tonic-gate 	}
22957c478bd9Sstevel@tonic-gate 	/*
22967c478bd9Sstevel@tonic-gate 	 * If we stored characters in the buffer, then we inputted a string.
22977c478bd9Sstevel@tonic-gate 	 * Push the delimiter back into the pipe and return the string.
22987c478bd9Sstevel@tonic-gate 	 */
22997c478bd9Sstevel@tonic-gate 	if (ptr - buf > 0) {
23007c478bd9Sstevel@tonic-gate 		sup_pushchar(c);
23017c478bd9Sstevel@tonic-gate 		return (SUP_STRING);
23027c478bd9Sstevel@tonic-gate 	}
23037c478bd9Sstevel@tonic-gate 	/*
23047c478bd9Sstevel@tonic-gate 	 * We didn't input a string, so we must have inputted a known delimiter.
23057c478bd9Sstevel@tonic-gate 	 * store the delimiter in the buffer, so it will get returned.
23067c478bd9Sstevel@tonic-gate 	 */
23077c478bd9Sstevel@tonic-gate 	buf[0] = c;
23087c478bd9Sstevel@tonic-gate 	/*
23097c478bd9Sstevel@tonic-gate 	 * Switch on the delimiter.  Return the appropriate value for each one.
23107c478bd9Sstevel@tonic-gate 	 */
23117c478bd9Sstevel@tonic-gate 	switch (c) {
23127c478bd9Sstevel@tonic-gate 	case '=':
23137c478bd9Sstevel@tonic-gate 		return (SUP_EQL);
23147c478bd9Sstevel@tonic-gate 	case ':':
23157c478bd9Sstevel@tonic-gate 		return (SUP_COLON);
23167c478bd9Sstevel@tonic-gate 	case ',':
23177c478bd9Sstevel@tonic-gate 		return (SUP_COMMA);
23187c478bd9Sstevel@tonic-gate 	case '\n':
23197c478bd9Sstevel@tonic-gate 		return (SUP_EOL);
23207c478bd9Sstevel@tonic-gate 	case '|':
23217c478bd9Sstevel@tonic-gate 		return (SUP_OR);
23227c478bd9Sstevel@tonic-gate 	case '&':
23237c478bd9Sstevel@tonic-gate 		return (SUP_AND);
23247c478bd9Sstevel@tonic-gate 	case '~':
23257c478bd9Sstevel@tonic-gate 		return (SUP_TILDE);
23267c478bd9Sstevel@tonic-gate 	case '#':
23277c478bd9Sstevel@tonic-gate 		/*
23287c478bd9Sstevel@tonic-gate 		 * For comments, we flush out the rest of the line and return
23297c478bd9Sstevel@tonic-gate 		 * an EOL.
23307c478bd9Sstevel@tonic-gate 		 */
23317c478bd9Sstevel@tonic-gate 		while ((c = sup_inputchar()) != '\n' && !feof(data_file))
23327c478bd9Sstevel@tonic-gate 			;
23337c478bd9Sstevel@tonic-gate 		if (feof(data_file))
23347c478bd9Sstevel@tonic-gate 			return (SUP_EOF);
23357c478bd9Sstevel@tonic-gate 		else
23367c478bd9Sstevel@tonic-gate 			return (SUP_EOL);
23377c478bd9Sstevel@tonic-gate 	/*
23387c478bd9Sstevel@tonic-gate 	 * Shouldn't ever get here.
23397c478bd9Sstevel@tonic-gate 	 */
23407c478bd9Sstevel@tonic-gate 	default:
23417c478bd9Sstevel@tonic-gate 		return (SUP_STRING);
23427c478bd9Sstevel@tonic-gate 	}
23437c478bd9Sstevel@tonic-gate }
23447c478bd9Sstevel@tonic-gate 
23457c478bd9Sstevel@tonic-gate /*
23467c478bd9Sstevel@tonic-gate  * Push back a token
23477c478bd9Sstevel@tonic-gate  */
23487c478bd9Sstevel@tonic-gate void
23497c478bd9Sstevel@tonic-gate sup_pushtoken(token_buf, token_type)
23507c478bd9Sstevel@tonic-gate 	char	*token_buf;
23517c478bd9Sstevel@tonic-gate 	int	token_type;
23527c478bd9Sstevel@tonic-gate {
23537c478bd9Sstevel@tonic-gate 	/*
23547c478bd9Sstevel@tonic-gate 	 * We can only push one token back at a time
23557c478bd9Sstevel@tonic-gate 	 */
23567c478bd9Sstevel@tonic-gate 	assert(have_pushed_token == 0);
23577c478bd9Sstevel@tonic-gate 
23587c478bd9Sstevel@tonic-gate 	have_pushed_token = 1;
23597c478bd9Sstevel@tonic-gate 	bcopy(token_buf, pushed_buf, TOKEN_SIZE+1);
23607c478bd9Sstevel@tonic-gate 	pushed_token = token_type;
23617c478bd9Sstevel@tonic-gate }
23627c478bd9Sstevel@tonic-gate 
23637c478bd9Sstevel@tonic-gate /*
23647c478bd9Sstevel@tonic-gate  * Get an entire line of input.  Handles logging, comments,
23657c478bd9Sstevel@tonic-gate  * and EOF.
23667c478bd9Sstevel@tonic-gate  */
23677c478bd9Sstevel@tonic-gate void
23687c478bd9Sstevel@tonic-gate get_inputline(line, nbytes)
23697c478bd9Sstevel@tonic-gate 	char	*line;
23707c478bd9Sstevel@tonic-gate 	int	nbytes;
23717c478bd9Sstevel@tonic-gate {
23727c478bd9Sstevel@tonic-gate 	char	*p = line;
23737c478bd9Sstevel@tonic-gate 	int	c;
23747c478bd9Sstevel@tonic-gate 
23757c478bd9Sstevel@tonic-gate 	/*
23767c478bd9Sstevel@tonic-gate 	 * Remove any leading white-space and comments
23777c478bd9Sstevel@tonic-gate 	 */
23787c478bd9Sstevel@tonic-gate 	do {
23797c478bd9Sstevel@tonic-gate 		while ((isspace(c = getchar())) && (c != '\n'))
23807c478bd9Sstevel@tonic-gate 			;
23817c478bd9Sstevel@tonic-gate 	} while (c == COMMENT_CHAR);
23827c478bd9Sstevel@tonic-gate 	/*
23837c478bd9Sstevel@tonic-gate 	 * Loop on each character until end of line
23847c478bd9Sstevel@tonic-gate 	 */
23857c478bd9Sstevel@tonic-gate 	while (c != '\n') {
23867c478bd9Sstevel@tonic-gate 		/*
23877c478bd9Sstevel@tonic-gate 		 * If we hit eof, get out.
23887c478bd9Sstevel@tonic-gate 		 */
23897c478bd9Sstevel@tonic-gate 		if (checkeof()) {
23907c478bd9Sstevel@tonic-gate 			fullabort();
23917c478bd9Sstevel@tonic-gate 		}
23927c478bd9Sstevel@tonic-gate 		/*
23937c478bd9Sstevel@tonic-gate 		 * Add the character to the buffer.
23947c478bd9Sstevel@tonic-gate 		 */
23957c478bd9Sstevel@tonic-gate 		if (nbytes > 1) {
23967c478bd9Sstevel@tonic-gate 			*p++ = (char)c;
23977c478bd9Sstevel@tonic-gate 			nbytes --;
23987c478bd9Sstevel@tonic-gate 		}
23997c478bd9Sstevel@tonic-gate 		/*
24007c478bd9Sstevel@tonic-gate 		 * Get the next character.
24017c478bd9Sstevel@tonic-gate 		 */
24027c478bd9Sstevel@tonic-gate 		c = getchar();
24037c478bd9Sstevel@tonic-gate 	}
24047c478bd9Sstevel@tonic-gate 	/*
24057c478bd9Sstevel@tonic-gate 	 * Null terminate the token.
24067c478bd9Sstevel@tonic-gate 	 */
24077c478bd9Sstevel@tonic-gate 	*p = 0;
24087c478bd9Sstevel@tonic-gate 	/*
24097c478bd9Sstevel@tonic-gate 	 * Indicate that we've emptied the pipe
24107c478bd9Sstevel@tonic-gate 	 */
24117c478bd9Sstevel@tonic-gate 	token_present = 0;
24127c478bd9Sstevel@tonic-gate 	/*
24137c478bd9Sstevel@tonic-gate 	 * If we're running out of a file, echo the line to
24147c478bd9Sstevel@tonic-gate 	 * the user, otherwise if we're logging, copy the
24157c478bd9Sstevel@tonic-gate 	 * input to the log file.
24167c478bd9Sstevel@tonic-gate 	 */
24177c478bd9Sstevel@tonic-gate 	if (option_f) {
24187c478bd9Sstevel@tonic-gate 		fmt_print("%s\n", line);
24197c478bd9Sstevel@tonic-gate 	} else if (log_file) {
24207c478bd9Sstevel@tonic-gate 		log_print("%s\n", line);
24217c478bd9Sstevel@tonic-gate 	}
24227c478bd9Sstevel@tonic-gate }
24237c478bd9Sstevel@tonic-gate 
24247c478bd9Sstevel@tonic-gate /*
24257c478bd9Sstevel@tonic-gate  * execute the shell escape command
24267c478bd9Sstevel@tonic-gate  */
24277c478bd9Sstevel@tonic-gate int
2428f1c60556Spr131582 execute_shell(s, buff_size)
24297c478bd9Sstevel@tonic-gate 	char	*s;
2430f1c60556Spr131582 	size_t	buff_size;
24317c478bd9Sstevel@tonic-gate {
24327c478bd9Sstevel@tonic-gate 	struct	termio	termio;
24337c478bd9Sstevel@tonic-gate 	struct	termios	tty;
24347c478bd9Sstevel@tonic-gate 	int	tty_flag, i, j;
24357c478bd9Sstevel@tonic-gate 	char	*shell_name;
24367c478bd9Sstevel@tonic-gate 	static char	*default_shell = "/bin/sh";
24377c478bd9Sstevel@tonic-gate 
24387c478bd9Sstevel@tonic-gate 	tty_flag = -1;
24397c478bd9Sstevel@tonic-gate 
24407c478bd9Sstevel@tonic-gate 	if (*s == NULL) {
24417c478bd9Sstevel@tonic-gate 		shell_name = getenv("SHELL");
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 		if (shell_name == NULL) {
24447c478bd9Sstevel@tonic-gate 			shell_name = default_shell;
24457c478bd9Sstevel@tonic-gate 		}
2446f1c60556Spr131582 		if (strlcpy(s, shell_name, buff_size) >=
2447f1c60556Spr131582 		    buff_size) {
2448f1c60556Spr131582 			err_print("Error: Shell command ($SHELL) too long.\n");
24497c478bd9Sstevel@tonic-gate 			fullabort();
24507c478bd9Sstevel@tonic-gate 		}
24517c478bd9Sstevel@tonic-gate 	}
24527c478bd9Sstevel@tonic-gate 
24537c478bd9Sstevel@tonic-gate 	/* save tty information */
24547c478bd9Sstevel@tonic-gate 
24557c478bd9Sstevel@tonic-gate 	if (isatty(0)) {
24567c478bd9Sstevel@tonic-gate 		if (ioctl(0, TCGETS, &tty) == 0)
24577c478bd9Sstevel@tonic-gate 			tty_flag = 1;
24587c478bd9Sstevel@tonic-gate 		else {
24597c478bd9Sstevel@tonic-gate 			if (ioctl(0, TCGETA, &termio) == 0) {
24607c478bd9Sstevel@tonic-gate 				tty_flag = 0;
24617c478bd9Sstevel@tonic-gate 				tty.c_iflag = termio.c_iflag;
24627c478bd9Sstevel@tonic-gate 				tty.c_oflag = termio.c_oflag;
24637c478bd9Sstevel@tonic-gate 				tty.c_cflag = termio.c_cflag;
24647c478bd9Sstevel@tonic-gate 				tty.c_lflag = termio.c_lflag;
24657c478bd9Sstevel@tonic-gate 				for (i = 0; i < NCC; i++)
24667c478bd9Sstevel@tonic-gate 					tty.c_cc[i] = termio.c_cc[i];
24677c478bd9Sstevel@tonic-gate 			}
24687c478bd9Sstevel@tonic-gate 		}
24697c478bd9Sstevel@tonic-gate 	}
24707c478bd9Sstevel@tonic-gate 
24717c478bd9Sstevel@tonic-gate 	/* close the current file descriptor */
24727c478bd9Sstevel@tonic-gate 	if (cur_disk != NULL) {
24737c478bd9Sstevel@tonic-gate 		(void) close(cur_file);
24747c478bd9Sstevel@tonic-gate 	}
24757c478bd9Sstevel@tonic-gate 
24767c478bd9Sstevel@tonic-gate 	/* execute the shell escape */
24777c478bd9Sstevel@tonic-gate 	(void) system(s);
24787c478bd9Sstevel@tonic-gate 
24797c478bd9Sstevel@tonic-gate 	/* reopen file descriptor if one was open before */
24807c478bd9Sstevel@tonic-gate 	if (cur_disk != NULL) {
24817c478bd9Sstevel@tonic-gate 		if ((cur_file = open_disk(cur_disk->disk_path,
24827c478bd9Sstevel@tonic-gate 			O_RDWR | O_NDELAY)) < 0) {
24837c478bd9Sstevel@tonic-gate 			err_print("Error: can't reopen selected disk '%s'. \n",
24847c478bd9Sstevel@tonic-gate 				cur_disk->disk_name);
24857c478bd9Sstevel@tonic-gate 			fullabort();
24867c478bd9Sstevel@tonic-gate 		}
24877c478bd9Sstevel@tonic-gate 	}
24887c478bd9Sstevel@tonic-gate 
24897c478bd9Sstevel@tonic-gate 	/* Restore tty information */
24907c478bd9Sstevel@tonic-gate 
24917c478bd9Sstevel@tonic-gate 	if (isatty(0)) {
24927c478bd9Sstevel@tonic-gate 		if (tty_flag > 0)
24937c478bd9Sstevel@tonic-gate 			(void) ioctl(0, TCSETSW, &tty);
24947c478bd9Sstevel@tonic-gate 		else if (tty_flag == 0) {
24957c478bd9Sstevel@tonic-gate 			termio.c_iflag = tty.c_iflag;
24967c478bd9Sstevel@tonic-gate 			termio.c_oflag = tty.c_oflag;
24977c478bd9Sstevel@tonic-gate 			termio.c_cflag = tty.c_cflag;
24987c478bd9Sstevel@tonic-gate 			termio.c_lflag = tty.c_lflag;
24997c478bd9Sstevel@tonic-gate 			for (j = 0; j < NCC; j++)
25007c478bd9Sstevel@tonic-gate 				termio.c_cc[j] = tty.c_cc[j];
25017c478bd9Sstevel@tonic-gate 			(void) ioctl(0, TCSETAW, &termio);
25027c478bd9Sstevel@tonic-gate 		}
25037c478bd9Sstevel@tonic-gate 
25047c478bd9Sstevel@tonic-gate 		if (isatty(1)) {
25057c478bd9Sstevel@tonic-gate 			fmt_print("\n[Hit Return to continue] \n");
25067c478bd9Sstevel@tonic-gate 			(void) fflush(stdin);
25077c478bd9Sstevel@tonic-gate 			if (getchar() == EOF)
25087c478bd9Sstevel@tonic-gate 				fullabort();
25097c478bd9Sstevel@tonic-gate 		}
25107c478bd9Sstevel@tonic-gate 	}
25117c478bd9Sstevel@tonic-gate 	return (0);
25127c478bd9Sstevel@tonic-gate }
25137c478bd9Sstevel@tonic-gate 
25147c478bd9Sstevel@tonic-gate void
25157c478bd9Sstevel@tonic-gate print_efi_string(char *vendor, char *product, char *revision,
25167c478bd9Sstevel@tonic-gate     uint64_t capacity)
25177c478bd9Sstevel@tonic-gate {
2518*f1bf0656SHans Rosenfeld 	char *new_vendor;
2519*f1bf0656SHans Rosenfeld 	char *new_product;
2520*f1bf0656SHans Rosenfeld 	char *new_revision;
25217c478bd9Sstevel@tonic-gate 	char capacity_string[10];
25227c478bd9Sstevel@tonic-gate 	float scaled;
25237c478bd9Sstevel@tonic-gate 	int i;
25247c478bd9Sstevel@tonic-gate 
25257c478bd9Sstevel@tonic-gate 	/* Strip whitespace from the end of inquiry strings */
2526*f1bf0656SHans Rosenfeld 	new_vendor = strdup(vendor);
2527*f1bf0656SHans Rosenfeld 	if (new_vendor == NULL)
2528*f1bf0656SHans Rosenfeld 		return;
2529*f1bf0656SHans Rosenfeld 
25307c478bd9Sstevel@tonic-gate 	for (i = (strlen(new_vendor) - 1); i >= 0; i--) {
25317c478bd9Sstevel@tonic-gate 		if (new_vendor[i] != 0x20) {
25327c478bd9Sstevel@tonic-gate 			new_vendor[i+1] = '\0';
25337c478bd9Sstevel@tonic-gate 			break;
25347c478bd9Sstevel@tonic-gate 		}
25357c478bd9Sstevel@tonic-gate 	}
25367c478bd9Sstevel@tonic-gate 
2537*f1bf0656SHans Rosenfeld 	new_product = strdup(product);
2538*f1bf0656SHans Rosenfeld 	if (new_product == NULL) {
2539*f1bf0656SHans Rosenfeld 		free(new_vendor);
2540*f1bf0656SHans Rosenfeld 		return;
2541*f1bf0656SHans Rosenfeld 	}
2542*f1bf0656SHans Rosenfeld 
25437c478bd9Sstevel@tonic-gate 	for (i = (strlen(new_product) - 1); i >= 0; i--) {
25447c478bd9Sstevel@tonic-gate 		if (new_product[i] != 0x20) {
25457c478bd9Sstevel@tonic-gate 			new_product[i+1] = '\0';
25467c478bd9Sstevel@tonic-gate 			break;
25477c478bd9Sstevel@tonic-gate 		}
25487c478bd9Sstevel@tonic-gate 	}
25497c478bd9Sstevel@tonic-gate 
2550*f1bf0656SHans Rosenfeld 	new_revision = strdup(revision);
2551*f1bf0656SHans Rosenfeld 	if (new_product == NULL) {
2552*f1bf0656SHans Rosenfeld 		free(new_vendor);
2553*f1bf0656SHans Rosenfeld 		free(new_product);
2554*f1bf0656SHans Rosenfeld 		return;
2555*f1bf0656SHans Rosenfeld 	}
2556*f1bf0656SHans Rosenfeld 
25577c478bd9Sstevel@tonic-gate 	for (i = (strlen(new_revision) - 1); i >= 0; i--) {
25587c478bd9Sstevel@tonic-gate 		if (new_revision[i] != 0x20) {
25597c478bd9Sstevel@tonic-gate 			new_revision[i+1] = '\0';
25607c478bd9Sstevel@tonic-gate 			break;
25617c478bd9Sstevel@tonic-gate 		}
25627c478bd9Sstevel@tonic-gate 	}
25637c478bd9Sstevel@tonic-gate 
25647c478bd9Sstevel@tonic-gate 	/* Now build size string */
25657c478bd9Sstevel@tonic-gate 	scaled = bn2mb(capacity);
25667c478bd9Sstevel@tonic-gate 	if (scaled >= (float)1024.0 * 1024) {
25677c478bd9Sstevel@tonic-gate 		(void) snprintf(capacity_string, sizeof (capacity_string),
25687c478bd9Sstevel@tonic-gate 		    "%.2fTB", scaled/((float)1024.0 * 1024));
25697c478bd9Sstevel@tonic-gate 	} else if (scaled >= (float)1024.0) {
25707c478bd9Sstevel@tonic-gate 		(void) snprintf(capacity_string, sizeof (capacity_string),
25717c478bd9Sstevel@tonic-gate 		    "%.2fGB", scaled/(float)1024.0);
25727c478bd9Sstevel@tonic-gate 	} else {
25737c478bd9Sstevel@tonic-gate 		(void) snprintf(capacity_string, sizeof (capacity_string),
25747c478bd9Sstevel@tonic-gate 		    "%.2fMB", scaled);
25757c478bd9Sstevel@tonic-gate 	}
25767c478bd9Sstevel@tonic-gate 
25777c478bd9Sstevel@tonic-gate 	fmt_print("<%s-%s-%s-%s>",
25787c478bd9Sstevel@tonic-gate 	    new_vendor, new_product, new_revision, capacity_string);
2579*f1bf0656SHans Rosenfeld 
2580*f1bf0656SHans Rosenfeld 	free(new_revision);
2581*f1bf0656SHans Rosenfeld 	free(new_product);
2582*f1bf0656SHans Rosenfeld 	free(new_vendor);
25837c478bd9Sstevel@tonic-gate }
2584