| File: | src/sbin/fdisk/misc.c |
| Warning: | line 183, column 27 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: misc.c,v 1.88 2022/07/10 20:34:31 krw Exp $ */ | |||
| 2 | ||||
| 3 | /* | |||
| 4 | * Copyright (c) 1997 Tobias Weingartner | |||
| 5 | * | |||
| 6 | * Permission to use, copy, modify, and distribute this software for any | |||
| 7 | * purpose with or without fee is hereby granted, provided that the above | |||
| 8 | * copyright notice and this permission notice appear in all copies. | |||
| 9 | * | |||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| 17 | */ | |||
| 18 | ||||
| 19 | #include <sys/types.h> | |||
| 20 | #include <sys/disklabel.h> | |||
| 21 | ||||
| 22 | #include <ctype.h> | |||
| 23 | #include <err.h> | |||
| 24 | #include <errno(*__errno()).h> | |||
| 25 | #include <stdio.h> | |||
| 26 | #include <stdlib.h> | |||
| 27 | #include <string.h> | |||
| 28 | ||||
| 29 | #include "part.h" | |||
| 30 | #include "disk.h" | |||
| 31 | #include "misc.h" | |||
| 32 | ||||
| 33 | const struct unit_type unit_types[] = { | |||
| 34 | { "b" , 1LL , "Bytes" }, | |||
| 35 | { " " , 0LL , "Sectors" }, | |||
| 36 | { "K" , 1024LL , "Kilobytes" }, | |||
| 37 | { "M" , 1024LL * 1024 , "Megabytes" }, | |||
| 38 | { "G" , 1024LL * 1024 *1024 , "Gigabytes" }, | |||
| 39 | { "T" , 1024LL * 1024 * 1024 * 1024 , "Terabytes" }, | |||
| 40 | }; | |||
| 41 | #define SECTORS1 1 | |||
| 42 | ||||
| 43 | double | |||
| 44 | units_size(const char *units, const uint64_t sectors, | |||
| 45 | const struct unit_type **ut) | |||
| 46 | { | |||
| 47 | double size; | |||
| 48 | unsigned int i; | |||
| 49 | ||||
| 50 | *ut = &unit_types[SECTORS1]; | |||
| 51 | size = sectors; | |||
| 52 | ||||
| 53 | for (i = 0; i < nitems(unit_types)(sizeof((unit_types)) / sizeof((unit_types)[0])); i++) { | |||
| 54 | if (strncasecmp(unit_types[i].ut_abbr, units, 1) == 0) | |||
| 55 | *ut = &unit_types[i]; | |||
| 56 | } | |||
| 57 | ||||
| 58 | if ((*ut)->ut_conversion == 0) | |||
| 59 | return size; | |||
| 60 | else | |||
| 61 | return (size * dl.d_secsize) / (*ut)->ut_conversion; | |||
| 62 | } | |||
| 63 | ||||
| 64 | void | |||
| 65 | string_from_line(char *buf, const size_t buflen, const int trim) | |||
| 66 | { | |||
| 67 | static char *line; | |||
| 68 | static size_t sz; | |||
| 69 | ssize_t len; | |||
| 70 | size_t n; | |||
| 71 | unsigned int i; | |||
| 72 | ||||
| 73 | len = getline(&line, &sz, stdin(&__sF[0])); | |||
| 74 | if (len == -1) | |||
| 75 | errx(1, "eof"); | |||
| 76 | ||||
| 77 | switch (trim) { | |||
| 78 | case UNTRIMMED0: | |||
| 79 | line[strcspn(line, "\n")] = '\0'; | |||
| 80 | n = strlcpy(buf, line, buflen); | |||
| 81 | break; | |||
| 82 | case TRIMMED1: | |||
| 83 | for (i = strlen(line); i > 0; i--) { | |||
| 84 | if (isspace((unsigned char)line[i - 1]) == 0) | |||
| 85 | break; | |||
| 86 | line[i - 1] = '\0'; | |||
| 87 | } | |||
| 88 | n = strlcpy(buf, line + strspn(line, WHITESPACE" \f\n\r\t\v"), buflen); | |||
| 89 | break; | |||
| 90 | } | |||
| 91 | ||||
| 92 | if (n >= buflen) { | |||
| 93 | printf("input too long\n"); | |||
| 94 | memset(buf, 0, buflen); | |||
| 95 | } | |||
| 96 | } | |||
| 97 | ||||
| 98 | int | |||
| 99 | ask_yn(const char *str) | |||
| 100 | { | |||
| 101 | int ch, first; | |||
| 102 | extern int y_flag; | |||
| 103 | ||||
| 104 | if (y_flag) | |||
| 105 | return 1; | |||
| 106 | ||||
| 107 | printf("%s [n] ", str); | |||
| 108 | fflush(stdout(&__sF[1])); | |||
| 109 | ||||
| 110 | first = ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0]))); | |||
| 111 | while (ch != '\n' && ch != EOF(-1)) | |||
| 112 | ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0]))); | |||
| 113 | ||||
| 114 | if (ch == EOF(-1) || first == EOF(-1)) | |||
| 115 | errx(1, "eof"); | |||
| 116 | ||||
| 117 | return first == 'y' || first == 'Y'; | |||
| 118 | } | |||
| 119 | ||||
| 120 | /* | |||
| 121 | * adapted from sbin/disklabel/editor.c | |||
| 122 | */ | |||
| 123 | uint64_t | |||
| 124 | getuint64(const char *prompt, uint64_t oval, const uint64_t minval, | |||
| 125 | const uint64_t maxval) | |||
| 126 | { | |||
| 127 | char buf[BUFSIZ1024], *endptr, *p, operator = '\0'; | |||
| 128 | const int secsize = dl.d_secsize; | |||
| ||||
| 129 | size_t n; | |||
| 130 | int64_t mult = 1; | |||
| 131 | double d, d2; | |||
| 132 | int rslt, secpercyl, saveerr; | |||
| 133 | char unit; | |||
| 134 | ||||
| 135 | if (oval > maxval) | |||
| 136 | oval = maxval; | |||
| 137 | if (oval < minval) | |||
| 138 | oval = minval; | |||
| 139 | ||||
| 140 | secpercyl = disk.dk_sectors * disk.dk_heads; | |||
| 141 | ||||
| 142 | do { | |||
| 143 | printf("%s [%llu - %llu]: [%llu] ", prompt, minval, maxval, | |||
| 144 | oval); | |||
| 145 | string_from_line(buf, sizeof(buf), TRIMMED1); | |||
| 146 | ||||
| 147 | if (buf[0] == '\0') { | |||
| 148 | rslt = snprintf(buf, sizeof(buf), "%llu", oval); | |||
| 149 | if (rslt < 0 || rslt >= sizeof(buf)) | |||
| 150 | errx(1, "default value too long"); | |||
| 151 | } else if (buf[0] == '*' && buf[1] == '\0') { | |||
| 152 | return maxval; | |||
| 153 | } | |||
| 154 | ||||
| 155 | /* deal with units */ | |||
| 156 | n = strlen(buf); | |||
| 157 | switch (tolower((unsigned char)buf[n-1])) { | |||
| 158 | case 'c': | |||
| 159 | unit = 'c'; | |||
| 160 | mult = secpercyl; | |||
| 161 | buf[--n] = '\0'; | |||
| 162 | break; | |||
| 163 | case 'b': | |||
| 164 | unit = 'b'; | |||
| 165 | mult = -(int64_t)secsize; | |||
| 166 | buf[--n] = '\0'; | |||
| 167 | break; | |||
| 168 | case 's': | |||
| 169 | unit = 's'; | |||
| 170 | mult = 1; | |||
| 171 | buf[--n] = '\0'; | |||
| 172 | break; | |||
| 173 | case 'k': | |||
| 174 | unit = 'k'; | |||
| 175 | if (secsize > 1024) | |||
| 176 | mult = -(int64_t)secsize / 1024LL; | |||
| 177 | else | |||
| 178 | mult = 1024LL / secsize; | |||
| 179 | buf[--n] = '\0'; | |||
| 180 | break; | |||
| 181 | case 'm': | |||
| 182 | unit = 'm'; | |||
| 183 | mult = (1024LL * 1024) / secsize; | |||
| ||||
| 184 | buf[--n] = '\0'; | |||
| 185 | break; | |||
| 186 | case 'g': | |||
| 187 | unit = 'g'; | |||
| 188 | mult = (1024LL * 1024 * 1024) / secsize; | |||
| 189 | buf[--n] = '\0'; | |||
| 190 | break; | |||
| 191 | case 't': | |||
| 192 | unit = 't'; | |||
| 193 | mult = (1024LL * 1024 * 1024 * 1024) / secsize; | |||
| 194 | buf[--n] = '\0'; | |||
| 195 | break; | |||
| 196 | default: | |||
| 197 | unit = ' '; | |||
| 198 | mult = 1; | |||
| 199 | break; | |||
| 200 | } | |||
| 201 | ||||
| 202 | /* deal with the operator */ | |||
| 203 | p = &buf[0]; | |||
| 204 | if (*p == '+' || *p == '-') | |||
| 205 | operator = *p++; | |||
| 206 | else | |||
| 207 | operator = ' '; | |||
| 208 | ||||
| 209 | endptr = p; | |||
| 210 | errno(*__errno()) = 0; | |||
| 211 | d = strtod(p, &endptr); | |||
| 212 | saveerr = errno(*__errno()); | |||
| 213 | d2 = d; | |||
| 214 | if (mult > 0) | |||
| 215 | d *= mult; | |||
| 216 | else { | |||
| 217 | d /= (-mult); | |||
| 218 | d2 = d; | |||
| 219 | } | |||
| 220 | ||||
| 221 | /* Apply the operator */ | |||
| 222 | if (operator == '+') | |||
| 223 | d = oval + d; | |||
| 224 | else if (operator == '-') { | |||
| 225 | d = oval - d; | |||
| 226 | d2 = d; | |||
| 227 | } | |||
| 228 | ||||
| 229 | if (saveerr == ERANGE34 || d > maxval || d < minval || d < d2) { | |||
| 230 | printf("%s is out of range: %c%s%c\n", prompt, operator, | |||
| 231 | p, unit); | |||
| 232 | } else if (*endptr != '\0') { | |||
| 233 | printf("%s is invalid: %c%s%c\n", prompt, operator, | |||
| 234 | p, unit); | |||
| 235 | } else { | |||
| 236 | break; | |||
| 237 | } | |||
| 238 | } while (1); | |||
| 239 | ||||
| 240 | return (uint64_t)d; | |||
| 241 | } | |||
| 242 | ||||
| 243 | int | |||
| 244 | hex_octet(char *buf) | |||
| 245 | { | |||
| 246 | char *cp; | |||
| 247 | long num; | |||
| 248 | ||||
| 249 | cp = buf; | |||
| 250 | num = strtol(buf, &cp, 16); | |||
| 251 | ||||
| 252 | if (cp == buf || *cp != '\0') | |||
| 253 | return -1; | |||
| 254 | ||||
| 255 | if (num < 0 || num > 0xff) | |||
| 256 | return -1; | |||
| 257 | ||||
| 258 | return num; | |||
| 259 | } |