Fix bunch of memory problems and implement hdbias
This commit is contained in:
parent
abda0cade5
commit
64ad6157ae
3 changed files with 153 additions and 44 deletions
|
@ -30,6 +30,8 @@
|
|||
#include <grub/legacy_parse.h>
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/auth.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
|
||||
static grub_err_t
|
||||
legacy_file (const char *filename)
|
||||
|
@ -67,7 +69,7 @@ legacy_file (const char *filename)
|
|||
while (1)
|
||||
{
|
||||
char *buf = grub_file_getline (file);
|
||||
char *parsed;
|
||||
char *parsed = NULL;
|
||||
|
||||
if (!buf && grub_errno)
|
||||
{
|
||||
|
@ -84,7 +86,7 @@ legacy_file (const char *filename)
|
|||
|
||||
oldname = entryname;
|
||||
parsed = grub_legacy_parse (buf, &entryname, &is_suffix);
|
||||
grub_free (buf);
|
||||
buf = NULL;
|
||||
if (is_suffix)
|
||||
{
|
||||
char *t;
|
||||
|
@ -100,7 +102,7 @@ legacy_file (const char *filename)
|
|||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed,
|
||||
grub_memcpy (suffix + grub_strlen (suffix), parsed,
|
||||
grub_strlen (parsed) + 1);
|
||||
grub_free (parsed);
|
||||
parsed = NULL;
|
||||
|
@ -117,6 +119,9 @@ legacy_file (const char *filename)
|
|||
args[0] = oldname;
|
||||
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
|
||||
entrysrc);
|
||||
grub_free (args);
|
||||
entrysrc[0] = 0;
|
||||
grub_free (oldname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,6 +130,7 @@ legacy_file (const char *filename)
|
|||
grub_normal_parse_line (parsed, getline);
|
||||
grub_print_error ();
|
||||
grub_free (parsed);
|
||||
parsed = NULL;
|
||||
}
|
||||
else if (parsed)
|
||||
{
|
||||
|
@ -163,11 +169,13 @@ legacy_file (const char *filename)
|
|||
}
|
||||
args[0] = entryname;
|
||||
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc);
|
||||
grub_free (args);
|
||||
}
|
||||
|
||||
grub_normal_parse_line (suffix, getline);
|
||||
grub_print_error ();
|
||||
grub_free (suffix);
|
||||
grub_free (entrysrc);
|
||||
|
||||
if (menu && menu->size)
|
||||
grub_show_menu (menu, 1);
|
||||
|
@ -215,6 +223,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
|||
struct grub_command *cmd;
|
||||
char **cutargs;
|
||||
int cutargc;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
/* FIXME: really support this. */
|
||||
|
@ -309,46 +318,118 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
|||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* k*BSD didn't really work well with grub-legacy. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == KFREEBSD)
|
||||
{
|
||||
int bsd_device = -1;
|
||||
int bsd_slice = -1;
|
||||
int bsd_part = -1;
|
||||
{
|
||||
cmd = grub_command_find ("kfreebsd");
|
||||
if (cmd)
|
||||
grub_device_t dev;
|
||||
char *hdbiasstr;
|
||||
int hdbias = 0;
|
||||
hdbiasstr = grub_env_get ("legacy_hdbias");
|
||||
if (hdbiasstr)
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = KFREEBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
hdbias = grub_strtoul (hdbiasstr, 0, 0);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
dev = grub_device_open (0);
|
||||
if (dev && dev->disk
|
||||
&& dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID
|
||||
&& dev->disk->dev->id >= 0x80 && dev->disk->dev->id <= 0x90)
|
||||
{
|
||||
struct grub_partition *part = dev->disk->partition;
|
||||
bsd_device = dev->disk->id - 0x80 - hdbias;
|
||||
if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0
|
||||
|| grub_strcmp (part->partmap->name, "openbsd") == 0
|
||||
|| grub_strcmp (part->partmap->name, "bsd") == 0))
|
||||
{
|
||||
bsd_part = part->number;
|
||||
part = part->parent;
|
||||
}
|
||||
if (part && grub_strcmp (part->partmap->name, "msdos") == 0)
|
||||
bsd_slice = part->number;
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (kernel_type == GUESS_IT || kernel_type == KNETBSD)
|
||||
|
||||
/* k*BSD didn't really work well with grub-legacy. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == KFREEBSD)
|
||||
{
|
||||
char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")];
|
||||
if (bsd_device != -1)
|
||||
{
|
||||
if (bsd_slice != -1 && bsd_part != -1)
|
||||
grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device,
|
||||
bsd_slice, 'a' + bsd_part);
|
||||
else if (bsd_slice != -1)
|
||||
grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device,
|
||||
bsd_slice);
|
||||
else
|
||||
grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device);
|
||||
grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf);
|
||||
}
|
||||
else
|
||||
grub_env_unset ("kFreeBSD.vfs.root.mountfrom");
|
||||
cmd = grub_command_find ("kfreebsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = KFREEBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
{
|
||||
cmd = grub_command_find ("knetbsd");
|
||||
if (cmd)
|
||||
char **bsdargs;
|
||||
int bsdargc;
|
||||
char bsddevname[sizeof ("wdXXXXXXXXXXXXY")];
|
||||
if (bsd_device == -1)
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = KNETBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
bsdargs = cutargs;
|
||||
bsdargc = cutargc;
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (kernel_type == GUESS_IT || kernel_type == KOPENBSD)
|
||||
{
|
||||
cmd = grub_command_find ("kopenbsd");
|
||||
if (cmd)
|
||||
else
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = KOPENBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
bsdargc = cutargc + 2;
|
||||
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
|
||||
grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0]));
|
||||
bsdargs[argc] = "-r";
|
||||
bsdargs[argc + 1] = bsddevname;
|
||||
grub_snprintf (bsddevname, sizeof (bsddevname),
|
||||
"wd%d%c", bsd_device,
|
||||
bsd_part != -1 ? bsd_part + 'a' : 'c');
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
if (kernel_type == GUESS_IT || kernel_type == KNETBSD)
|
||||
{
|
||||
cmd = grub_command_find ("knetbsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KNETBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (kernel_type == GUESS_IT || kernel_type == KOPENBSD)
|
||||
{
|
||||
cmd = grub_command_find ("kopenbsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KOPENBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (bsdargs != cutargs)
|
||||
grub_free (bsdargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (0);
|
||||
|
||||
|
|
|
@ -195,7 +195,9 @@ struct legacy_command legacy_commands[] =
|
|||
{"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."},
|
||||
/* FIXME: Support HDBIAS. */
|
||||
/* FIXME: Support printing. */
|
||||
{"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, "[DEVICE [HDBIAS]]",
|
||||
{"root", "set root='%s'; set legacy_hdbias='%s'\n",
|
||||
2, {TYPE_PARTITION, TYPE_INT}, 0,
|
||||
"[DEVICE [HDBIAS]]",
|
||||
"Set the current \"root device\" to the device DEVICE, then"
|
||||
" attempt to mount it to get the partition size (for passing the"
|
||||
" partition descriptor in `ES:ESI', used by some chain-loaded"
|
||||
|
@ -206,7 +208,8 @@ struct legacy_command legacy_commands[] =
|
|||
" how many BIOS drive numbers are on controllers before the current"
|
||||
" one. For example, if there is an IDE disk and a SCSI disk, and your"
|
||||
" FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."},
|
||||
{"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0,
|
||||
{"rootnoverify", "set root='%s'; set legacy_hdbias='%s'\n",
|
||||
2, {TYPE_PARTITION, TYPE_INT}, 0,
|
||||
"[DEVICE [HDBIAS]]",
|
||||
"Similar to `root', but don't attempt to mount the partition. This"
|
||||
" is useful for when an OS is outside of the area of the disk that"
|
||||
|
@ -265,7 +268,7 @@ grub_legacy_escape (const char *in, grub_size_t len)
|
|||
for (ptr = in; ptr < in + len && *ptr; ptr++)
|
||||
if (*ptr == '\'' || *ptr == '\\')
|
||||
overhead++;
|
||||
ret = grub_malloc (ptr - in + overhead);
|
||||
ret = grub_malloc (ptr - in + overhead + 1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
outptr = ret;
|
||||
|
@ -371,7 +374,15 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix)
|
|||
|
||||
for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
|
||||
if (!*ptr || *ptr == '#')
|
||||
return grub_strdup (buf);
|
||||
{
|
||||
char *ret;
|
||||
int len = grub_strlen (buf);
|
||||
ret = grub_malloc (len + 2);
|
||||
grub_memcpy (ret, buf, len);
|
||||
ret[len] = '\n';
|
||||
ret[len + 1] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmdname = ptr;
|
||||
for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++);
|
||||
|
@ -412,7 +423,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix)
|
|||
unsigned j = 0;
|
||||
int hold_arg = 0;
|
||||
const char *curarg = NULL;
|
||||
for (i = 0; i < legacy_commands[cmdnum].argc; i++)
|
||||
for (i = 0; i < legacy_commands[cmdnum].argc + hold_arg; i++)
|
||||
{
|
||||
grub_size_t curarglen;
|
||||
if (hold_arg)
|
||||
|
@ -495,7 +506,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix)
|
|||
args[j++] = grub_strndup (curarg, curarglen);
|
||||
break;
|
||||
}
|
||||
args[j++] = "";
|
||||
args[j++] = grub_strdup ("");
|
||||
hold_arg = 1;
|
||||
break;
|
||||
case TYPE_INT:
|
||||
|
@ -537,6 +548,13 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix)
|
|||
}
|
||||
}
|
||||
|
||||
return grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2],
|
||||
args[3]);
|
||||
{
|
||||
char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1],
|
||||
args[2], args[3]);
|
||||
grub_free (args[0]);
|
||||
grub_free (args[1]);
|
||||
grub_free (args[2]);
|
||||
grub_free (args[3]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,12 +88,18 @@ main (int argc, char **argv)
|
|||
if (oldname != entryname && oldname)
|
||||
fprintf (out, "}\n\n");
|
||||
if (oldname != entryname)
|
||||
fprintf (out, "menuentry \'%s\' {\n",
|
||||
grub_legacy_escape (entryname, strlen (entryname)));
|
||||
{
|
||||
char *escaped = grub_legacy_escape (entryname, strlen (entryname));
|
||||
fprintf (out, "menuentry \'%s\' {\n", escaped);
|
||||
grub_free (escaped);
|
||||
grub_free (oldname);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed)
|
||||
fprintf (out, "%s%s", entryname ? " " : "", parsed);
|
||||
grub_free (parsed);
|
||||
parsed = NULL;
|
||||
}
|
||||
|
||||
if (entryname)
|
||||
|
@ -101,6 +107,10 @@ main (int argc, char **argv)
|
|||
|
||||
fwrite (out, 1, suffixlen, suffix);
|
||||
|
||||
grub_free (buf);
|
||||
grub_free (suffix);
|
||||
grub_free (entryname);
|
||||
|
||||
if (in != stdin)
|
||||
fclose (in);
|
||||
if (out != stdout)
|
||||
|
|
Loading…
Reference in a new issue