X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=fish%2Ffish.c;h=cbbbf970469335c8bdcd56e58b4ff69d80f18f24;hp=13f1e99041e420b7845ea3bdb34554d7e8b272c7;hb=7fd6e4bfb11d1f86c585de06fb2146aa5cbd400e;hpb=01fedcde05c930c1413e9fe0909fa1da1f360cdf diff --git a/fish/fish.c b/fish/fish.c index 13f1e99..cbbbf97 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2010 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -65,7 +65,10 @@ static void script (int prompt); static void cmdline (char *argv[], int optind, int argc); static void initialize_readline (void); static void cleanup_readline (void); +#ifdef HAVE_LIBREADLINE static void add_history_line (const char *); +#endif +static void print_shell_quote (FILE *stream, const char *str); /* Currently open libguestfs handle. */ guestfs_h *g; @@ -362,9 +365,6 @@ main (int argc, char *argv[]) /* Inspector mode invalidates most of the other arguments. */ if (inspector) { - char cmd[1024]; - int r; - if (drvs || mps || remote_control_listen || remote_control || guestfs_get_selinux (g)) { fprintf (stderr, _("%s: cannot use -i option with -a, -m, -N, " @@ -379,42 +379,89 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } - strcpy (cmd, "a=`virt-inspector"); + char *cmd; + size_t cmdlen; + FILE *fp = open_memstream (&cmd, &cmdlen); + if (fp == NULL) { + perror ("open_memstream"); + exit (EXIT_FAILURE); + } + + fprintf (fp, "virt-inspector"); while (optind < argc) { - if (strlen (cmd) + strlen (argv[optind]) + strlen (real_argv0) + 60 - >= sizeof cmd) { - fprintf (stderr, - _("%s: virt-inspector command too long for fixed-size buffer\n"), - program_name); - exit (EXIT_FAILURE); - } - strcat (cmd, " '"); - strcat (cmd, argv[optind]); - strcat (cmd, "'"); + fputc (' ', fp); + print_shell_quote (fp, argv[optind]); optind++; } if (read_only) - strcat (cmd, " --ro-fish"); + fprintf (fp, " --ro-fish"); else - strcat (cmd, " --fish"); + fprintf (fp, " --fish"); - sprintf (&cmd[strlen(cmd)], "` && %s $a", real_argv0); + if (fclose (fp) == -1) { + perror ("fclose"); + exit (EXIT_FAILURE); + } + + if (verbose) + fprintf (stderr, + "%s -i: running: %s\n", program_name, cmd); + + FILE *pp = popen (cmd, "r"); + if (pp == NULL) { + perror (cmd); + exit (EXIT_FAILURE); + } + + char *cmd2; + fp = open_memstream (&cmd2, &cmdlen); + if (fp == NULL) { + perror ("open_memstream"); + exit (EXIT_FAILURE); + } + + fprintf (fp, "%s", real_argv0); if (guestfs_get_verbose (g)) - strcat (cmd, " -v"); + fprintf (fp, " -v"); if (!guestfs_get_autosync (g)) - strcat (cmd, " -n"); + fprintf (fp, " -n"); + if (guestfs_get_trace (g)) + fprintf (fp, " -x"); + + char *insp = NULL; + size_t insplen; + if (getline (&insp, &insplen, pp) == -1) { + perror (cmd); + exit (EXIT_FAILURE); + } + fprintf (fp, " %s", insp); + + if (pclose (pp) == -1) { + perror (cmd); + exit (EXIT_FAILURE); + } + + if (fclose (fp) == -1) { + perror ("fclose"); + exit (EXIT_FAILURE); + } if (verbose) fprintf (stderr, - "%s -i: running virt-inspector command:\n%s\n", program_name, cmd); + "%s -i: running: %s\n", program_name, cmd2); - r = system (cmd); + int r = system (cmd2); if (r == -1) { - perror ("system"); + perror (cmd2); exit (EXIT_FAILURE); } + + free (cmd); + free (cmd2); + free (insp); + exit (WEXITSTATUS (r)); } @@ -547,8 +594,6 @@ static int launch (void) { if (guestfs_is_config (g)) { - if (isatty (0)) - printf (_("guestfish: wait a moment while we launch libguestfs ...\n")); if (guestfs_launch (g) == -1) return -1; } @@ -947,6 +992,8 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) r = do_reopen (cmd, argc, argv); else if (STRCASEEQ (cmd, "sparse")) r = do_sparse (cmd, argc, argv); + else if (STRCASEEQ (cmd, "supported")) + r = do_supported (cmd, argc, argv); else if (STRCASEEQ (cmd, "time")) r = do_time (cmd, argc, argv); else @@ -1004,6 +1051,8 @@ list_builtin_commands (void) printf ("%-20s %s\n", "sparse", _("allocate a sparse image file")); printf ("%-20s %s\n", + "supported", _("list supported groups of commands")); + printf ("%-20s %s\n", "time", _("measure time taken to run command")); /* actions are printed after this (see list_commands) */ @@ -1024,16 +1073,8 @@ display_builtin_command (const char *cmd) "\n" " For more advanced image creation, see qemu-img utility.\n" "\n" - " Size can be specified (where means a number):\n" - " number of kilobytes\n" - " eg: 1440 standard 3.5\" floppy\n" - " K or KB number of kilobytes\n" - " M or MB number of megabytes\n" - " G or GB number of gigabytes\n" - " T or TB number of terabytes\n" - " P or PB number of petabytes\n" - " E or EB number of exabytes\n" - " sects number of 512 byte sectors\n")); + " Size can be specified using standard suffixes, eg. '1M'.\n" + )); else if (STRCASEEQ (cmd, "echo")) printf (_("echo - display a line of text\n" " echo [ ...]\n" @@ -1048,7 +1089,7 @@ display_builtin_command (const char *cmd) " This is used to edit a file.\n" "\n" " It is the equivalent of (and is implemented by)\n" - " running \"cat\", editing locally, and then \"write-file\".\n" + " running \"cat\", editing locally, and then \"write\".\n" "\n" " Normally it uses $EDITOR, but if you use the aliases\n" " \"vi\" or \"emacs\" you will get those editors.\n" @@ -1123,16 +1164,18 @@ display_builtin_command (const char *cmd) "\n" " For more advanced image creation, see qemu-img utility.\n" "\n" - " Size can be specified (where means a number):\n" - " number of kilobytes\n" - " eg: 1440 standard 3.5\" floppy\n" - " K or KB number of kilobytes\n" - " M or MB number of megabytes\n" - " G or GB number of gigabytes\n" - " T or TB number of terabytes\n" - " P or PB number of petabytes\n" - " E or EB number of exabytes\n" - " sects number of 512 byte sectors\n")); + " Size can be specified using standard suffixes, eg. '1M'.\n" + )); + else if (STRCASEEQ (cmd, "supported")) + printf (_("supported - list supported groups of commands\n" + " supported\n" + "\n" + " This command returns a list of the optional groups\n" + " known to the daemon, and indicates which ones are\n" + " supported by this build of the libguestfs appliance.\n" + "\n" + " See also guestfs(3) section AVAILABILITY.\n" + )); else if (STRCASEEQ (cmd, "time")) printf (_("time - measure time taken to run command\n" " time [ ...]\n" @@ -1400,14 +1443,14 @@ cleanup_readline (void) #endif } +#ifdef HAVE_LIBREADLINE static void add_history_line (const char *line) { -#ifdef HAVE_LIBREADLINE add_history (line); nr_history_lines++; -#endif } +#endif int xwrite (int fd, const void *v_buf, size_t len) @@ -1616,3 +1659,17 @@ file_out (const char *arg) } return ret; } + +static void +print_shell_quote (FILE *stream, const char *str) +{ +#define SAFE(c) (c_isalnum((c)) || \ + (c) == '/' || (c) == '-' || (c) == '_' || (c) == '.') + int i; + + for (i = 0; str[i]; ++i) { + if (!SAFE(str[i])) + putc ('\\', stream); + putc (str[i], stream); + } +}