~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to cmd.c

  • Committer: Bazaar Package Importer
  • Author(s): Riku Voipio, Josh Triplett, Riku Voipio
  • Date: 2009-07-29 13:28:05 UTC
  • mfrom: (1.4.1 upstream)
  • mto: (12.1.1 sid) (10.1.13 sid)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20090729132805-cau7rfexh7dawyb8
Tags: 0.10.50+git20090729-1
[ Josh Triplett ]
* Remove myself from Uploaders.

[ Riku Voipio ]
* new upstream RC version
* nuke all linux-user patches (applied upstream)
  06_exit_segfault
  12_signal_powerpc_support
  21_net_soopts
  30_syscall_ipc
  32_syscall_sysctl
  35_syscall_sockaddr
  48_signal_terminate
  55_unmux_socketcall
* nuke all other applied-upstream patches
  01_nostrip (better version upstream)
  07_i386_exec_name (can be reintroduced in debian/rules)
  50_linuxbios_isa_bios_ram (shouldn't be needed anymore)
  51_linuxbios_piix_ram_size (applied)
  56_dhcp (crap)
  60_ppc_ld (reintroduce if needed)
  64_ppc_asm_constraints (ditto)
  66_tls_ld.patch (ditto)
  81_compile_dtb.patch (applied upstream)
  82_qemu-img_decimal (ditto)
* move to git
* simplify build rules
* Correct my email address

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, see <http://www.gnu.org/licenses/>.
 
16
 */
 
17
 
 
18
#include <stdio.h>
 
19
#include <stdlib.h>
 
20
#include <string.h>
 
21
#include <ctype.h>
 
22
#include <errno.h>
 
23
 
 
24
#include "cmd.h"
 
25
 
 
26
#define _(x)    x       /* not gettext support yet */
 
27
 
 
28
extern int optind;
 
29
 
 
30
/* from libxcmd/command.c */
 
31
 
 
32
cmdinfo_t       *cmdtab;
 
33
int             ncmds;
 
34
 
 
35
static argsfunc_t       args_func;
 
36
static checkfunc_t      check_func;
 
37
static int              ncmdline;
 
38
static char             **cmdline;
 
39
 
 
40
static int
 
41
compare(const void *a, const void *b)
 
42
{
 
43
        return strcmp(((const cmdinfo_t *)a)->name,
 
44
                      ((const cmdinfo_t *)b)->name);
 
45
}
 
46
 
 
47
void
 
48
add_command(
 
49
        const cmdinfo_t *ci)
 
50
{
 
51
        cmdtab = realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
 
52
        cmdtab[ncmds - 1] = *ci;
 
53
        qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
 
54
}
 
55
 
 
56
static int
 
57
check_command(
 
58
        const cmdinfo_t *ci)
 
59
{
 
60
        if (check_func)
 
61
                return check_func(ci);
 
62
        return 1;
 
63
}
 
64
 
 
65
void
 
66
add_check_command(
 
67
        checkfunc_t     cf)
 
68
{
 
69
        check_func = cf;
 
70
}
 
71
 
 
72
int
 
73
command_usage(
 
74
        const cmdinfo_t *ci)
 
75
{
 
76
        printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
 
77
        return 0;
 
78
}
 
79
 
 
80
int
 
81
command(
 
82
        const cmdinfo_t *ct,
 
83
        int             argc,
 
84
        char            **argv)
 
85
{
 
86
        char            *cmd = argv[0];
 
87
 
 
88
        if (!check_command(ct))
 
89
                return 0;
 
90
 
 
91
        if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) {
 
92
                if (ct->argmax == -1)
 
93
                        fprintf(stderr,
 
94
        _("bad argument count %d to %s, expected at least %d arguments\n"),
 
95
                                argc-1, cmd, ct->argmin);
 
96
                else if (ct->argmin == ct->argmax)
 
97
                        fprintf(stderr,
 
98
        _("bad argument count %d to %s, expected %d arguments\n"),
 
99
                                argc-1, cmd, ct->argmin);
 
100
                else
 
101
                        fprintf(stderr,
 
102
        _("bad argument count %d to %s, expected between %d and %d arguments\n"),
 
103
                        argc-1, cmd, ct->argmin, ct->argmax);
 
104
                return 0;
 
105
        }
 
106
        optind = 0;
 
107
        return ct->cfunc(argc, argv);
 
108
}
 
