File: | src/sbin/fdisk/misc.c |
Warning: | line 193, column 41 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 | } |