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