109
 
 
110
const cmdinfo_t *
 
111
find_command(
 
112
        const char      *cmd)
 
113
{
 
114
        cmdinfo_t       *ct;
 
115
 
 
116
        for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
 
117
                if (strcmp(ct->name, cmd) == 0 ||
 
118
                    (ct->altname && strcmp(ct->altname, cmd) == 0))
 
119
                        return (const cmdinfo_t *)ct;
 
120
        }
 
121
        return NULL;
 
122
}
 
123
 
 
124
void
 
125
add_user_command(char *optarg)
 
126
{
 
127
        ncmdline++;
 
128
        cmdline = realloc(cmdline, sizeof(char*) * (ncmdline));
 
129
        if (!cmdline) {
 
130
                perror("realloc");
 
131
                exit(1);
 
132
        }
 
133
        cmdline[ncmdline-1] = optarg;
 
134
}
 
135
 
 
136
static int
 
137
args_command(
 
138
        int     index)
 
139
{
 
140
        if (args_func)
 
141
                return args_func(index);
 
142
        return 0;
 
143
}
 
144
 
 
145
void
 
146
add_args_command(
 
147
        argsfunc_t      af)
 
148
{
 
149
        args_func = af;
 
150
}
 
151
 
 
152
void
 
153
command_loop(void)
 
154
{
 
155
        int             c, i, j = 0, done = 0;
 
156
        char            *input;
 
157
        char            **v;
 
158
        const cmdinfo_t *ct;
 
159
 
 
160
        for (i = 0; !done && i < ncmdline; i++) {
 
161
                input = strdup(cmdline[i]);
 
162
                if (!input) {
 
163
                        fprintf(stderr,
 
164
                                _("cannot strdup command '%s': %s\n"),
 
165
                                cmdline[i], strerror(errno));
 
166
                        exit(1);
 
167
                }
 
168
                v = breakline(input, &c);
 
169
                if (c) {
 
170
                        ct = find_command(v[0]);
 
171
                        if (ct) {
 
172
                                if (ct->flags & CMD_FLAG_GLOBAL)
 
173
                                        done = command(ct, c, v);
 
174
                                else {
 
175
                                        j = 0;
 
176
                                        while (!done && (j = args_command(j)))
 
177
                                                done = command(ct, c, v);
 
178
                                }
 
179
                        } else
 
180
                                fprintf(stderr, _("command \"%s\" not found\n"),
 
181
                                        v[0]);
 
182
                }
 
183
                doneline(input, v);
 
184
        }
 
185
        if (cmdline) {
 
186
                free(cmdline);
 
187
                return;
 
188
        }
 
189
        while (!done) {
 
190
                if ((input = fetchline()) == NULL)
 
191
                        break;
 
192
                v = breakline(input, &c);
 
193
                if (c) {
 
194
                        ct = find_command(v[0]);
 
195
                        if (ct)
 
196
                                done = command(ct, c, v);
 
197
                        else
 
198
                                fprintf(stderr, _("command \"%s\" not found\n"),
 
199
                                        v[0]);
 
200
                }
 
201
                doneline(input, v);
 
202
        }
 
203
}
 
204
 
 
205
/* from libxcmd/input.c */
 
206
 
 
207
#if defined(ENABLE_READLINE)
 
208
# include <readline/history.h>
 
209
# include <readline/readline.h>
 
210
#elif defined(ENABLE_EDITLINE)
 
211
# include <histedit.h>
 
212
#endif
 
213
 
 
214
static char *
 
215
get_prompt(void)
 
216
{
 
217
        static char     prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
 
218
 
 
219
        if (!prompt[0])
 
220
                snprintf(prompt, sizeof(prompt), "%s> ", progname);
 
221
        return prompt;
 
222
}
 
223
 
 
224
#if defined(ENABLE_READLINE)
 
225
char *
 
226
fetchline(void)
 
