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