protocol: Really read 4 bytes while checking for cancellation.
[libguestfs.git] / fish / fish.c
index 559d609..50340a3 100644 (file)
@@ -30,7 +30,6 @@
 #include <sys/wait.h>
 #include <locale.h>
 #include <langinfo.h>
 #include <sys/wait.h>
 #include <locale.h>
 #include <langinfo.h>
-#include <termios.h>
 
 #ifdef HAVE_LIBREADLINE
 #include <readline/readline.h>
 
 #ifdef HAVE_LIBREADLINE
 #include <readline/readline.h>
@@ -68,6 +67,7 @@ int read_only = 0;
 int quit = 0;
 int verbose = 0;
 int remote_control_listen = 0;
 int quit = 0;
 int verbose = 0;
 int remote_control_listen = 0;
+int remote_control_csh = 0;
 int remote_control = 0;
 int exit_on_error = 1;
 int command_num = 0;
 int remote_control = 0;
 int exit_on_error = 1;
 int command_num = 0;
@@ -106,6 +106,7 @@ usage (int status)
              "  -h|--cmd-help cmd    Display detailed help on 'cmd'\n"
              "  -a|--add image       Add image\n"
              "  -c|--connect uri     Specify libvirt URI for -d option\n"
              "  -h|--cmd-help cmd    Display detailed help on 'cmd'\n"
              "  -a|--add image       Add image\n"
              "  -c|--connect uri     Specify libvirt URI for -d option\n"
+             "  --csh                Make --listen csh-compatible\n"
              "  -d|--domain guest    Add disks from libvirt guest\n"
              "  -D|--no-dest-paths   Don't tab-complete paths from guest fs\n"
              "  --echo-keys          Don't turn off echo for passphrases\n"
              "  -d|--domain guest    Add disks from libvirt guest\n"
              "  -D|--no-dest-paths   Don't tab-complete paths from guest fs\n"
              "  --echo-keys          Don't turn off echo for passphrases\n"
@@ -149,11 +150,12 @@ main (int argc, char *argv[])
 
   enum { HELP_OPTION = CHAR_MAX + 1 };
 
 
   enum { HELP_OPTION = CHAR_MAX + 1 };
 
-  static const char *options = "a:c:d:Df:h::im:nN:rv?Vx";
+  static const char *options = "a:c:d:Df:h::im:nN:rv?Vwx";
   static const struct option long_options[] = {
     { "add", 1, 0, 'a' },
     { "cmd-help", 2, 0, 'h' },
     { "connect", 1, 0, 'c' },
   static const struct option long_options[] = {
     { "add", 1, 0, 'a' },
     { "cmd-help", 2, 0, 'h' },
     { "connect", 1, 0, 'c' },
+    { "csh", 0, 0, 0 },
     { "domain", 1, 0, 'd' },
     { "echo-keys", 0, 0, 0 },
     { "file", 1, 0, 'f' },
     { "domain", 1, 0, 'd' },
     { "echo-keys", 0, 0, 0 },
     { "file", 1, 0, 'f' },
@@ -170,6 +172,7 @@ main (int argc, char *argv[])
     { "no-progress-bars", 0, 0, 0 },
     { "remote", 2, 0, 0 },
     { "ro", 0, 0, 'r' },
     { "no-progress-bars", 0, 0, 0 },
     { "remote", 2, 0, 0 },
     { "ro", 0, 0, 'r' },
+    { "rw", 0, 0, 'w' },
     { "selinux", 0, 0, 0 },
     { "verbose", 0, 0, 'v' },
     { "version", 0, 0, 'V' },
     { "selinux", 0, 0, 0 },
     { "verbose", 0, 0, 'v' },
     { "version", 0, 0, 'V' },
@@ -263,6 +266,8 @@ main (int argc, char *argv[])
           format = NULL;
         else
           format = optarg;
           format = NULL;
         else
           format = optarg;
+      } else if (STREQ (long_options[option_index].name, "csh")) {
+        remote_control_csh = 1;
       } else {
         fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                  program_name, long_options[option_index].name, option_index);
       } else {
         fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                  program_name, long_options[option_index].name, option_index);
@@ -334,6 +339,8 @@ main (int argc, char *argv[])
         exit (EXIT_FAILURE);
       }
       drv->type = drv_N;
         exit (EXIT_FAILURE);
       }
       drv->type = drv_N;
+      drv->device = NULL;
+      drv->nr_drives = -1;
       if (asprintf (&drv->N.filename, "test%d.img",
                     next_prepared_drive++) == -1) {
         perror ("asprintf");
       if (asprintf (&drv->N.filename, "test%d.img",
                     next_prepared_drive++) == -1) {
         perror ("asprintf");
@@ -341,7 +348,6 @@ main (int argc, char *argv[])
       }
       drv->N.data = create_prepared_file (optarg, drv->N.filename);
       drv->N.data_free = free_prep_data;
       }
       drv->N.data = create_prepared_file (optarg, drv->N.filename);
       drv->N.data_free = free_prep_data;