227
{
 
228
        char    *line;
 
229
 
 
230
        line = readline(get_prompt());
 
231
        if (line && *line)
 
232
                add_history(line);
 
233
        return line;
 
234
}
 
235
#elif defined(ENABLE_EDITLINE)
 
236
static char *el_get_prompt(EditLine *e) { return get_prompt(); }
 
237
char *
 
238
fetchline(void)
 
239
{
 
240
        static EditLine *el;
 
241
        static History  *hist;
 
242
        HistEvent       hevent;
 
243
        char            *line;
 
244
        int             count;
 
245
 
 
246
        if (!el) {
 
247
                hist = history_init();
 
248
                history(hist, &hevent, H_SETSIZE, 100);
 
249
                el = el_init(progname, stdin, stdout, stderr);
 
250
                el_source(el, NULL);
 
251
                el_set(el, EL_SIGNAL, 1);
 
252
                el_set(el, EL_PROMPT, el_get_prompt);
 
253
                el_set(el, EL_HIST, history, (const char *)hist);
 
254
        }
 
255
        line = strdup(el_gets(el, &count));
 
256
        if (line) {
 
257
                if (count > 0)
 
258
                        line[count-1] = '\0';
 
259
                if (*line)
 
260
                        history(hist, &hevent, H_ENTER, line);
 
261
        }
 
262
        return line;
 
263
}
 
264
#else
 
265
# define MAXREADLINESZ  1024
 
266
char *
 
267
fetchline(void)
 
268
{
 
269
        char    *p, *line = malloc(MAXREADLINESZ);
 
270
 
 
271
        if (!line)
 
272
                return NULL;
 
273
        printf("%s", get_prompt());
 
274
        fflush(stdout);
 
275
        if (!fgets(line, MAXREADLINESZ, stdin)) {
 
276
                free(line);
 
277
                return NULL;
 
278
        }
 
279
        p = line + strlen(line);
 
280
        if (p != line && p[-1] == '\n')
 
281
                p[-1] = '\0';
 
282
        return line;
 
283
}
 
284
#endif
 
285
 
 
286
char **
 
287
breakline(
 
288
        char    *input,
 
289
        int     *count)
 
290
{
 
291
        int     c = 0;
 
292
        char    *p;
 
293
        char    **rval = calloc(sizeof(char *), 1);
 
294
 
 
295
        while (rval && (p = strsep(&input, " ")) != NULL) {
 
296
                if (!*p)
 
297
                        continue;
 
298
                c++;
 
299
                rval = realloc(rval, sizeof(*rval) * (c + 1));
 
300
                if (!rval) {
 
301
                        c = 0;
 
302
                        break;
 
303
                }
 
304
                rval[c - 1] = p;
 
305
                rval[c] = NULL;
 
306
        }
 
307
        *count = c;
 
308
        return rval;
 
309
}
 
310
 
 
311
void
 
312
doneline(
 
313
        char    *input,
 
314
        char    **vec)
 
315
{
 
316
        free(input);
 
317
        free(vec);
 
318
}
 
319
 
 
320
#define EXABYTES(x)     ((long long)(x) << 60)
 
321
#define PETABYTES(x)    ((long long)(x) << 50)
 
322
#define TERABYTES(x)    ((long long)(x) << 40)
 
323
#define GIGABYTES(x)    ((long long)(x) << 30)
 
324
#define MEGABYTES(x)    ((long long)(x) << 20)
 
325
#define KILOBYTES(x)    ((long long)(x) << 10)
 
326
 
 
327
long long
 
328
cvtnum(
 
329
        char            *s)
 
330
{
 
331
        long long       i;
 
332
        char            *sp;
 
333
        int             c;
 
334
 
 
335
        i = strtoll(s, &sp, 0);
 
336
        if (i == 0 && sp == s)
 
337
                return -1LL;
 
338
        if (*sp == '\0')
 
339
                return i;
 
340
 
 
341
        if (sp[1] != '\0')
 
342
                return -1LL;
 
343
 
 
344
        c = tolower(*sp);
 
345
        switch (c) {
 
346
        default:
 
347
                return i;
 
348
        case 'k':
 
349
                return KILOBYTES(i);
 
350
        case 'm':
 
351
                return MEGABYTES(i);
 
352
        case 'g':
 
353
                return GIGABYTES(i);
 
354
        case 't':
 
355
                return TERABYTES(i);
 
356
        case 'p':
 
357
                return PETABYTES(i);
 
358
        case 'e':
 
359
                return  EXABYTES(i);
 
360
        }
 
361
        return -1LL;
 
362
}
 
