virt-resize: Document guest boot stops at "GRUB" (RHBZ#640961).
[libguestfs.git] / fish / inspect.c
1 /* guestfish - the filesystem interactive shell
2  * Copyright (C) 2010 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will 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, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "fish.h"
26
27 /* Global that saves the root device between inspect_mount and
28  * print_inspect_prompt.
29  */
30 static char *root = NULL;
31
32 static int
33 compare_keys_len (const void *p1, const void *p2)
34 {
35   const char *key1 = * (char * const *) p1;
36   const char *key2 = * (char * const *) p2;
37   return strlen (key1) - strlen (key2);
38 }
39
40 static int
41 compare_keys (const void *p1, const void *p2)
42 {
43   const char *key1 = * (char * const *) p1;
44   const char *key2 = * (char * const *) p2;
45   return strcasecmp (key1, key2);
46 }
47
48 /* This function implements the -i option. */
49 void
50 inspect_mount (void)
51 {
52   char **roots = guestfs_inspect_os (g);
53   if (roots == NULL)
54     exit (EXIT_FAILURE);
55
56   if (roots[0] == NULL) {
57     fprintf (stderr, _("guestfish: no operating system was found on this disk\n"));
58     exit (EXIT_FAILURE);
59   }
60
61   if (roots[1] != NULL) {
62     fprintf (stderr, _("guestfish: multi-boot operating systems are not supported by the -i option\n"));
63     exit (EXIT_FAILURE);
64   }
65
66   root = roots[0];
67   free (roots);
68
69   char **mountpoints = guestfs_inspect_get_mountpoints (g, root);
70   if (mountpoints == NULL)
71     exit (EXIT_FAILURE);
72
73   /* Sort by key length, shortest key first, so that we end up
74    * mounting the filesystems in the correct order.
75    */
76   qsort (mountpoints, count_strings (mountpoints) / 2, 2 * sizeof (char *),
77          compare_keys_len);
78
79   size_t i;
80   for (i = 0; mountpoints[i] != NULL; i += 2) {
81     int r;
82     if (!read_only)
83       r = guestfs_mount_options (g, "", mountpoints[i+1], mountpoints[i]);
84     else
85       r = guestfs_mount_ro (g, mountpoints[i+1], mountpoints[i]);
86     if (r == -1)
87       exit (EXIT_FAILURE);
88   }
89
90   free_strings (mountpoints);
91 }
92
93 /* This function is called only if the above function was called,
94  * and only after we've printed the prompt in interactive mode.
95  */
96 void
97 print_inspect_prompt (void)
98 {
99   char *name = guestfs_inspect_get_product_name (g, root);
100   if (STRNEQ (name, "unknown"))
101     printf (_("Operating system: %s\n"), name);
102   free (name);
103
104   char **mountpoints = guestfs_inspect_get_mountpoints (g, root);
105   if (mountpoints == NULL)
106     return;
107
108   /* Sort by key. */
109   qsort (mountpoints, count_strings (mountpoints) / 2, 2 * sizeof (char *),
110          compare_keys);
111
112   size_t i;
113   for (i = 0; mountpoints[i] != NULL; i += 2)
114     printf (_("%s mounted on %s\n"), mountpoints[i+1], mountpoints[i]);
115
116   free_strings (mountpoints);
117 }