]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxcmd/input.c
GCC4 signedness fixes
[thirdparty/xfsprogs-dev.git] / libxcmd / input.c
1 /*
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <xfs/libxfs.h>
34 #include <xfs/input.h>
35
36 #if defined(ENABLE_READLINE)
37 # include <readline/history.h>
38 # include <readline/readline.h>
39 #elif defined(ENABLE_EDITLINE)
40 # include <histedit.h>
41 #endif
42
43 static char *
44 get_prompt(void)
45 {
46 static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
47
48 if (!prompt[0])
49 snprintf(prompt, sizeof(prompt), "%s> ", progname);
50 return prompt;
51 }
52
53 #if defined(ENABLE_READLINE)
54 char *
55 fetchline(void)
56 {
57 char *line;
58
59 line = readline(get_prompt());
60 if (line && *line)
61 add_history(line);
62 return line;
63 }
64 #elif defined(ENABLE_EDITLINE)
65 static char *el_get_prompt(EditLine *e) { return get_prompt(); }
66 char *
67 fetchline(void)
68 {
69 static EditLine *el;
70 static History *hist;
71 HistEvent hevent;
72 char *line;
73 int count;
74
75 if (!el) {
76 hist = history_init();
77 history(hist, &hevent, H_SETSIZE, 100);
78 el = el_init(progname, stdin, stdout, stderr);
79 el_source(el, NULL);
80 el_set(el, EL_SIGNAL, 1);
81 el_set(el, EL_PROMPT, el_get_prompt);
82 el_set(el, EL_HIST, history, (const char *)hist);
83 }
84 line = strdup(el_gets(el, &count));
85 if (line) {
86 if (count > 0)
87 line[count-1] = '\0';
88 if (*line)
89 history(hist, &hevent, H_ENTER, line);
90 }
91 return line;
92 }
93 #else
94 # define MAXREADLINESZ 1024
95 char *
96 fetchline(void)
97 {
98 char *p, *line = malloc(MAXREADLINESZ);
99
100 if (!line)
101 return NULL;
102 printf(get_prompt());
103 fflush(stdout);
104 if (!fgets(line, MAXREADLINESZ, stdin)) {
105 free(line);
106 return NULL;
107 }
108 p = line + strlen(line);
109 if (p != line && p[-1] == '\n')
110 p[-1] = '\0';
111 return line;
112 }
113 #endif
114
115 char **
116 breakline(
117 char *input,
118 int *count)
119 {
120 int c = 0;
121 char *p;
122 char **rval = calloc(sizeof(char *), 1);
123
124 while (rval && (p = strsep(&input, " ")) != NULL) {
125 if (!*p)
126 continue;
127 c++;
128 rval = realloc(rval, sizeof(*rval) * (c + 1));
129 if (!rval) {
130 c = 0;
131 break;
132 }
133 rval[c - 1] = p;
134 rval[c] = NULL;
135 }
136 *count = c;
137 return rval;
138 }
139
140 void
141 doneline(
142 char *input,
143 char **vec)
144 {
145 free(input);
146 free(vec);
147 }
148
149 #define EXABYTES(x) ((long long)(x) << 60)
150 #define PETABYTES(x) ((long long)(x) << 50)
151 #define TERABYTES(x) ((long long)(x) << 40)
152 #define GIGABYTES(x) ((long long)(x) << 30)
153 #define MEGABYTES(x) ((long long)(x) << 20)
154 #define KILOBYTES(x) ((long long)(x) << 10)
155
156 long long
157 cvtnum(
158 unsigned int blocksize,
159 unsigned int sectorsize,
160 char *s)
161 {
162 long long i;
163 char *sp;
164
165 i = strtoll(s, &sp, 0);
166 if (i == 0 && sp == s)
167 return -1LL;
168 if (*sp == '\0')
169 return i;
170
171 if (*sp == 'b' && sp[1] == '\0')
172 return i * blocksize;
173 if (*sp == 's' && sp[1] == '\0')
174 return i * sectorsize;
175 if (*sp == 'k' && sp[1] == '\0')
176 return KILOBYTES(i);
177 if (*sp == 'm' && sp[1] == '\0')
178 return MEGABYTES(i);
179 if (*sp == 'g' && sp[1] == '\0')
180 return GIGABYTES(i);
181 if (*sp == 't' && sp[1] == '\0')
182 return TERABYTES(i);
183 if (*sp == 'p' && sp[1] == '\0')
184 return PETABYTES(i);
185 if (*sp == 'e' && sp[1] == '\0')
186 return EXABYTES(i);
187 return -1LL;
188 }
189
190 #define TO_EXABYTES(x) ((x) / EXABYTES(1))
191 #define TO_PETABYTES(x) ((x) / PETABYTES(1))
192 #define TO_TERABYTES(x) ((x) / TERABYTES(1))
193 #define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
194 #define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
195 #define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
196
197 void
198 cvtstr(
199 double value,
200 char *str,
201 size_t size)
202 {
203 char *fmt;
204 int precise;
205
206 precise = ((double)value * 1000 == (double)(int)value * 1000);
207
208 if (value >= EXABYTES(1)) {
209 fmt = precise ? "%.f EiB" : "%.3f EiB";
210 snprintf(str, size, fmt, TO_EXABYTES(value));
211 } else if (value >= PETABYTES(1)) {
212 fmt = precise ? "%.f PiB" : "%.3f PiB";
213 snprintf(str, size, fmt, TO_PETABYTES(value));
214 } else if (value >= TERABYTES(1)) {
215 fmt = precise ? "%.f TiB" : "%.3f TiB";
216 snprintf(str, size, fmt, TO_TERABYTES(value));
217 } else if (value >= GIGABYTES(1)) {
218 fmt = precise ? "%.f GiB" : "%.3f GiB";
219 snprintf(str, size, fmt, TO_GIGABYTES(value));
220 } else if (value >= MEGABYTES(1)) {
221 fmt = precise ? "%.f MiB" : "%.3f MiB";
222 snprintf(str, size, fmt, TO_MEGABYTES(value));
223 } else if (value >= KILOBYTES(1)) {
224 fmt = precise ? "%.f KiB" : "%.3f KiB";
225 snprintf(str, size, fmt, TO_KILOBYTES(value));
226 } else {
227 snprintf(str, size, "%f bytes", value);
228 }
229 }
230
231 #define MINUTES_TO_SECONDS(m) ((m) * 60)
232 #define HOURS_TO_SECONDS(h) ((h) * MINUTES_TO_SECONDS(60))
233 #define DAYS_TO_SECONDS(d) ((d) * HOURS_TO_SECONDS(24))
234 #define WEEKS_TO_SECONDS(w) ((w) * DAYS_TO_SECONDS(7))
235
236 unsigned long
237 cvttime(
238 char *s)
239 {
240 unsigned long i;
241 char *sp;
242
243 i = strtoul(s, &sp, 0);
244 if (i == 0 && sp == s)
245 return 0;
246 if (*sp == '\0')
247 return i;
248 if ((*sp == 'm' && sp[1] == '\0') ||
249 (strcmp(sp, "minutes") == 0) ||
250 (strcmp(sp, "minute") == 0))
251 return MINUTES_TO_SECONDS(i);
252 if ((*sp == 'h' && sp[1] == '\0') ||
253 (strcmp(sp, "hours") == 0) ||
254 (strcmp(sp, "hour") == 0))
255 return HOURS_TO_SECONDS(i);
256 if ((*sp == 'd' && sp[1] == '\0') ||
257 (strcmp(sp, "days") == 0) ||
258 (strcmp(sp, "day") == 0))
259 return DAYS_TO_SECONDS(i);
260 if ((*sp == 'w' && sp[1] == '\0') ||
261 (strcmp(sp, "weeks") == 0) ||
262 (strcmp(sp, "week") == 0))
263 return WEEKS_TO_SECONDS(i);
264 return 0;
265 }
266
267 struct timeval
268 tadd(struct timeval t1, struct timeval t2)
269 {
270 t1.tv_usec += t2.tv_usec;
271 if (t1.tv_usec > 1000000) {
272 t1.tv_usec -= 1000000;
273 t1.tv_sec++;
274 }
275 t1.tv_sec += t2.tv_sec;
276 return t1;
277 }
278
279 struct timeval
280 tsub(struct timeval t1, struct timeval t2)
281 {
282 t1.tv_usec -= t2.tv_usec;
283 if (t1.tv_usec < 0) {
284 t1.tv_usec += 1000000;
285 t1.tv_sec--;
286 }
287 t1.tv_sec -= t2.tv_sec;
288 return t1;
289 }
290
291 double
292 tdiv(double value, struct timeval tv)
293 {
294 return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
295 }
296
297 #define HOURS(sec) ((sec) / (60 * 60))
298 #define MINUTES(sec) (((sec) % (60 * 60)) / 60)
299 #define SECONDS(sec) ((sec) % 60)
300
301 void
302 timestr(
303 struct timeval *tv,
304 char *ts,
305 size_t size,
306 int format)
307 {
308 double usec = (double)tv->tv_usec / 1000000.0;
309
310 if (format & TERSE_FIXED_TIME) {
311 if (!HOURS(tv->tv_sec)) {
312 snprintf(ts, size, "%u:%02u.%02u",
313 (unsigned int) MINUTES(tv->tv_sec),
314 (unsigned int) SECONDS(tv->tv_sec),
315 (unsigned int) usec * 100);
316 return;
317 }
318 format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
319 }
320
321 if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
322 snprintf(ts, size, "%u:%02u:%02u.%02u",
323 (unsigned int) HOURS(tv->tv_sec),
324 (unsigned int) MINUTES(tv->tv_sec),
325 (unsigned int) SECONDS(tv->tv_sec),
326 (unsigned int) usec * 100);
327 } else {
328 snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000);
329 }
330 }
331
332 /*
333 * Convert from arbitrary user strings into a numeric ID.
334 * If its all numeric, we convert that inplace, else we do
335 * the name lookup, and return the found identifier.
336 */
337
338 prid_t
339 prid_from_string(
340 char *project)
341 {
342 fs_project_t *prj;
343 prid_t prid;
344 char *sp;
345
346 prid = strtoul(project, &sp, 10);
347 if (sp != project)
348 return prid;
349 prj = getprnam(project);
350 if (prj)
351 return prj->pr_prid;
352 return -1;
353 }
354
355 uid_t
356 uid_from_string(
357 char *user)
358 {
359 struct passwd *pwd;
360 uid_t uid;
361 char *sp;
362
363 uid = strtoul(user, &sp, 10);
364 if (sp != user)
365 return uid;
366 pwd = getpwnam(user);
367 if (pwd)
368 return pwd->pw_uid;
369 return -1;
370 }
371
372 gid_t
373 gid_from_string(
374 char *group)
375 {
376 struct group *grp;
377 gid_t gid;
378 char *sp;
379
380 gid = strtoul(group, &sp, 10);
381 if (sp != group)
382 return gid;
383 grp = getgrnam(group);
384 if (grp)
385 return grp->gr_gid;
386 return -1;
387 }
388
389 #define HAVE_FTW_H 1 /* TODO: configure me */
390
391 #ifndef HAVE_FTW_H
392 int
393 nftw(
394 char *dir,
395 int (*fn)(const char *, const struct stat *, int, struct FTW *),
396 int depth,
397 int flags)
398 {
399 fprintf(stderr, "%s: not implemented, no recursion available\n",
400 __FUNCTION__);
401 return 0;
402 }
403 #endif