363
 
 
364
#define TO_EXABYTES(x)  ((x) / EXABYTES(1))
 
365
#define TO_PETABYTES(x) ((x) / PETABYTES(1))
 
366
#define TO_TERABYTES(x) ((x) / TERABYTES(1))
 
367
#define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
 
368
#define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
 
369
#define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
 
370
 
 
371
void
 
372
cvtstr(
 
373
        double          value,
 
374
        char            *str,
 
375
        size_t          size)
 
376
{
 
377
        const char      *fmt;
 
378
        int             precise;
 
379
 
 
380
        precise = ((double)value * 1000 == (double)(int)value * 1000);
 
381
 
 
382
        if (value >= EXABYTES(1)) {
 
383
                fmt = precise ? "%.f EiB" : "%.3f EiB";
 
384
                snprintf(str, size, fmt, TO_EXABYTES(value));
 
385
        } else if (value >= PETABYTES(1)) {
 
386
                fmt = precise ? "%.f PiB" : "%.3f PiB";
 
387
                snprintf(str, size, fmt, TO_PETABYTES(value));
 
388
        } else if (value >= TERABYTES(1)) {
 
389
                fmt = precise ? "%.f TiB" : "%.3f TiB";
 
390
                snprintf(str, size, fmt, TO_TERABYTES(value));
 
391
        } else if (value >= GIGABYTES(1)) {
 
392
                fmt = precise ? "%.f GiB" : "%.3f GiB";
 
393
                snprintf(str, size, fmt, TO_GIGABYTES(value));
 
394
        } else if (value >= MEGABYTES(1)) {
 
395
                fmt = precise ? "%.f MiB" : "%.3f MiB";
 
396
                snprintf(str, size, fmt, TO_MEGABYTES(value));
 
397
        } else if (value >= KILOBYTES(1)) {
 
398
                fmt = precise ? "%.f KiB" : "%.3f KiB";
 
399
                snprintf(str, size, fmt, TO_KILOBYTES(value));
 
400
        } else {
 
401
                snprintf(str, size, "%f bytes", value);
 
402
        }
 
403
}
 
404
 
 
405
struct timeval
 
406
tsub(struct timeval t1, struct timeval t2)
 
407
{
 
408
        t1.tv_usec -= t2.tv_usec;
 
409
        if (t1.tv_usec < 0) {
 
410
                t1.tv_usec += 1000000;
 
411
                t1.tv_sec--;
 
412
        }
 
413
        t1.tv_sec -= t2.tv_sec;
 
414
        return t1;
 
415
}
 
416
 
 
417
double
 
418
tdiv(double value, struct timeval tv)
 
419
{
 
420
        return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
 
421
}
 
422
 
 
423
#define HOURS(sec)      ((sec) / (60 * 60))
 
424
#define MINUTES(sec)    (((sec) % (60 * 60)) / 60)
 
425
#define SECONDS(sec)    ((sec) % 60)
 
426
 
 
427
void
 
428
timestr(
 
429
        struct timeval  *tv,
 
430
        char            *ts,
 
431
        size_t          size,
 
432
        int             format)
 
