X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=fish%2Ffish.c;h=cf547c4e02d34ec693835eaa83cece6820148b84;hb=3578f170a1f70a86fb2213fc576190ad5aff61be;hp=c535e062fa582ddb3e0b4ffb48ff1278674bbd29;hpb=4932fdca3ca1e9002164a1c0b73876f32739d34d;p=libguestfs.git diff --git a/fish/fish.c b/fish/fish.c index c535e06..cf547c4 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #ifdef HAVE_LIBREADLINE @@ -69,6 +70,7 @@ struct mp { char *mountpoint; }; +static void set_up_terminal (void); static char add_drives (struct drv *drv, char next_drive); static void prepare_drives (struct drv *drv); static void mount_mps (struct mp *mp); @@ -83,6 +85,8 @@ static void cleanup_readline (void); static void add_history_line (const char *); #endif +static int override_progress_bars = -1; + /* Currently open libguestfs handle. */ guestfs_h *g; @@ -96,6 +100,9 @@ int command_num = 0; int keys_from_stdin = 0; const char *libvirt_uri = NULL; int inspector = 0; +int utf8_mode = 0; +int have_terminfo = 0; +int progress_bars = 0; static void __attribute__((noreturn)) usage (int status) @@ -133,6 +140,8 @@ usage (int status) " -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n" " -n|--no-sync Don't autosync\n" " -N|--new type Create prepared disk (test1.img, ...)\n" + " --progress-bars Enable progress bars even when not interactive\n" + " --no-progress-bars Disable progress bars\n" " --remote[=pid] Send commands to remote %s\n" " -r|--ro Mount read-only\n" " --selinux Enable SELinux support\n" @@ -159,6 +168,8 @@ main (int argc, char *argv[]) bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); + set_up_terminal (); + enum { HELP_OPTION = CHAR_MAX + 1 }; static const char *options = "a:c:d:Df:h::im:nN:rv?Vx"; @@ -176,6 +187,8 @@ main (int argc, char *argv[]) { "new", 1, 0, 'N' }, { "no-dest-paths", 0, 0, 'D' }, { "no-sync", 0, 0, 'n' }, + { "progress-bars", 0, 0, 0 }, + { "no-progress-bars", 0, 0, 0 }, { "remote", 2, 0, 0 }, { "ro", 0, 0, 'r' }, { "selinux", 0, 0, 0 }, @@ -261,6 +274,10 @@ main (int argc, char *argv[]) guestfs_set_selinux (g, 1); } else if (STREQ (long_options[option_index].name, "keys-from-stdin")) { keys_from_stdin = 1; + } else if (STREQ (long_options[option_index].name, "progress-bars")) { + override_progress_bars = 1; + } else if (STREQ (long_options[option_index].name, "no-progress-bars")) { + override_progress_bars = 0; } else { fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), program_name, long_options[option_index].name, option_index); @@ -301,7 +318,10 @@ main (int argc, char *argv[]) break; case 'N': - if (STRCASEEQ (optarg, "list")) { + if (STRCASEEQ (optarg, "list") || + STRCASEEQ (optarg, "help") || + STRCASEEQ (optarg, "h") || + STRCASEEQ (optarg, "?")) { list_prepared_drives (); exit (EXIT_SUCCESS); } @@ -494,6 +514,15 @@ main (int argc, char *argv[]) } } + /* Decide if we display progress bars. */ + progress_bars = + override_progress_bars >= 0 + ? override_progress_bars + : (optind >= argc && isatty (0)); + + if (progress_bars) + guestfs_set_progress_callback (g, progress_callback, NULL); + /* Interactive, shell script, or command(s) on the command line? */ if (optind >= argc) { if (isatty (0)) @@ -509,6 +538,35 @@ main (int argc, char *argv[]) exit (EXIT_SUCCESS); } +/* The header file which defines this has "issues". */ +extern int tgetent (char *, const char *); + +static void +set_up_terminal (void) +{ + /* http://www.cl.cam.ac.uk/~mgk25/unicode.html#activate */ + utf8_mode = STREQ (nl_langinfo (CODESET), "UTF-8"); + + char *term = getenv ("TERM"); + if (term == NULL) { + //fprintf (stderr, _("guestfish: TERM (terminal type) not defined.\n")); + return; + } + + int r = tgetent (NULL, term); + if (r == -1) { + fprintf (stderr, _("guestfish: could not access termcap or terminfo database.\n")); + return; + } + if (r == 0) { + fprintf (stderr, _("guestfish: terminal type \"%s\" not defined.\n"), + term); + return; + } + + have_terminfo = 1; +} + void pod2text (const char *name, const char *shortdesc, const char *str) { @@ -928,6 +986,8 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) int pid = 0; int i, r; + reset_progress_bar (); + /* This counts the commands issued, starting at 1. */ command_num++; @@ -1001,6 +1061,12 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) else if (STRCASEEQ (cmd, "alloc") || STRCASEEQ (cmd, "allocate")) r = do_alloc (cmd, argc, argv); + else if (STRCASEEQ (cmd, "copy-in") || + STRCASEEQ (cmd, "copy_in")) + r = do_copy_in (cmd, argc, argv); + else if (STRCASEEQ (cmd, "copy-out") || + STRCASEEQ (cmd, "copy_out")) + r = do_copy_out (cmd, argc, argv); else if (STRCASEEQ (cmd, "echo")) r = do_echo (cmd, argc, argv); else if (STRCASEEQ (cmd, "edit") || @@ -1066,6 +1132,10 @@ list_builtin_commands (void) printf ("%-20s %s\n", "alloc", _("allocate an image")); printf ("%-20s %s\n", + "copy-in", _("copy files into an image")); + printf ("%-20s %s\n", + "copy-out", _("copy files out of an image")); + printf ("%-20s %s\n", "echo", _("display a line of text")); printf ("%-20s %s\n", "edit", _("edit a file in the image")); @@ -1106,6 +1176,26 @@ display_builtin_command (const char *cmd) )); return 0; } + else if (STRCASEEQ (cmd, "copy-in") || + STRCASEEQ (cmd, "copy_in")) { + printf (_("copy-in - copy files into an image\n" + " copy-in [ ...] \n" + "\n" + " Copy local files or directories recursively into the\n" + " image, placing them on a remote directory.\n" + )); + return 0; + } + else if (STRCASEEQ (cmd, "copy-out") || + STRCASEEQ (cmd, "copy_out")) { + printf (_("copy-out - copy files out of an image\n" + " copy-out [ ...] \n" + "\n" + " Copy remote files or directories recursively out of the\n" + " image, placing them in a local directory.\n" + )); + return 0; + } else if (STRCASEEQ (cmd, "echo")) { printf (_("echo - display a line of text\n" " echo [ ...]\n"