-      drv->N.device = NULL;     /* filled in by add_drives */
       drv->next = drvs;
       drvs = drv;
       break;
       drv->next = drvs;
       drvs = drv;
       break;
@@ -358,6 +364,10 @@ main (int argc, char *argv[])
       OPTION_V;
       break;
 
       OPTION_V;
       break;
 
+    case 'w':
+      OPTION_w;
+      break;
+
     case 'x':
       OPTION_x;
       break;
     case 'x':
       OPTION_x;
       break;
@@ -521,31 +531,13 @@ set_up_terminal (void)
   have_terminfo = 1;
 }
 
   have_terminfo = 1;
 }
 
-void
-pod2text (const char *name, const char *shortdesc, const char *str)
-{
-  FILE *fp;
-
-  fp = popen ("pod2text", "w");
-  if (fp == NULL) {
-    /* pod2text failed, maybe not found, so let's just print the
-     * source instead, since that's better than doing nothing.
-     */
-    printf ("%s - %s\n\n%s\n", name, shortdesc, str);
-    return;
-  }
-  fprintf (fp, "=head1 NAME\n\n%s - %s\n\n", name, shortdesc);
-  fputs (str, fp);
-  pclose (fp);
-}
-
 static void
 prepare_drives (struct drv *drv)
 {
   if (drv) {
     prepare_drives (drv->next);
     if (drv->type == drv_N)
 static void
 prepare_drives (struct drv *drv)
 {
   if (drv) {
     prepare_drives (drv->next);
     if (drv->type == drv_N)
-      prepare_drive (drv->N.filename, drv->N.data, drv->N.device);
+      prepare_drive (drv->N.filename, drv->N.data, drv->device);
   }
 }
 
   }
 }
 
@@ -626,7 +618,7 @@ script (int prompt)
               "Welcome to guestfish, the libguestfs filesystem interactive shell for\n"
               "editing virtual machine filesystems.\n"
               "\n"
               "Welcome to guestfish, the libguestfs filesystem interactive shell for\n"
               "editing virtual machine filesystems.\n"
               "\n"
-              "Type: 'help' for a list of commands\n"
+              "Type: 'help' for help on commands\n"
               "      'man' to read the manual\n"
               "      'quit' to quit the shell\n"
               "\n"));
               "      'man' to read the manual\n"
               "      'quit' to quit the shell\n"
               "\n"));
@@ -925,7 +917,7 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd)
   /* Otherwise execute it locally. */
   else if (STRCASEEQ (cmd, "help")) {
     if (argc == 0) {
   /* Otherwise execute it locally. */
   else if (STRCASEEQ (cmd, "help")) {
     if (argc == 0) {
-      list_commands ();
+      display_help ();
       r = 0;
     } else
       r = display_command (argv[0]);
       r = 0;
     } else
       r = display_command (argv[0]);
@@ -1480,66 +1472,3 @@ file_out (const char *arg)
   }
   return ret;
 }
   }
   return ret;
 }
-
-/* Read a passphrase ('Key') from /dev/tty with echo off.
- * The caller (cmds.c) will call free on the string afterwards.
- * Based on the code in cryptsetup file lib/utils.c.
- */
-char *
-read_key (const char *param)
-{
-  FILE *infp, *outfp;
-  struct termios orig, temp;
-  char *ret = NULL;
-
-  /* Read and write to /dev/tty if available. */
-  if (keys_from_stdin ||
-      (infp = outfp = fopen ("/dev/tty", "w+")) == NULL) {
-    infp = stdin;
-    outfp = stdout;
-  }
-
-  /* Print the prompt and set no echo. */
-  int tty = isatty (fileno (infp));
-  int tcset = 0;
-  if (tty) {
-    fprintf (outfp, _("Enter key or passphrase (\"%s\"): "), param);
-
-    if (!echo_keys) {
-      if (tcgetattr (fileno (infp), &orig) == -1) {
-        perror ("tcgetattr");
-        goto error;
-      }
-      memcpy (&temp, &orig, sizeof temp);
-      temp.c_lflag &= ~ECHO;
-
-      tcsetattr (fileno (infp), TCSAFLUSH, &temp);
-      tcset = 1;
-    }
-  }
-
-  size_t n = 0;
-  ssize_t len;
-  len = getline (&ret, &n, infp);
-  if (len == -1) {
-    perror ("getline");
-    ret = NULL;
-    goto error;
-  }
-
-  /* Remove the terminating \n if there is one. */
-  if (len > 0 && ret[len-1] == '\n')
-    ret[len-1] = '\0';
-
- error:
-  /* Restore echo, close file descriptor. */
-  if (tty && tcset) {
-    printf ("\n");
-    tcsetattr (fileno (infp), TCSAFLUSH, &orig);
-  }
-
-  if (infp != stdin)
-    fclose (infp); /* outfp == infp, so this is closed also */
-
-  return ret;
-}