433
{
 
434
        double          usec = (double)tv->tv_usec / 1000000.0;
 
435
 
 
436
        if (format & TERSE_FIXED_TIME) {
 
437
                if (!HOURS(tv->tv_sec)) {
 
438
                        snprintf(ts, size, "%u:%02u.%02u",
 
439
                                (unsigned int) MINUTES(tv->tv_sec),
 
440
                                (unsigned int) SECONDS(tv->tv_sec),
 
441
                                (unsigned int) usec * 100);
 
442
                        return;
 
443
                }
 
444
                format |= VERBOSE_FIXED_TIME;   /* fallback if hours needed */
 
445
        }
 
446
 
 
447
        if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
 
448
                snprintf(ts, size, "%u:%02u:%02u.%02u",
 
449
                        (unsigned int) HOURS(tv->tv_sec),
 
450
                        (unsigned int) MINUTES(tv->tv_sec),
 
451
                        (unsigned int) SECONDS(tv->tv_sec),
 
452
                        (unsigned int) usec * 100);
 
453
        } else {
 
454
                snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000);
 
455
        }
 
456
}
 
457
 
 
458
 
 
459
/* from libxcmd/quit.c */
 
460
 
 
461
static cmdinfo_t quit_cmd;
 
462
 
 
463
/* ARGSUSED */
 
464
static int
 
465
quit_f(
 
466
        int     argc,
 
467
        char    **argv)
 
468
{
 
469
        return 1;
 
470
}
 
471
 
 
472
void
 
473
quit_init(void)
 
474
{
 
475
        quit_cmd.name = _("quit");
 
476
        quit_cmd.altname = _("q");
 
477
        quit_cmd.cfunc = quit_f;
 
478
        quit_cmd.argmin = -1;
 
479
        quit_cmd.argmax = -1;
 
480
        quit_cmd.flags = CMD_FLAG_GLOBAL;
 
481
        quit_cmd.oneline = _("exit the program");
 
482
 
 
483
        add_command(&quit_cmd);
 
484
}
 
485
 
 
486
/* from libxcmd/help.c */
 
487
 
 
488
static cmdinfo_t help_cmd;
 
489
static void help_onecmd(const char *cmd, const cmdinfo_t *ct);
 
490
static void help_oneline(const char *cmd, const cmdinfo_t *ct);
 
491
 
 
492
static void
 
493
help_all(void)
 
494
{
 
495
        const cmdinfo_t *ct;
 
496
 
 
497
        for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++)
 
498
                help_oneline(ct->name, ct);
 
499
        printf(_("\nUse 'help commandname' for extended help.\n"));
 
500
}
 
501
 
 
502
static int
 
503
help_f(
 
504
        int             argc,
 
505
        char            **argv)
 
506
{
 
507
        const cmdinfo_t *ct;
 
508
 
 
509
        if (argc == 1) {
 
510
                help_all();
 
511
                return 0;
 
512
        }
 
513
        ct = find_command(argv[1]);
 
514
        if (ct == NULL) {
 
515
                printf(_("command %s not found\n"), argv[1]);
 
516
                return 0;
 
517
        }
 
518
        help_onecmd(argv[1], ct);
 
519
        return 0;
 
520
}
 
521
 
 
522
static void
 
523
help_onecmd(
 
524
        const char      *cmd,
 
525
        const cmdinfo_t *ct)
 
526
{
 
527
        help_oneline(cmd, ct);
 
528
        if (ct->help)
 
529
                ct->help();
 
530
}
 
531
 
 
532
static void
 
533
help_oneline(
 
534
        const char      *cmd,
 
535
        const cmdinfo_t *ct)
 
536
{
 
537
        if (cmd)
 
538
                printf("%s ", cmd);
 
539
        else {
 
540
                printf("%s ", ct->name);
 
541
                if (ct->altname)
 
542
                        printf("(or %s) ", ct->altname);
 
543
        }
 
544
        if (ct->args)
 
545
                printf("%s ", ct->args);
 
546
        printf("-- %s\n", ct->oneline);
 
547
}
 
548
 
 
549
void
 
550
help_init(void)
 
551
{
 
552
        help_cmd.name = _("help");
 
553
        help_cmd.altname = _("?");
 
554
        help_cmd.cfunc = help_f;
 
555
        help_cmd.argmin = 0;
 
556
        help_cmd.argmax = 1;
 
557
        help_cmd.flags = CMD_FLAG_GLOBAL;
 
558
        help_cmd.args = _("[command]");
 
559
        help_cmd.oneline = _("help for one or all commands");
 
560
 
 
561
        add_command(&help_cmd);
 
562
}