1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * This file contains I/O related functions. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate #include "global.h" 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include <unistd.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include <signal.h> 38*7c478bd9Sstevel@tonic-gate #include <ctype.h> 39*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/tty.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/termio.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/termios.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include "startup.h" 45*7c478bd9Sstevel@tonic-gate #include "misc.h" 46*7c478bd9Sstevel@tonic-gate #include "menu_partition.h" 47*7c478bd9Sstevel@tonic-gate #include "param.h" 48*7c478bd9Sstevel@tonic-gate #include "menu.h" 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate extern int data_lineno; 52*7c478bd9Sstevel@tonic-gate extern char *space2str(); 53*7c478bd9Sstevel@tonic-gate extern long strtol(); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * This variable is used to determine whether a token is present in the pipe 57*7c478bd9Sstevel@tonic-gate * already. 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate static char token_present = 0; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* 62*7c478bd9Sstevel@tonic-gate * This variable always gives us access to the most recent token type 63*7c478bd9Sstevel@tonic-gate */ 64*7c478bd9Sstevel@tonic-gate int last_token_type = 0; 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate * Prototypes for ANSI C compilers 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate static int sup_get_token(char *); 71*7c478bd9Sstevel@tonic-gate static void pushchar(int c); 72*7c478bd9Sstevel@tonic-gate static int checkeof(void); 73*7c478bd9Sstevel@tonic-gate static void flushline(void); 74*7c478bd9Sstevel@tonic-gate static int strcnt(char *s1, char *s2); 75*7c478bd9Sstevel@tonic-gate static int getbn(char *str, daddr_t *iptr); 76*7c478bd9Sstevel@tonic-gate static void print_input_choices(int type, u_ioparam_t *param); 77*7c478bd9Sstevel@tonic-gate static int slist_widest_str(slist_t *slist); 78*7c478bd9Sstevel@tonic-gate static void ljust_print(char *str, int width); 79*7c478bd9Sstevel@tonic-gate static int sup_inputchar(void); 80*7c478bd9Sstevel@tonic-gate static void sup_pushchar(int c); 81*7c478bd9Sstevel@tonic-gate static int geti64(char *str, uint64_t *iptr, uint64_t *wild); 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 84*7c478bd9Sstevel@tonic-gate /* 85*7c478bd9Sstevel@tonic-gate * Prototypes for non-ANSI C compilers 86*7c478bd9Sstevel@tonic-gate */ 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate static int sup_get_token(); 89*7c478bd9Sstevel@tonic-gate static void pushchar(int c); 90*7c478bd9Sstevel@tonic-gate static int checkeof(void); 91*7c478bd9Sstevel@tonic-gate static void flushline(void); 92*7c478bd9Sstevel@tonic-gate static int strcnt(char *s1, char *s2); 93*7c478bd9Sstevel@tonic-gate static int getbn(char *str, daddr_t *iptr); 94*7c478bd9Sstevel@tonic-gate static void print_input_choices(int type, u_ioparam_t *param); 95*7c478bd9Sstevel@tonic-gate static int slist_widest_str(slist_t *slist); 96*7c478bd9Sstevel@tonic-gate static void ljust_print(char *str, int width); 97*7c478bd9Sstevel@tonic-gate static int sup_inputchar(void); 98*7c478bd9Sstevel@tonic-gate static void sup_pushchar(int c); 99*7c478bd9Sstevel@tonic-gate static int geti64(char *str, uint64_t *iptr, uint64_t *wild); 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate * This routine pushes the given character back onto the input stream. 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate static void 108*7c478bd9Sstevel@tonic-gate pushchar(c) 109*7c478bd9Sstevel@tonic-gate int c; 110*7c478bd9Sstevel@tonic-gate { 111*7c478bd9Sstevel@tonic-gate (void) ungetc(c, stdin); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * This routine checks the input stream for an eof condition. 116*7c478bd9Sstevel@tonic-gate */ 117*7c478bd9Sstevel@tonic-gate static int 118*7c478bd9Sstevel@tonic-gate checkeof() 119*7c478bd9Sstevel@tonic-gate { 120*7c478bd9Sstevel@tonic-gate return (feof(stdin)); 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate /* 124*7c478bd9Sstevel@tonic-gate * This routine gets the next token off the input stream. A token is 125*7c478bd9Sstevel@tonic-gate * basically any consecutive non-white characters. 126*7c478bd9Sstevel@tonic-gate */ 127*7c478bd9Sstevel@tonic-gate char * 128*7c478bd9Sstevel@tonic-gate gettoken(inbuf) 129*7c478bd9Sstevel@tonic-gate char *inbuf; 130*7c478bd9Sstevel@tonic-gate { 131*7c478bd9Sstevel@tonic-gate char *ptr = inbuf; 132*7c478bd9Sstevel@tonic-gate int c, quoted = 0; 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate retoke: 135*7c478bd9Sstevel@tonic-gate /* 136*7c478bd9Sstevel@tonic-gate * Remove any leading white-space. 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate while ((isspace(c = getchar())) && (c != '\n')) 139*7c478bd9Sstevel@tonic-gate ; 140*7c478bd9Sstevel@tonic-gate /* 141*7c478bd9Sstevel@tonic-gate * If we are at the beginning of a line and hit the comment character, 142*7c478bd9Sstevel@tonic-gate * flush the line and start again. 143*7c478bd9Sstevel@tonic-gate */ 144*7c478bd9Sstevel@tonic-gate if (!token_present && c == COMMENT_CHAR) { 145*7c478bd9Sstevel@tonic-gate token_present = 1; 146*7c478bd9Sstevel@tonic-gate flushline(); 147*7c478bd9Sstevel@tonic-gate goto retoke; 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate /* 150*7c478bd9Sstevel@tonic-gate * Loop on each character until we hit unquoted white-space. 151*7c478bd9Sstevel@tonic-gate */ 152*7c478bd9Sstevel@tonic-gate while (!isspace(c) || quoted && (c != '\n')) { 153*7c478bd9Sstevel@tonic-gate /* 154*7c478bd9Sstevel@tonic-gate * If we hit eof, get out. 155*7c478bd9Sstevel@tonic-gate */ 156*7c478bd9Sstevel@tonic-gate if (checkeof()) 157*7c478bd9Sstevel@tonic-gate return (NULL); 158*7c478bd9Sstevel@tonic-gate /* 159*7c478bd9Sstevel@tonic-gate * If we hit a double quote, change the state of quotedness. 160*7c478bd9Sstevel@tonic-gate */ 161*7c478bd9Sstevel@tonic-gate if (c == '"') 162*7c478bd9Sstevel@tonic-gate quoted = !quoted; 163*7c478bd9Sstevel@tonic-gate /* 164*7c478bd9Sstevel@tonic-gate * If there's room in the buffer, add the character to the end. 165*7c478bd9Sstevel@tonic-gate */ 166*7c478bd9Sstevel@tonic-gate else if (ptr - inbuf < TOKEN_SIZE) 167*7c478bd9Sstevel@tonic-gate *ptr++ = (char)c; 168*7c478bd9Sstevel@tonic-gate /* 169*7c478bd9Sstevel@tonic-gate * Get the next character. 170*7c478bd9Sstevel@tonic-gate */ 171*7c478bd9Sstevel@tonic-gate c = getchar(); 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate /* 174*7c478bd9Sstevel@tonic-gate * Null terminate the token. 175*7c478bd9Sstevel@tonic-gate */ 176*7c478bd9Sstevel@tonic-gate *ptr = '\0'; 177*7c478bd9Sstevel@tonic-gate /* 178*7c478bd9Sstevel@tonic-gate * Peel off white-space still in the pipe. 179*7c478bd9Sstevel@tonic-gate */ 180*7c478bd9Sstevel@tonic-gate while (isspace(c) && (c != '\n')) 181*7c478bd9Sstevel@tonic-gate c = getchar(); 182*7c478bd9Sstevel@tonic-gate /* 183*7c478bd9Sstevel@tonic-gate * If we hit another token, push it back and set state. 184*7c478bd9Sstevel@tonic-gate */ 185*7c478bd9Sstevel@tonic-gate if (c != '\n') { 186*7c478bd9Sstevel@tonic-gate pushchar(c); 187*7c478bd9Sstevel@tonic-gate token_present = 1; 188*7c478bd9Sstevel@tonic-gate } else 189*7c478bd9Sstevel@tonic-gate token_present = 0; 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * Return the token. 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate return (inbuf); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* 197*7c478bd9Sstevel@tonic-gate * This routine removes the leading and trailing spaces from a token. 198*7c478bd9Sstevel@tonic-gate */ 199*7c478bd9Sstevel@tonic-gate void 200*7c478bd9Sstevel@tonic-gate clean_token(cleantoken, token) 201*7c478bd9Sstevel@tonic-gate char *cleantoken, *token; 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate char *ptr; 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate /* 206*7c478bd9Sstevel@tonic-gate * Strip off leading white-space. 207*7c478bd9Sstevel@tonic-gate */ 208*7c478bd9Sstevel@tonic-gate for (ptr = token; isspace(*ptr); ptr++) 209*7c478bd9Sstevel@tonic-gate ; 210*7c478bd9Sstevel@tonic-gate /* 211*7c478bd9Sstevel@tonic-gate * Copy it into the clean buffer. 212*7c478bd9Sstevel@tonic-gate */ 213*7c478bd9Sstevel@tonic-gate (void) strcpy(cleantoken, ptr); 214*7c478bd9Sstevel@tonic-gate /* 215*7c478bd9Sstevel@tonic-gate * Strip off trailing white-space. 216*7c478bd9Sstevel@tonic-gate */ 217*7c478bd9Sstevel@tonic-gate for (ptr = cleantoken + strlen(cleantoken) - 1; 218*7c478bd9Sstevel@tonic-gate isspace(*ptr) && (ptr >= cleantoken); ptr--) { 219*7c478bd9Sstevel@tonic-gate *ptr = '\0'; 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* 224*7c478bd9Sstevel@tonic-gate * This routine checks if a token is already present on the input line 225*7c478bd9Sstevel@tonic-gate */ 226*7c478bd9Sstevel@tonic-gate int 227*7c478bd9Sstevel@tonic-gate istokenpresent() 228*7c478bd9Sstevel@tonic-gate { 229*7c478bd9Sstevel@tonic-gate return (token_present); 230*7c478bd9Sstevel@tonic-gate } 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate /* 233*7c478bd9Sstevel@tonic-gate * This routine flushes the rest of an input line if there is known 234*7c478bd9Sstevel@tonic-gate * to be data in it. The flush has to be qualified because the newline 235*7c478bd9Sstevel@tonic-gate * may have already been swallowed by the last gettoken. 236*7c478bd9Sstevel@tonic-gate */ 237*7c478bd9Sstevel@tonic-gate static void 238*7c478bd9Sstevel@tonic-gate flushline() 239*7c478bd9Sstevel@tonic-gate { 240*7c478bd9Sstevel@tonic-gate if (token_present) { 241*7c478bd9Sstevel@tonic-gate /* 242*7c478bd9Sstevel@tonic-gate * Flush the pipe to eol or eof. 243*7c478bd9Sstevel@tonic-gate */ 244*7c478bd9Sstevel@tonic-gate while ((getchar() != '\n') && !checkeof()) 245*7c478bd9Sstevel@tonic-gate ; 246*7c478bd9Sstevel@tonic-gate /* 247*7c478bd9Sstevel@tonic-gate * Mark the pipe empty. 248*7c478bd9Sstevel@tonic-gate */ 249*7c478bd9Sstevel@tonic-gate token_present = 0; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate /* 254*7c478bd9Sstevel@tonic-gate * This routine returns the number of characters that are identical 255*7c478bd9Sstevel@tonic-gate * between s1 and s2, stopping as soon as a mismatch is found. 256*7c478bd9Sstevel@tonic-gate */ 257*7c478bd9Sstevel@tonic-gate static int 258*7c478bd9Sstevel@tonic-gate strcnt(s1, s2) 259*7c478bd9Sstevel@tonic-gate char *s1, *s2; 260*7c478bd9Sstevel@tonic-gate { 261*7c478bd9Sstevel@tonic-gate int i = 0; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate while ((*s1 != '\0') && (*s1++ == *s2++)) 264*7c478bd9Sstevel@tonic-gate i++; 265*7c478bd9Sstevel@tonic-gate return (i); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate /* 269*7c478bd9Sstevel@tonic-gate * This routine converts the given token into an integer. The token 270*7c478bd9Sstevel@tonic-gate * must convert cleanly into an integer with no unknown characters. 271*7c478bd9Sstevel@tonic-gate * If the token is the wildcard string, and the wildcard parameter 272*7c478bd9Sstevel@tonic-gate * is present, the wildcard value will be returned. 273*7c478bd9Sstevel@tonic-gate */ 274*7c478bd9Sstevel@tonic-gate int 275*7c478bd9Sstevel@tonic-gate geti(str, iptr, wild) 276*7c478bd9Sstevel@tonic-gate char *str; 277*7c478bd9Sstevel@tonic-gate int *iptr, *wild; 278*7c478bd9Sstevel@tonic-gate { 279*7c478bd9Sstevel@tonic-gate char *str2; 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* 282*7c478bd9Sstevel@tonic-gate * If there's a wildcard value and the string is wild, return the 283*7c478bd9Sstevel@tonic-gate * wildcard value. 284*7c478bd9Sstevel@tonic-gate */ 285*7c478bd9Sstevel@tonic-gate if (wild != NULL && strcmp(str, WILD_STRING) == 0) 286*7c478bd9Sstevel@tonic-gate *iptr = *wild; 287*7c478bd9Sstevel@tonic-gate else { 288*7c478bd9Sstevel@tonic-gate /* 289*7c478bd9Sstevel@tonic-gate * Conver the string to an integer. 290*7c478bd9Sstevel@tonic-gate */ 291*7c478bd9Sstevel@tonic-gate *iptr = (int)strtol(str, &str2, 0); 292*7c478bd9Sstevel@tonic-gate /* 293*7c478bd9Sstevel@tonic-gate * If any characters didn't convert, it's an error. 294*7c478bd9Sstevel@tonic-gate */ 295*7c478bd9Sstevel@tonic-gate if (*str2 != '\0') { 296*7c478bd9Sstevel@tonic-gate err_print("`%s' is not an integer.\n", str); 297*7c478bd9Sstevel@tonic-gate return (-1); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate return (0); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate /* 304*7c478bd9Sstevel@tonic-gate * This routine converts the given token into a long long. The token 305*7c478bd9Sstevel@tonic-gate * must convert cleanly into a 64-bit integer with no unknown characters. 306*7c478bd9Sstevel@tonic-gate * If the token is the wildcard string, and the wildcard parameter 307*7c478bd9Sstevel@tonic-gate * is present, the wildcard value will be returned. 308*7c478bd9Sstevel@tonic-gate */ 309*7c478bd9Sstevel@tonic-gate static int 310*7c478bd9Sstevel@tonic-gate geti64(str, iptr, wild) 311*7c478bd9Sstevel@tonic-gate char *str; 312*7c478bd9Sstevel@tonic-gate uint64_t *iptr, *wild; 313*7c478bd9Sstevel@tonic-gate { 314*7c478bd9Sstevel@tonic-gate char *str2; 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate /* 317*7c478bd9Sstevel@tonic-gate * If there's a wildcard value and the string is wild, return the 318*7c478bd9Sstevel@tonic-gate * wildcard value. 319*7c478bd9Sstevel@tonic-gate */ 320*7c478bd9Sstevel@tonic-gate if ((wild != NULL) && (strcmp(str, WILD_STRING)) == 0) { 321*7c478bd9Sstevel@tonic-gate *iptr = *wild; 322*7c478bd9Sstevel@tonic-gate } else { 323*7c478bd9Sstevel@tonic-gate /* 324*7c478bd9Sstevel@tonic-gate * Conver the string to an integer. 325*7c478bd9Sstevel@tonic-gate */ 326*7c478bd9Sstevel@tonic-gate *iptr = (uint64_t)strtoll(str, &str2, 0); 327*7c478bd9Sstevel@tonic-gate /* 328*7c478bd9Sstevel@tonic-gate * If any characters didn't convert, it's an error. 329*7c478bd9Sstevel@tonic-gate */ 330*7c478bd9Sstevel@tonic-gate if (*str2 != '\0') { 331*7c478bd9Sstevel@tonic-gate err_print("`%s' is not an integer.\n", str); 332*7c478bd9Sstevel@tonic-gate return (-1); 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate return (0); 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate /* 339*7c478bd9Sstevel@tonic-gate * This routine converts the given string into a block number on the 340*7c478bd9Sstevel@tonic-gate * current disk. The format of a block number is either a self-based 341*7c478bd9Sstevel@tonic-gate * number, or a series of self-based numbers separated by slashes. 342*7c478bd9Sstevel@tonic-gate * Any number preceeding the first slash is considered a cylinder value. 343*7c478bd9Sstevel@tonic-gate * Any number succeeding the first slash but preceeding the second is 344*7c478bd9Sstevel@tonic-gate * considered a head value. Any number succeeding the second slash is 345*7c478bd9Sstevel@tonic-gate * considered a sector value. Any of these numbers can be wildcarded 346*7c478bd9Sstevel@tonic-gate * to the highest possible legal value. 347*7c478bd9Sstevel@tonic-gate */ 348*7c478bd9Sstevel@tonic-gate static int 349*7c478bd9Sstevel@tonic-gate getbn(str, iptr) 350*7c478bd9Sstevel@tonic-gate char *str; 351*7c478bd9Sstevel@tonic-gate daddr_t *iptr; 352*7c478bd9Sstevel@tonic-gate { 353*7c478bd9Sstevel@tonic-gate char *cptr, *hptr, *sptr; 354*7c478bd9Sstevel@tonic-gate int cyl, head, sect, wild; 355*7c478bd9Sstevel@tonic-gate TOKEN buf; 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate /* 358*7c478bd9Sstevel@tonic-gate * Set cylinder pointer to beginning of string. 359*7c478bd9Sstevel@tonic-gate */ 360*7c478bd9Sstevel@tonic-gate cptr = str; 361*7c478bd9Sstevel@tonic-gate /* 362*7c478bd9Sstevel@tonic-gate * Look for the first slash. 363*7c478bd9Sstevel@tonic-gate */ 364*7c478bd9Sstevel@tonic-gate while ((*str != '\0') && (*str != '/')) 365*7c478bd9Sstevel@tonic-gate str++; 366*7c478bd9Sstevel@tonic-gate /* 367*7c478bd9Sstevel@tonic-gate * If there wasn't one, convert string to an integer and return it. 368*7c478bd9Sstevel@tonic-gate */ 369*7c478bd9Sstevel@tonic-gate if (*str == '\0') { 370*7c478bd9Sstevel@tonic-gate wild = physsects() - 1; 371*7c478bd9Sstevel@tonic-gate if (geti(cptr, (int *)iptr, &wild)) 372*7c478bd9Sstevel@tonic-gate return (-1); 373*7c478bd9Sstevel@tonic-gate return (0); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate /* 376*7c478bd9Sstevel@tonic-gate * Null out the slash and set head pointer just beyond it. 377*7c478bd9Sstevel@tonic-gate */ 378*7c478bd9Sstevel@tonic-gate *str++ = '\0'; 379*7c478bd9Sstevel@tonic-gate hptr = str; 380*7c478bd9Sstevel@tonic-gate /* 381*7c478bd9Sstevel@tonic-gate * Look for the second slash. 382*7c478bd9Sstevel@tonic-gate */ 383*7c478bd9Sstevel@tonic-gate while ((*str != '\0') && (*str != '/')) 384*7c478bd9Sstevel@tonic-gate str++; 385*7c478bd9Sstevel@tonic-gate /* 386*7c478bd9Sstevel@tonic-gate * If there wasn't one, sector pointer points to a . 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate if (*str == '\0') 389*7c478bd9Sstevel@tonic-gate sptr = str; 390*7c478bd9Sstevel@tonic-gate /* 391*7c478bd9Sstevel@tonic-gate * If there was, null it out and set sector point just beyond it. 392*7c478bd9Sstevel@tonic-gate */ 393*7c478bd9Sstevel@tonic-gate else { 394*7c478bd9Sstevel@tonic-gate *str++ = '\0'; 395*7c478bd9Sstevel@tonic-gate sptr = str; 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate /* 398*7c478bd9Sstevel@tonic-gate * Convert the cylinder part to an integer and store it. 399*7c478bd9Sstevel@tonic-gate */ 400*7c478bd9Sstevel@tonic-gate clean_token(buf, cptr); 401*7c478bd9Sstevel@tonic-gate wild = ncyl + acyl - 1; 402*7c478bd9Sstevel@tonic-gate if (geti(buf, &cyl, &wild)) 403*7c478bd9Sstevel@tonic-gate return (-1); 404*7c478bd9Sstevel@tonic-gate if ((cyl < 0) || (cyl >= (ncyl + acyl))) { 405*7c478bd9Sstevel@tonic-gate err_print("`%d' is out of range.\n", cyl); 406*7c478bd9Sstevel@tonic-gate return (-1); 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate /* 409*7c478bd9Sstevel@tonic-gate * Convert the head part to an integer and store it. 410*7c478bd9Sstevel@tonic-gate */ 411*7c478bd9Sstevel@tonic-gate clean_token(buf, hptr); 412*7c478bd9Sstevel@tonic-gate wild = nhead - 1; 413*7c478bd9Sstevel@tonic-gate if (geti(buf, &head, &wild)) 414*7c478bd9Sstevel@tonic-gate return (-1); 415*7c478bd9Sstevel@tonic-gate if ((head < 0) || (head >= nhead)) { 416*7c478bd9Sstevel@tonic-gate err_print("`%d' is out of range.\n", head); 417*7c478bd9Sstevel@tonic-gate return (-1); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate /* 420*7c478bd9Sstevel@tonic-gate * Convert the sector part to an integer and store it. 421*7c478bd9Sstevel@tonic-gate */ 422*7c478bd9Sstevel@tonic-gate clean_token(buf, sptr); 423*7c478bd9Sstevel@tonic-gate wild = sectors(head) - 1; 424*7c478bd9Sstevel@tonic-gate if (geti(buf, §, &wild)) 425*7c478bd9Sstevel@tonic-gate return (-1); 426*7c478bd9Sstevel@tonic-gate if ((sect < 0) || (sect >= sectors(head))) { 427*7c478bd9Sstevel@tonic-gate err_print("`%d' is out of range.\n", sect); 428*7c478bd9Sstevel@tonic-gate return (-1); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate /* 431*7c478bd9Sstevel@tonic-gate * Combine the pieces into a block number and return it. 432*7c478bd9Sstevel@tonic-gate */ 433*7c478bd9Sstevel@tonic-gate *iptr = chs2bn(cyl, head, sect); 434*7c478bd9Sstevel@tonic-gate return (0); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate /* 438*7c478bd9Sstevel@tonic-gate * This routine is the basis for all input into the program. It 439*7c478bd9Sstevel@tonic-gate * understands the semantics of a set of input types, and provides 440*7c478bd9Sstevel@tonic-gate * consistent error messages for all input. It allows for default 441*7c478bd9Sstevel@tonic-gate * values and prompt strings. 442*7c478bd9Sstevel@tonic-gate */ 443*7c478bd9Sstevel@tonic-gate uint64_t 444*7c478bd9Sstevel@tonic-gate input(type, promptstr, delim, param, deflt, cmdflag) 445*7c478bd9Sstevel@tonic-gate int type; 446*7c478bd9Sstevel@tonic-gate char *promptstr; 447*7c478bd9Sstevel@tonic-gate int delim; 448*7c478bd9Sstevel@tonic-gate u_ioparam_t *param; 449*7c478bd9Sstevel@tonic-gate int *deflt; 450*7c478bd9Sstevel@tonic-gate int cmdflag; 451*7c478bd9Sstevel@tonic-gate { 452*7c478bd9Sstevel@tonic-gate int interactive, help, i, length, index, tied; 453*7c478bd9Sstevel@tonic-gate daddr_t bn; 454*7c478bd9Sstevel@tonic-gate diskaddr_t bn64; 455*7c478bd9Sstevel@tonic-gate char **str, **strings; 456*7c478bd9Sstevel@tonic-gate TOKEN token, cleantoken; 457*7c478bd9Sstevel@tonic-gate TOKEN token2, cleantoken2; 458*7c478bd9Sstevel@tonic-gate struct bounds *bounds; 459*7c478bd9Sstevel@tonic-gate char *s; 460*7c478bd9Sstevel@tonic-gate int value; 461*7c478bd9Sstevel@tonic-gate int cyls, cylno; 462*7c478bd9Sstevel@tonic-gate uint64_t blokno; 463*7c478bd9Sstevel@tonic-gate float nmegs; 464*7c478bd9Sstevel@tonic-gate float ngigs; 465*7c478bd9Sstevel@tonic-gate char shell_argv[MAXPATHLEN]; 466*7c478bd9Sstevel@tonic-gate part_deflt_t *part_deflt; 467*7c478bd9Sstevel@tonic-gate efi_deflt_t *efi_deflt; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate /* 470*7c478bd9Sstevel@tonic-gate * Optional integer input has been added as a hack. 471*7c478bd9Sstevel@tonic-gate * Function result is 1 if user typed anything. 472*7c478bd9Sstevel@tonic-gate * Whatever they typed is returned in *deflt. 473*7c478bd9Sstevel@tonic-gate * This permits us to distinguish between "no value", 474*7c478bd9Sstevel@tonic-gate * and actually entering in some value, for instance. 475*7c478bd9Sstevel@tonic-gate */ 476*7c478bd9Sstevel@tonic-gate if (type == FIO_OPINT) { 477*7c478bd9Sstevel@tonic-gate assert(deflt != NULL); 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate reprompt: 480*7c478bd9Sstevel@tonic-gate help = interactive = 0; 481*7c478bd9Sstevel@tonic-gate /* 482*7c478bd9Sstevel@tonic-gate * If we are inputting a command, flush any current input in the pipe. 483*7c478bd9Sstevel@tonic-gate */ 484*7c478bd9Sstevel@tonic-gate if (cmdflag == CMD_INPUT) 485*7c478bd9Sstevel@tonic-gate flushline(); 486*7c478bd9Sstevel@tonic-gate /* 487*7c478bd9Sstevel@tonic-gate * Note whether the token is already present. 488*7c478bd9Sstevel@tonic-gate */ 489*7c478bd9Sstevel@tonic-gate if (!token_present) 490*7c478bd9Sstevel@tonic-gate interactive = 1; 491*7c478bd9Sstevel@tonic-gate /* 492*7c478bd9Sstevel@tonic-gate * Print the prompt. 493*7c478bd9Sstevel@tonic-gate */ 494*7c478bd9Sstevel@tonic-gate fmt_print(promptstr); 495*7c478bd9Sstevel@tonic-gate /* 496*7c478bd9Sstevel@tonic-gate * If there is a default value, print it in a format appropriate 497*7c478bd9Sstevel@tonic-gate * for the input type. 498*7c478bd9Sstevel@tonic-gate */ 499*7c478bd9Sstevel@tonic-gate if (deflt != NULL) { 500*7c478bd9Sstevel@tonic-gate switch (type) { 501*7c478bd9Sstevel@tonic-gate case FIO_BN: 502*7c478bd9Sstevel@tonic-gate fmt_print("[%d, ", *deflt); 503*7c478bd9Sstevel@tonic-gate pr_dblock(fmt_print, (daddr_t)*deflt); 504*7c478bd9Sstevel@tonic-gate fmt_print("]"); 505*7c478bd9Sstevel@tonic-gate break; 506*7c478bd9Sstevel@tonic-gate case FIO_INT: 507*7c478bd9Sstevel@tonic-gate fmt_print("[%d]", *deflt); 508*7c478bd9Sstevel@tonic-gate break; 509*7c478bd9Sstevel@tonic-gate case FIO_INT64: 510*7c478bd9Sstevel@tonic-gate #if defined(lint) 511*7c478bd9Sstevel@tonic-gate /* caller is longlong aligned specifying FIO_INT64 */ 512*7c478bd9Sstevel@tonic-gate efi_deflt = NULL; 513*7c478bd9Sstevel@tonic-gate #else 514*7c478bd9Sstevel@tonic-gate efi_deflt = (efi_deflt_t *)deflt; 515*7c478bd9Sstevel@tonic-gate #endif 516*7c478bd9Sstevel@tonic-gate fmt_print("[%llu]", efi_deflt->start_sector); 517*7c478bd9Sstevel@tonic-gate break; 518*7c478bd9Sstevel@tonic-gate case FIO_CSTR: 519*7c478bd9Sstevel@tonic-gate case FIO_MSTR: 520*7c478bd9Sstevel@tonic-gate strings = (char **)param->io_charlist; 521*7c478bd9Sstevel@tonic-gate for (i = 0, str = strings; i < *deflt; i++, str++) 522*7c478bd9Sstevel@tonic-gate ; 523*7c478bd9Sstevel@tonic-gate fmt_print("[%s]", *str); 524*7c478bd9Sstevel@tonic-gate break; 525*7c478bd9Sstevel@tonic-gate case FIO_OSTR: 526*7c478bd9Sstevel@tonic-gate fmt_print("[\"%s\"]", (char *)deflt); 527*7c478bd9Sstevel@tonic-gate break; 528*7c478bd9Sstevel@tonic-gate case FIO_SLIST: 529*7c478bd9Sstevel@tonic-gate /* 530*7c478bd9Sstevel@tonic-gate * Search for a string matching the default 531*7c478bd9Sstevel@tonic-gate * value. If found, use it. Otherwise 532*7c478bd9Sstevel@tonic-gate * assume the default value is actually 533*7c478bd9Sstevel@tonic-gate * an illegal choice, and default to 534*7c478bd9Sstevel@tonic-gate * the first item in the list. 535*7c478bd9Sstevel@tonic-gate */ 536*7c478bd9Sstevel@tonic-gate s = find_string(param->io_slist, *deflt); 537*7c478bd9Sstevel@tonic-gate if (s == (char *)NULL) { 538*7c478bd9Sstevel@tonic-gate s = (param->io_slist)->str; 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate fmt_print("[%s]", s); 541*7c478bd9Sstevel@tonic-gate break; 542*7c478bd9Sstevel@tonic-gate case FIO_CYL: 543*7c478bd9Sstevel@tonic-gate /* 544*7c478bd9Sstevel@tonic-gate * Old-style partition size input, used to 545*7c478bd9Sstevel@tonic-gate * modify complete partition tables 546*7c478bd9Sstevel@tonic-gate */ 547*7c478bd9Sstevel@tonic-gate fmt_print("[%db, %dc, %1.2fmb, %1.2fgb]", *deflt, 548*7c478bd9Sstevel@tonic-gate bn2c(*deflt), bn2mb(*deflt), bn2gb(*deflt)); 549*7c478bd9Sstevel@tonic-gate break; 550*7c478bd9Sstevel@tonic-gate case FIO_ECYL: 551*7c478bd9Sstevel@tonic-gate /* 552*7c478bd9Sstevel@tonic-gate * set up pointer to partition defaults 553*7c478bd9Sstevel@tonic-gate * structure 554*7c478bd9Sstevel@tonic-gate */ 555*7c478bd9Sstevel@tonic-gate part_deflt = (part_deflt_t *)deflt; 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate /* 558*7c478bd9Sstevel@tonic-gate * Build print format specifier. We use the 559*7c478bd9Sstevel@tonic-gate * starting cylinder number which was entered 560*7c478bd9Sstevel@tonic-gate * before this call to input(), in case the 561*7c478bd9Sstevel@tonic-gate * user has changed it from the value in the 562*7c478bd9Sstevel@tonic-gate * cur_parts->pinfo_map[].dkl_cylno 563*7c478bd9Sstevel@tonic-gate * field for the current parition 564*7c478bd9Sstevel@tonic-gate */ 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate /* 567*7c478bd9Sstevel@tonic-gate * Determine the proper default end cylinder: 568*7c478bd9Sstevel@tonic-gate * Start Cyl Default Size End Cylinder 569*7c478bd9Sstevel@tonic-gate * 0 0 0 570*7c478bd9Sstevel@tonic-gate * >0 0 Start Cyl 571*7c478bd9Sstevel@tonic-gate * 0 >0 Default Size 572*7c478bd9Sstevel@tonic-gate * (Cyls) - 1 573*7c478bd9Sstevel@tonic-gate * >0 >0 (Start + 574*7c478bd9Sstevel@tonic-gate * Default Size 575*7c478bd9Sstevel@tonic-gate * (Cyls)) -1 576*7c478bd9Sstevel@tonic-gate */ 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate if (part_deflt->deflt_size == 0) { 579*7c478bd9Sstevel@tonic-gate cylno = part_deflt->start_cyl; 580*7c478bd9Sstevel@tonic-gate } else if (part_deflt->start_cyl == 0) { 581*7c478bd9Sstevel@tonic-gate cylno = bn2c(part_deflt->deflt_size) 582*7c478bd9Sstevel@tonic-gate - 1; 583*7c478bd9Sstevel@tonic-gate } else { 584*7c478bd9Sstevel@tonic-gate cylno = (bn2c(part_deflt->deflt_size) + 585*7c478bd9Sstevel@tonic-gate part_deflt->start_cyl) - 1; 586*7c478bd9Sstevel@tonic-gate } 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate fmt_print("[%db, %dc, %de, %1.2fmb, %1.2fgb]", 589*7c478bd9Sstevel@tonic-gate part_deflt->deflt_size, 590*7c478bd9Sstevel@tonic-gate bn2c(part_deflt->deflt_size), 591*7c478bd9Sstevel@tonic-gate cylno, 592*7c478bd9Sstevel@tonic-gate bn2mb(part_deflt->deflt_size), 593*7c478bd9Sstevel@tonic-gate bn2gb(part_deflt->deflt_size)); 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate break; 596*7c478bd9Sstevel@tonic-gate case FIO_EFI: 597*7c478bd9Sstevel@tonic-gate #if defined(lint) 598*7c478bd9Sstevel@tonic-gate /* caller is longlong aligned when specifying FIO_EFI */ 599*7c478bd9Sstevel@tonic-gate efi_deflt = NULL; 600*7c478bd9Sstevel@tonic-gate #else 601*7c478bd9Sstevel@tonic-gate efi_deflt = (efi_deflt_t *)deflt; 602*7c478bd9Sstevel@tonic-gate #endif 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate fmt_print("[%llub, %llue, %llumb, %llugb, %llutb]", 605*7c478bd9Sstevel@tonic-gate efi_deflt->end_sector, 606*7c478bd9Sstevel@tonic-gate efi_deflt->start_sector + efi_deflt->end_sector - 1, 607*7c478bd9Sstevel@tonic-gate (efi_deflt->end_sector * DEV_BSIZE) / 608*7c478bd9Sstevel@tonic-gate (1024 * 1024), 609*7c478bd9Sstevel@tonic-gate (efi_deflt->end_sector * DEV_BSIZE) / 610*7c478bd9Sstevel@tonic-gate (1024 * 1024 * 1024), 611*7c478bd9Sstevel@tonic-gate (efi_deflt->end_sector * DEV_BSIZE) / 612*7c478bd9Sstevel@tonic-gate ((uint64_t)1024 * 1024 * 1024 * 1024)); 613*7c478bd9Sstevel@tonic-gate break; 614*7c478bd9Sstevel@tonic-gate case FIO_OPINT: 615*7c478bd9Sstevel@tonic-gate /* no default value for optional input type */ 616*7c478bd9Sstevel@tonic-gate fmt_print("[default]"); 617*7c478bd9Sstevel@tonic-gate break; 618*7c478bd9Sstevel@tonic-gate default: 619*7c478bd9Sstevel@tonic-gate err_print("Error: unknown input type.\n"); 620*7c478bd9Sstevel@tonic-gate fullabort(); 621*7c478bd9Sstevel@tonic-gate } 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate /* 624*7c478bd9Sstevel@tonic-gate * Print the delimiter character. 625*7c478bd9Sstevel@tonic-gate */ 626*7c478bd9Sstevel@tonic-gate fmt_print("%c ", delim); 627*7c478bd9Sstevel@tonic-gate /* 628*7c478bd9Sstevel@tonic-gate * Get the token. If we hit eof, exit the program gracefully. 629*7c478bd9Sstevel@tonic-gate */ 630*7c478bd9Sstevel@tonic-gate if (gettoken(token) == NULL) 631*7c478bd9Sstevel@tonic-gate fullabort(); 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate /* 634*7c478bd9Sstevel@tonic-gate * check if the user has issued (!) , escape to shell 635*7c478bd9Sstevel@tonic-gate */ 636*7c478bd9Sstevel@tonic-gate if ((cmdflag == CMD_INPUT) && (token[0] == '!')) { 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate /* get the list of arguments to shell command */ 639*7c478bd9Sstevel@tonic-gate (void) memset(shell_argv, 0, MAXPATHLEN); 640*7c478bd9Sstevel@tonic-gate if (strlen(token) > 1) { 641*7c478bd9Sstevel@tonic-gate if (strlcpy(shell_argv, &token[1], MAXPATHLEN) >= 642*7c478bd9Sstevel@tonic-gate MAXPATHLEN) { 643*7c478bd9Sstevel@tonic-gate err_print("Error: token length exceeds " 644*7c478bd9Sstevel@tonic-gate "MAXPATHLEN\n"); 645*7c478bd9Sstevel@tonic-gate fullabort(); 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate } 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate /* 650*7c478bd9Sstevel@tonic-gate * collect all tokens till the end of line as arguments 651*7c478bd9Sstevel@tonic-gate */ 652*7c478bd9Sstevel@tonic-gate while (token_present && (gettoken(token) != NULL)) { 653*7c478bd9Sstevel@tonic-gate (void) strcat(shell_argv, " "); 654*7c478bd9Sstevel@tonic-gate (void) strcat(shell_argv, token); 655*7c478bd9Sstevel@tonic-gate } 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate /* execute the shell command */ 658*7c478bd9Sstevel@tonic-gate (void) execute_shell(shell_argv); 659*7c478bd9Sstevel@tonic-gate redisplay_menu_list((char **)param->io_charlist); 660*7c478bd9Sstevel@tonic-gate if (interactive) { 661*7c478bd9Sstevel@tonic-gate goto reprompt; 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate } 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate /* 666*7c478bd9Sstevel@tonic-gate * Certain commands accept up to two tokens 667*7c478bd9Sstevel@tonic-gate * Unfortunately, this is kind of a hack. 668*7c478bd9Sstevel@tonic-gate */ 669*7c478bd9Sstevel@tonic-gate token2[0] = 0; 670*7c478bd9Sstevel@tonic-gate cleantoken2[0] = 0; 671*7c478bd9Sstevel@tonic-gate if (type == FIO_CYL || type == FIO_ECYL) { 672*7c478bd9Sstevel@tonic-gate if (token_present) { 673*7c478bd9Sstevel@tonic-gate if (gettoken(token2) == NULL) 674*7c478bd9Sstevel@tonic-gate fullabort(); 675*7c478bd9Sstevel@tonic-gate clean_token(cleantoken2, token2); 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate /* 679*7c478bd9Sstevel@tonic-gate * Echo the token back to the user if it was in the pipe or we 680*7c478bd9Sstevel@tonic-gate * are running out of a command file. 681*7c478bd9Sstevel@tonic-gate */ 682*7c478bd9Sstevel@tonic-gate if (!interactive || option_f) { 683*7c478bd9Sstevel@tonic-gate if (token2[0] == 0) { 684*7c478bd9Sstevel@tonic-gate fmt_print("%s\n", token); 685*7c478bd9Sstevel@tonic-gate } else { 686*7c478bd9Sstevel@tonic-gate fmt_print("%s %s\n", token, token2); 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate /* 690*7c478bd9Sstevel@tonic-gate * If we are logging, echo the token to the log file. The else 691*7c478bd9Sstevel@tonic-gate * is necessary here because the above printf will also put the 692*7c478bd9Sstevel@tonic-gate * token in the log file. 693*7c478bd9Sstevel@tonic-gate */ 694*7c478bd9Sstevel@tonic-gate else if (log_file) { 695*7c478bd9Sstevel@tonic-gate log_print("%s %s\n", token, token2); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate /* 698*7c478bd9Sstevel@tonic-gate * If the token was not in the pipe and it wasn't a command, flush 699*7c478bd9Sstevel@tonic-gate * the rest of the line to keep things in sync. 700*7c478bd9Sstevel@tonic-gate */ 701*7c478bd9Sstevel@tonic-gate if (interactive && cmdflag != CMD_INPUT) 702*7c478bd9Sstevel@tonic-gate flushline(); 703*7c478bd9Sstevel@tonic-gate /* 704*7c478bd9Sstevel@tonic-gate * Scrub off the white-space. 705*7c478bd9Sstevel@tonic-gate */ 706*7c478bd9Sstevel@tonic-gate clean_token(cleantoken, token); 707*7c478bd9Sstevel@tonic-gate /* 708*7c478bd9Sstevel@tonic-gate * If the input was a blank line and we weren't prompting 709*7c478bd9Sstevel@tonic-gate * specifically for a blank line... 710*7c478bd9Sstevel@tonic-gate */ 711*7c478bd9Sstevel@tonic-gate if ((strcmp(cleantoken, "") == 0) && (type != FIO_BLNK)) { 712*7c478bd9Sstevel@tonic-gate /* 713*7c478bd9Sstevel@tonic-gate * If there's a default, return it. 714*7c478bd9Sstevel@tonic-gate */ 715*7c478bd9Sstevel@tonic-gate if (deflt != NULL) { 716*7c478bd9Sstevel@tonic-gate if (type == FIO_OSTR) { 717*7c478bd9Sstevel@tonic-gate /* 718*7c478bd9Sstevel@tonic-gate * Duplicate and return the default string 719*7c478bd9Sstevel@tonic-gate */ 720*7c478bd9Sstevel@tonic-gate return ((int)alloc_string((char *)deflt)); 721*7c478bd9Sstevel@tonic-gate } else if (type == FIO_SLIST) { 722*7c478bd9Sstevel@tonic-gate /* 723*7c478bd9Sstevel@tonic-gate * If we can find a match for the default 724*7c478bd9Sstevel@tonic-gate * value in the list, return the default 725*7c478bd9Sstevel@tonic-gate * value. If there's no match for the 726*7c478bd9Sstevel@tonic-gate * default value, it's an illegal 727*7c478bd9Sstevel@tonic-gate * choice. Return the first value in 728*7c478bd9Sstevel@tonic-gate * the list. 729*7c478bd9Sstevel@tonic-gate */ 730*7c478bd9Sstevel@tonic-gate s = find_string(param->io_slist, *deflt); 731*7c478bd9Sstevel@tonic-gate if ((cur_label == L_TYPE_EFI) && 732*7c478bd9Sstevel@tonic-gate (s == (char *)NULL)) { 733*7c478bd9Sstevel@tonic-gate return (*deflt); 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate if (s == (char *)NULL) { 736*7c478bd9Sstevel@tonic-gate return ((param->io_slist)->value); 737*7c478bd9Sstevel@tonic-gate } else { 738*7c478bd9Sstevel@tonic-gate return (*deflt); 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate } else if (type == FIO_OPINT) { 741*7c478bd9Sstevel@tonic-gate /* 742*7c478bd9Sstevel@tonic-gate * The user didn't enter anything 743*7c478bd9Sstevel@tonic-gate */ 744*7c478bd9Sstevel@tonic-gate return (0); 745*7c478bd9Sstevel@tonic-gate } else if (type == FIO_ECYL) { 746*7c478bd9Sstevel@tonic-gate return (part_deflt->deflt_size); 747*7c478bd9Sstevel@tonic-gate } else if (type == FIO_INT64) { 748*7c478bd9Sstevel@tonic-gate return (efi_deflt->start_sector); 749*7c478bd9Sstevel@tonic-gate } else if (type == FIO_EFI) { 750*7c478bd9Sstevel@tonic-gate return (efi_deflt->end_sector); 751*7c478bd9Sstevel@tonic-gate } else { 752*7c478bd9Sstevel@tonic-gate return (*deflt); 753*7c478bd9Sstevel@tonic-gate } 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate /* 756*7c478bd9Sstevel@tonic-gate * If the blank was not in the pipe, just reprompt. 757*7c478bd9Sstevel@tonic-gate */ 758*7c478bd9Sstevel@tonic-gate if (interactive) { 759*7c478bd9Sstevel@tonic-gate goto reprompt; 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate /* 762*7c478bd9Sstevel@tonic-gate * If the blank was in the pipe, it's an error. 763*7c478bd9Sstevel@tonic-gate */ 764*7c478bd9Sstevel@tonic-gate err_print("No default for this entry.\n"); 765*7c478bd9Sstevel@tonic-gate cmdabort(SIGINT); 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate /* 768*7c478bd9Sstevel@tonic-gate * If token is a '?' or a 'h', it is a request for help. 769*7c478bd9Sstevel@tonic-gate */ 770*7c478bd9Sstevel@tonic-gate if ((strcmp(cleantoken, "?") == 0) || 771*7c478bd9Sstevel@tonic-gate (strcmp(cleantoken, "h") == 0) || 772*7c478bd9Sstevel@tonic-gate (strcmp(cleantoken, "help") == 0)) { 773*7c478bd9Sstevel@tonic-gate help = 1; 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate /* 776*7c478bd9Sstevel@tonic-gate * Switch on the type of input expected. 777*7c478bd9Sstevel@tonic-gate */ 778*7c478bd9Sstevel@tonic-gate switch (type) { 779*7c478bd9Sstevel@tonic-gate /* 780*7c478bd9Sstevel@tonic-gate * Expecting a disk block number. 781*7c478bd9Sstevel@tonic-gate */ 782*7c478bd9Sstevel@tonic-gate case FIO_BN: 783*7c478bd9Sstevel@tonic-gate /* 784*7c478bd9Sstevel@tonic-gate * Parameter is the bounds of legal block numbers. 785*7c478bd9Sstevel@tonic-gate */ 786*7c478bd9Sstevel@tonic-gate bounds = (struct bounds *)¶m->io_bounds; 787*7c478bd9Sstevel@tonic-gate /* 788*7c478bd9Sstevel@tonic-gate * Print help message if required. 789*7c478bd9Sstevel@tonic-gate */ 790*7c478bd9Sstevel@tonic-gate if (help) { 791*7c478bd9Sstevel@tonic-gate fmt_print("Expecting a block number from %llu (", 792*7c478bd9Sstevel@tonic-gate bounds->lower); 793*7c478bd9Sstevel@tonic-gate pr_dblock(fmt_print, bounds->lower); 794*7c478bd9Sstevel@tonic-gate fmt_print(") to %llu (", bounds->upper); 795*7c478bd9Sstevel@tonic-gate pr_dblock(fmt_print, bounds->upper); 796*7c478bd9Sstevel@tonic-gate fmt_print(")\n"); 797*7c478bd9Sstevel@tonic-gate break; 798*7c478bd9Sstevel@tonic-gate } 799*7c478bd9Sstevel@tonic-gate /* 800*7c478bd9Sstevel@tonic-gate * Convert token to a disk block number. 801*7c478bd9Sstevel@tonic-gate */ 802*7c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 803*7c478bd9Sstevel@tonic-gate if (geti64(cleantoken, (uint64_t *)&bn64, 804*7c478bd9Sstevel@tonic-gate (uint64_t *)NULL)) 805*7c478bd9Sstevel@tonic-gate break; 806*7c478bd9Sstevel@tonic-gate } else { 807*7c478bd9Sstevel@tonic-gate if (getbn(cleantoken, &bn)) 808*7c478bd9Sstevel@tonic-gate break; 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) { 811*7c478bd9Sstevel@tonic-gate if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) { 812*7c478bd9Sstevel@tonic-gate err_print("`"); 813*7c478bd9Sstevel@tonic-gate pr_dblock(err_print, bn64); 814*7c478bd9Sstevel@tonic-gate err_print("' is out of range.\n"); 815*7c478bd9Sstevel@tonic-gate break; 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate return (bn64); 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate /* 820*7c478bd9Sstevel@tonic-gate * Check to be sure it is within the legal bounds. 821*7c478bd9Sstevel@tonic-gate */ 822*7c478bd9Sstevel@tonic-gate if ((bn < bounds->lower) || (bn > bounds->upper)) { 823*7c478bd9Sstevel@tonic-gate err_print("`"); 824*7c478bd9Sstevel@tonic-gate pr_dblock(err_print, bn); 825*7c478bd9Sstevel@tonic-gate err_print("' is out of range.\n"); 826*7c478bd9Sstevel@tonic-gate break; 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate /* 829*7c478bd9Sstevel@tonic-gate * If it's ok, return it. 830*7c478bd9Sstevel@tonic-gate */ 831*7c478bd9Sstevel@tonic-gate return (bn); 832*7c478bd9Sstevel@tonic-gate /* 833*7c478bd9Sstevel@tonic-gate * Expecting an integer. 834*7c478bd9Sstevel@tonic-gate */ 835*7c478bd9Sstevel@tonic-gate case FIO_INT: 836*7c478bd9Sstevel@tonic-gate /* 837*7c478bd9Sstevel@tonic-gate * Parameter is the bounds of legal integers. 838*7c478bd9Sstevel@tonic-gate */ 839*7c478bd9Sstevel@tonic-gate bounds = (struct bounds *)¶m->io_bounds; 840*7c478bd9Sstevel@tonic-gate /* 841*7c478bd9Sstevel@tonic-gate * Print help message if required. 842*7c478bd9Sstevel@tonic-gate */ 843*7c478bd9Sstevel@tonic-gate if (help) { 844*7c478bd9Sstevel@tonic-gate fmt_print("Expecting an integer from %llu", 845*7c478bd9Sstevel@tonic-gate bounds->lower); 846*7c478bd9Sstevel@tonic-gate fmt_print(" to %llu\n", bounds->upper); 847*7c478bd9Sstevel@tonic-gate break; 848*7c478bd9Sstevel@tonic-gate } 849*7c478bd9Sstevel@tonic-gate /* 850*7c478bd9Sstevel@tonic-gate * Convert the token into an integer. 851*7c478bd9Sstevel@tonic-gate */ 852*7c478bd9Sstevel@tonic-gate if (geti(cleantoken, (int *)&bn, (int *)NULL)) 853*7c478bd9Sstevel@tonic-gate break; 854*7c478bd9Sstevel@tonic-gate /* 855*7c478bd9Sstevel@tonic-gate * Check to be sure it is within the legal bounds. 856*7c478bd9Sstevel@tonic-gate */ 857*7c478bd9Sstevel@tonic-gate if ((bn < bounds->lower) || (bn > bounds->upper)) { 858*7c478bd9Sstevel@tonic-gate err_print("`%ld' is out of range.\n", bn); 859*7c478bd9Sstevel@tonic-gate break; 860*7c478bd9Sstevel@tonic-gate } 861*7c478bd9Sstevel@tonic-gate /* 862*7c478bd9Sstevel@tonic-gate * If it's ok, return it. 863*7c478bd9Sstevel@tonic-gate */ 864*7c478bd9Sstevel@tonic-gate return (bn); 865*7c478bd9Sstevel@tonic-gate case FIO_INT64: 866*7c478bd9Sstevel@tonic-gate /* 867*7c478bd9Sstevel@tonic-gate * Parameter is the bounds of legal integers. 868*7c478bd9Sstevel@tonic-gate */ 869*7c478bd9Sstevel@tonic-gate bounds = (struct bounds *)¶m->io_bounds; 870*7c478bd9Sstevel@tonic-gate /* 871*7c478bd9Sstevel@tonic-gate * Print help message if required. 872*7c478bd9Sstevel@tonic-gate */ 873*7c478bd9Sstevel@tonic-gate if (help) { 874*7c478bd9Sstevel@tonic-gate fmt_print("Expecting an integer from %llu", 875*7c478bd9Sstevel@tonic-gate bounds->lower); 876*7c478bd9Sstevel@tonic-gate fmt_print(" to %llu\n", bounds->upper); 877*7c478bd9Sstevel@tonic-gate break; 878*7c478bd9Sstevel@tonic-gate } 879*7c478bd9Sstevel@tonic-gate /* 880*7c478bd9Sstevel@tonic-gate * Convert the token into an integer. 881*7c478bd9Sstevel@tonic-gate */ 882*7c478bd9Sstevel@tonic-gate if (geti64(cleantoken, (uint64_t *)&bn64, (uint64_t *)NULL)) { 883*7c478bd9Sstevel@tonic-gate break; 884*7c478bd9Sstevel@tonic-gate } 885*7c478bd9Sstevel@tonic-gate /* 886*7c478bd9Sstevel@tonic-gate * Check to be sure it is within the legal bounds. 887*7c478bd9Sstevel@tonic-gate */ 888*7c478bd9Sstevel@tonic-gate if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) { 889*7c478bd9Sstevel@tonic-gate err_print("`%llu' is out of range.\n", bn64); 890*7c478bd9Sstevel@tonic-gate break; 891*7c478bd9Sstevel@tonic-gate } 892*7c478bd9Sstevel@tonic-gate /* 893*7c478bd9Sstevel@tonic-gate * If it's ok, return it. 894*7c478bd9Sstevel@tonic-gate */ 895*7c478bd9Sstevel@tonic-gate return (bn64); 896*7c478bd9Sstevel@tonic-gate /* 897*7c478bd9Sstevel@tonic-gate * Expecting an integer, or no input. 898*7c478bd9Sstevel@tonic-gate */ 899*7c478bd9Sstevel@tonic-gate case FIO_OPINT: 900*7c478bd9Sstevel@tonic-gate /* 901*7c478bd9Sstevel@tonic-gate * Parameter is the bounds of legal integers. 902*7c478bd9Sstevel@tonic-gate */ 903*7c478bd9Sstevel@tonic-gate bounds = (struct bounds *)¶m->io_bounds; 904*7c478bd9Sstevel@tonic-gate /* 905*7c478bd9Sstevel@tonic-gate * Print help message if required. 906*7c478bd9Sstevel@tonic-gate */ 907*7c478bd9Sstevel@tonic-gate if (help) { 908*7c478bd9Sstevel@tonic-gate fmt_print("Expecting an integer from %llu", 909*7c478bd9Sstevel@tonic-gate bounds->lower); 910*7c478bd9Sstevel@tonic-gate fmt_print(" to %llu, or no input\n", bounds->upper); 911*7c478bd9Sstevel@tonic-gate break; 912*7c478bd9Sstevel@tonic-gate } 913*7c478bd9Sstevel@tonic-gate /* 914*7c478bd9Sstevel@tonic-gate * Convert the token into an integer. 915*7c478bd9Sstevel@tonic-gate */ 916*7c478bd9Sstevel@tonic-gate if (geti(cleantoken, (int *)&bn, (int *)NULL)) 917*7c478bd9Sstevel@tonic-gate break; 918*7c478bd9Sstevel@tonic-gate /* 919*7c478bd9Sstevel@tonic-gate * Check to be sure it is within the legal bounds. 920*7c478bd9Sstevel@tonic-gate */ 921*7c478bd9Sstevel@tonic-gate if ((bn < bounds->lower) || (bn > bounds->upper)) { 922*7c478bd9Sstevel@tonic-gate err_print("`%ld' is out of range.\n", bn); 923*7c478bd9Sstevel@tonic-gate break; 924*7c478bd9Sstevel@tonic-gate } 925*7c478bd9Sstevel@tonic-gate /* 926*7c478bd9Sstevel@tonic-gate * For optional case, return 1 indicating that 927*7c478bd9Sstevel@tonic-gate * the user actually did enter something. 928*7c478bd9Sstevel@tonic-gate */ 929*7c478bd9Sstevel@tonic-gate *deflt = bn; 930*7c478bd9Sstevel@tonic-gate return (1); 931*7c478bd9Sstevel@tonic-gate /* 932*7c478bd9Sstevel@tonic-gate * Expecting a closed string. This means that the input 933*7c478bd9Sstevel@tonic-gate * string must exactly match one of the strings passed in 934*7c478bd9Sstevel@tonic-gate * as the parameter. 935*7c478bd9Sstevel@tonic-gate */ 936*7c478bd9Sstevel@tonic-gate case FIO_CSTR: 937*7c478bd9Sstevel@tonic-gate /* 938*7c478bd9Sstevel@tonic-gate * The parameter is a null terminated array of character 939*7c478bd9Sstevel@tonic-gate * pointers, each one pointing to a legal input string. 940*7c478bd9Sstevel@tonic-gate */ 941*7c478bd9Sstevel@tonic-gate strings = (char **)param->io_charlist; 942*7c478bd9Sstevel@tonic-gate /* 943*7c478bd9Sstevel@tonic-gate * Walk through the legal strings, seeing if any of them 944*7c478bd9Sstevel@tonic-gate * match the token. If a match is made, return the index 945*7c478bd9Sstevel@tonic-gate * of the string that was matched. 946*7c478bd9Sstevel@tonic-gate */ 947*7c478bd9Sstevel@tonic-gate for (str = strings; *str != NULL; str++) 948*7c478bd9Sstevel@tonic-gate if (strcmp(cleantoken, *str) == 0) 949*7c478bd9Sstevel@tonic-gate return (str - strings); 950*7c478bd9Sstevel@tonic-gate /* 951*7c478bd9Sstevel@tonic-gate * Print help message if required. 952*7c478bd9Sstevel@tonic-gate */ 953*7c478bd9Sstevel@tonic-gate if (help) { 954*7c478bd9Sstevel@tonic-gate print_input_choices(type, param); 955*7c478bd9Sstevel@tonic-gate } else { 956*7c478bd9Sstevel@tonic-gate err_print("`%s' is not expected.\n", cleantoken); 957*7c478bd9Sstevel@tonic-gate } 958*7c478bd9Sstevel@tonic-gate break; 959*7c478bd9Sstevel@tonic-gate /* 960*7c478bd9Sstevel@tonic-gate * Expecting a matched string. This means that the input 961*7c478bd9Sstevel@tonic-gate * string must either match one of the strings passed in, 962*7c478bd9Sstevel@tonic-gate * or be a unique abbreviation of one of them. 963*7c478bd9Sstevel@tonic-gate */ 964*7c478bd9Sstevel@tonic-gate case FIO_MSTR: 965*7c478bd9Sstevel@tonic-gate /* 966*7c478bd9Sstevel@tonic-gate * The parameter is a null terminated array of character 967*7c478bd9Sstevel@tonic-gate * pointers, each one pointing to a legal input string. 968*7c478bd9Sstevel@tonic-gate */ 969*7c478bd9Sstevel@tonic-gate strings = (char **)param->io_charlist; 970*7c478bd9Sstevel@tonic-gate length = index = tied = 0; 971*7c478bd9Sstevel@tonic-gate /* 972*7c478bd9Sstevel@tonic-gate * Loop through the legal input strings. 973*7c478bd9Sstevel@tonic-gate */ 974*7c478bd9Sstevel@tonic-gate for (str = strings; *str != NULL; str++) { 975*7c478bd9Sstevel@tonic-gate /* 976*7c478bd9Sstevel@tonic-gate * See how many characters of the token match 977*7c478bd9Sstevel@tonic-gate * this legal string. 978*7c478bd9Sstevel@tonic-gate */ 979*7c478bd9Sstevel@tonic-gate i = strcnt(cleantoken, *str); 980*7c478bd9Sstevel@tonic-gate /* 981*7c478bd9Sstevel@tonic-gate * If it's not the whole token, then it's not a match. 982*7c478bd9Sstevel@tonic-gate */ 983*7c478bd9Sstevel@tonic-gate if ((uint_t)i < strlen(cleantoken)) 984*7c478bd9Sstevel@tonic-gate continue; 985*7c478bd9Sstevel@tonic-gate /* 986*7c478bd9Sstevel@tonic-gate * If it ties with another input, remember that. 987*7c478bd9Sstevel@tonic-gate */ 988*7c478bd9Sstevel@tonic-gate if (i == length) 989*7c478bd9Sstevel@tonic-gate tied = 1; 990*7c478bd9Sstevel@tonic-gate /* 991*7c478bd9Sstevel@tonic-gate * If it matches the most so far, record that. 992*7c478bd9Sstevel@tonic-gate */ 993*7c478bd9Sstevel@tonic-gate if (i > length) { 994*7c478bd9Sstevel@tonic-gate index = str - strings; 995*7c478bd9Sstevel@tonic-gate tied = 0; 996*7c478bd9Sstevel@tonic-gate length = i; 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate } 999*7c478bd9Sstevel@tonic-gate /* 1000*7c478bd9Sstevel@tonic-gate * Print help message if required. 1001*7c478bd9Sstevel@tonic-gate */ 1002*7c478bd9Sstevel@tonic-gate if (length == 0) { 1003*7c478bd9Sstevel@tonic-gate if (help) { 1004*7c478bd9Sstevel@tonic-gate print_input_choices(type, param); 1005*7c478bd9Sstevel@tonic-gate } else { 1006*7c478bd9Sstevel@tonic-gate err_print("`%s' is not expected.\n", 1007*7c478bd9Sstevel@tonic-gate cleantoken); 1008*7c478bd9Sstevel@tonic-gate } 1009*7c478bd9Sstevel@tonic-gate break; 1010*7c478bd9Sstevel@tonic-gate } 1011*7c478bd9Sstevel@tonic-gate /* 1012*7c478bd9Sstevel@tonic-gate * If the abbreviation was non-unique, it's an error. 1013*7c478bd9Sstevel@tonic-gate */ 1014*7c478bd9Sstevel@tonic-gate if (tied) { 1015*7c478bd9Sstevel@tonic-gate err_print("`%s' is ambiguous.\n", cleantoken); 1016*7c478bd9Sstevel@tonic-gate break; 1017*7c478bd9Sstevel@tonic-gate } 1018*7c478bd9Sstevel@tonic-gate /* 1019*7c478bd9Sstevel@tonic-gate * We matched one. Return the index of the string we matched. 1020*7c478bd9Sstevel@tonic-gate */ 1021*7c478bd9Sstevel@tonic-gate return (index); 1022*7c478bd9Sstevel@tonic-gate /* 1023*7c478bd9Sstevel@tonic-gate * Expecting an open string. This means that any string is legal. 1024*7c478bd9Sstevel@tonic-gate */ 1025*7c478bd9Sstevel@tonic-gate case FIO_OSTR: 1026*7c478bd9Sstevel@tonic-gate /* 1027*7c478bd9Sstevel@tonic-gate * Print a help message if required. 1028*7c478bd9Sstevel@tonic-gate */ 1029*7c478bd9Sstevel@tonic-gate if (help) { 1030*7c478bd9Sstevel@tonic-gate fmt_print("Expecting a string\n"); 1031*7c478bd9Sstevel@tonic-gate break; 1032*7c478bd9Sstevel@tonic-gate } 1033*7c478bd9Sstevel@tonic-gate /* 1034*7c478bd9Sstevel@tonic-gate * alloc a copy of the string and return it 1035*7c478bd9Sstevel@tonic-gate */ 1036*7c478bd9Sstevel@tonic-gate return ((int)alloc_string(token)); 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate /* 1039*7c478bd9Sstevel@tonic-gate * Expecting a blank line. 1040*7c478bd9Sstevel@tonic-gate */ 1041*7c478bd9Sstevel@tonic-gate case FIO_BLNK: 1042*7c478bd9Sstevel@tonic-gate /* 1043*7c478bd9Sstevel@tonic-gate * We are always in non-echo mode when we are inputting 1044*7c478bd9Sstevel@tonic-gate * this type. We echo the newline as a carriage return 1045*7c478bd9Sstevel@tonic-gate * only so the prompt string will be covered over. 1046*7c478bd9Sstevel@tonic-gate */ 1047*7c478bd9Sstevel@tonic-gate nolog_print("\015"); 1048*7c478bd9Sstevel@tonic-gate /* 1049*7c478bd9Sstevel@tonic-gate * If we are logging, send a newline to the log file. 1050*7c478bd9Sstevel@tonic-gate */ 1051*7c478bd9Sstevel@tonic-gate if (log_file) 1052*7c478bd9Sstevel@tonic-gate log_print("\n"); 1053*7c478bd9Sstevel@tonic-gate /* 1054*7c478bd9Sstevel@tonic-gate * There is no value returned for this type. 1055*7c478bd9Sstevel@tonic-gate */ 1056*7c478bd9Sstevel@tonic-gate return (0); 1057*7c478bd9Sstevel@tonic-gate 1058*7c478bd9Sstevel@tonic-gate /* 1059*7c478bd9Sstevel@tonic-gate * Expecting one of the entries in a string list. 1060*7c478bd9Sstevel@tonic-gate * Accept unique abbreviations. 1061*7c478bd9Sstevel@tonic-gate * Return the value associated with the matched string. 1062*7c478bd9Sstevel@tonic-gate */ 1063*7c478bd9Sstevel@tonic-gate case FIO_SLIST: 1064*7c478bd9Sstevel@tonic-gate i = find_value((slist_t *)param->io_slist, 1065*7c478bd9Sstevel@tonic-gate cleantoken, &value); 1066*7c478bd9Sstevel@tonic-gate if (i == 1) { 1067*7c478bd9Sstevel@tonic-gate return (value); 1068*7c478bd9Sstevel@tonic-gate } else { 1069*7c478bd9Sstevel@tonic-gate /* 1070*7c478bd9Sstevel@tonic-gate * Print help message if required. 1071*7c478bd9Sstevel@tonic-gate */ 1072*7c478bd9Sstevel@tonic-gate 1073*7c478bd9Sstevel@tonic-gate if (help) { 1074*7c478bd9Sstevel@tonic-gate print_input_choices(type, param); 1075*7c478bd9Sstevel@tonic-gate } else { 1076*7c478bd9Sstevel@tonic-gate if (i == 0) 1077*7c478bd9Sstevel@tonic-gate err_print("`%s' not expected.\n", 1078*7c478bd9Sstevel@tonic-gate cleantoken); 1079*7c478bd9Sstevel@tonic-gate else 1080*7c478bd9Sstevel@tonic-gate err_print("`%s' is ambiguous.\n", 1081*7c478bd9Sstevel@tonic-gate cleantoken); 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate } 1084*7c478bd9Sstevel@tonic-gate break; 1085*7c478bd9Sstevel@tonic-gate 1086*7c478bd9Sstevel@tonic-gate /* 1087*7c478bd9Sstevel@tonic-gate * Cylinder size input when modifying a complete partition map 1088*7c478bd9Sstevel@tonic-gate */ 1089*7c478bd9Sstevel@tonic-gate case FIO_CYL: 1090*7c478bd9Sstevel@tonic-gate /* 1091*7c478bd9Sstevel@tonic-gate * Parameter is the bounds of legal block numbers. 1092*7c478bd9Sstevel@tonic-gate */ 1093*7c478bd9Sstevel@tonic-gate bounds = (struct bounds *)¶m->io_bounds; 1094*7c478bd9Sstevel@tonic-gate assert(bounds->lower == 0); 1095*7c478bd9Sstevel@tonic-gate /* 1096*7c478bd9Sstevel@tonic-gate * Print help message if required. 1097*7c478bd9Sstevel@tonic-gate */ 1098*7c478bd9Sstevel@tonic-gate if (help) { 1099*7c478bd9Sstevel@tonic-gate fmt_print("Expecting up to %llu blocks,", 1100*7c478bd9Sstevel@tonic-gate bounds->upper); 1101*7c478bd9Sstevel@tonic-gate fmt_print(" %llu cylinders, ", bn2c(bounds->upper)); 1102*7c478bd9Sstevel@tonic-gate fmt_print(" %1.2f megabytes, ", bn2mb(bounds->upper)); 1103*7c478bd9Sstevel@tonic-gate fmt_print("or %1.2f gigabytes\n", bn2gb(bounds->upper)); 1104*7c478bd9Sstevel@tonic-gate break; 1105*7c478bd9Sstevel@tonic-gate } 1106*7c478bd9Sstevel@tonic-gate /* 1107*7c478bd9Sstevel@tonic-gate * Parse the first token: try to find 'b', 'c' or 'm' 1108*7c478bd9Sstevel@tonic-gate */ 1109*7c478bd9Sstevel@tonic-gate s = cleantoken; 1110*7c478bd9Sstevel@tonic-gate while (*s && (isdigit(*s) || (*s == '.') || (*s == '$'))) { 1111*7c478bd9Sstevel@tonic-gate s++; 1112*7c478bd9Sstevel@tonic-gate } 1113*7c478bd9Sstevel@tonic-gate /* 1114*7c478bd9Sstevel@tonic-gate * If we found a conversion specifier, second token is unused 1115*7c478bd9Sstevel@tonic-gate * Otherwise, the second token should supply it. 1116*7c478bd9Sstevel@tonic-gate */ 1117*7c478bd9Sstevel@tonic-gate if (*s != 0) { 1118*7c478bd9Sstevel@tonic-gate value = *s; 1119*7c478bd9Sstevel@tonic-gate *s = 0; 1120*7c478bd9Sstevel@tonic-gate } else { 1121*7c478bd9Sstevel@tonic-gate value = cleantoken2[0]; 1122*7c478bd9Sstevel@tonic-gate } 1123*7c478bd9Sstevel@tonic-gate /* 1124*7c478bd9Sstevel@tonic-gate * If the token is the wild card, simply supply the max 1125*7c478bd9Sstevel@tonic-gate * This order allows the user to specify the maximum in 1126*7c478bd9Sstevel@tonic-gate * either blocks/cyls/megabytes - a convenient fiction. 1127*7c478bd9Sstevel@tonic-gate */ 1128*7c478bd9Sstevel@tonic-gate if (strcmp(cleantoken, WILD_STRING) == 0) { 1129*7c478bd9Sstevel@tonic-gate return (bounds->upper); 1130*7c478bd9Sstevel@tonic-gate } 1131*7c478bd9Sstevel@tonic-gate /* 1132*7c478bd9Sstevel@tonic-gate * Allow the user to specify zero with no units, 1133*7c478bd9Sstevel@tonic-gate * by just defaulting to cylinders. 1134*7c478bd9Sstevel@tonic-gate */ 1135*7c478bd9Sstevel@tonic-gate if (strcmp(cleantoken, "0") == 0) { 1136*7c478bd9Sstevel@tonic-gate value = 'c'; 1137*7c478bd9Sstevel@tonic-gate } 1138*7c478bd9Sstevel@tonic-gate /* 1139*7c478bd9Sstevel@tonic-gate * If there's a decimal point, but no unit specification, 1140*7c478bd9Sstevel@tonic-gate * let's assume megabytes. 1141*7c478bd9Sstevel@tonic-gate */ 1142*7c478bd9Sstevel@tonic-gate if ((value == 0) && (strchr(cleantoken, '.') != NULL)) { 1143*7c478bd9Sstevel@tonic-gate value = 'm'; 1144*7c478bd9Sstevel@tonic-gate } 1145*7c478bd9Sstevel@tonic-gate /* 1146*7c478bd9Sstevel@tonic-gate * Handle each unit type we support 1147*7c478bd9Sstevel@tonic-gate */ 1148*7c478bd9Sstevel@tonic-gate switch (value) { 1149*7c478bd9Sstevel@tonic-gate case 'b': 1150*7c478bd9Sstevel@tonic-gate /* 1151*7c478bd9Sstevel@tonic-gate * Convert token to a disk block number. 1152*7c478bd9Sstevel@tonic-gate */ 1153*7c478bd9Sstevel@tonic-gate i = bounds->upper; 1154*7c478bd9Sstevel@tonic-gate if (geti(cleantoken, &value, &i)) 1155*7c478bd9Sstevel@tonic-gate break; 1156*7c478bd9Sstevel@tonic-gate bn = value; 1157*7c478bd9Sstevel@tonic-gate /* 1158*7c478bd9Sstevel@tonic-gate * Check to be sure it is within the legal bounds. 1159*7c478bd9Sstevel@tonic-gate */ 1160*7c478bd9Sstevel@tonic-gate if ((bn < bounds->lower) || (bn > bounds->upper)) { 1161*7c478bd9Sstevel@tonic-gate err_print( 1162*7c478bd9Sstevel@tonic-gate "`%ldb' is out of the range %llu to %llu\n", 1163*7c478bd9Sstevel@tonic-gate bn, bounds->lower, bounds->upper); 1164*7c478bd9Sstevel@tonic-gate break; 1165*7c478bd9Sstevel@tonic-gate } 1166*7c478bd9Sstevel@tonic-gate /* 1167*7c478bd9Sstevel@tonic-gate * Verify the block lies on a cylinder boundary 1168*7c478bd9Sstevel@tonic-gate */ 1169*7c478bd9Sstevel@tonic-gate if ((bn % spc()) != 0) { 1170*7c478bd9Sstevel@tonic-gate err_print( 1171*7c478bd9Sstevel@tonic-gate "partition size must be a multiple of %d blocks to lie on a cylinder \ 1172*7c478bd9Sstevel@tonic-gate boundary\n", 1173*7c478bd9Sstevel@tonic-gate spc()); 1174*7c478bd9Sstevel@tonic-gate err_print( 1175*7c478bd9Sstevel@tonic-gate "%ld blocks is approximately %ld cylinders, %1.2f megabytes or %1.2f\ 1176*7c478bd9Sstevel@tonic-gate gigabytes\n", 1177*7c478bd9Sstevel@tonic-gate bn, bn2c(bn), bn2mb(bn), bn2gb(bn)); 1178*7c478bd9Sstevel@tonic-gate break; 1179*7c478bd9Sstevel@tonic-gate } 1180*7c478bd9Sstevel@tonic-gate return (bn); 1181*7c478bd9Sstevel@tonic-gate case 'c': 1182*7c478bd9Sstevel@tonic-gate /* 1183*7c478bd9Sstevel@tonic-gate * Convert token from a number of cylinders to 1184*7c478bd9Sstevel@tonic-gate * a number of blocks. 1185*7c478bd9Sstevel@tonic-gate */ 1186*7c478bd9Sstevel@tonic-gate i = bn2c(bounds->upper); 1187*7c478bd9Sstevel@tonic-gate if (geti(cleantoken, &cyls, &i)) 1188*7c478bd9Sstevel@tonic-gate break; 1189*7c478bd9Sstevel@tonic-gate /* 1190*7c478bd9Sstevel@tonic-gate * Check the bounds - cyls is number of cylinders 1191*7c478bd9Sstevel@tonic-gate */ 1192*7c478bd9Sstevel@tonic-gate if (cyls > (bounds->upper/spc())) { 1193*7c478bd9Sstevel@tonic-gate err_print("`%dc' is out of range\n", cyls); 1194*7c478bd9Sstevel@tonic-gate break; 1195*7c478bd9Sstevel@tonic-gate } 1196*7c478bd9Sstevel@tonic-gate /* 1197*7c478bd9Sstevel@tonic-gate * Convert cylinders to blocks and return 1198*7c478bd9Sstevel@tonic-gate */ 1199*7c478bd9Sstevel@tonic-gate return (cyls * spc()); 1200*7c478bd9Sstevel@tonic-gate case 'm': 1201*7c478bd9Sstevel@tonic-gate /* 1202*7c478bd9Sstevel@tonic-gate * Convert token from megabytes to a block number. 1203*7c478bd9Sstevel@tonic-gate */ 1204*7c478bd9Sstevel@tonic-gate if (sscanf(cleantoken, "%f2", &nmegs) == 0) { 1205*7c478bd9Sstevel@tonic-gate err_print("`%s' is not recognized\n", 1206*7c478bd9Sstevel@tonic-gate cleantoken); 1207*7c478bd9Sstevel@tonic-gate break; 1208*7c478bd9Sstevel@tonic-gate } 1209*7c478bd9Sstevel@tonic-gate /* 1210*7c478bd9Sstevel@tonic-gate * Check the bounds 1211*7c478bd9Sstevel@tonic-gate */ 1212*7c478bd9Sstevel@tonic-gate if (nmegs > bn2mb(bounds->upper)) { 1213*7c478bd9Sstevel@tonic-gate err_print("`%1.2fmb' is out of range\n", nmegs); 1214*7c478bd9Sstevel@tonic-gate break; 1215*7c478bd9Sstevel@tonic-gate } 1216*7c478bd9Sstevel@tonic-gate /* 1217*7c478bd9Sstevel@tonic-gate * Convert to blocks 1218*7c478bd9Sstevel@tonic-gate */ 1219*7c478bd9Sstevel@tonic-gate bn = mb2bn(nmegs); 1220*7c478bd9Sstevel@tonic-gate /* 1221*7c478bd9Sstevel@tonic-gate * Round value up to nearest cylinder 1222*7c478bd9Sstevel@tonic-gate */ 1223*7c478bd9Sstevel@tonic-gate i = spc(); 1224*7c478bd9Sstevel@tonic-gate bn = ((bn + (i-1)) / i) * i; 1225*7c478bd9Sstevel@tonic-gate return (bn); 1226*7c478bd9Sstevel@tonic-gate case 'g': 1227*7c478bd9Sstevel@tonic-gate /* 1228*7c478bd9Sstevel@tonic-gate * Convert token from gigabytes to a block number. 1229*7c478bd9Sstevel@tonic-gate */ 1230*7c478bd9Sstevel@tonic-gate if (sscanf(cleantoken, "%f2", &ngigs) == 0) { 1231*7c478bd9Sstevel@tonic-gate err_print("`%s' is not recognized\n", 1232*7c478bd9Sstevel@tonic-gate cleantoken); 1233*7c478bd9Sstevel@tonic-gate break; 1234*7c478bd9Sstevel@tonic-gate } 1235*7c478bd9Sstevel@tonic-gate /* 1236*7c478bd9Sstevel@tonic-gate * Check the bounds 1237*7c478bd9Sstevel@tonic-gate */ 1238*7c478bd9Sstevel@tonic-gate if (ngigs > bn2gb(bounds->upper)) { 1239*7c478bd9Sstevel@tonic-gate err_print("`%1.2fgb' is out of range\n", ngigs); 1240*7c478bd9Sstevel@tonic-gate break; 1241*7c478bd9Sstevel@tonic-gate } 1242*7c478bd9Sstevel@tonic-gate /* 1243*7c478bd9Sstevel@tonic-gate * Convert to blocks 1244*7c478bd9Sstevel@tonic-gate */ 1245*7c478bd9Sstevel@tonic-gate bn = gb2bn(ngigs); 1246*7c478bd9Sstevel@tonic-gate /* 1247*7c478bd9Sstevel@tonic-gate * Round value up to nearest cylinder 1248*7c478bd9Sstevel@tonic-gate */ 1249*7c478bd9Sstevel@tonic-gate i = spc(); 1250*7c478bd9Sstevel@tonic-gate bn = ((bn + (i-1)) / i) * i; 1251*7c478bd9Sstevel@tonic-gate return (bn); 1252*7c478bd9Sstevel@tonic-gate default: 1253*7c478bd9Sstevel@tonic-gate err_print( 1254*7c478bd9Sstevel@tonic-gate "Please specify units in either b(blocks), c(cylinders), m(megabytes) \ 1255*7c478bd9Sstevel@tonic-gate or g(gigabytes)\n"); 1256*7c478bd9Sstevel@tonic-gate break; 1257*7c478bd9Sstevel@tonic-gate } 1258*7c478bd9Sstevel@tonic-gate break; 1259*7c478bd9Sstevel@tonic-gate 1260*7c478bd9Sstevel@tonic-gate case FIO_ECYL: 1261*7c478bd9Sstevel@tonic-gate /* 1262*7c478bd9Sstevel@tonic-gate * Parameter is the bounds of legal block numbers. 1263*7c478bd9Sstevel@tonic-gate */ 1264*7c478bd9Sstevel@tonic-gate bounds = (struct bounds *)¶m->io_bounds; 1265*7c478bd9Sstevel@tonic-gate assert(bounds->lower == 0); 1266*7c478bd9Sstevel@tonic-gate 1267*7c478bd9Sstevel@tonic-gate /* 1268*7c478bd9Sstevel@tonic-gate * Print help message if required. 1269*7c478bd9Sstevel@tonic-gate */ 1270*7c478bd9Sstevel@tonic-gate if (help) { 1271*7c478bd9Sstevel@tonic-gate fmt_print("Expecting up to %llu blocks,", 1272*7c478bd9Sstevel@tonic-gate bounds->upper); 1273*7c478bd9Sstevel@tonic-gate fmt_print(" %llu cylinders, ", 1274*7c478bd9Sstevel@tonic-gate bn2c(bounds->upper)); 1275*7c478bd9Sstevel@tonic-gate fmt_print(" %llu end cylinder, ", 1276*7c478bd9Sstevel@tonic-gate (bounds->upper / spc())); 1277*7c478bd9Sstevel@tonic-gate fmt_print(" %1.2f megabytes, ", 1278*7c478bd9Sstevel@tonic-gate bn2mb(bounds->upper)); 1279*7c478bd9Sstevel@tonic-gate fmt_print("or %1.2f gigabytes\n", 1280*7c478bd9Sstevel@tonic-gate bn2gb(bounds->upper)); 1281*7c478bd9Sstevel@tonic-gate break; 1282*7c478bd9Sstevel@tonic-gate } 1283*7c478bd9Sstevel@tonic-gate 1284*7c478bd9Sstevel@tonic-gate /* 1285*7c478bd9Sstevel@tonic-gate * Parse the first token: try to find 'b', 'c', 'e' 1286*7c478bd9Sstevel@tonic-gate * or 'm' 1287*7c478bd9Sstevel@tonic-gate */ 1288*7c478bd9Sstevel@tonic-gate s = cleantoken; 1289*7c478bd9Sstevel@tonic-gate while (*s && (isdigit(*s) || (*s == '.') || (*s == '$'))) { 1290*7c478bd9Sstevel@tonic-gate s++; 1291*7c478bd9Sstevel@tonic-gate } 1292*7c478bd9Sstevel@tonic-gate 1293*7c478bd9Sstevel@tonic-gate /* 1294*7c478bd9Sstevel@tonic-gate * If we found a conversion specifier, second token is 1295*7c478bd9Sstevel@tonic-gate * unused Otherwise, the second token should supply it. 1296*7c478bd9Sstevel@tonic-gate */ 1297*7c478bd9Sstevel@tonic-gate if (*s != 0) { 1298*7c478bd9Sstevel@tonic-gate value = *s; 1299*7c478bd9Sstevel@tonic-gate *s = 0; 1300*7c478bd9Sstevel@tonic-gate } else { 1301*7c478bd9Sstevel@tonic-gate value = cleantoken2[0]; 1302*7c478bd9Sstevel@tonic-gate } 1303*7c478bd9Sstevel@tonic-gate 1304*7c478bd9Sstevel@tonic-gate /* 1305*7c478bd9Sstevel@tonic-gate * If the token is the wild card, simply supply the max 1306*7c478bd9Sstevel@tonic-gate * This order allows the user to specify the maximum in 1307*7c478bd9Sstevel@tonic-gate * either blocks/cyls/megabytes - a convenient fiction. 1308*7c478bd9Sstevel@tonic-gate */ 1309*7c478bd9Sstevel@tonic-gate if (strcmp(cleantoken, WILD_STRING) == 0) { 1310*7c478bd9Sstevel@tonic-gate return (bounds->upper); 1311*7c478bd9Sstevel@tonic-gate } 1312*7c478bd9Sstevel@tonic-gate 1313*7c478bd9Sstevel@tonic-gate /* 1314*7c478bd9Sstevel@tonic-gate * Allow the user to specify zero with no units, 1315*7c478bd9Sstevel@tonic-gate * by just defaulting to cylinders. 1316*7c478bd9Sstevel@tonic-gate */ 1317*7c478bd9Sstevel@tonic-gate 1318*7c478bd9Sstevel@tonic-gate if (value != 'e' && strcmp(cleantoken, "0") == 0) { 1319*7c478bd9Sstevel@tonic-gate value = 'c'; 1320*7c478bd9Sstevel@tonic-gate } 1321*7c478bd9Sstevel@tonic-gate 1322*7c478bd9Sstevel@tonic-gate 1323*7c478bd9Sstevel@tonic-gate /* 1324*7c478bd9Sstevel@tonic-gate * If there's a decimal point, but no unit 1325*7c478bd9Sstevel@tonic-gate * specification, let's assume megabytes. 1326*7c478bd9Sstevel@tonic-gate */ 1327*7c478bd9Sstevel@tonic-gate if ((value == 0) && (strchr(cleantoken, '.') != NULL)) { 1328*7c478bd9Sstevel@tonic-gate value = 'm'; 1329*7c478bd9Sstevel@tonic-gate } 1330*7c478bd9Sstevel@tonic-gate 1331*7c478bd9Sstevel@tonic-gate /* 1332*7c478bd9Sstevel@tonic-gate * Handle each unit type we support 1333*7c478bd9Sstevel@tonic-gate */ 1334*7c478bd9Sstevel@tonic-gate switch (value) { 1335*7c478bd9Sstevel@tonic-gate case 'b': 1336*7c478bd9Sstevel@tonic-gate /* 1337*7c478bd9Sstevel@tonic-gate * Convert token to a disk block number. 1338*7c478bd9Sstevel@tonic-gate */ 1339*7c478bd9Sstevel@tonic-gate i = bounds->upper; 1340*7c478bd9Sstevel@tonic-gate if (geti(cleantoken, &value, &i)) 1341*7c478bd9Sstevel@tonic-gate break; 1342*7c478bd9Sstevel@tonic-gate bn = value; 1343*7c478bd9Sstevel@tonic-gate /* 1344*7c478bd9Sstevel@tonic-gate * Check to be sure it is within the 1345*7c478bd9Sstevel@tonic-gate * legal bounds. 1346*7c478bd9Sstevel@tonic-gate */ 1347*7c478bd9Sstevel@tonic-gate if ((bn < bounds->lower) || (bn > bounds->upper)) { 1348*7c478bd9Sstevel@tonic-gate err_print( 1349*7c478bd9Sstevel@tonic-gate "`%ldb' is out of the range %llu to %llu\n", 1350*7c478bd9Sstevel@tonic-gate bn, bounds->lower, bounds->upper); 1351*7c478bd9Sstevel@tonic-gate break; 1352*7c478bd9Sstevel@tonic-gate } 1353*7c478bd9Sstevel@tonic-gate 1354*7c478bd9Sstevel@tonic-gate /* 1355*7c478bd9Sstevel@tonic-gate * Verify the block lies on a cylinder 1356*7c478bd9Sstevel@tonic-gate * boundary 1357*7c478bd9Sstevel@tonic-gate */ 1358*7c478bd9Sstevel@tonic-gate if ((bn % spc()) != 0) { 1359*7c478bd9Sstevel@tonic-gate err_print( 1360*7c478bd9Sstevel@tonic-gate "partition size must be a multiple of %d blocks to lie on a cylinder \ 1361*7c478bd9Sstevel@tonic-gate boundary\n", 1362*7c478bd9Sstevel@tonic-gate spc()); 1363*7c478bd9Sstevel@tonic-gate err_print( 1364*7c478bd9Sstevel@tonic-gate "%ld blocks is approximately %ld cylinders, %1.2f \ 1365*7c478bd9Sstevel@tonic-gate megabytes or %1.2f gigabytes\n", 1366*7c478bd9Sstevel@tonic-gate bn, bn2c(bn), bn2mb(bn), bn2gb(bn)); 1367*7c478bd9Sstevel@tonic-gate break; 1368*7c478bd9Sstevel@tonic-gate } 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate return (bn); 1371*7c478bd9Sstevel@tonic-gate 1372*7c478bd9Sstevel@tonic-gate case 'e': 1373*7c478bd9Sstevel@tonic-gate /* 1374*7c478bd9Sstevel@tonic-gate * Token is ending cylinder 1375*7c478bd9Sstevel@tonic-gate */ 1376*7c478bd9Sstevel@tonic-gate 1377*7c478bd9Sstevel@tonic-gate /* convert token to integer */ 1378*7c478bd9Sstevel@tonic-gate if (geti(cleantoken, &cylno, (int *)NULL)) { 1379*7c478bd9Sstevel@tonic-gate break; 1380*7c478bd9Sstevel@tonic-gate } 1381*7c478bd9Sstevel@tonic-gate 1382*7c478bd9Sstevel@tonic-gate /* 1383*7c478bd9Sstevel@tonic-gate * check that input cylno isn't before the current 1384*7c478bd9Sstevel@tonic-gate * starting cylinder number. Note that we are NOT 1385*7c478bd9Sstevel@tonic-gate * using the starting cylinder from 1386*7c478bd9Sstevel@tonic-gate * cur_parts->pinfo_map[].dkl_cylno! 1387*7c478bd9Sstevel@tonic-gate */ 1388*7c478bd9Sstevel@tonic-gate if (cylno < part_deflt->start_cyl) { 1389*7c478bd9Sstevel@tonic-gate err_print( 1390*7c478bd9Sstevel@tonic-gate "End cylinder must fall on or after start cylinder %d\n", 1391*7c478bd9Sstevel@tonic-gate part_deflt->start_cyl); 1392*7c478bd9Sstevel@tonic-gate break; 1393*7c478bd9Sstevel@tonic-gate } 1394*7c478bd9Sstevel@tonic-gate 1395*7c478bd9Sstevel@tonic-gate /* 1396*7c478bd9Sstevel@tonic-gate * calculate cylinder number of upper boundary, and 1397*7c478bd9Sstevel@tonic-gate * verify that our input is within range 1398*7c478bd9Sstevel@tonic-gate */ 1399*7c478bd9Sstevel@tonic-gate i = (bn2c(bounds->upper) + part_deflt->start_cyl - 1); 1400*7c478bd9Sstevel@tonic-gate 1401*7c478bd9Sstevel@tonic-gate if (cylno > i) { 1402*7c478bd9Sstevel@tonic-gate err_print( 1403*7c478bd9Sstevel@tonic-gate "End cylinder %d is beyond max cylinder %d\n", 1404*7c478bd9Sstevel@tonic-gate cylno, i); 1405*7c478bd9Sstevel@tonic-gate break; 1406*7c478bd9Sstevel@tonic-gate } 1407*7c478bd9Sstevel@tonic-gate 1408*7c478bd9Sstevel@tonic-gate /* 1409*7c478bd9Sstevel@tonic-gate * calculate number of cylinders based on input 1410*7c478bd9Sstevel@tonic-gate */ 1411*7c478bd9Sstevel@tonic-gate cyls = ((cylno - part_deflt->start_cyl) + 1); 1412*7c478bd9Sstevel@tonic-gate 1413*7c478bd9Sstevel@tonic-gate return (cyls * spc()); 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate case 'c': 1416*7c478bd9Sstevel@tonic-gate /* 1417*7c478bd9Sstevel@tonic-gate * Convert token from a number of 1418*7c478bd9Sstevel@tonic-gate * cylinders to a number of blocks. 1419*7c478bd9Sstevel@tonic-gate */ 1420*7c478bd9Sstevel@tonic-gate i = bn2c(bounds->upper); 1421*7c478bd9Sstevel@tonic-gate if (geti(cleantoken, &cyls, &i)) 1422*7c478bd9Sstevel@tonic-gate break; 1423*7c478bd9Sstevel@tonic-gate 1424*7c478bd9Sstevel@tonic-gate /* 1425*7c478bd9Sstevel@tonic-gate * Check the bounds - cyls is number of 1426*7c478bd9Sstevel@tonic-gate * cylinders 1427*7c478bd9Sstevel@tonic-gate */ 1428*7c478bd9Sstevel@tonic-gate if (cyls > (bounds->upper/spc())) { 1429*7c478bd9Sstevel@tonic-gate err_print("`%dc' is out of range\n", cyls); 1430*7c478bd9Sstevel@tonic-gate break; 1431*7c478bd9Sstevel@tonic-gate } 1432*7c478bd9Sstevel@tonic-gate 1433*7c478bd9Sstevel@tonic-gate /* 1434*7c478bd9Sstevel@tonic-gate * Convert cylinders to blocks and 1435*7c478bd9Sstevel@tonic-gate * return 1436*7c478bd9Sstevel@tonic-gate */ 1437*7c478bd9Sstevel@tonic-gate return (cyls * spc()); 1438*7c478bd9Sstevel@tonic-gate 1439*7c478bd9Sstevel@tonic-gate case 'm': 1440*7c478bd9Sstevel@tonic-gate /* 1441*7c478bd9Sstevel@tonic-gate * Convert token from megabytes to a 1442*7c478bd9Sstevel@tonic-gate * block number. 1443*7c478bd9Sstevel@tonic-gate */ 1444*7c478bd9Sstevel@tonic-gate if (sscanf(cleantoken, "%f2", &nmegs) == 0) { 1445*7c478bd9Sstevel@tonic-gate err_print("`%s' is not recognized\n", 1446*7c478bd9Sstevel@tonic-gate cleantoken); 1447*7c478bd9Sstevel@tonic-gate break; 1448*7c478bd9Sstevel@tonic-gate } 1449*7c478bd9Sstevel@tonic-gate 1450*7c478bd9Sstevel@tonic-gate /* 1451*7c478bd9Sstevel@tonic-gate * Check the bounds 1452*7c478bd9Sstevel@tonic-gate */ 1453*7c478bd9Sstevel@tonic-gate if (nmegs > bn2mb(bounds->upper)) { 1454*7c478bd9Sstevel@tonic-gate err_print("`%1.2fmb' is out of range\n", nmegs); 1455*7c478bd9Sstevel@tonic-gate break; 1456*7c478bd9Sstevel@tonic-gate } 1457*7c478bd9Sstevel@tonic-gate 1458*7c478bd9Sstevel@tonic-gate /* 1459*7c478bd9Sstevel@tonic-gate * Convert to blocks 1460*7c478bd9Sstevel@tonic-gate */ 1461*7c478bd9Sstevel@tonic-gate bn = mb2bn(nmegs); 1462*7c478bd9Sstevel@tonic-gate 1463*7c478bd9Sstevel@tonic-gate /* 1464*7c478bd9Sstevel@tonic-gate * Round value up to nearest cylinder 1465*7c478bd9Sstevel@tonic-gate */ 1466*7c478bd9Sstevel@tonic-gate i = spc(); 1467*7c478bd9Sstevel@tonic-gate bn = ((bn + (i-1)) / i) * i; 1468*7c478bd9Sstevel@tonic-gate return (bn); 1469*7c478bd9Sstevel@tonic-gate 1470*7c478bd9Sstevel@tonic-gate case 'g': 1471*7c478bd9Sstevel@tonic-gate /* 1472*7c478bd9Sstevel@tonic-gate * Convert token from gigabytes to a 1473*7c478bd9Sstevel@tonic-gate * block number. 1474*7c478bd9Sstevel@tonic-gate */ 1475*7c478bd9Sstevel@tonic-gate if (sscanf(cleantoken, "%f2", &ngigs) == 0) { 1476*7c478bd9Sstevel@tonic-gate err_print("`%s' is not recognized\n", 1477*7c478bd9Sstevel@tonic-gate cleantoken); 1478*7c478bd9Sstevel@tonic-gate break; 1479*7c478bd9Sstevel@tonic-gate } 1480*7c478bd9Sstevel@tonic-gate 1481*7c478bd9Sstevel@tonic-gate /* 1482*7c478bd9Sstevel@tonic-gate * Check the bounds 1483*7c478bd9Sstevel@tonic-gate */ 1484*7c478bd9Sstevel@tonic-gate if (ngigs > bn2gb(bounds->upper)) { 1485*7c478bd9Sstevel@tonic-gate err_print("`%1.2fgb' is out of range\n", ngigs); 1486*7c478bd9Sstevel@tonic-gate break; 1487*7c478bd9Sstevel@tonic-gate } 1488*7c478bd9Sstevel@tonic-gate 1489*7c478bd9Sstevel@tonic-gate /* 1490*7c478bd9Sstevel@tonic-gate * Convert to blocks 1491*7c478bd9Sstevel@tonic-gate */ 1492*7c478bd9Sstevel@tonic-gate bn = gb2bn(ngigs); 1493*7c478bd9Sstevel@tonic-gate 1494*7c478bd9Sstevel@tonic-gate /* 1495*7c478bd9Sstevel@tonic-gate * Round value up to nearest cylinder 1496*7c478bd9Sstevel@tonic-gate */ 1497*7c478bd9Sstevel@tonic-gate i = spc(); 1498*7c478bd9Sstevel@tonic-gate bn = ((bn + (i-1)) / i) * i; 1499*7c478bd9Sstevel@tonic-gate return (bn); 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate default: 1502*7c478bd9Sstevel@tonic-gate err_print( 1503*7c478bd9Sstevel@tonic-gate "Please specify units in either b(blocks), c(cylinders), e(end cylinder),\n"); 1504*7c478bd9Sstevel@tonic-gate err_print("m(megabytes) or g(gigabytes)\n"); 1505*7c478bd9Sstevel@tonic-gate break; 1506*7c478bd9Sstevel@tonic-gate } 1507*7c478bd9Sstevel@tonic-gate break; 1508*7c478bd9Sstevel@tonic-gate case FIO_EFI: 1509*7c478bd9Sstevel@tonic-gate /* 1510*7c478bd9Sstevel@tonic-gate * Parameter is the bounds of legal block numbers. 1511*7c478bd9Sstevel@tonic-gate */ 1512*7c478bd9Sstevel@tonic-gate bounds = (struct bounds *)¶m->io_bounds; 1513*7c478bd9Sstevel@tonic-gate 1514*7c478bd9Sstevel@tonic-gate /* 1515*7c478bd9Sstevel@tonic-gate * Print help message if required. 1516*7c478bd9Sstevel@tonic-gate */ 1517*7c478bd9Sstevel@tonic-gate if (help) { 1518*7c478bd9Sstevel@tonic-gate fmt_print("Expecting up to %llu sectors,", 1519*7c478bd9Sstevel@tonic-gate cur_parts->etoc->efi_last_u_lba); 1520*7c478bd9Sstevel@tonic-gate fmt_print("or %llu megabytes,", 1521*7c478bd9Sstevel@tonic-gate (cur_parts->etoc->efi_last_u_lba * DEV_BSIZE)/ 1522*7c478bd9Sstevel@tonic-gate (1024 * 1024)); 1523*7c478bd9Sstevel@tonic-gate fmt_print("or %llu gigabytes\n", 1524*7c478bd9Sstevel@tonic-gate (cur_parts->etoc->efi_last_u_lba * DEV_BSIZE)/ 1525*7c478bd9Sstevel@tonic-gate (1024 * 1024 * 1024)); 1526*7c478bd9Sstevel@tonic-gate fmt_print("or %llu terabytes\n", 1527*7c478bd9Sstevel@tonic-gate (cur_parts->etoc->efi_last_u_lba * DEV_BSIZE)/ 1528*7c478bd9Sstevel@tonic-gate ((uint64_t)1024 * 1024 * 1024 * 1024)); 1529*7c478bd9Sstevel@tonic-gate break; 1530*7c478bd9Sstevel@tonic-gate } 1531*7c478bd9Sstevel@tonic-gate 1532*7c478bd9Sstevel@tonic-gate /* 1533*7c478bd9Sstevel@tonic-gate * Parse the first token: try to find 'b', 'c', 'e' 1534*7c478bd9Sstevel@tonic-gate * or 'm' 1535*7c478bd9Sstevel@tonic-gate */ 1536*7c478bd9Sstevel@tonic-gate s = cleantoken; 1537*7c478bd9Sstevel@tonic-gate while (*s && (isdigit(*s) || (*s == '.') || (*s == '$'))) { 1538*7c478bd9Sstevel@tonic-gate s++; 1539*7c478bd9Sstevel@tonic-gate } 1540*7c478bd9Sstevel@tonic-gate 1541*7c478bd9Sstevel@tonic-gate /* 1542*7c478bd9Sstevel@tonic-gate * If we found a conversion specifier, second token is 1543*7c478bd9Sstevel@tonic-gate * unused Otherwise, the second token should supply it. 1544*7c478bd9Sstevel@tonic-gate */ 1545*7c478bd9Sstevel@tonic-gate if (*s != 0) { 1546*7c478bd9Sstevel@tonic-gate value = *s; 1547*7c478bd9Sstevel@tonic-gate *s = 0; 1548*7c478bd9Sstevel@tonic-gate } else { 1549*7c478bd9Sstevel@tonic-gate value = cleantoken2[0]; 1550*7c478bd9Sstevel@tonic-gate } 1551*7c478bd9Sstevel@tonic-gate 1552*7c478bd9Sstevel@tonic-gate /* 1553*7c478bd9Sstevel@tonic-gate * If the token is the wild card, simply supply the max 1554*7c478bd9Sstevel@tonic-gate * This order allows the user to specify the maximum in 1555*7c478bd9Sstevel@tonic-gate * either blocks/cyls/megabytes - a convenient fiction. 1556*7c478bd9Sstevel@tonic-gate */ 1557*7c478bd9Sstevel@tonic-gate if (strcmp(cleantoken, WILD_STRING) == 0) { 1558*7c478bd9Sstevel@tonic-gate return (bounds->upper - EFI_MIN_RESV_SIZE - 1559*7c478bd9Sstevel@tonic-gate efi_deflt->start_sector); 1560*7c478bd9Sstevel@tonic-gate } 1561*7c478bd9Sstevel@tonic-gate 1562*7c478bd9Sstevel@tonic-gate /* 1563*7c478bd9Sstevel@tonic-gate * Allow the user to specify zero with no units, 1564*7c478bd9Sstevel@tonic-gate * by just defaulting to sectors. 1565*7c478bd9Sstevel@tonic-gate */ 1566*7c478bd9Sstevel@tonic-gate 1567*7c478bd9Sstevel@tonic-gate if (value != 'e' && strcmp(cleantoken, "0") == 0) { 1568*7c478bd9Sstevel@tonic-gate value = 'm'; 1569*7c478bd9Sstevel@tonic-gate } 1570*7c478bd9Sstevel@tonic-gate 1571*7c478bd9Sstevel@tonic-gate 1572*7c478bd9Sstevel@tonic-gate /* 1573*7c478bd9Sstevel@tonic-gate * If there's a decimal point, but no unit 1574*7c478bd9Sstevel@tonic-gate * specification, let's assume megabytes. 1575*7c478bd9Sstevel@tonic-gate */ 1576*7c478bd9Sstevel@tonic-gate if ((value == 0) && (strchr(cleantoken, '.') != NULL)) { 1577*7c478bd9Sstevel@tonic-gate value = 'm'; 1578*7c478bd9Sstevel@tonic-gate } 1579*7c478bd9Sstevel@tonic-gate 1580*7c478bd9Sstevel@tonic-gate /* 1581*7c478bd9Sstevel@tonic-gate * Handle each unit type we support 1582*7c478bd9Sstevel@tonic-gate */ 1583*7c478bd9Sstevel@tonic-gate switch (value) { 1584*7c478bd9Sstevel@tonic-gate case 'b': 1585*7c478bd9Sstevel@tonic-gate /* 1586*7c478bd9Sstevel@tonic-gate * Token is number of blocks 1587*7c478bd9Sstevel@tonic-gate */ 1588*7c478bd9Sstevel@tonic-gate if (geti64(cleantoken, &blokno, (uint64_t *)NULL)) { 1589*7c478bd9Sstevel@tonic-gate break; 1590*7c478bd9Sstevel@tonic-gate } 1591*7c478bd9Sstevel@tonic-gate if (blokno > bounds->upper) { 1592*7c478bd9Sstevel@tonic-gate err_print( 1593*7c478bd9Sstevel@tonic-gate "Number of blocks must be less that the total available blocks.\n"); 1594*7c478bd9Sstevel@tonic-gate break; 1595*7c478bd9Sstevel@tonic-gate } 1596*7c478bd9Sstevel@tonic-gate return (blokno); 1597*7c478bd9Sstevel@tonic-gate 1598*7c478bd9Sstevel@tonic-gate case 'e': 1599*7c478bd9Sstevel@tonic-gate /* 1600*7c478bd9Sstevel@tonic-gate * Token is ending block number 1601*7c478bd9Sstevel@tonic-gate */ 1602*7c478bd9Sstevel@tonic-gate 1603*7c478bd9Sstevel@tonic-gate /* convert token to integer */ 1604*7c478bd9Sstevel@tonic-gate if (geti64(cleantoken, &blokno, (uint64_t *)NULL)) { 1605*7c478bd9Sstevel@tonic-gate break; 1606*7c478bd9Sstevel@tonic-gate } 1607*7c478bd9Sstevel@tonic-gate 1608*7c478bd9Sstevel@tonic-gate /* 1609*7c478bd9Sstevel@tonic-gate * Some sanity check 1610*7c478bd9Sstevel@tonic-gate */ 1611*7c478bd9Sstevel@tonic-gate if (blokno < efi_deflt->start_sector) { 1612*7c478bd9Sstevel@tonic-gate err_print( 1613*7c478bd9Sstevel@tonic-gate "End Sector must fall on or after start sector %llu\n", 1614*7c478bd9Sstevel@tonic-gate efi_deflt->start_sector); 1615*7c478bd9Sstevel@tonic-gate break; 1616*7c478bd9Sstevel@tonic-gate } 1617*7c478bd9Sstevel@tonic-gate 1618*7c478bd9Sstevel@tonic-gate /* 1619*7c478bd9Sstevel@tonic-gate * verify that our input is within range 1620*7c478bd9Sstevel@tonic-gate */ 1621*7c478bd9Sstevel@tonic-gate if (blokno > cur_parts->etoc->efi_last_u_lba) { 1622*7c478bd9Sstevel@tonic-gate err_print( 1623*7c478bd9Sstevel@tonic-gate "End Sector %llu is beyond max Sector %llu\n", 1624*7c478bd9Sstevel@tonic-gate blokno, cur_parts->etoc->efi_last_u_lba); 1625*7c478bd9Sstevel@tonic-gate break; 1626*7c478bd9Sstevel@tonic-gate } 1627*7c478bd9Sstevel@tonic-gate 1628*7c478bd9Sstevel@tonic-gate /* 1629*7c478bd9Sstevel@tonic-gate * calculate number of blocks based on input 1630*7c478bd9Sstevel@tonic-gate */ 1631*7c478bd9Sstevel@tonic-gate 1632*7c478bd9Sstevel@tonic-gate return (blokno - efi_deflt->start_sector + 1); 1633*7c478bd9Sstevel@tonic-gate 1634*7c478bd9Sstevel@tonic-gate case 'm': 1635*7c478bd9Sstevel@tonic-gate /* 1636*7c478bd9Sstevel@tonic-gate * Convert token from megabytes to a 1637*7c478bd9Sstevel@tonic-gate * block number. 1638*7c478bd9Sstevel@tonic-gate */ 1639*7c478bd9Sstevel@tonic-gate if (sscanf(cleantoken, "%f2", &nmegs) == 0) { 1640*7c478bd9Sstevel@tonic-gate err_print("`%s' is not recognized\n", 1641*7c478bd9Sstevel@tonic-gate cleantoken); 1642*7c478bd9Sstevel@tonic-gate break; 1643*7c478bd9Sstevel@tonic-gate } 1644*7c478bd9Sstevel@tonic-gate 1645*7c478bd9Sstevel@tonic-gate /* 1646*7c478bd9Sstevel@tonic-gate * Check the bounds 1647*7c478bd9Sstevel@tonic-gate */ 1648*7c478bd9Sstevel@tonic-gate if (nmegs > bn2mb(bounds->upper - bounds->lower)) { 1649*7c478bd9Sstevel@tonic-gate err_print("`%1.2fmb' is out of range\n", nmegs); 1650*7c478bd9Sstevel@tonic-gate break; 1651*7c478bd9Sstevel@tonic-gate } 1652*7c478bd9Sstevel@tonic-gate 1653*7c478bd9Sstevel@tonic-gate return (mb2bn(nmegs)); 1654*7c478bd9Sstevel@tonic-gate 1655*7c478bd9Sstevel@tonic-gate case 'g': 1656*7c478bd9Sstevel@tonic-gate if (sscanf(cleantoken, "%f2", &nmegs) == 0) { 1657*7c478bd9Sstevel@tonic-gate err_print("`%s' is not recognized\n", 1658*7c478bd9Sstevel@tonic-gate cleantoken); 1659*7c478bd9Sstevel@tonic-gate break; 1660*7c478bd9Sstevel@tonic-gate } 1661*7c478bd9Sstevel@tonic-gate if (nmegs > bn2gb(bounds->upper - bounds->lower)) { 1662*7c478bd9Sstevel@tonic-gate err_print("`%1.2fgb' is out of range\n", nmegs); 1663*7c478bd9Sstevel@tonic-gate break; 1664*7c478bd9Sstevel@tonic-gate } 1665*7c478bd9Sstevel@tonic-gate 1666*7c478bd9Sstevel@tonic-gate return (gb2bn(nmegs)); 1667*7c478bd9Sstevel@tonic-gate 1668*7c478bd9Sstevel@tonic-gate case 't': 1669*7c478bd9Sstevel@tonic-gate if (sscanf(cleantoken, "%f2", &nmegs) == 0) { 1670*7c478bd9Sstevel@tonic-gate err_print("`%s' is not recognized\n", 1671*7c478bd9Sstevel@tonic-gate cleantoken); 1672*7c478bd9Sstevel@tonic-gate break; 1673*7c478bd9Sstevel@tonic-gate } 1674*7c478bd9Sstevel@tonic-gate if (nmegs > bn2tb(bounds->upper - bounds->lower)) { 1675*7c478bd9Sstevel@tonic-gate err_print("`%1.2ftb' is out of range\n", nmegs); 1676*7c478bd9Sstevel@tonic-gate break; 1677*7c478bd9Sstevel@tonic-gate } 1678*7c478bd9Sstevel@tonic-gate return (uint64_t)((float)nmegs * 1024.0 * 1679*7c478bd9Sstevel@tonic-gate 1024.0 * 1024.0 * 1024.0 / DEV_BSIZE); 1680*7c478bd9Sstevel@tonic-gate 1681*7c478bd9Sstevel@tonic-gate default: 1682*7c478bd9Sstevel@tonic-gate err_print( 1683*7c478bd9Sstevel@tonic-gate "Please specify units in either b(number of blocks), e(end sector),\n"); 1684*7c478bd9Sstevel@tonic-gate err_print(" g(gigabytes), m(megabytes)"); 1685*7c478bd9Sstevel@tonic-gate err_print(" or t(terabytes)\n"); 1686*7c478bd9Sstevel@tonic-gate break; 1687*7c478bd9Sstevel@tonic-gate } 1688*7c478bd9Sstevel@tonic-gate break; 1689*7c478bd9Sstevel@tonic-gate 1690*7c478bd9Sstevel@tonic-gate /* 1691*7c478bd9Sstevel@tonic-gate * If we don't recognize the input type, it's bad news. 1692*7c478bd9Sstevel@tonic-gate */ 1693*7c478bd9Sstevel@tonic-gate default: 1694*7c478bd9Sstevel@tonic-gate err_print("Error: unknown input type.\n"); 1695*7c478bd9Sstevel@tonic-gate fullabort(); 1696*7c478bd9Sstevel@tonic-gate } 1697*7c478bd9Sstevel@tonic-gate /* 1698*7c478bd9Sstevel@tonic-gate * If we get here, it's because some error kept us from accepting 1699*7c478bd9Sstevel@tonic-gate * the token. If we are running out of a command file, gracefully 1700*7c478bd9Sstevel@tonic-gate * leave the program. If we are interacting with the user, simply 1701*7c478bd9Sstevel@tonic-gate * reprompt. If the token was in the pipe, abort the current command. 1702*7c478bd9Sstevel@tonic-gate */ 1703*7c478bd9Sstevel@tonic-gate if (option_f) 1704*7c478bd9Sstevel@tonic-gate fullabort(); 1705*7c478bd9Sstevel@tonic-gate else if (interactive) 1706*7c478bd9Sstevel@tonic-gate goto reprompt; 1707*7c478bd9Sstevel@tonic-gate else 1708*7c478bd9Sstevel@tonic-gate cmdabort(SIGINT); 1709*7c478bd9Sstevel@tonic-gate /* 1710*7c478bd9Sstevel@tonic-gate * Never actually reached. 1711*7c478bd9Sstevel@tonic-gate */ 1712*7c478bd9Sstevel@tonic-gate return (-1); 1713*7c478bd9Sstevel@tonic-gate } 1714*7c478bd9Sstevel@tonic-gate 1715*7c478bd9Sstevel@tonic-gate /* 1716*7c478bd9Sstevel@tonic-gate * Print input choices 1717*7c478bd9Sstevel@tonic-gate */ 1718*7c478bd9Sstevel@tonic-gate static void 1719*7c478bd9Sstevel@tonic-gate print_input_choices(type, param) 1720*7c478bd9Sstevel@tonic-gate int type; 1721*7c478bd9Sstevel@tonic-gate u_ioparam_t *param; 1722*7c478bd9Sstevel@tonic-gate { 1723*7c478bd9Sstevel@tonic-gate char **sp; 1724*7c478bd9Sstevel@tonic-gate slist_t *lp; 1725*7c478bd9Sstevel@tonic-gate int width; 1726*7c478bd9Sstevel@tonic-gate int col; 1727*7c478bd9Sstevel@tonic-gate int ncols; 1728*7c478bd9Sstevel@tonic-gate 1729*7c478bd9Sstevel@tonic-gate switch (type) { 1730*7c478bd9Sstevel@tonic-gate case FIO_CSTR: 1731*7c478bd9Sstevel@tonic-gate fmt_print("Expecting one of the following:\n"); 1732*7c478bd9Sstevel@tonic-gate goto common; 1733*7c478bd9Sstevel@tonic-gate 1734*7c478bd9Sstevel@tonic-gate case FIO_MSTR: 1735*7c478bd9Sstevel@tonic-gate fmt_print("Expecting one of the following: "); 1736*7c478bd9Sstevel@tonic-gate fmt_print("(abbreviations ok):\n"); 1737*7c478bd9Sstevel@tonic-gate common: 1738*7c478bd9Sstevel@tonic-gate for (sp = (char **)param->io_charlist; *sp != NULL; sp++) { 1739*7c478bd9Sstevel@tonic-gate fmt_print("\t%s\n", *sp); 1740*7c478bd9Sstevel@tonic-gate } 1741*7c478bd9Sstevel@tonic-gate break; 1742*7c478bd9Sstevel@tonic-gate 1743*7c478bd9Sstevel@tonic-gate case FIO_SLIST: 1744*7c478bd9Sstevel@tonic-gate fmt_print("Expecting one of the following: "); 1745*7c478bd9Sstevel@tonic-gate fmt_print("(abbreviations ok):\n"); 1746*7c478bd9Sstevel@tonic-gate /* 1747*7c478bd9Sstevel@tonic-gate * Figure out the width of the widest string 1748*7c478bd9Sstevel@tonic-gate */ 1749*7c478bd9Sstevel@tonic-gate width = slist_widest_str((slist_t *)param->io_slist); 1750*7c478bd9Sstevel@tonic-gate width += 4; 1751*7c478bd9Sstevel@tonic-gate /* 1752*7c478bd9Sstevel@tonic-gate * If the help messages are empty, print the 1753*7c478bd9Sstevel@tonic-gate * possible choices in left-justified columns 1754*7c478bd9Sstevel@tonic-gate */ 1755*7c478bd9Sstevel@tonic-gate lp = (slist_t *)param->io_slist; 1756*7c478bd9Sstevel@tonic-gate if (*lp->help == 0) { 1757*7c478bd9Sstevel@tonic-gate col = 0; 1758*7c478bd9Sstevel@tonic-gate ncols = 60 / width; 1759*7c478bd9Sstevel@tonic-gate for (; lp->str != NULL; lp++) { 1760*7c478bd9Sstevel@tonic-gate if (col == 0) 1761*7c478bd9Sstevel@tonic-gate fmt_print("\t"); 1762*7c478bd9Sstevel@tonic-gate ljust_print(lp->str, 1763*7c478bd9Sstevel@tonic-gate (++col == ncols) ? 0 : width); 1764*7c478bd9Sstevel@tonic-gate if (col == ncols) { 1765*7c478bd9Sstevel@tonic-gate col = 0; 1766*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 1767*7c478bd9Sstevel@tonic-gate } 1768*7c478bd9Sstevel@tonic-gate } 1769*7c478bd9Sstevel@tonic-gate if (col != 0) 1770*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 1771*7c478bd9Sstevel@tonic-gate } else { 1772*7c478bd9Sstevel@tonic-gate /* 1773*7c478bd9Sstevel@tonic-gate * With help messages, print each choice, 1774*7c478bd9Sstevel@tonic-gate * and help message, on its own line. 1775*7c478bd9Sstevel@tonic-gate */ 1776*7c478bd9Sstevel@tonic-gate for (; lp->str != NULL; lp++) { 1777*7c478bd9Sstevel@tonic-gate fmt_print("\t"); 1778*7c478bd9Sstevel@tonic-gate ljust_print(lp->str, width); 1779*7c478bd9Sstevel@tonic-gate fmt_print("- %s\n", lp->help); 1780*7c478bd9Sstevel@tonic-gate } 1781*7c478bd9Sstevel@tonic-gate } 1782*7c478bd9Sstevel@tonic-gate break; 1783*7c478bd9Sstevel@tonic-gate 1784*7c478bd9Sstevel@tonic-gate default: 1785*7c478bd9Sstevel@tonic-gate err_print("Error: unknown input type.\n"); 1786*7c478bd9Sstevel@tonic-gate fullabort(); 1787*7c478bd9Sstevel@tonic-gate } 1788*7c478bd9Sstevel@tonic-gate 1789*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 1790*7c478bd9Sstevel@tonic-gate } 1791*7c478bd9Sstevel@tonic-gate 1792*7c478bd9Sstevel@tonic-gate 1793*7c478bd9Sstevel@tonic-gate /* 1794*7c478bd9Sstevel@tonic-gate * Search a string list for a particular string. 1795*7c478bd9Sstevel@tonic-gate * Use minimum recognition, to accept unique abbreviations 1796*7c478bd9Sstevel@tonic-gate * Return the number of possible matches found. 1797*7c478bd9Sstevel@tonic-gate * If only one match was found, return the arbitrary value 1798*7c478bd9Sstevel@tonic-gate * associated with the matched string in match_value. 1799*7c478bd9Sstevel@tonic-gate */ 1800*7c478bd9Sstevel@tonic-gate int 1801*7c478bd9Sstevel@tonic-gate find_value(slist, match_str, match_value) 1802*7c478bd9Sstevel@tonic-gate slist_t *slist; 1803*7c478bd9Sstevel@tonic-gate char *match_str; 1804*7c478bd9Sstevel@tonic-gate int *match_value; 1805*7c478bd9Sstevel@tonic-gate { 1806*7c478bd9Sstevel@tonic-gate int i; 1807*7c478bd9Sstevel@tonic-gate int nmatches; 1808*7c478bd9Sstevel@tonic-gate int length; 1809*7c478bd9Sstevel@tonic-gate int match_length; 1810*7c478bd9Sstevel@tonic-gate 1811*7c478bd9Sstevel@tonic-gate nmatches = 0; 1812*7c478bd9Sstevel@tonic-gate length = 0; 1813*7c478bd9Sstevel@tonic-gate 1814*7c478bd9Sstevel@tonic-gate match_length = strlen(match_str); 1815*7c478bd9Sstevel@tonic-gate 1816*7c478bd9Sstevel@tonic-gate for (; slist->str != NULL; slist++) { 1817*7c478bd9Sstevel@tonic-gate /* 1818*7c478bd9Sstevel@tonic-gate * See how many characters of the token match 1819*7c478bd9Sstevel@tonic-gate */ 1820*7c478bd9Sstevel@tonic-gate i = strcnt(match_str, slist->str); 1821*7c478bd9Sstevel@tonic-gate /* 1822*7c478bd9Sstevel@tonic-gate * If it's not the whole token, then it's not a match. 1823*7c478bd9Sstevel@tonic-gate */ 1824*7c478bd9Sstevel@tonic-gate if (i < match_length) 1825*7c478bd9Sstevel@tonic-gate continue; 1826*7c478bd9Sstevel@tonic-gate /* 1827*7c478bd9Sstevel@tonic-gate * If it ties with another input, remember that. 1828*7c478bd9Sstevel@tonic-gate */ 1829*7c478bd9Sstevel@tonic-gate if (i == length) 1830*7c478bd9Sstevel@tonic-gate nmatches++; 1831*7c478bd9Sstevel@tonic-gate /* 1832*7c478bd9Sstevel@tonic-gate * If it matches the most so far, record that. 1833*7c478bd9Sstevel@tonic-gate */ 1834*7c478bd9Sstevel@tonic-gate if (i > length) { 1835*7c478bd9Sstevel@tonic-gate *match_value = slist->value; 1836*7c478bd9Sstevel@tonic-gate nmatches = 1; 1837*7c478bd9Sstevel@tonic-gate length = i; 1838*7c478bd9Sstevel@tonic-gate } 1839*7c478bd9Sstevel@tonic-gate } 1840*7c478bd9Sstevel@tonic-gate 1841*7c478bd9Sstevel@tonic-gate return (nmatches); 1842*7c478bd9Sstevel@tonic-gate } 1843*7c478bd9Sstevel@tonic-gate 1844*7c478bd9Sstevel@tonic-gate /* 1845*7c478bd9Sstevel@tonic-gate * Search a string list for a particular value. 1846*7c478bd9Sstevel@tonic-gate * Return the string associated with that value. 1847*7c478bd9Sstevel@tonic-gate */ 1848*7c478bd9Sstevel@tonic-gate char * 1849*7c478bd9Sstevel@tonic-gate find_string(slist, match_value) 1850*7c478bd9Sstevel@tonic-gate slist_t *slist; 1851*7c478bd9Sstevel@tonic-gate int match_value; 1852*7c478bd9Sstevel@tonic-gate { 1853*7c478bd9Sstevel@tonic-gate for (; slist->str != NULL; slist++) { 1854*7c478bd9Sstevel@tonic-gate if (slist->value == match_value) { 1855*7c478bd9Sstevel@tonic-gate return (slist->str); 1856*7c478bd9Sstevel@tonic-gate } 1857*7c478bd9Sstevel@tonic-gate } 1858*7c478bd9Sstevel@tonic-gate 1859*7c478bd9Sstevel@tonic-gate return ((char *)NULL); 1860*7c478bd9Sstevel@tonic-gate } 1861*7c478bd9Sstevel@tonic-gate 1862*7c478bd9Sstevel@tonic-gate /* 1863*7c478bd9Sstevel@tonic-gate * Return the width of the widest string in an slist 1864*7c478bd9Sstevel@tonic-gate */ 1865*7c478bd9Sstevel@tonic-gate static int 1866*7c478bd9Sstevel@tonic-gate slist_widest_str(slist) 1867*7c478bd9Sstevel@tonic-gate slist_t *slist; 1868*7c478bd9Sstevel@tonic-gate { 1869*7c478bd9Sstevel@tonic-gate int i; 1870*7c478bd9Sstevel@tonic-gate int width; 1871*7c478bd9Sstevel@tonic-gate 1872*7c478bd9Sstevel@tonic-gate width = 0; 1873*7c478bd9Sstevel@tonic-gate for (; slist->str != NULL; slist++) { 1874*7c478bd9Sstevel@tonic-gate if ((i = strlen(slist->str)) > width) 1875*7c478bd9Sstevel@tonic-gate width = i; 1876*7c478bd9Sstevel@tonic-gate } 1877*7c478bd9Sstevel@tonic-gate 1878*7c478bd9Sstevel@tonic-gate return (width); 1879*7c478bd9Sstevel@tonic-gate } 1880*7c478bd9Sstevel@tonic-gate 1881*7c478bd9Sstevel@tonic-gate /* 1882*7c478bd9Sstevel@tonic-gate * Print a string left-justified to a fixed width. 1883*7c478bd9Sstevel@tonic-gate */ 1884*7c478bd9Sstevel@tonic-gate static void 1885*7c478bd9Sstevel@tonic-gate ljust_print(str, width) 1886*7c478bd9Sstevel@tonic-gate char *str; 1887*7c478bd9Sstevel@tonic-gate int width; 1888*7c478bd9Sstevel@tonic-gate { 1889*7c478bd9Sstevel@tonic-gate int i; 1890*7c478bd9Sstevel@tonic-gate 1891*7c478bd9Sstevel@tonic-gate fmt_print("%s", str); 1892*7c478bd9Sstevel@tonic-gate for (i = width - strlen(str); i > 0; i--) { 1893*7c478bd9Sstevel@tonic-gate fmt_print(" "); 1894*7c478bd9Sstevel@tonic-gate } 1895*7c478bd9Sstevel@tonic-gate } 1896*7c478bd9Sstevel@tonic-gate 1897*7c478bd9Sstevel@tonic-gate /* 1898*7c478bd9Sstevel@tonic-gate * This routine is a modified version of printf. It handles the cases 1899*7c478bd9Sstevel@tonic-gate * of silent mode and logging; other than that it is identical to the 1900*7c478bd9Sstevel@tonic-gate * library version. 1901*7c478bd9Sstevel@tonic-gate */ 1902*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 1903*7c478bd9Sstevel@tonic-gate void 1904*7c478bd9Sstevel@tonic-gate fmt_print(char *format, ...) 1905*7c478bd9Sstevel@tonic-gate { 1906*7c478bd9Sstevel@tonic-gate va_list ap; 1907*7c478bd9Sstevel@tonic-gate 1908*7c478bd9Sstevel@tonic-gate va_start(ap, format); 1909*7c478bd9Sstevel@tonic-gate 1910*7c478bd9Sstevel@tonic-gate /* 1911*7c478bd9Sstevel@tonic-gate * If we are running silent, skip it. 1912*7c478bd9Sstevel@tonic-gate */ 1913*7c478bd9Sstevel@tonic-gate if (option_s == 0) { 1914*7c478bd9Sstevel@tonic-gate /* 1915*7c478bd9Sstevel@tonic-gate * Do the print to standard out. 1916*7c478bd9Sstevel@tonic-gate */ 1917*7c478bd9Sstevel@tonic-gate if (need_newline) { 1918*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 1919*7c478bd9Sstevel@tonic-gate } 1920*7c478bd9Sstevel@tonic-gate (void) vprintf(format, ap); 1921*7c478bd9Sstevel@tonic-gate /* 1922*7c478bd9Sstevel@tonic-gate * If we are logging, also print to the log file. 1923*7c478bd9Sstevel@tonic-gate */ 1924*7c478bd9Sstevel@tonic-gate if (log_file) { 1925*7c478bd9Sstevel@tonic-gate if (need_newline) { 1926*7c478bd9Sstevel@tonic-gate (void) fprintf(log_file, "\n"); 1927*7c478bd9Sstevel@tonic-gate } 1928*7c478bd9Sstevel@tonic-gate (void) vfprintf(log_file, format, ap); 1929*7c478bd9Sstevel@tonic-gate (void) fflush(log_file); 1930*7c478bd9Sstevel@tonic-gate } 1931*7c478bd9Sstevel@tonic-gate } 1932*7c478bd9Sstevel@tonic-gate 1933*7c478bd9Sstevel@tonic-gate need_newline = 0; 1934*7c478bd9Sstevel@tonic-gate 1935*7c478bd9Sstevel@tonic-gate va_end(ap); 1936*7c478bd9Sstevel@tonic-gate } 1937*7c478bd9Sstevel@tonic-gate 1938*7c478bd9Sstevel@tonic-gate /* 1939*7c478bd9Sstevel@tonic-gate * This routine is a modified version of printf. It handles the cases 1940*7c478bd9Sstevel@tonic-gate * of silent mode; other than that it is identical to the 1941*7c478bd9Sstevel@tonic-gate * library version. It differs from the above printf in that it does 1942*7c478bd9Sstevel@tonic-gate * not print the message to a log file. 1943*7c478bd9Sstevel@tonic-gate */ 1944*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 1945*7c478bd9Sstevel@tonic-gate void 1946*7c478bd9Sstevel@tonic-gate nolog_print(char *format, ...) 1947*7c478bd9Sstevel@tonic-gate { 1948*7c478bd9Sstevel@tonic-gate va_list ap; 1949*7c478bd9Sstevel@tonic-gate 1950*7c478bd9Sstevel@tonic-gate va_start(ap, format); 1951*7c478bd9Sstevel@tonic-gate 1952*7c478bd9Sstevel@tonic-gate /* 1953*7c478bd9Sstevel@tonic-gate * If we are running silent, skip it. 1954*7c478bd9Sstevel@tonic-gate */ 1955*7c478bd9Sstevel@tonic-gate if (option_s == 0) { 1956*7c478bd9Sstevel@tonic-gate /* 1957*7c478bd9Sstevel@tonic-gate * Do the print to standard out. 1958*7c478bd9Sstevel@tonic-gate */ 1959*7c478bd9Sstevel@tonic-gate if (need_newline) { 1960*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 1961*7c478bd9Sstevel@tonic-gate } 1962*7c478bd9Sstevel@tonic-gate (void) vprintf(format, ap); 1963*7c478bd9Sstevel@tonic-gate } 1964*7c478bd9Sstevel@tonic-gate 1965*7c478bd9Sstevel@tonic-gate va_end(ap); 1966*7c478bd9Sstevel@tonic-gate 1967*7c478bd9Sstevel@tonic-gate need_newline = 0; 1968*7c478bd9Sstevel@tonic-gate } 1969*7c478bd9Sstevel@tonic-gate 1970*7c478bd9Sstevel@tonic-gate /* 1971*7c478bd9Sstevel@tonic-gate * This routine is a modified version of printf. It handles the cases 1972*7c478bd9Sstevel@tonic-gate * of silent mode, and only prints the message to the log file, not 1973*7c478bd9Sstevel@tonic-gate * stdout. Other than that is identical to the library version. 1974*7c478bd9Sstevel@tonic-gate */ 1975*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 1976*7c478bd9Sstevel@tonic-gate void 1977*7c478bd9Sstevel@tonic-gate log_print(char *format, ...) 1978*7c478bd9Sstevel@tonic-gate { 1979*7c478bd9Sstevel@tonic-gate va_list ap; 1980*7c478bd9Sstevel@tonic-gate 1981*7c478bd9Sstevel@tonic-gate va_start(ap, format); 1982*7c478bd9Sstevel@tonic-gate 1983*7c478bd9Sstevel@tonic-gate /* 1984*7c478bd9Sstevel@tonic-gate * If we are running silent, skip it. 1985*7c478bd9Sstevel@tonic-gate */ 1986*7c478bd9Sstevel@tonic-gate if (option_s == 0) { 1987*7c478bd9Sstevel@tonic-gate /* 1988*7c478bd9Sstevel@tonic-gate * Do the print to the log file. 1989*7c478bd9Sstevel@tonic-gate */ 1990*7c478bd9Sstevel@tonic-gate if (need_newline) { 1991*7c478bd9Sstevel@tonic-gate (void) fprintf(log_file, "\n"); 1992*7c478bd9Sstevel@tonic-gate } 1993*7c478bd9Sstevel@tonic-gate (void) vfprintf(log_file, format, ap); 1994*7c478bd9Sstevel@tonic-gate (void) fflush(log_file); 1995*7c478bd9Sstevel@tonic-gate } 1996*7c478bd9Sstevel@tonic-gate 1997*7c478bd9Sstevel@tonic-gate va_end(ap); 1998*7c478bd9Sstevel@tonic-gate 1999*7c478bd9Sstevel@tonic-gate need_newline = 0; 2000*7c478bd9Sstevel@tonic-gate } 2001*7c478bd9Sstevel@tonic-gate 2002*7c478bd9Sstevel@tonic-gate /* 2003*7c478bd9Sstevel@tonic-gate * This routine is a modified version of printf. It prints the message 2004*7c478bd9Sstevel@tonic-gate * to stderr, and to the log file is appropriate. 2005*7c478bd9Sstevel@tonic-gate * Other than that is identical to the library version. 2006*7c478bd9Sstevel@tonic-gate */ 2007*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 2008*7c478bd9Sstevel@tonic-gate void 2009*7c478bd9Sstevel@tonic-gate err_print(char *format, ...) 2010*7c478bd9Sstevel@tonic-gate { 2011*7c478bd9Sstevel@tonic-gate va_list ap; 2012*7c478bd9Sstevel@tonic-gate 2013*7c478bd9Sstevel@tonic-gate va_start(ap, format); 2014*7c478bd9Sstevel@tonic-gate 2015*7c478bd9Sstevel@tonic-gate /* 2016*7c478bd9Sstevel@tonic-gate * Flush anything pending to stdout 2017*7c478bd9Sstevel@tonic-gate */ 2018*7c478bd9Sstevel@tonic-gate if (need_newline) { 2019*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 2020*7c478bd9Sstevel@tonic-gate } 2021*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 2022*7c478bd9Sstevel@tonic-gate /* 2023*7c478bd9Sstevel@tonic-gate * Do the print to stderr. 2024*7c478bd9Sstevel@tonic-gate */ 2025*7c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, format, ap); 2026*7c478bd9Sstevel@tonic-gate /* 2027*7c478bd9Sstevel@tonic-gate * If we are logging, also print to the log file. 2028*7c478bd9Sstevel@tonic-gate */ 2029*7c478bd9Sstevel@tonic-gate if (log_file) { 2030*7c478bd9Sstevel@tonic-gate if (need_newline) { 2031*7c478bd9Sstevel@tonic-gate (void) fprintf(log_file, "\n"); 2032*7c478bd9Sstevel@tonic-gate } 2033*7c478bd9Sstevel@tonic-gate (void) vfprintf(log_file, format, ap); 2034*7c478bd9Sstevel@tonic-gate (void) fflush(log_file); 2035*7c478bd9Sstevel@tonic-gate } 2036*7c478bd9Sstevel@tonic-gate va_end(ap); 2037*7c478bd9Sstevel@tonic-gate 2038*7c478bd9Sstevel@tonic-gate need_newline = 0; 2039*7c478bd9Sstevel@tonic-gate } 2040*7c478bd9Sstevel@tonic-gate 2041*7c478bd9Sstevel@tonic-gate /* 2042*7c478bd9Sstevel@tonic-gate * Print a number of characters from a buffer. The buffer 2043*7c478bd9Sstevel@tonic-gate * does not need to be null-terminated. Since the data 2044*7c478bd9Sstevel@tonic-gate * may be coming from a device, we cannot be sure the 2045*7c478bd9Sstevel@tonic-gate * data is not crud, so be rather defensive. 2046*7c478bd9Sstevel@tonic-gate */ 2047*7c478bd9Sstevel@tonic-gate void 2048*7c478bd9Sstevel@tonic-gate print_buf(buf, nbytes) 2049*7c478bd9Sstevel@tonic-gate char *buf; 2050*7c478bd9Sstevel@tonic-gate int nbytes; 2051*7c478bd9Sstevel@tonic-gate { 2052*7c478bd9Sstevel@tonic-gate int c; 2053*7c478bd9Sstevel@tonic-gate 2054*7c478bd9Sstevel@tonic-gate while (nbytes-- > 0) { 2055*7c478bd9Sstevel@tonic-gate c = *buf++; 2056*7c478bd9Sstevel@tonic-gate if (isascii(c) && isprint(c)) { 2057*7c478bd9Sstevel@tonic-gate fmt_print("%c", c); 2058*7c478bd9Sstevel@tonic-gate } else 2059*7c478bd9Sstevel@tonic-gate break; 2060*7c478bd9Sstevel@tonic-gate } 2061*7c478bd9Sstevel@tonic-gate } 2062*7c478bd9Sstevel@tonic-gate 2063*7c478bd9Sstevel@tonic-gate #ifdef not 2064*7c478bd9Sstevel@tonic-gate /* 2065*7c478bd9Sstevel@tonic-gate * This routine prints out a message describing the given ctlr. 2066*7c478bd9Sstevel@tonic-gate * The message is identical to the one printed by the kernel during 2067*7c478bd9Sstevel@tonic-gate * booting. 2068*7c478bd9Sstevel@tonic-gate */ 2069*7c478bd9Sstevel@tonic-gate void 2070*7c478bd9Sstevel@tonic-gate pr_ctlrline(ctlr) 2071*7c478bd9Sstevel@tonic-gate register struct ctlr_info *ctlr; 2072*7c478bd9Sstevel@tonic-gate { 2073*7c478bd9Sstevel@tonic-gate 2074*7c478bd9Sstevel@tonic-gate fmt_print(" %s%d at %s 0x%x ", 2075*7c478bd9Sstevel@tonic-gate ctlr->ctlr_cname, ctlr->ctlr_num, 2076*7c478bd9Sstevel@tonic-gate space2str(ctlr->ctlr_space), ctlr->ctlr_addr); 2077*7c478bd9Sstevel@tonic-gate if (ctlr->ctlr_vec != 0) 2078*7c478bd9Sstevel@tonic-gate fmt_print("vec 0x%x ", ctlr->ctlr_vec); 2079*7c478bd9Sstevel@tonic-gate else 2080*7c478bd9Sstevel@tonic-gate fmt_print("pri %d ", ctlr->ctlr_prio); 2081*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 2082*7c478bd9Sstevel@tonic-gate } 2083*7c478bd9Sstevel@tonic-gate #endif /* not */ 2084*7c478bd9Sstevel@tonic-gate 2085*7c478bd9Sstevel@tonic-gate /* 2086*7c478bd9Sstevel@tonic-gate * This routine prints out a message describing the given disk. 2087*7c478bd9Sstevel@tonic-gate * The message is identical to the one printed by the kernel during 2088*7c478bd9Sstevel@tonic-gate * booting. 2089*7c478bd9Sstevel@tonic-gate */ 2090*7c478bd9Sstevel@tonic-gate void 2091*7c478bd9Sstevel@tonic-gate pr_diskline(disk, num) 2092*7c478bd9Sstevel@tonic-gate register struct disk_info *disk; 2093*7c478bd9Sstevel@tonic-gate int num; 2094*7c478bd9Sstevel@tonic-gate { 2095*7c478bd9Sstevel@tonic-gate struct ctlr_info *ctlr = disk->disk_ctlr; 2096*7c478bd9Sstevel@tonic-gate struct disk_type *type = disk->disk_type; 2097*7c478bd9Sstevel@tonic-gate 2098*7c478bd9Sstevel@tonic-gate fmt_print(" %4d. %s ", num, disk->disk_name); 2099*7c478bd9Sstevel@tonic-gate if ((type != NULL) && (disk->label_type == L_TYPE_SOLARIS)) { 2100*7c478bd9Sstevel@tonic-gate fmt_print("<%s cyl %d alt %d hd %d sec %d>", 2101*7c478bd9Sstevel@tonic-gate type->dtype_asciilabel, type->dtype_ncyl, 2102*7c478bd9Sstevel@tonic-gate type->dtype_acyl, type->dtype_nhead, 2103*7c478bd9Sstevel@tonic-gate type->dtype_nsect); 2104*7c478bd9Sstevel@tonic-gate } else if ((type != NULL) && (disk->label_type == L_TYPE_EFI)) { 2105*7c478bd9Sstevel@tonic-gate print_efi_string(type->vendor, type->product, 2106*7c478bd9Sstevel@tonic-gate type->revision, type->capacity); 2107*7c478bd9Sstevel@tonic-gate } else if (disk->disk_flags & DSK_RESERVED) { 2108*7c478bd9Sstevel@tonic-gate fmt_print("<drive not available: reserved>"); 2109*7c478bd9Sstevel@tonic-gate } else if (disk->disk_flags & DSK_UNAVAILABLE) { 2110*7c478bd9Sstevel@tonic-gate fmt_print("<drive not available>"); 2111*7c478bd9Sstevel@tonic-gate } else { 2112*7c478bd9Sstevel@tonic-gate fmt_print("<drive type unknown>"); 2113*7c478bd9Sstevel@tonic-gate } 2114*7c478bd9Sstevel@tonic-gate if (chk_volname(disk)) { 2115*7c478bd9Sstevel@tonic-gate fmt_print(" "); 2116*7c478bd9Sstevel@tonic-gate print_volname(disk); 2117*7c478bd9Sstevel@tonic-gate } 2118*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 2119*7c478bd9Sstevel@tonic-gate 2120*7c478bd9Sstevel@tonic-gate if (disk->devfs_name != NULL) { 2121*7c478bd9Sstevel@tonic-gate fmt_print(" %s\n", disk->devfs_name); 2122*7c478bd9Sstevel@tonic-gate } else { 2123*7c478bd9Sstevel@tonic-gate fmt_print(" %s%d at %s%d slave %d\n", 2124*7c478bd9Sstevel@tonic-gate ctlr->ctlr_dname, disk->disk_dkinfo.dki_unit, 2125*7c478bd9Sstevel@tonic-gate ctlr->ctlr_cname, ctlr->ctlr_num, 2126*7c478bd9Sstevel@tonic-gate disk->disk_dkinfo.dki_slave); 2127*7c478bd9Sstevel@tonic-gate } 2128*7c478bd9Sstevel@tonic-gate 2129*7c478bd9Sstevel@tonic-gate #ifdef OLD 2130*7c478bd9Sstevel@tonic-gate fmt_print(" %4d. %s at %s%d slave %d", num, disk->disk_name, 2131*7c478bd9Sstevel@tonic-gate ctlr->ctlr_cname, ctlr->ctlr_num, disk->disk_dkinfo.dki_slave); 2132*7c478bd9Sstevel@tonic-gate if (chk_volname(disk)) { 2133*7c478bd9Sstevel@tonic-gate fmt_print(": "); 2134*7c478bd9Sstevel@tonic-gate print_volname(disk); 2135*7c478bd9Sstevel@tonic-gate } 2136*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 2137*7c478bd9Sstevel@tonic-gate if (type != NULL) { 2138*7c478bd9Sstevel@tonic-gate fmt_print( 2139*7c478bd9Sstevel@tonic-gate " %s%d: <%s cyl %d alt %d hd %d sec %d>\n", 2140*7c478bd9Sstevel@tonic-gate ctlr->ctlr_dname, disk->disk_dkinfo.dki_unit, 2141*7c478bd9Sstevel@tonic-gate type->dtype_asciilabel, type->dtype_ncyl, 2142*7c478bd9Sstevel@tonic-gate type->dtype_acyl, type->dtype_nhead, 2143*7c478bd9Sstevel@tonic-gate type->dtype_nsect); 2144*7c478bd9Sstevel@tonic-gate } else { 2145*7c478bd9Sstevel@tonic-gate fmt_print(" %s%d: <drive type unknown>\n", 2146*7c478bd9Sstevel@tonic-gate ctlr->ctlr_dname, disk->disk_dkinfo.dki_unit); 2147*7c478bd9Sstevel@tonic-gate } 2148*7c478bd9Sstevel@tonic-gate #endif /* OLD */ 2149*7c478bd9Sstevel@tonic-gate } 2150*7c478bd9Sstevel@tonic-gate 2151*7c478bd9Sstevel@tonic-gate /* 2152*7c478bd9Sstevel@tonic-gate * This routine prints out a given disk block number in cylinder/head/sector 2153*7c478bd9Sstevel@tonic-gate * format. It uses the printing routine passed in to do the actual output. 2154*7c478bd9Sstevel@tonic-gate * Downcasting bn is okay for L_TYPE_SOLARIS because the number of blocks 2155*7c478bd9Sstevel@tonic-gate * on a Solaris (VTOC) label will never exceed 4 bytes (daddr_t). 2156*7c478bd9Sstevel@tonic-gate */ 2157*7c478bd9Sstevel@tonic-gate void 2158*7c478bd9Sstevel@tonic-gate pr_dblock(void (*func)(char *, ...), diskaddr_t bn) 2159*7c478bd9Sstevel@tonic-gate { 2160*7c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_SOLARIS) { 2161*7c478bd9Sstevel@tonic-gate (*func)("%d/%d/%d", bn2c((daddr_t)bn), 2162*7c478bd9Sstevel@tonic-gate bn2h((daddr_t)bn), bn2s((daddr_t)bn)); 2163*7c478bd9Sstevel@tonic-gate } else { 2164*7c478bd9Sstevel@tonic-gate (*func)("%llu", bn); 2165*7c478bd9Sstevel@tonic-gate } 2166*7c478bd9Sstevel@tonic-gate } 2167*7c478bd9Sstevel@tonic-gate 2168*7c478bd9Sstevel@tonic-gate /* 2169*7c478bd9Sstevel@tonic-gate * This routine inputs a character from the data file. It understands 2170*7c478bd9Sstevel@tonic-gate * the use of '\' to prevent interpretation of a newline. It also keeps 2171*7c478bd9Sstevel@tonic-gate * track of the current line in the data file via a global variable. 2172*7c478bd9Sstevel@tonic-gate */ 2173*7c478bd9Sstevel@tonic-gate static int 2174*7c478bd9Sstevel@tonic-gate sup_inputchar() 2175*7c478bd9Sstevel@tonic-gate { 2176*7c478bd9Sstevel@tonic-gate int c; 2177*7c478bd9Sstevel@tonic-gate 2178*7c478bd9Sstevel@tonic-gate /* 2179*7c478bd9Sstevel@tonic-gate * Input the character. 2180*7c478bd9Sstevel@tonic-gate */ 2181*7c478bd9Sstevel@tonic-gate c = getc(data_file); 2182*7c478bd9Sstevel@tonic-gate /* 2183*7c478bd9Sstevel@tonic-gate * If it's not a backslash, return it. 2184*7c478bd9Sstevel@tonic-gate */ 2185*7c478bd9Sstevel@tonic-gate if (c != '\\') 2186*7c478bd9Sstevel@tonic-gate return (c); 2187*7c478bd9Sstevel@tonic-gate /* 2188*7c478bd9Sstevel@tonic-gate * It was a backslash. Get the next character. 2189*7c478bd9Sstevel@tonic-gate */ 2190*7c478bd9Sstevel@tonic-gate c = getc(data_file); 2191*7c478bd9Sstevel@tonic-gate /* 2192*7c478bd9Sstevel@tonic-gate * If it was a newline, update the line counter and get the next 2193*7c478bd9Sstevel@tonic-gate * character. 2194*7c478bd9Sstevel@tonic-gate */ 2195*7c478bd9Sstevel@tonic-gate if (c == '\n') { 2196*7c478bd9Sstevel@tonic-gate data_lineno++; 2197*7c478bd9Sstevel@tonic-gate c = getc(data_file); 2198*7c478bd9Sstevel@tonic-gate } 2199*7c478bd9Sstevel@tonic-gate /* 2200*7c478bd9Sstevel@tonic-gate * Return the character. 2201*7c478bd9Sstevel@tonic-gate */ 2202*7c478bd9Sstevel@tonic-gate return (c); 2203*7c478bd9Sstevel@tonic-gate } 2204*7c478bd9Sstevel@tonic-gate 2205*7c478bd9Sstevel@tonic-gate /* 2206*7c478bd9Sstevel@tonic-gate * This routine pushes a character back onto the input pipe for the data file. 2207*7c478bd9Sstevel@tonic-gate */ 2208*7c478bd9Sstevel@tonic-gate static void 2209*7c478bd9Sstevel@tonic-gate sup_pushchar(c) 2210*7c478bd9Sstevel@tonic-gate int c; 2211*7c478bd9Sstevel@tonic-gate { 2212*7c478bd9Sstevel@tonic-gate (void) ungetc(c, data_file); 2213*7c478bd9Sstevel@tonic-gate } 2214*7c478bd9Sstevel@tonic-gate 2215*7c478bd9Sstevel@tonic-gate /* 2216*7c478bd9Sstevel@tonic-gate * Variables to support pushing back tokens 2217*7c478bd9Sstevel@tonic-gate */ 2218*7c478bd9Sstevel@tonic-gate static int have_pushed_token = 0; 2219*7c478bd9Sstevel@tonic-gate static TOKEN pushed_buf; 2220*7c478bd9Sstevel@tonic-gate static int pushed_token; 2221*7c478bd9Sstevel@tonic-gate 2222*7c478bd9Sstevel@tonic-gate /* 2223*7c478bd9Sstevel@tonic-gate * This routine inputs a token from the data file. A token is a series 2224*7c478bd9Sstevel@tonic-gate * of contiguous non-white characters or a recognized special delimiter 2225*7c478bd9Sstevel@tonic-gate * character. Use of the wrapper lets us always have the value of the 2226*7c478bd9Sstevel@tonic-gate * last token around, which is useful for error recovery. 2227*7c478bd9Sstevel@tonic-gate */ 2228*7c478bd9Sstevel@tonic-gate int 2229*7c478bd9Sstevel@tonic-gate sup_gettoken(buf) 2230*7c478bd9Sstevel@tonic-gate char *buf; 2231*7c478bd9Sstevel@tonic-gate { 2232*7c478bd9Sstevel@tonic-gate last_token_type = sup_get_token(buf); 2233*7c478bd9Sstevel@tonic-gate return (last_token_type); 2234*7c478bd9Sstevel@tonic-gate } 2235*7c478bd9Sstevel@tonic-gate 2236*7c478bd9Sstevel@tonic-gate static int 2237*7c478bd9Sstevel@tonic-gate sup_get_token(buf) 2238*7c478bd9Sstevel@tonic-gate char *buf; 2239*7c478bd9Sstevel@tonic-gate { 2240*7c478bd9Sstevel@tonic-gate char *ptr = buf; 2241*7c478bd9Sstevel@tonic-gate int c, quoted = 0; 2242*7c478bd9Sstevel@tonic-gate 2243*7c478bd9Sstevel@tonic-gate /* 2244*7c478bd9Sstevel@tonic-gate * First check for presence of push-backed token. 2245*7c478bd9Sstevel@tonic-gate * If so, return it. 2246*7c478bd9Sstevel@tonic-gate */ 2247*7c478bd9Sstevel@tonic-gate if (have_pushed_token) { 2248*7c478bd9Sstevel@tonic-gate have_pushed_token = 0; 2249*7c478bd9Sstevel@tonic-gate bcopy(pushed_buf, buf, TOKEN_SIZE+1); 2250*7c478bd9Sstevel@tonic-gate return (pushed_token); 2251*7c478bd9Sstevel@tonic-gate } 2252*7c478bd9Sstevel@tonic-gate /* 2253*7c478bd9Sstevel@tonic-gate * Zero out the returned token buffer 2254*7c478bd9Sstevel@tonic-gate */ 2255*7c478bd9Sstevel@tonic-gate bzero(buf, TOKEN_SIZE + 1); 2256*7c478bd9Sstevel@tonic-gate /* 2257*7c478bd9Sstevel@tonic-gate * Strip off leading white-space. 2258*7c478bd9Sstevel@tonic-gate */ 2259*7c478bd9Sstevel@tonic-gate while ((isspace(c = sup_inputchar())) && (c != '\n')) 2260*7c478bd9Sstevel@tonic-gate ; 2261*7c478bd9Sstevel@tonic-gate /* 2262*7c478bd9Sstevel@tonic-gate * Read in characters until we hit unquoted white-space. 2263*7c478bd9Sstevel@tonic-gate */ 2264*7c478bd9Sstevel@tonic-gate for (; !isspace(c) || quoted; c = sup_inputchar()) { 2265*7c478bd9Sstevel@tonic-gate /* 2266*7c478bd9Sstevel@tonic-gate * If we hit eof, that's a token. 2267*7c478bd9Sstevel@tonic-gate */ 2268*7c478bd9Sstevel@tonic-gate if (feof(data_file)) 2269*7c478bd9Sstevel@tonic-gate return (SUP_EOF); 2270*7c478bd9Sstevel@tonic-gate /* 2271*7c478bd9Sstevel@tonic-gate * If we hit a double quote, change the state of quoting. 2272*7c478bd9Sstevel@tonic-gate */ 2273*7c478bd9Sstevel@tonic-gate if (c == '"') { 2274*7c478bd9Sstevel@tonic-gate quoted = !quoted; 2275*7c478bd9Sstevel@tonic-gate continue; 2276*7c478bd9Sstevel@tonic-gate } 2277*7c478bd9Sstevel@tonic-gate /* 2278*7c478bd9Sstevel@tonic-gate * If we hit a newline, that delimits a token. 2279*7c478bd9Sstevel@tonic-gate */ 2280*7c478bd9Sstevel@tonic-gate if (c == '\n') 2281*7c478bd9Sstevel@tonic-gate break; 2282*7c478bd9Sstevel@tonic-gate /* 2283*7c478bd9Sstevel@tonic-gate * If we hit any nonquoted special delimiters, that delimits 2284*7c478bd9Sstevel@tonic-gate * a token. 2285*7c478bd9Sstevel@tonic-gate */ 2286*7c478bd9Sstevel@tonic-gate if (!quoted && (c == '=' || c == ',' || c == ':' || 2287*7c478bd9Sstevel@tonic-gate c == '#' || c == '|' || c == '&' || c == '~')) 2288*7c478bd9Sstevel@tonic-gate break; 2289*7c478bd9Sstevel@tonic-gate /* 2290*7c478bd9Sstevel@tonic-gate * Store the character if there's room left. 2291*7c478bd9Sstevel@tonic-gate */ 2292*7c478bd9Sstevel@tonic-gate if (ptr - buf < TOKEN_SIZE) 2293*7c478bd9Sstevel@tonic-gate *ptr++ = (char)c; 2294*7c478bd9Sstevel@tonic-gate } 2295*7c478bd9Sstevel@tonic-gate /* 2296*7c478bd9Sstevel@tonic-gate * If we stored characters in the buffer, then we inputted a string. 2297*7c478bd9Sstevel@tonic-gate * Push the delimiter back into the pipe and return the string. 2298*7c478bd9Sstevel@tonic-gate */ 2299*7c478bd9Sstevel@tonic-gate if (ptr - buf > 0) { 2300*7c478bd9Sstevel@tonic-gate sup_pushchar(c); 2301*7c478bd9Sstevel@tonic-gate return (SUP_STRING); 2302*7c478bd9Sstevel@tonic-gate } 2303*7c478bd9Sstevel@tonic-gate /* 2304*7c478bd9Sstevel@tonic-gate * We didn't input a string, so we must have inputted a known delimiter. 2305*7c478bd9Sstevel@tonic-gate * store the delimiter in the buffer, so it will get returned. 2306*7c478bd9Sstevel@tonic-gate */ 2307*7c478bd9Sstevel@tonic-gate buf[0] = c; 2308*7c478bd9Sstevel@tonic-gate /* 2309*7c478bd9Sstevel@tonic-gate * Switch on the delimiter. Return the appropriate value for each one. 2310*7c478bd9Sstevel@tonic-gate */ 2311*7c478bd9Sstevel@tonic-gate switch (c) { 2312*7c478bd9Sstevel@tonic-gate case '=': 2313*7c478bd9Sstevel@tonic-gate return (SUP_EQL); 2314*7c478bd9Sstevel@tonic-gate case ':': 2315*7c478bd9Sstevel@tonic-gate return (SUP_COLON); 2316*7c478bd9Sstevel@tonic-gate case ',': 2317*7c478bd9Sstevel@tonic-gate return (SUP_COMMA); 2318*7c478bd9Sstevel@tonic-gate case '\n': 2319*7c478bd9Sstevel@tonic-gate return (SUP_EOL); 2320*7c478bd9Sstevel@tonic-gate case '|': 2321*7c478bd9Sstevel@tonic-gate return (SUP_OR); 2322*7c478bd9Sstevel@tonic-gate case '&': 2323*7c478bd9Sstevel@tonic-gate return (SUP_AND); 2324*7c478bd9Sstevel@tonic-gate case '~': 2325*7c478bd9Sstevel@tonic-gate return (SUP_TILDE); 2326*7c478bd9Sstevel@tonic-gate case '#': 2327*7c478bd9Sstevel@tonic-gate /* 2328*7c478bd9Sstevel@tonic-gate * For comments, we flush out the rest of the line and return 2329*7c478bd9Sstevel@tonic-gate * an EOL. 2330*7c478bd9Sstevel@tonic-gate */ 2331*7c478bd9Sstevel@tonic-gate while ((c = sup_inputchar()) != '\n' && !feof(data_file)) 2332*7c478bd9Sstevel@tonic-gate ; 2333*7c478bd9Sstevel@tonic-gate if (feof(data_file)) 2334*7c478bd9Sstevel@tonic-gate return (SUP_EOF); 2335*7c478bd9Sstevel@tonic-gate else 2336*7c478bd9Sstevel@tonic-gate return (SUP_EOL); 2337*7c478bd9Sstevel@tonic-gate /* 2338*7c478bd9Sstevel@tonic-gate * Shouldn't ever get here. 2339*7c478bd9Sstevel@tonic-gate */ 2340*7c478bd9Sstevel@tonic-gate default: 2341*7c478bd9Sstevel@tonic-gate return (SUP_STRING); 2342*7c478bd9Sstevel@tonic-gate } 2343*7c478bd9Sstevel@tonic-gate } 2344*7c478bd9Sstevel@tonic-gate 2345*7c478bd9Sstevel@tonic-gate /* 2346*7c478bd9Sstevel@tonic-gate * Push back a token 2347*7c478bd9Sstevel@tonic-gate */ 2348*7c478bd9Sstevel@tonic-gate void 2349*7c478bd9Sstevel@tonic-gate sup_pushtoken(token_buf, token_type) 2350*7c478bd9Sstevel@tonic-gate char *token_buf; 2351*7c478bd9Sstevel@tonic-gate int token_type; 2352*7c478bd9Sstevel@tonic-gate { 2353*7c478bd9Sstevel@tonic-gate /* 2354*7c478bd9Sstevel@tonic-gate * We can only push one token back at a time 2355*7c478bd9Sstevel@tonic-gate */ 2356*7c478bd9Sstevel@tonic-gate assert(have_pushed_token == 0); 2357*7c478bd9Sstevel@tonic-gate 2358*7c478bd9Sstevel@tonic-gate have_pushed_token = 1; 2359*7c478bd9Sstevel@tonic-gate bcopy(token_buf, pushed_buf, TOKEN_SIZE+1); 2360*7c478bd9Sstevel@tonic-gate pushed_token = token_type; 2361*7c478bd9Sstevel@tonic-gate } 2362*7c478bd9Sstevel@tonic-gate 2363*7c478bd9Sstevel@tonic-gate /* 2364*7c478bd9Sstevel@tonic-gate * Get an entire line of input. Handles logging, comments, 2365*7c478bd9Sstevel@tonic-gate * and EOF. 2366*7c478bd9Sstevel@tonic-gate */ 2367*7c478bd9Sstevel@tonic-gate void 2368*7c478bd9Sstevel@tonic-gate get_inputline(line, nbytes) 2369*7c478bd9Sstevel@tonic-gate char *line; 2370*7c478bd9Sstevel@tonic-gate int nbytes; 2371*7c478bd9Sstevel@tonic-gate { 2372*7c478bd9Sstevel@tonic-gate char *p = line; 2373*7c478bd9Sstevel@tonic-gate int c; 2374*7c478bd9Sstevel@tonic-gate 2375*7c478bd9Sstevel@tonic-gate /* 2376*7c478bd9Sstevel@tonic-gate * Remove any leading white-space and comments 2377*7c478bd9Sstevel@tonic-gate */ 2378*7c478bd9Sstevel@tonic-gate do { 2379*7c478bd9Sstevel@tonic-gate while ((isspace(c = getchar())) && (c != '\n')) 2380*7c478bd9Sstevel@tonic-gate ; 2381*7c478bd9Sstevel@tonic-gate } while (c == COMMENT_CHAR); 2382*7c478bd9Sstevel@tonic-gate /* 2383*7c478bd9Sstevel@tonic-gate * Loop on each character until end of line 2384*7c478bd9Sstevel@tonic-gate */ 2385*7c478bd9Sstevel@tonic-gate while (c != '\n') { 2386*7c478bd9Sstevel@tonic-gate /* 2387*7c478bd9Sstevel@tonic-gate * If we hit eof, get out. 2388*7c478bd9Sstevel@tonic-gate */ 2389*7c478bd9Sstevel@tonic-gate if (checkeof()) { 2390*7c478bd9Sstevel@tonic-gate fullabort(); 2391*7c478bd9Sstevel@tonic-gate } 2392*7c478bd9Sstevel@tonic-gate /* 2393*7c478bd9Sstevel@tonic-gate * Add the character to the buffer. 2394*7c478bd9Sstevel@tonic-gate */ 2395*7c478bd9Sstevel@tonic-gate if (nbytes > 1) { 2396*7c478bd9Sstevel@tonic-gate *p++ = (char)c; 2397*7c478bd9Sstevel@tonic-gate nbytes --; 2398*7c478bd9Sstevel@tonic-gate } 2399*7c478bd9Sstevel@tonic-gate /* 2400*7c478bd9Sstevel@tonic-gate * Get the next character. 2401*7c478bd9Sstevel@tonic-gate */ 2402*7c478bd9Sstevel@tonic-gate c = getchar(); 2403*7c478bd9Sstevel@tonic-gate } 2404*7c478bd9Sstevel@tonic-gate /* 2405*7c478bd9Sstevel@tonic-gate * Null terminate the token. 2406*7c478bd9Sstevel@tonic-gate */ 2407*7c478bd9Sstevel@tonic-gate *p = 0; 2408*7c478bd9Sstevel@tonic-gate /* 2409*7c478bd9Sstevel@tonic-gate * Indicate that we've emptied the pipe 2410*7c478bd9Sstevel@tonic-gate */ 2411*7c478bd9Sstevel@tonic-gate token_present = 0; 2412*7c478bd9Sstevel@tonic-gate /* 2413*7c478bd9Sstevel@tonic-gate * If we're running out of a file, echo the line to 2414*7c478bd9Sstevel@tonic-gate * the user, otherwise if we're logging, copy the 2415*7c478bd9Sstevel@tonic-gate * input to the log file. 2416*7c478bd9Sstevel@tonic-gate */ 2417*7c478bd9Sstevel@tonic-gate if (option_f) { 2418*7c478bd9Sstevel@tonic-gate fmt_print("%s\n", line); 2419*7c478bd9Sstevel@tonic-gate } else if (log_file) { 2420*7c478bd9Sstevel@tonic-gate log_print("%s\n", line); 2421*7c478bd9Sstevel@tonic-gate } 2422*7c478bd9Sstevel@tonic-gate } 2423*7c478bd9Sstevel@tonic-gate 2424*7c478bd9Sstevel@tonic-gate /* 2425*7c478bd9Sstevel@tonic-gate * execute the shell escape command 2426*7c478bd9Sstevel@tonic-gate */ 2427*7c478bd9Sstevel@tonic-gate int 2428*7c478bd9Sstevel@tonic-gate execute_shell(s) 2429*7c478bd9Sstevel@tonic-gate char *s; 2430*7c478bd9Sstevel@tonic-gate { 2431*7c478bd9Sstevel@tonic-gate struct termio termio; 2432*7c478bd9Sstevel@tonic-gate struct termios tty; 2433*7c478bd9Sstevel@tonic-gate int tty_flag, i, j; 2434*7c478bd9Sstevel@tonic-gate char *shell_name; 2435*7c478bd9Sstevel@tonic-gate static char *default_shell = "/bin/sh"; 2436*7c478bd9Sstevel@tonic-gate 2437*7c478bd9Sstevel@tonic-gate tty_flag = -1; 2438*7c478bd9Sstevel@tonic-gate 2439*7c478bd9Sstevel@tonic-gate if (*s == NULL) { 2440*7c478bd9Sstevel@tonic-gate shell_name = getenv("SHELL"); 2441*7c478bd9Sstevel@tonic-gate 2442*7c478bd9Sstevel@tonic-gate if (shell_name == NULL) { 2443*7c478bd9Sstevel@tonic-gate shell_name = default_shell; 2444*7c478bd9Sstevel@tonic-gate } 2445*7c478bd9Sstevel@tonic-gate 2446*7c478bd9Sstevel@tonic-gate if (strlcpy(s, shell_name, MAXPATHLEN) >= 2447*7c478bd9Sstevel@tonic-gate MAXPATHLEN) { 2448*7c478bd9Sstevel@tonic-gate err_print("Error: length of shell command" 2449*7c478bd9Sstevel@tonic-gate " ($SHELL) exceeds MAXPATHLEN\n"); 2450*7c478bd9Sstevel@tonic-gate fullabort(); 2451*7c478bd9Sstevel@tonic-gate } 2452*7c478bd9Sstevel@tonic-gate } 2453*7c478bd9Sstevel@tonic-gate 2454*7c478bd9Sstevel@tonic-gate /* save tty information */ 2455*7c478bd9Sstevel@tonic-gate 2456*7c478bd9Sstevel@tonic-gate if (isatty(0)) { 2457*7c478bd9Sstevel@tonic-gate if (ioctl(0, TCGETS, &tty) == 0) 2458*7c478bd9Sstevel@tonic-gate tty_flag = 1; 2459*7c478bd9Sstevel@tonic-gate else { 2460*7c478bd9Sstevel@tonic-gate if (ioctl(0, TCGETA, &termio) == 0) { 2461*7c478bd9Sstevel@tonic-gate tty_flag = 0; 2462*7c478bd9Sstevel@tonic-gate tty.c_iflag = termio.c_iflag; 2463*7c478bd9Sstevel@tonic-gate tty.c_oflag = termio.c_oflag; 2464*7c478bd9Sstevel@tonic-gate tty.c_cflag = termio.c_cflag; 2465*7c478bd9Sstevel@tonic-gate tty.c_lflag = termio.c_lflag; 2466*7c478bd9Sstevel@tonic-gate for (i = 0; i < NCC; i++) 2467*7c478bd9Sstevel@tonic-gate tty.c_cc[i] = termio.c_cc[i]; 2468*7c478bd9Sstevel@tonic-gate } 2469*7c478bd9Sstevel@tonic-gate } 2470*7c478bd9Sstevel@tonic-gate } 2471*7c478bd9Sstevel@tonic-gate 2472*7c478bd9Sstevel@tonic-gate /* close the current file descriptor */ 2473*7c478bd9Sstevel@tonic-gate if (cur_disk != NULL) { 2474*7c478bd9Sstevel@tonic-gate (void) close(cur_file); 2475*7c478bd9Sstevel@tonic-gate } 2476*7c478bd9Sstevel@tonic-gate 2477*7c478bd9Sstevel@tonic-gate /* execute the shell escape */ 2478*7c478bd9Sstevel@tonic-gate (void) system(s); 2479*7c478bd9Sstevel@tonic-gate 2480*7c478bd9Sstevel@tonic-gate /* reopen file descriptor if one was open before */ 2481*7c478bd9Sstevel@tonic-gate if (cur_disk != NULL) { 2482*7c478bd9Sstevel@tonic-gate if ((cur_file = open_disk(cur_disk->disk_path, 2483*7c478bd9Sstevel@tonic-gate O_RDWR | O_NDELAY)) < 0) { 2484*7c478bd9Sstevel@tonic-gate err_print("Error: can't reopen selected disk '%s'. \n", 2485*7c478bd9Sstevel@tonic-gate cur_disk->disk_name); 2486*7c478bd9Sstevel@tonic-gate fullabort(); 2487*7c478bd9Sstevel@tonic-gate } 2488*7c478bd9Sstevel@tonic-gate } 2489*7c478bd9Sstevel@tonic-gate 2490*7c478bd9Sstevel@tonic-gate /* Restore tty information */ 2491*7c478bd9Sstevel@tonic-gate 2492*7c478bd9Sstevel@tonic-gate if (isatty(0)) { 2493*7c478bd9Sstevel@tonic-gate if (tty_flag > 0) 2494*7c478bd9Sstevel@tonic-gate (void) ioctl(0, TCSETSW, &tty); 2495*7c478bd9Sstevel@tonic-gate else if (tty_flag == 0) { 2496*7c478bd9Sstevel@tonic-gate termio.c_iflag = tty.c_iflag; 2497*7c478bd9Sstevel@tonic-gate termio.c_oflag = tty.c_oflag; 2498*7c478bd9Sstevel@tonic-gate termio.c_cflag = tty.c_cflag; 2499*7c478bd9Sstevel@tonic-gate termio.c_lflag = tty.c_lflag; 2500*7c478bd9Sstevel@tonic-gate for (j = 0; j < NCC; j++) 2501*7c478bd9Sstevel@tonic-gate termio.c_cc[j] = tty.c_cc[j]; 2502*7c478bd9Sstevel@tonic-gate (void) ioctl(0, TCSETAW, &termio); 2503*7c478bd9Sstevel@tonic-gate } 2504*7c478bd9Sstevel@tonic-gate 2505*7c478bd9Sstevel@tonic-gate if (isatty(1)) { 2506*7c478bd9Sstevel@tonic-gate fmt_print("\n[Hit Return to continue] \n"); 2507*7c478bd9Sstevel@tonic-gate (void) fflush(stdin); 2508*7c478bd9Sstevel@tonic-gate if (getchar() == EOF) 2509*7c478bd9Sstevel@tonic-gate fullabort(); 2510*7c478bd9Sstevel@tonic-gate } 2511*7c478bd9Sstevel@tonic-gate } 2512*7c478bd9Sstevel@tonic-gate return (0); 2513*7c478bd9Sstevel@tonic-gate } 2514*7c478bd9Sstevel@tonic-gate 2515*7c478bd9Sstevel@tonic-gate void 2516*7c478bd9Sstevel@tonic-gate print_efi_string(char *vendor, char *product, char *revision, 2517*7c478bd9Sstevel@tonic-gate uint64_t capacity) 2518*7c478bd9Sstevel@tonic-gate { 2519*7c478bd9Sstevel@tonic-gate char new_vendor[9]; 2520*7c478bd9Sstevel@tonic-gate char new_product[17]; 2521*7c478bd9Sstevel@tonic-gate char new_revision[5]; 2522*7c478bd9Sstevel@tonic-gate char capacity_string[10]; 2523*7c478bd9Sstevel@tonic-gate float scaled; 2524*7c478bd9Sstevel@tonic-gate int i; 2525*7c478bd9Sstevel@tonic-gate 2526*7c478bd9Sstevel@tonic-gate /* Strip whitespace from the end of inquiry strings */ 2527*7c478bd9Sstevel@tonic-gate (void) strlcpy(new_vendor, vendor, sizeof (new_vendor)); 2528*7c478bd9Sstevel@tonic-gate for (i = (strlen(new_vendor) - 1); i >= 0; i--) { 2529*7c478bd9Sstevel@tonic-gate if (new_vendor[i] != 0x20) { 2530*7c478bd9Sstevel@tonic-gate new_vendor[i+1] = '\0'; 2531*7c478bd9Sstevel@tonic-gate break; 2532*7c478bd9Sstevel@tonic-gate } 2533*7c478bd9Sstevel@tonic-gate } 2534*7c478bd9Sstevel@tonic-gate 2535*7c478bd9Sstevel@tonic-gate (void) strlcpy(new_product, product, sizeof (new_product)); 2536*7c478bd9Sstevel@tonic-gate for (i = (strlen(new_product) - 1); i >= 0; i--) { 2537*7c478bd9Sstevel@tonic-gate if (new_product[i] != 0x20) { 2538*7c478bd9Sstevel@tonic-gate new_product[i+1] = '\0'; 2539*7c478bd9Sstevel@tonic-gate break; 2540*7c478bd9Sstevel@tonic-gate } 2541*7c478bd9Sstevel@tonic-gate } 2542*7c478bd9Sstevel@tonic-gate 2543*7c478bd9Sstevel@tonic-gate (void) strlcpy(new_revision, revision, sizeof (new_revision)); 2544*7c478bd9Sstevel@tonic-gate for (i = (strlen(new_revision) - 1); i >= 0; i--) { 2545*7c478bd9Sstevel@tonic-gate if (new_revision[i] != 0x20) { 2546*7c478bd9Sstevel@tonic-gate new_revision[i+1] = '\0'; 2547*7c478bd9Sstevel@tonic-gate break; 2548*7c478bd9Sstevel@tonic-gate } 2549*7c478bd9Sstevel@tonic-gate } 2550*7c478bd9Sstevel@tonic-gate 2551*7c478bd9Sstevel@tonic-gate /* Now build size string */ 2552*7c478bd9Sstevel@tonic-gate scaled = bn2mb(capacity); 2553*7c478bd9Sstevel@tonic-gate if (scaled >= (float)1024.0 * 1024) { 2554*7c478bd9Sstevel@tonic-gate (void) snprintf(capacity_string, sizeof (capacity_string), 2555*7c478bd9Sstevel@tonic-gate "%.2fTB", scaled/((float)1024.0 * 1024)); 2556*7c478bd9Sstevel@tonic-gate } else if (scaled >= (float)1024.0) { 2557*7c478bd9Sstevel@tonic-gate (void) snprintf(capacity_string, sizeof (capacity_string), 2558*7c478bd9Sstevel@tonic-gate "%.2fGB", scaled/(float)1024.0); 2559*7c478bd9Sstevel@tonic-gate } else { 2560*7c478bd9Sstevel@tonic-gate (void) snprintf(capacity_string, sizeof (capacity_string), 2561*7c478bd9Sstevel@tonic-gate "%.2fMB", scaled); 2562*7c478bd9Sstevel@tonic-gate } 2563*7c478bd9Sstevel@tonic-gate 2564*7c478bd9Sstevel@tonic-gate fmt_print("<%s-%s-%s-%s>", 2565*7c478bd9Sstevel@tonic-gate new_vendor, new_product, new_revision, capacity_string); 2566*7c478bd9Sstevel@tonic-gate } 2567