const char *libvirt_uri = NULL;
int inspector = 1;
+static int do_ls (const char *dir);
+static int do_ls_l (const char *dir);
+static int do_ls_R (const char *dir);
+
static inline char *
bad_cast (char const *s)
{
else {
fprintf (stdout,
_("%s: list files in a virtual machine\n"
- "Copyright (C) 2010 Red Hat Inc.\n"
+ "Copyright (C) 2010-2011 Red Hat Inc.\n"
"Usage:\n"
" %s [--options] -d domname dir [dir ...]\n"
" %s [--options] -a disk.img [-a disk.img ...] dir [dir ...]\n"
const char *format = NULL;
int c;
int option_index;
- char mode = 0;
+#define MODE_LS_L 1
+#define MODE_LS_R 2
+#define MODE_LS_LR (MODE_LS_L|MODE_LS_R)
+ int mode = 0;
g = guestfs_create ();
if (g == NULL) {
usage (EXIT_SUCCESS);
case 'l':
- mode = 'l';
+ mode |= MODE_LS_L;
break;
case 'R':
- mode = 'R';
+ mode |= MODE_LS_R;
break;
case 'v':
}
}
+ if (mode == MODE_LS_LR) {
+ fprintf (stderr, _("%s: cannot combine -l and -R options\n"),
+ program_name);
+ exit (EXIT_FAILURE);
+ }
+
/* These are really constants, but they have to be variables for the
* options parsing code. Assert here that they have known-good
* values.
while (optind < argc) {
const char *dir = argv[optind];
- if (mode == 0) {
- char **lines;
- size_t i;
+ switch (mode) {
+ case 0: /* no -l or -R option */
+ if (do_ls (dir) == -1)
+ errors++;
+ break;
- if ((lines = guestfs_ls (g, dir)) == NULL)
+ case MODE_LS_L: /* virt-ls -l */
+ if (do_ls_l (dir) == -1)
errors++;
- else {
- for (i = 0; lines[i] != NULL; ++i) {
- printf ("%s\n", lines[i]);
- free (lines[i]);
- }
- free (lines);
- }
- }
- else if (mode == 'l') {
- char *out;
+ break;
- if ((out = guestfs_ll (g, dir)) == NULL)
+ case MODE_LS_R: /* virt-ls -R */
+ if (do_ls_R (dir) == -1)
errors++;
- else {
- printf ("%s", out);
- free (out);
- }
+ break;
+
+ default:
+ abort (); /* can't happen */
}
- else if (mode == 'R') {
- /* This is TMP_TEMPLATE_ON_STACK expanded from fish.h. */
- const char *tmpdir = guestfs_tmpdir ();
- char tmpfile[strlen (tmpdir) + 32];
- sprintf (tmpfile, "%s/virtlsXXXXXX", tmpdir);
-
- int fd = mkstemp (tmpfile);
- if (fd == -1) {
- perror ("mkstemp");
- exit (EXIT_FAILURE);
- }
- char buf[BUFSIZ]; /* also used below */
- snprintf (buf, sizeof buf, "/dev/fd/%d", fd);
+ optind++;
+ }
- if (guestfs_find0 (g, dir, buf) == -1)
- errors++;
- else {
- if (close (fd) == -1) {
- perror (tmpfile);
- exit (EXIT_FAILURE);
- }
+ guestfs_close (g);
- /* The output of find0 is a \0-separated file. Turn each \0 into
- * a \n character.
- */
- fd = open (tmpfile, O_RDONLY);
- if (fd == -1) {
- perror (tmpfile);
- exit (EXIT_FAILURE);
- }
+ exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
- ssize_t r;
- while ((r = read (fd, buf, sizeof buf)) > 0) {
- size_t i;
- for (i = 0; i < (size_t) r; ++i)
- if (buf[i] == '\0')
- buf[i] = '\n';
-
- size_t n = r;
- while (n > 0) {
- r = write (1, buf, n);
- if (r == -1) {
- perror ("write");
- exit (EXIT_FAILURE);
- }
- n -= r;
- }
- }
+static int
+do_ls (const char *dir)
+{
+ char **lines;
+ size_t i;
- if (r == -1 || close (fd) == -1) {
- perror (tmpfile);
- exit (EXIT_FAILURE);
- }
- }
+ if ((lines = guestfs_ls (g, dir)) == NULL) {
+ return -1;
+ }
+
+ for (i = 0; lines[i] != NULL; ++i) {
+ printf ("%s\n", lines[i]);
+ free (lines[i]);
+ }
+ free (lines);
+
+ return 0;
+}
+
+static int
+do_ls_l (const char *dir)
+{
+ char *out;
+
+ if ((out = guestfs_ll (g, dir)) == NULL)
+ return -1;
+
+ printf ("%s", out);
+ free (out);
+
+ return 0;
+}
+
+static int
+do_ls_R (const char *dir)
+{
+ /* This is TMP_TEMPLATE_ON_STACK expanded from fish.h. */
+ const char *tmpdir = guestfs_tmpdir ();
+ char tmpfile[strlen (tmpdir) + 32];
+ sprintf (tmpfile, "%s/virtlsXXXXXX", tmpdir);
+
+ int fd = mkstemp (tmpfile);
+ if (fd == -1) {
+ perror ("mkstemp");
+ exit (EXIT_FAILURE);
+ }
+
+ char buf[BUFSIZ]; /* also used below */
+ snprintf (buf, sizeof buf, "/dev/fd/%d", fd);
- unlink (tmpfile);
+ if (guestfs_find0 (g, dir, buf) == -1)
+ return -1;
+
+ if (close (fd) == -1) {
+ perror (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ /* The output of find0 is a \0-separated file. Turn each \0 into
+ * a \n character.
+ */
+ fd = open (tmpfile, O_RDONLY);
+ if (fd == -1) {
+ perror (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ ssize_t r;
+ while ((r = read (fd, buf, sizeof buf)) > 0) {
+ size_t i;
+ for (i = 0; i < (size_t) r; ++i)
+ if (buf[i] == '\0')
+ buf[i] = '\n';
+
+ size_t n = r;
+ while (n > 0) {
+ r = write (1, buf, n);
+ if (r == -1) {
+ perror ("write");
+ exit (EXIT_FAILURE);
+ }
+ n -= r;
}
- optind++;
}
- guestfs_close (g);
+ if (r == -1 || close (fd) == -1) {
+ perror (tmpfile);
+ exit (EXIT_FAILURE);
+ }
- exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ unlink (tmpfile);
+
+ return 0;
}