#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)
while (1)
{
char *buf = grub_file_getline (file);
- char *parsed;
+ char *parsed = NULL;
if (!buf && grub_errno)
{
oldname = entryname;
parsed = grub_legacy_parse (buf, &entryname, &is_suffix);
- grub_free (buf);
+ buf = NULL;
if (is_suffix)
{
char *t;
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;
args[0] = oldname;
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
entrysrc);
+ grub_free (args);
+ entrysrc[0] = 0;
+ grub_free (oldname);
}
}
grub_normal_parse_line (parsed, getline);
grub_print_error ();
grub_free (parsed);
+ parsed = NULL;
}
else if (parsed)
{
}
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);
struct grub_command *cmd;
char **cutargs;
int cutargc;
+
for (i = 0; i < 2; i++)
{
/* FIXME: really support this. */
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))
+ 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))
{
- kernel_type = KFREEBSD;
- return GRUB_ERR_NONE;
+ 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))
+ bsdargs = cutargs;
+ bsdargc = cutargc;
+ }
+ else
+ {
+ 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');
+ }
+ if (kernel_type == GUESS_IT || kernel_type == KNETBSD)
+ {
+ cmd = grub_command_find ("knetbsd");
+ if (cmd)
{
- kernel_type = KNETBSD;
- return GRUB_ERR_NONE;
+ if (!(cmd->func) (cmd, bsdargc, bsdargs))
+ {
+ kernel_type = KNETBSD;
+ return GRUB_ERR_NONE;
+ }
}
+ grub_errno = GRUB_ERR_NONE;
}
- grub_errno = GRUB_ERR_NONE;
- }
- if (kernel_type == GUESS_IT || kernel_type == KOPENBSD)
- {
- cmd = grub_command_find ("kopenbsd");
- if (cmd)
+ if (kernel_type == GUESS_IT || kernel_type == KOPENBSD)
{
- if (!(cmd->func) (cmd, cutargc, cutargs))
+ cmd = grub_command_find ("kopenbsd");
+ if (cmd)
{
- kernel_type = KOPENBSD;
- return GRUB_ERR_NONE;
+ if (!(cmd->func) (cmd, bsdargc, bsdargs))
+ {
+ kernel_type = KOPENBSD;
+ return GRUB_ERR_NONE;
+ }
}
+ grub_errno = GRUB_ERR_NONE;
}
- grub_errno = GRUB_ERR_NONE;
+ if (bsdargs != cutargs)
+ grub_free (bsdargs);
}
+ }
}
while (0);
{"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"
" 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"
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;
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++);
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)
args[j++] = grub_strndup (curarg, curarglen);
break;
}
- args[j++] = "";
+ args[j++] = grub_strdup ("");
hold_arg = 1;
break;
case TYPE_INT:
}
}
}
-
- 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;
+ }
}