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