1217309Snwhitehorn/* $OpenBSD: io.c,v 1.31 2016/02/01 18:55:00 krw Exp $ */ 2224014Snwhitehorn 3217309Snwhitehorn/* 4217309Snwhitehorn * io.c - simple io and input parsing routines 5217309Snwhitehorn * 6220749Snwhitehorn * Written by Eryk Vershen 7217309Snwhitehorn */ 8217309Snwhitehorn 9217309Snwhitehorn/* 10217309Snwhitehorn * Copyright 1996,1997,1998 by Apple Computer, Inc. 11217309Snwhitehorn * All Rights Reserved 12217309Snwhitehorn * 13217309Snwhitehorn * Permission to use, copy, modify, and distribute this software and 14217309Snwhitehorn * its documentation for any purpose and without fee is hereby granted, 15217309Snwhitehorn * provided that the above copyright notice appears in all copies and 16217309Snwhitehorn * that both the copyright notice and this permission notice appear in 17217309Snwhitehorn * supporting documentation. 18217309Snwhitehorn * 19217309Snwhitehorn * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 20217309Snwhitehorn * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21217309Snwhitehorn * FOR A PARTICULAR PURPOSE. 22217309Snwhitehorn * 23217309Snwhitehorn * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 24217309Snwhitehorn * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 25217309Snwhitehorn * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 26217309Snwhitehorn * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 27217309Snwhitehorn * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28217309Snwhitehorn */ 29217309Snwhitehorn 30217309Snwhitehorn#include <sys/queue.h> 31217309Snwhitehorn 32217309Snwhitehorn#include <err.h> 33217309Snwhitehorn#include <stdio.h> 34217309Snwhitehorn#include <stdlib.h> 35217309Snwhitehorn#include <string.h> 36217309Snwhitehorn#include <stdarg.h> 37217309Snwhitehorn 38217309Snwhitehorn#include "partition_map.h" 39217309Snwhitehorn#include "io.h" 40217309Snwhitehorn 41217309Snwhitehorn#define UNGET_MAX_COUNT 10 42217309Snwhitehorn 43217309Snwhitehornshort unget_buf[UNGET_MAX_COUNT + 1]; 44217309Snwhitehornint unget_count; 45217309Snwhitehorn 46217309Snwhitehornstatic int get_number(long *); 47217309Snwhitehornstatic char *get_string(int); 48217309Snwhitehornstatic int my_getch (void); 49217309Snwhitehorn 50217309Snwhitehornint 51217309Snwhitehornmy_getch() 52217309Snwhitehorn{ 53217309Snwhitehorn if (unget_count > 0) 54217309Snwhitehorn return unget_buf[--unget_count]; 55217309Snwhitehorn else 56217309Snwhitehorn return getc(stdin); 57217309Snwhitehorn} 58217309Snwhitehorn 59217309Snwhitehorn 60217309Snwhitehornvoid 61217309Snwhitehornmy_ungetch(int c) 62217309Snwhitehorn{ 63217309Snwhitehorn /* 64217309Snwhitehorn * In practice there is never more than one character in 65217309Snwhitehorn * the unget_buf, but what's a little overkill among friends? 66217309Snwhitehorn */ 67217309Snwhitehorn if (unget_count < UNGET_MAX_COUNT) 68217309Snwhitehorn unget_buf[unget_count++] = c; 69217309Snwhitehorn else 70217309Snwhitehorn errx(1, "Programmer error in my_ungetch()."); 71217309Snwhitehorn} 72217309Snwhitehorn 73217309Snwhitehornvoid 74224014Snwhitehornflush_to_newline(int keep_newline) 75217309Snwhitehorn{ 76224014Snwhitehorn int c; 77217309Snwhitehorn 78217309Snwhitehorn for (;;) { 79217309Snwhitehorn c = my_getch(); 80217309Snwhitehorn 81217309Snwhitehorn if (c <= 0) { 82217309Snwhitehorn break; 83217309Snwhitehorn } else if (c == '\n') { 84217309Snwhitehorn if (keep_newline) 85217309Snwhitehorn my_ungetch(c); 86217309Snwhitehorn break; 87217309Snwhitehorn } else { 88217309Snwhitehorn /* skip */ 89217309Snwhitehorn } 90217309Snwhitehorn } 91217309Snwhitehorn return; 92217309Snwhitehorn} 93217309Snwhitehorn 94217309Snwhitehorn 95217309Snwhitehornint 96217309Snwhitehornget_okay(const char *prompt, int default_value) 97217309Snwhitehorn{ 98217309Snwhitehorn int c; 99217309Snwhitehorn 100220749Snwhitehorn flush_to_newline(0); 101224014Snwhitehorn printf("%s", prompt); 102217309Snwhitehorn 103217309Snwhitehorn for (;;) { 104217309Snwhitehorn c = my_getch(); 105217309Snwhitehorn 106217309Snwhitehorn if (c <= 0) { 107217309Snwhitehorn break; 108217309Snwhitehorn } else if (c == ' ' || c == '\t') { 109217309Snwhitehorn /* skip blanks and tabs */ 110217309Snwhitehorn } else if (c == '\n') { 111217309Snwhitehorn my_ungetch(c); 112220749Snwhitehorn return default_value; 113217309Snwhitehorn } else if (c == 'y' || c == 'Y') { 114217309Snwhitehorn return 1; 115217309Snwhitehorn } else if (c == 'n' || c == 'N') { 116220749Snwhitehorn return 0; 117217309Snwhitehorn } else { 118217309Snwhitehorn flush_to_newline(0); 119217309Snwhitehorn printf("%s", prompt); 120217309Snwhitehorn } 121217309Snwhitehorn } 122217309Snwhitehorn return -1; 123217309Snwhitehorn} 124217309Snwhitehorn 125217309Snwhitehornint 126217309Snwhitehornget_command(const char *prompt, int promptBeforeGet, int *command) 127217309Snwhitehorn{ 128217309Snwhitehorn int c; 129217309Snwhitehorn 130217309Snwhitehorn if (promptBeforeGet) 131217309Snwhitehorn printf("%s", prompt); 132217309Snwhitehorn 133217309Snwhitehorn for (;;) { 134217309Snwhitehorn c = my_getch(); 135217309Snwhitehorn 136217309Snwhitehorn if (c <= 0) { 137217309Snwhitehorn break; 138217309Snwhitehorn } else if (c == ' ' || c == '\t') { 139217309Snwhitehorn /* skip blanks and tabs */ 140217309Snwhitehorn } else if (c == '\n') { 141217309Snwhitehorn printf("%s", prompt); 142217309Snwhitehorn } else { 143224014Snwhitehorn *command = c; 144217309Snwhitehorn return 1; 145217309Snwhitehorn } 146217309Snwhitehorn } 147217309Snwhitehorn return 0; 148217309Snwhitehorn} 149217309Snwhitehorn 150217309Snwhitehornint 151217309Snwhitehornget_number_argument(const char *prompt, long *number) 152217309Snwhitehorn{ 153217309Snwhitehorn int c; 154217309Snwhitehorn int result = 0; 155217309Snwhitehorn 156217309Snwhitehorn for (;;) { 157217309Snwhitehorn c = my_getch(); 158217309Snwhitehorn 159217309Snwhitehorn if (c <= 0) { 160217309Snwhitehorn break; 161217309Snwhitehorn } else if (c == ' ' || c == '\t') { 162217309Snwhitehorn /* skip blanks and tabs */ 163217309Snwhitehorn } else if (c == '\n') { 164217309Snwhitehorn printf("%s", prompt); 165217309Snwhitehorn } else if ('0' <= c && c <= '9') { 166217309Snwhitehorn my_ungetch(c); 167217309Snwhitehorn result = get_number(number); 168217309Snwhitehorn break; 169217309Snwhitehorn } else { 170217309Snwhitehorn my_ungetch(c); 171217309Snwhitehorn *number = 0; 172217309Snwhitehorn break; 173217309Snwhitehorn } 174217309Snwhitehorn } 175217309Snwhitehorn return result; 176217309Snwhitehorn} 177217309Snwhitehorn 178217309Snwhitehorn 179217309Snwhitehornint 180217309Snwhitehornget_number(long *number) 181217309Snwhitehorn{ 182217309Snwhitehorn long value; 183217309Snwhitehorn int c; 184217309Snwhitehorn 185217309Snwhitehorn value = 0; 186217309Snwhitehorn while ((c = my_getch())) { 187217309Snwhitehorn if (c >= '0' && c <= '9') { 188217309Snwhitehorn value = value * 10 + (c - '0'); 189217309Snwhitehorn } else if (c == ' ' || c == '\t' || c == '\n') { 190217309Snwhitehorn my_ungetch(c); 191217309Snwhitehorn *number = value; 192217309Snwhitehorn return 1; 193217309Snwhitehorn } else { 194217309Snwhitehorn return 0; 195217309Snwhitehorn } 196217309Snwhitehorn } 197217309Snwhitehorn 198217309Snwhitehorn return 0; 199217309Snwhitehorn} 200217309Snwhitehorn 201217309Snwhitehornchar * 202217309Snwhitehornget_dpistr_argument(const char *prompt) 203217309Snwhitehorn{ 204217309Snwhitehorn int c; 205217309Snwhitehorn 206217309Snwhitehorn for (;;) { 207217309Snwhitehorn c = my_getch(); 208217309Snwhitehorn 209217309Snwhitehorn if (c <= 0) { 210217309Snwhitehorn break; 211217309Snwhitehorn } else if (c == ' ' || c == '\t') { 212217309Snwhitehorn /* skip blanks and tabs */ 213217309Snwhitehorn } else if (c == '\n') { 214217309Snwhitehorn printf("%s", prompt); 215217309Snwhitehorn } else if (c == '"' || c == '\'') { 216217309Snwhitehorn return get_string(c); 217217309Snwhitehorn } else if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 218217309Snwhitehorn (c == '-' || c == '/' || c == '.' || c == ':')) { 219217309Snwhitehorn my_ungetch(c); 220217309Snwhitehorn return get_string(' '); 221217309Snwhitehorn } else { 222224014Snwhitehorn my_ungetch(c); 223224014Snwhitehorn return NULL; 224217309Snwhitehorn } 225217309Snwhitehorn } 226217309Snwhitehorn return NULL; 227217309Snwhitehorn} 228217309Snwhitehorn 229217309Snwhitehorn 230217309Snwhitehornchar * 231217309Snwhitehornget_string(int eos) 232217309Snwhitehorn{ 233217309Snwhitehorn char buf[DPISTRLEN+1]; 234217309Snwhitehorn char *s, *limit; 235217309Snwhitehorn int c; 236217309Snwhitehorn 237217309Snwhitehorn memset(buf, 0, sizeof(buf)); 238217309Snwhitehorn limit = buf + sizeof(buf); 239217309Snwhitehorn 240217309Snwhitehorn c = my_getch(); 241217309Snwhitehorn for (s = buf;; c = my_getch()) { 242217309Snwhitehorn if (c <= 0 || c == eos || (eos == ' ' && c == '\t')) { 243217309Snwhitehorn *s = 0; 244217309Snwhitehorn break; 245217309Snwhitehorn } else if (c == '\n') { 246217309Snwhitehorn *s = 0; 247220749Snwhitehorn my_ungetch(c); 248224014Snwhitehorn break; 249217309Snwhitehorn } else { 250217309Snwhitehorn *s++ = c; 251217309Snwhitehorn if (s >= limit) 252217309Snwhitehorn return NULL; 253217309Snwhitehorn } 254217309Snwhitehorn } 255217309Snwhitehorn return strdup(buf); 256217309Snwhitehorn} 257217309Snwhitehorn 258217309Snwhitehorn 259217309Snwhitehornunsigned long 260220749Snwhitehornget_multiplier(long divisor) 261217309Snwhitehorn{ 262217309Snwhitehorn unsigned long result, extra; 263217309Snwhitehorn int c; 264220749Snwhitehorn 265220749Snwhitehorn c = my_getch(); 266217309Snwhitehorn 267217309Snwhitehorn extra = 1; 268217309Snwhitehorn if (c <= 0 || divisor <= 0) { 269217309Snwhitehorn result = 0; 270217309Snwhitehorn } else if (c == 't' || c == 'T') { 271217309Snwhitehorn result = 1024 * 1024; 272217309Snwhitehorn extra = 1024 * 1024; 273217309Snwhitehorn } else if (c == 'g' || c == 'G') { 274217309Snwhitehorn result = 1024 * 1024 * 1024; 275217309Snwhitehorn } else if (c == 'm' || c == 'M') { 276217309Snwhitehorn result = 1024 * 1024; 277217309Snwhitehorn } else if (c == 'k' || c == 'K') { 278217309Snwhitehorn result = 1024; 279217309Snwhitehorn } else { 280217309Snwhitehorn my_ungetch(c); 281217309Snwhitehorn result = 1; 282217309Snwhitehorn } 283217309Snwhitehorn if (result > 1) { 284217309Snwhitehorn if (extra > 1) { 285217309Snwhitehorn result /= divisor; 286217309Snwhitehorn if (result >= 4096) 287217309Snwhitehorn result = 0; /* overflow -> 20bits + >12bits */ 288217309Snwhitehorn else 289217309Snwhitehorn result *= extra; 290217309Snwhitehorn } else if (result >= divisor) { 291224014Snwhitehorn result /= divisor; 292217309Snwhitehorn } else { 293217309Snwhitehorn result = 1; 294217309Snwhitehorn } 295217309Snwhitehorn } 296217309Snwhitehorn return result; 297217309Snwhitehorn} 298217309Snwhitehorn 299217309Snwhitehorn 300217309Snwhitehornint 301217309Snwhitehornget_partition_modifier(void) 302217309Snwhitehorn{ 303217309Snwhitehorn int c, result; 304217309Snwhitehorn 305217309Snwhitehorn result = 0; 306217309Snwhitehorn 307217309Snwhitehorn c = my_getch(); 308217309Snwhitehorn 309217309Snwhitehorn if (c == 'p' || c == 'P') 310217309Snwhitehorn result = 1; 311217309Snwhitehorn else if (c > 0) 312217309Snwhitehorn my_ungetch(c); 313217309Snwhitehorn 314217309Snwhitehorn return result; 315217309Snwhitehorn} 316217309Snwhitehorn 317217309Snwhitehorn 318217309Snwhitehornint 319217309Snwhitehornnumber_of_digits(unsigned long value) 320217309Snwhitehorn{ 321217309Snwhitehorn int j; 322217309Snwhitehorn 323217309Snwhitehorn j = 1; 324217309Snwhitehorn while (value > 9) { 325217309Snwhitehorn j++; 326217309Snwhitehorn value = value / 10; 327217309Snwhitehorn } 328217309Snwhitehorn return j; 329217309Snwhitehorn} 330217309Snwhitehorn 331217309Snwhitehorn 332220749Snwhitehorn/* 333217309Snwhitehorn * Print a message on standard error & flush the input. 334217309Snwhitehorn */ 335217309Snwhitehornvoid 336217309Snwhitehornbad_input(const char *fmt,...) 337217309Snwhitehorn{ 338220749Snwhitehorn va_list ap; 339217309Snwhitehorn 340217309Snwhitehorn va_start(ap, fmt); 341217309Snwhitehorn vfprintf(stderr, fmt, ap); 342217309Snwhitehorn va_end(ap); 343217309Snwhitehorn fprintf(stderr, "\n"); 344217309Snwhitehorn flush_to_newline(1); 345217309Snwhitehorn} 346217309Snwhitehorn