diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2001-03-24 00:14:39 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2001-03-24 00:14:39 +0000 |
commit | ffb72f990c9933280de104024acf91acee02c1a5 (patch) | |
tree | 8312fd465c763b17886e6e1795ab48bde45c2381 /sbin/pdisk/io.c | |
parent | fa5275b22eb94a7d990e643d54768420845d618c (diff) |
Import of pdisk from apple, BSD licensed code. Archive dated Feb 18 1998
This is a HFS partition editing tool.
Diffstat (limited to 'sbin/pdisk/io.c')
-rw-r--r-- | sbin/pdisk/io.c | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/sbin/pdisk/io.c b/sbin/pdisk/io.c new file mode 100644 index 00000000000..64d2ed495cb --- /dev/null +++ b/sbin/pdisk/io.c @@ -0,0 +1,463 @@ +// +// io.c - simple io and input parsing routines +// +// Written by Eryk Vershen (eryk@apple.com) +// + +/* + * Copyright 1996,1997,1998 by Apple Computer, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +// for *printf() +#include <stdio.h> + +// for malloc() & free() +#if !defined(__linux__) && !defined(__unix__) +#include <stdlib.h> +#else +#include <malloc.h> +#endif +// for strncpy() +#include <string.h> +// for va_start(), etc. +#include <stdarg.h> +// for errno +#include <errno.h> + +#include "io.h" +#include "errors.h" + + +// +// Defines +// +#define BAD_DIGIT 17 /* must be greater than any base */ +#define STRING_CHUNK 16 +#define UNGET_MAX_COUNT 10 +#ifndef __linux__ +#ifndef __unix__ +#define SCSI_FD 8 +#endif +#ifdef NeXT +#define loff_t off_t +#define llseek lseek +#else +#define loff_t long +#define llseek lseek +#endif +#endif + + +// +// Types +// + + +// +// Global Constants +// +const long kDefault = -1; + + +// +// Global Variables +// +short unget_buf[UNGET_MAX_COUNT+1]; +int unget_count; +char io_buffer[MAXIOSIZE]; + + +// +// Forward declarations +// +long get_number(int first_char); +char* get_string(int eos); +int my_getch(); +void my_ungetch(int c); + + +// +// Routines +// +int +my_getch() +{ + if (unget_count > 0) { + return (unget_buf[--unget_count]); + } else { + return (getc(stdin)); + } +} + + +void +my_ungetch(int c) +{ + // In practice there is never more than one character in + // the unget_buf, but what's a little overkill among friends? + + if (unget_count < UNGET_MAX_COUNT) { + unget_buf[unget_count++] = c; + } else { + fatal(-1, "Programmer error in my_ungetch()."); + } +} + + +void +flush_to_newline(int keep_newline) +{ + int c; + + for (;;) { + c = my_getch(); + + if (c <= 0) { + break; + } else if (c == '\n') { + if (keep_newline) { + my_ungetch(c); + } + break; + } else { + // skip + } + } + return; +} + + +int +get_okay(char *prompt, int default_value) +{ + int c; + + flush_to_newline(0); + printf(prompt); + + for (;;) { + c = my_getch(); + + if (c <= 0) { + break; + } else if (c == ' ' || c == '\t') { + // skip blanks and tabs + } else if (c == '\n') { + my_ungetch(c); + return default_value; + } else if (c == 'y' || c == 'Y') { + return 1; + } else if (c == 'n' || c == 'N') { + return 0; + } else { + flush_to_newline(0); + printf(prompt); + } + } + return -1; +} + + +int +get_command(char *prompt, int promptBeforeGet, int *command) +{ + int c; + + if (promptBeforeGet) { + printf(prompt); + } + for (;;) { + c = my_getch(); + + if (c <= 0) { + break; + } else if (c == ' ' || c == '\t') { + // skip blanks and tabs + } else if (c == '\n') { + printf(prompt); + } else { + *command = c; + return 1; + } + } + return 0; +} + + +int +get_number_argument(char *prompt, long *number, long default_value) +{ + int c; + int result = 0; + + for (;;) { + c = my_getch(); + + if (c <= 0) { + break; + } else if (c == ' ' || c == '\t') { + // skip blanks and tabs + } else if (c == '\n') { + if (default_value == kDefault) { + printf(prompt); + } else { + my_ungetch(c); + *number = default_value; + result = 1; + break; + } + } else if ('0' <= c && c <= '9') { + *number = get_number(c); + result = 1; + break; + } else { + my_ungetch(c); + *number = 0; + break; + } + } + return result; +} + + +long +get_number(int first_char) +{ + register int c; + int base; + int digit; + int ret_value; + + if (first_char != '0') { + c = first_char; + base = 10; + digit = BAD_DIGIT; + } else if ((c=my_getch()) == 'x' || c == 'X') { + c = my_getch(); + base = 16; + digit = BAD_DIGIT; + } else { + my_ungetch(c); + c = first_char; + base = 8; + digit = 0; + } + ret_value = 0; + for (ret_value = 0; ; c = my_getch()) { + if (c >= '0' && c <= '9') { + digit = c - '0'; + } else if (c >='A' && c <= 'F') { + digit = 10 + (c - 'A'); + } else if (c >='a' && c <= 'f') { + digit = 10 + (c - 'a'); + } else { + digit = BAD_DIGIT; + } + if (digit >= base) { + break; + } + ret_value = ret_value * base + digit; + } + my_ungetch(c); + return(ret_value); +} + + +int +get_string_argument(char *prompt, char **string, int reprompt) +{ + int c; + int result = 0; + + for (;;) { + c = my_getch(); + + if (c <= 0) { + break; + } else if (c == ' ' || c == '\t') { + // skip blanks and tabs + } else if (c == '\n') { + if (reprompt) { + printf(prompt); + } else { + my_ungetch(c); + *string = NULL; + break; + } + } else if (c == '"' || c == '\'') { + *string = get_string(c); + result = 1; + break; + } else if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') + || (c == '-' || c == '/' || c == '.' || c == ':')) { + my_ungetch(c); + *string = get_string(' '); + result = 1; + break; + } else { + my_ungetch(c); + *string = NULL; + break; + } + } + return result; +} + + +char * +get_string(int eos) +{ + int c; + char *s; + char *ret_value; + char *limit; + int length; + + ret_value = (char *) malloc(STRING_CHUNK); + if (ret_value == NULL) { + error(errno, "can't allocate memory for string buffer"); + return NULL; + } + length = STRING_CHUNK; + limit = ret_value + length; + + c = my_getch(); + for (s = ret_value; ; c = my_getch()) { + if (s >= limit) { + // expand string + limit = (char *) malloc(length+STRING_CHUNK); + if (limit == NULL) { + error(errno, "can't allocate memory for string buffer"); + ret_value[length-1] = 0; + break; + } + strncpy(limit, ret_value, length); + free(ret_value); + s = limit + (s - ret_value); + ret_value = limit; + length += STRING_CHUNK; + limit = ret_value + length; + } + if (c <= 0 || c == eos || (eos == ' ' && c == '\t')) { + *s++ = 0; + break; + } else if (c == '\n') { + *s++ = 0; + my_ungetch(c); + break; + } else { + *s++ = c; + } + } + return(ret_value); +} + + +unsigned long +get_multiplier(long divisor) +{ + int c; + unsigned long result; + unsigned long extra; + + c = my_getch(); + + extra = 1; + if (c <= 0 || divisor <= 0) { + result = 0; + } else if (c == 't' || c == 'T') { + result = 1024*1024; + extra = 1024*1024; + } else if (c == 'g' || c == 'G') { + result = 1024*1024*1024; + } else if (c == 'm' || c == 'M') { + result = 1024*1024; + } else if (c == 'k' || c == 'K') { + result = 1024; + } else { + my_ungetch(c); + result = 1; + } + if (result > 1) { + if (extra > 1) { + result /= divisor; + if (result >= 4096) { + /* overflow -> 20bits + >12bits */ + result = 0; + } else { + result *= extra; + } + } else if (result >= divisor) { + result /= divisor; + } else { + result = 1; + } + } + return result; +} + + +int +get_partition_modifier(void) +{ + int c; + int result; + + result = 0; + + c = my_getch(); + + if (c == 'p' || c == 'P') { + result = 1; + } else if (c > 0) { + my_ungetch(c); + } + return result; +} + + +int +number_of_digits(unsigned long value) +{ + int j; + + j = 1; + while (value > 9) { + j++; + value = value / 10; + } + return j; +} + + +// +// Print a message on standard error & flush the input. +// +void +bad_input(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + flush_to_newline(1); +} |