2 * Copyright (C) 2010-2011 Red Hat Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library 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 GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
39 #include "ignore-value.h"
43 #include "guestfs-internal.h"
44 #include "guestfs-internal-actions.h"
45 #include "guestfs_protocol.h"
47 #if defined(HAVE_HIVEX)
49 /* Debian/Ubuntu install disks are easy ...
51 * These files are added by the debian-cd program, and it is worth
52 * looking at the source code to determine exact values, in
53 * particular '/usr/share/debian-cd/tools/start_new_disc'
55 * XXX Architecture? We could parse it out of the product name
56 * string, but that seems quite hairy. We could look for the names
57 * of packages. Also note that some Debian install disks are
61 check_debian_installer_root (guestfs_h *g, struct inspect_fs *fs)
63 fs->product_name = guestfs___first_line_of_file (g, "/.disk/info");
64 if (!fs->product_name)
67 fs->type = OS_TYPE_LINUX;
68 if (STRPREFIX (fs->product_name, "Ubuntu"))
69 fs->distro = OS_DISTRO_UBUNTU;
70 else if (STRPREFIX (fs->product_name, "Debian"))
71 fs->distro = OS_DISTRO_DEBIAN;
73 (void) guestfs___parse_major_minor (g, fs);
75 if (guestfs_is_file (g, "/.disk/cd_type") > 0) {
76 char *cd_type = guestfs___first_line_of_file (g, "/.disk/cd_type");
80 if (STRPREFIX (cd_type, "dvd/single") ||
81 STRPREFIX (cd_type, "full_cd/single")) {
82 fs->is_multipart_disk = 0;
83 fs->is_netinst_disk = 0;
85 else if (STRPREFIX (cd_type, "dvd") ||
86 STRPREFIX (cd_type, "full_cd")) {
87 fs->is_multipart_disk = 1;
88 fs->is_netinst_disk = 0;
90 else if (STRPREFIX (cd_type, "not_complete")) {
91 fs->is_multipart_disk = 0;
92 fs->is_netinst_disk = 1;
101 /* Take string which must look like "key = value" and find the value.
102 * There may or may not be spaces before and after the equals sign.
103 * This function is used by both check_fedora_installer_root and
104 * check_w2k3_installer_root.
107 find_value (const char *kv)
111 p = strchr (kv, '=');
117 } while (c_isspace (*p));
122 /* Fedora CDs and DVD (not netinst). The /.treeinfo file contains
123 * an initial section somewhat like this:
134 check_fedora_installer_root (guestfs_h *g, struct inspect_fs *fs)
139 int discnum = 0, totaldiscs = 0;
141 fs->type = OS_TYPE_LINUX;
143 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
144 "^family = Fedora$", 0, &str);
148 fs->distro = OS_DISTRO_FEDORA;
152 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
153 "^family = Red Hat Enterprise Linux$",
158 fs->distro = OS_DISTRO_RHEL;
162 /* XXX should do major.minor before this */
163 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
164 "^version = [[:digit:]]+", 0, &str);
168 v = find_value (str);
169 fs->major_version = guestfs___parse_unsigned_int_ignore_trailing (g, v);
171 if (fs->major_version == -1)
175 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
176 "^arch = [-_[:alnum:]]+$", 0, &str);
180 v = find_value (str);
181 fs->arch = safe_strdup (g, v);
185 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
186 "^discnum = [[:digit:]]+$", 0, &str);
190 v = find_value (str);
191 discnum = guestfs___parse_unsigned_int (g, v);
197 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
198 "^totaldiscs = [[:digit:]]+$", 0, &str);
202 v = find_value (str);
203 totaldiscs = guestfs___parse_unsigned_int (g, v);
205 if (totaldiscs == -1)
209 fs->is_multipart_disk = totaldiscs > 0;
210 /* and what about discnum? */
215 /* Linux with /isolinux/isolinux.cfg.
217 * This file is not easily parsable so we have to do our best.
218 * Look for the "menu title" line which contains:
219 * menu title Welcome to Fedora 14! # since at least Fedora 10
220 * menu title Welcome to Red Hat Enterprise Linux 6.0!
223 check_isolinux_installer_root (guestfs_h *g, struct inspect_fs *fs)
228 fs->type = OS_TYPE_LINUX;
230 r = guestfs___first_egrep_of_file (g, "/isolinux/isolinux.cfg",
231 "^menu title Welcome to Fedora [[:digit:]]+",
236 fs->distro = OS_DISTRO_FEDORA;
238 guestfs___parse_unsigned_int_ignore_trailing (g, &str[29]);
240 if (fs->major_version == -1)
244 /* XXX parse major.minor */
245 r = guestfs___first_egrep_of_file (g, "/isolinux/isolinux.cfg",
246 "^menu title Welcome to Red Hat Enterprise Linux [[:digit:]]+",
251 fs->distro = OS_DISTRO_RHEL;
253 guestfs___parse_unsigned_int_ignore_trailing (g, &str[47]);
255 if (fs->major_version == -1)
262 /* Windows 2003 and similar versions.
264 * NB: txtsetup file contains Windows \r\n line endings, which guestfs_grep
265 * does not remove. We have to remove them by hand here.
270 size_t n = strlen (str);
271 if (n > 0 && str[n-1] == '\r')
276 trim_quot (char *str)
278 size_t n = strlen (str);
279 if (n > 0 && str[n-1] == '"')
284 check_w2k3_installer_root (guestfs_h *g, struct inspect_fs *fs,
285 const char *txtsetup)
291 fs->type = OS_TYPE_WINDOWS;
292 fs->distro = OS_DISTRO_WINDOWS;
294 r = guestfs___first_egrep_of_file (g, txtsetup,
295 "^productname[[:space:]]*=[[:space:]]*\"", 1, &str);
301 v = find_value (str);
302 fs->product_name = safe_strdup (g, v+1);
306 r = guestfs___first_egrep_of_file (g, txtsetup,
307 "^majorversion[[:space:]]*=[[:space:]]*[[:digit:]]+",
313 v = find_value (str);
314 fs->major_version = guestfs___parse_unsigned_int_ignore_trailing (g, v);
316 if (fs->major_version == -1)
320 r = guestfs___first_egrep_of_file (g, txtsetup,
321 "^minorversion[[:space:]]*=[[:space:]]*[[:digit:]]+",
327 v = find_value (str);
328 fs->minor_version = guestfs___parse_unsigned_int_ignore_trailing (g, v);
330 if (fs->minor_version == -1)
334 /* This is the windows systemroot that would be chosen on
335 * installation by default, although not necessarily the one that
336 * the user will finally choose.
338 r = guestfs___first_egrep_of_file (g, txtsetup,
339 "^defaultpath[[:space:]]*=[[:space:]]*",
345 v = find_value (str);
346 fs->windows_systemroot = safe_strdup (g, v);
353 /* The currently mounted device is very likely to be an installer. */
355 guestfs___check_installer_root (guestfs_h *g, struct inspect_fs *fs)
357 /* The presence of certain files indicates a live CD.
359 * XXX Fedora netinst contains a ~120MB squashfs called
360 * /images/install.img. However this is not a live CD (unlike the
361 * Fedora live CDs which contain the same, but larger file). We
362 * need to unpack this and look inside to tell the difference.
364 if (guestfs_is_file (g, "/casper/filesystem.squashfs") > 0)
365 fs->is_live_disk = 1;
368 if (guestfs_is_file (g, "/.disk/info") > 0) {
369 if (check_debian_installer_root (g, fs) == -1)
373 /* Fedora CDs and DVD (not netinst). */
374 else if (guestfs_is_file (g, "/.treeinfo") > 0) {
375 if (check_fedora_installer_root (g, fs) == -1)
379 /* Linux with /isolinux/isolinux.cfg. */
380 else if (guestfs_is_file (g, "/isolinux/isolinux.cfg") > 0) {
381 if (check_isolinux_installer_root (g, fs) == -1)
385 /* Windows 2003 64 bit */
386 else if (guestfs_is_file (g, "/amd64/txtsetup.sif") > 0) {
387 fs->arch = safe_strdup (g, "x86_64");
388 if (check_w2k3_installer_root (g, fs, "/amd64/txtsetup.sif") == -1)
392 /* Windows 2003 32 bit */
393 else if (guestfs_is_file (g, "/i386/txtsetup.sif") > 0) {
394 fs->arch = safe_strdup (g, "i386");
395 if (check_w2k3_installer_root (g, fs, "/i386/txtsetup.sif") == -1)
402 #endif /* defined(HAVE_HIVEX) */