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
41 #include "ignore-value.h"
45 #include "guestfs-internal.h"
46 #include "guestfs-internal-actions.h"
47 #include "guestfs_protocol.h"
49 #if defined(HAVE_PCRE) && defined(HAVE_HIVEX)
51 /* Debian/Ubuntu install disks are easy ...
53 * These files are added by the debian-cd program, and it is worth
54 * looking at the source code to determine exact values, in
55 * particular '/usr/share/debian-cd/tools/start_new_disc'
57 * XXX Architecture? We could parse it out of the product name
58 * string, but that seems quite hairy. We could look for the names
59 * of packages. Also note that some Debian install disks are
63 check_debian_installer_root (guestfs_h *g, struct inspect_fs *fs)
65 fs->product_name = guestfs___first_line_of_file (g, "/.disk/info");
66 if (!fs->product_name)
69 fs->type = OS_TYPE_LINUX;
70 if (STRPREFIX (fs->product_name, "Ubuntu"))
71 fs->distro = OS_DISTRO_UBUNTU;
72 else if (STRPREFIX (fs->product_name, "Debian"))
73 fs->distro = OS_DISTRO_DEBIAN;
75 (void) guestfs___parse_major_minor (g, fs);
77 if (guestfs_is_file (g, "/.disk/cd_type") > 0) {
78 char *cd_type = guestfs___first_line_of_file (g, "/.disk/cd_type");
82 if (STRPREFIX (cd_type, "dvd/single") ||
83 STRPREFIX (cd_type, "full_cd/single")) {
84 fs->is_multipart_disk = 0;
85 fs->is_netinst_disk = 0;
87 else if (STRPREFIX (cd_type, "dvd") ||
88 STRPREFIX (cd_type, "full_cd")) {
89 fs->is_multipart_disk = 1;
90 fs->is_netinst_disk = 0;
92 else if (STRPREFIX (cd_type, "not_complete")) {
93 fs->is_multipart_disk = 0;
94 fs->is_netinst_disk = 1;
103 /* Take string which must look like "key = value" and find the value.
104 * There may or may not be spaces before and after the equals sign.
105 * This function is used by both check_fedora_installer_root and
106 * check_w2k3_installer_root.
109 find_value (const char *kv)
113 p = strchr (kv, '=');
119 } while (c_isspace (*p));
124 /* Fedora CDs and DVD (not netinst). The /.treeinfo file contains
125 * an initial section somewhat like this:
136 check_fedora_installer_root (guestfs_h *g, struct inspect_fs *fs)
141 int discnum = 0, totaldiscs = 0;
143 fs->type = OS_TYPE_LINUX;
145 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
146 "^family = Fedora$", 0, &str);
150 fs->distro = OS_DISTRO_FEDORA;
154 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
155 "^family = Red Hat Enterprise Linux$",
160 fs->distro = OS_DISTRO_RHEL;
164 /* XXX should do major.minor before this */
165 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
166 "^version = [[:digit:]]+", 0, &str);
170 v = find_value (str);
171 fs->major_version = guestfs___parse_unsigned_int_ignore_trailing (g, v);
173 if (fs->major_version == -1)
177 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
178 "^arch = [-_[:alnum:]]+$", 0, &str);
182 v = find_value (str);
183 fs->arch = safe_strdup (g, v);
187 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
188 "^discnum = [[:digit:]]+$", 0, &str);
192 v = find_value (str);
193 discnum = guestfs___parse_unsigned_int (g, v);
199 r = guestfs___first_egrep_of_file (g, "/.treeinfo",
200 "^totaldiscs = [[:digit:]]+$", 0, &str);
204 v = find_value (str);
205 totaldiscs = guestfs___parse_unsigned_int (g, v);
207 if (totaldiscs == -1)
211 fs->is_multipart_disk = totaldiscs > 0;
212 /* and what about discnum? */
217 /* Linux with /isolinux/isolinux.cfg.
219 * This file is not easily parsable so we have to do our best.
220 * Look for the "menu title" line which contains:
221 * menu title Welcome to Fedora 14! # since at least Fedora 10
222 * menu title Welcome to Red Hat Enterprise Linux 6.0!
225 check_isolinux_installer_root (guestfs_h *g, struct inspect_fs *fs)
230 fs->type = OS_TYPE_LINUX;
232 r = guestfs___first_egrep_of_file (g, "/isolinux/isolinux.cfg",
233 "^menu title Welcome to Fedora [[:digit:]]+",
238 fs->distro = OS_DISTRO_FEDORA;
240 guestfs___parse_unsigned_int_ignore_trailing (g, &str[29]);
242 if (fs->major_version == -1)
246 /* XXX parse major.minor */
247 r = guestfs___first_egrep_of_file (g, "/isolinux/isolinux.cfg",
248 "^menu title Welcome to Red Hat Enterprise Linux [[:digit:]]+",
253 fs->distro = OS_DISTRO_RHEL;
255 guestfs___parse_unsigned_int_ignore_trailing (g, &str[47]);
257 if (fs->major_version == -1)
264 /* Windows 2003 and similar versions.
266 * NB: txtsetup file contains Windows \r\n line endings, which guestfs_grep
267 * does not remove. We have to remove them by hand here.
272 size_t n = strlen (str);
273 if (n > 0 && str[n-1] == '\r')
278 trim_quot (char *str)
280 size_t n = strlen (str);
281 if (n > 0 && str[n-1] == '"')
286 check_w2k3_installer_root (guestfs_h *g, struct inspect_fs *fs,
287 const char *txtsetup)
293 fs->type = OS_TYPE_WINDOWS;
294 fs->distro = OS_DISTRO_WINDOWS;
296 r = guestfs___first_egrep_of_file (g, txtsetup,
297 "^productname[[:space:]]*=[[:space:]]*\"", 1, &str);
303 v = find_value (str);
304 fs->product_name = safe_strdup (g, v+1);
308 r = guestfs___first_egrep_of_file (g, txtsetup,
309 "^majorversion[[:space:]]*=[[:space:]]*[[:digit:]]+",
315 v = find_value (str);
316 fs->major_version = guestfs___parse_unsigned_int_ignore_trailing (g, v);
318 if (fs->major_version == -1)
322 r = guestfs___first_egrep_of_file (g, txtsetup,
323 "^minorversion[[:space:]]*=[[:space:]]*[[:digit:]]+",
329 v = find_value (str);
330 fs->minor_version = guestfs___parse_unsigned_int_ignore_trailing (g, v);
332 if (fs->minor_version == -1)
336 /* This is the windows systemroot that would be chosen on
337 * installation by default, although not necessarily the one that
338 * the user will finally choose.
340 r = guestfs___first_egrep_of_file (g, txtsetup,
341 "^defaultpath[[:space:]]*=[[:space:]]*",
347 v = find_value (str);
348 fs->windows_systemroot = safe_strdup (g, v);
355 /* The currently mounted device is very likely to be an installer. */
357 guestfs___check_installer_root (guestfs_h *g, struct inspect_fs *fs)
359 /* The presence of certain files indicates a live CD.
361 * XXX Fedora netinst contains a ~120MB squashfs called
362 * /images/install.img. However this is not a live CD (unlike the
363 * Fedora live CDs which contain the same, but larger file). We
364 * need to unpack this and look inside to tell the difference.
366 if (guestfs_is_file (g, "/casper/filesystem.squashfs") > 0)
367 fs->is_live_disk = 1;
370 if (guestfs_is_file (g, "/.disk/info") > 0) {
371 if (check_debian_installer_root (g, fs) == -1)
375 /* Fedora CDs and DVD (not netinst). */
376 else if (guestfs_is_file (g, "/.treeinfo") > 0) {
377 if (check_fedora_installer_root (g, fs) == -1)
381 /* Linux with /isolinux/isolinux.cfg. */
382 else if (guestfs_is_file (g, "/isolinux/isolinux.cfg") > 0) {
383 if (check_isolinux_installer_root (g, fs) == -1)
387 /* Windows 2003 64 bit */
388 else if (guestfs_is_file (g, "/amd64/txtsetup.sif") > 0) {
389 fs->arch = safe_strdup (g, "x86_64");
390 if (check_w2k3_installer_root (g, fs, "/amd64/txtsetup.sif") == -1)
394 /* Windows 2003 32 bit */
395 else if (guestfs_is_file (g, "/i386/txtsetup.sif") > 0) {
396 fs->arch = safe_strdup (g, "i386");
397 if (check_w2k3_installer_root (g, fs, "/i386/txtsetup.sif") == -1)
404 #endif /* defined(HAVE_PCRE) && defined(HAVE_HIVEX) */