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