summaryrefslogtreecommitdiffstats
path: root/lib/libdisk/open_disk.c
diff options
context:
space:
mode:
authorrink <rink@FreeBSD.org>2007-08-05 16:55:40 +0000
committerrink <rink@FreeBSD.org>2007-08-05 16:55:40 +0000
commitbdcc40a9d2d923ac7310cde90e01075fc79624dc (patch)
treea8a4a4484bf4b314198998a49068ce2150062f4e /lib/libdisk/open_disk.c
parent0646d6debe5d3260543b0f01e7260e97e770741f (diff)
downloadFreeBSD-src-bdcc40a9d2d923ac7310cde90e01075fc79624dc.zip
FreeBSD-src-bdcc40a9d2d923ac7310cde90e01075fc79624dc.tar.gz
Improve error handling in libdisk while parsing the kern.geom.conftxt sysctl.
Previously, any parse error will result in the calling program exiting with an unpleasant message. This change will cause libdisk to issue a warning and ignore lines it cannot parse instead of bluntly terminating the unfortunate enough program. This change will allow you to use sysinstall if you have a NTFS parition with a space in the name (such as 'Win Xp'). In such a case, a line like the following will appear in the kern.geom.conftxt output: 2 LABEL ntfs/Win Xp 209818635264 512 i 0 o 0 As the fields are space-separated, libdisk would go beserk and exit the program. This would happen if using FreeBSD 7.0 snapshot images (as GEOM_LABEL is in the installation kernel as well), thus making it impossible to install FreeBSD without renaming your NTFS paritions. Reported by: Dwight Berendse <dwight at berendse dot org> Nod from: phk Reviewed by: imp Approved by: re (bmah), imp (mentor) MFC after: 1 month
Diffstat (limited to 'lib/libdisk/open_disk.c')
-rw-r--r--lib/libdisk/open_disk.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/lib/libdisk/open_disk.c b/lib/libdisk/open_disk.c
index 7450652..798a72a 100644
--- a/lib/libdisk/open_disk.c
+++ b/lib/libdisk/open_disk.c
@@ -43,19 +43,24 @@ struct disk *
Int_Open_Disk(const char *name, char *conftxt)
{
struct disk *d;
- int i;
+ int i, line = 1;
char *p, *q, *r, *a, *b, *n, *t, *sn;
daddr_t o, len, off;
u_int l, s, ty, sc, hd, alt;
daddr_t lo[10];
- for (p = conftxt; p != NULL && *p; p = strchr(p, '\n')) {
+ /*
+ * Locate the disk (by name) in our sysctl output
+ */
+ for (p = conftxt; p != NULL && *p; p = strchr(p, '\n'), line++) {
if (*p == '\n')
p++;
a = strsep(&p, " ");
+ /* Skip anything not with index 0 */
if (strcmp(a, "0"))
continue;
+ /* Skip anything not a disk */
a = strsep(&p, " ");
if (strcmp(a, "DISK"))
continue;
@@ -79,15 +84,17 @@ Int_Open_Disk(const char *name, char *conftxt)
a = strsep(&p, " "); /* length in bytes */
len = strtoimax(a, &r, 0);
if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
+ printf("libdisk: Int_Open_Disk(%s): can't parse length in line %d (r='%s')\n",
+ name, line, r);
+ return NULL;
}
a = strsep(&p, " "); /* sectorsize */
s = strtoul(a, &r, 0);
if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
+ printf("libdisk: Int_Open_Disk(%s): can't parse sector size in line %d (r='%s')\n",
+ name, line, r);
+ return NULL;
}
if (s == 0)
@@ -99,6 +106,7 @@ Int_Open_Disk(const char *name, char *conftxt)
DPRINT(("Failed to add 'whole' chunk"));
}
+ /* Try to parse any fields after the sector size in the DISK entry line */
for (;;) {
a = strsep(&p, " ");
if (a == NULL)
@@ -106,15 +114,17 @@ Int_Open_Disk(const char *name, char *conftxt)
b = strsep(&p, " ");
o = strtoimax(b, &r, 0);
if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
+ printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
+ name, a, line, r);
+ return NULL;
}
if (!strcmp(a, "hd"))
d->bios_hd = o;
else if (!strcmp(a, "sc"))
d->bios_sect = o;
else
- printf("HUH ? <%s> <%s>\n", a, b);
+ printf("libdisk: Int_Open_Disk(%s): unknown parameter '%s' with value '%s' in line %d, ignored\n",
+ name, a, b, line);
}
/*
@@ -124,35 +134,43 @@ Int_Open_Disk(const char *name, char *conftxt)
o = d->bios_hd * d->bios_sect;
d->bios_cyl = (o != 0) ? len / o : 0;
- p = q;
+ p = q; line++; /* p is now the start of the line _after_ the DISK entry */
lo[0] = 0;
- for (; p != NULL && *p; p = q) {
+ for (; p != NULL && *p; p = q, line++) {
sn = NULL;
q = strchr(p, '\n');
if (q != NULL)
*q++ = '\0';
a = strsep(&p, " "); /* Index */
+ /*
+ * If we find index 0 again, this means we've encountered another disk, so it's safe to assume this disk
+ * has been processed.
+ */
if (!strcmp(a, "0"))
break;
l = strtoimax(a, &r, 0);
if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
+ printf("libdisk: Int_Open_Disk(%s): can't parse depth '%s' in line %d (r='%s')\n",
+ name, a, line, r);
+ return NULL;
+
}
t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */
n = strsep(&p, " "); /* name */
a = strsep(&p, " "); /* len */
len = strtoimax(a, &r, 0);
if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
+ printf("libdisk: Int_Open_Disk(%s): can't parse length '%s' in line %d (r='%s')\n",
+ name, a, line, r);
+ continue;
}
a = strsep(&p, " "); /* secsize */
s = strtoimax(a, &r, 0);
if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
+ printf("libdisk: Int_Open_Disk(%s): can't parse sector size '%s' in line %d (r='%s')\n",
+ name, a, line, r);
+ continue;
}
for (;;) {
a = strsep(&p, " ");
@@ -167,8 +185,9 @@ Int_Open_Disk(const char *name, char *conftxt)
o = strtoimax(b, &r, 0);
/* APPLE have ty as a string */
if ((*r) && (strcmp(t, "APPLE") && strcmp(t, "GPT"))) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
+ printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
+ name, a, line, r);
+ break;
}
if (!strcmp(a, "o"))
off = o;
OpenPOWER on IntegriCloud