31004e6
From 5605655af5a8fbb1d26ad567082c00606b425ae4 Mon Sep 17 00:00:00 2001
31004e6
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
31004e6
Date: Mon, 29 Apr 2013 11:59:18 +0200
f74b50e
Subject: [PATCH 384/482] 	* grub-core/kern/mips/arc/init.c: Fix prefix
31004e6
 detection.
31004e6
31004e6
---
31004e6
 ChangeLog                      |  4 +++
31004e6
 grub-core/kern/mips/arc/init.c | 64 ++++++++++++++++++++++++++++++++++++++----
31004e6
 2 files changed, 62 insertions(+), 6 deletions(-)
31004e6
31004e6
diff --git a/ChangeLog b/ChangeLog
31004e6
index 41a941c..f444ea9 100644
31004e6
--- a/ChangeLog
31004e6
+++ b/ChangeLog
31004e6
@@ -1,5 +1,9 @@
31004e6
 2013-04-29  Vladimir Serbinenko  <phcoder@gmail.com>
31004e6
 
31004e6
+	* grub-core/kern/mips/arc/init.c: Fix prefix detection.
31004e6
+
31004e6
+2013-04-29  Vladimir Serbinenko  <phcoder@gmail.com>
31004e6
+
31004e6
 	* grub-core/lib/arg.c (grub_arg_show_help): Fix a NULL pointer
31004e6
 	dereference.
31004e6
 	Reported by: qwertial.
31004e6
diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c
31004e6
index d279ada..fdcc2bd 100644
31004e6
--- a/grub-core/kern/mips/arc/init.c
31004e6
+++ b/grub-core/kern/mips/arc/init.c
31004e6
@@ -179,19 +179,26 @@ norm_name_to_alt (const char *name)
31004e6
   optr = grub_stpcpy (ret, "arc/");
31004e6
   for (iptr = name; *iptr; iptr++)
31004e6
     {
31004e6
-      if (state == 1)
31004e6
+      if (state == 3)
31004e6
 	{
31004e6
 	  *optr++ = '/';
31004e6
 	  state = 0;
31004e6
 	}
31004e6
       if (*iptr == '(')
31004e6
-	continue;
31004e6
-      if (*iptr == ')')
31004e6
 	{
31004e6
 	  state = 1;
31004e6
 	  continue;
31004e6
 	}
31004e6
+      if (*iptr == ')')
31004e6
+	{
31004e6
+	  if (state == 1)
31004e6
+	    *optr++ = '0';
31004e6
+	  state = 3;
31004e6
+	  continue;
31004e6
+	}
31004e6
       *optr++ = *iptr;
31004e6
+      if (state == 1)
31004e6
+	state = 2;
31004e6
     }
31004e6
   *optr = '\0';
31004e6
   return ret;
31004e6
@@ -353,13 +360,48 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
31004e6
   grub_disk_addr_t poff = -1, pend;
31004e6
   struct get_device_name_ctx ctx;
31004e6
   grub_disk_t parent = 0;
31004e6
-
31004e6
-  pptr = grub_strchr (loaddev, '/');
31004e6
-  if (pptr)
31004e6
+  unsigned i;
31004e6
+
31004e6
+  for (i = 0; i < ARRAY_SIZE (type_names); i++)
31004e6
+    if (type_names[i]
31004e6
+	&& grub_memcmp (loaddev, type_names[i], grub_strlen (type_names[i])) == 0
31004e6
+	&& loaddev[grub_strlen (type_names[i])] == '(')
31004e6
+      break;
31004e6
+  if (i == ARRAY_SIZE (type_names))
31004e6
+    pptr = loaddev;
31004e6
+  else
31004e6
+    for (pptr = loaddev; *pptr && *pptr != '/' && *pptr != '\\'; pptr++);
31004e6
+  if (*pptr)
31004e6
     {
31004e6
+      char *iptr, *optr;
31004e6
+      char sep = *pptr;
31004e6
+      *path = grub_malloc (grub_strlen (pptr) + 1);
31004e6
+      if (!*path)
31004e6
+	return;
31004e6
+      for (iptr = pptr, optr = *path; *iptr; iptr++, optr++)
31004e6
+	if (*iptr == sep)
31004e6
+	  *optr = '/';
31004e6
+	else
31004e6
+	  *optr = *iptr;
31004e6
+      *optr = '\0';
31004e6
       *path = grub_strdup (pptr);
31004e6
       *pptr = '\0';
31004e6
     }
31004e6
+
31004e6
+  if (*loaddev == '\0')
31004e6
+    {
31004e6
+      const char *syspart = 0;
31004e6
+
31004e6
+      if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length
31004e6
+	  >= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
31004e6
+	      - (char *) GRUB_ARC_FIRMWARE_VECTOR)
31004e6
+	  && GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable)
31004e6
+	syspart = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("SystemPartition");
31004e6
+      if (!syspart)
31004e6
+	return;
31004e6
+      loaddev = grub_strdup (syspart);
31004e6
+    }
31004e6
+
31004e6
   partptr = get_part (loaddev);
31004e6
   if (partptr)
31004e6
     {
31004e6
@@ -370,6 +412,8 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
31004e6
   if (poff == (grub_addr_t) -1)
31004e6
     {
31004e6
       *device = dname;
31004e6
+      if (loaddev != boot_location)
31004e6
+	grub_free (loaddev);
31004e6
       return;
31004e6
     }
31004e6
 
31004e6
@@ -377,6 +421,8 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
31004e6
   if (!parent)
31004e6
     {
31004e6
       *device = dname;
31004e6
+      if (loaddev != boot_location)
31004e6
+	grub_free (loaddev);
31004e6
       return;
31004e6
     }
31004e6
 
31004e6
@@ -385,6 +431,8 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
31004e6
     {
31004e6
       grub_disk_close (parent);
31004e6
       *device = dname;
31004e6
+      if (loaddev != boot_location)
31004e6
+	grub_free (loaddev);
31004e6
       return;
31004e6
     }
31004e6
 
31004e6
@@ -398,6 +446,8 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
31004e6
   if (! ctx.partition_name)
31004e6
     {
31004e6
       *device = dname;
31004e6
+      if (loaddev != boot_location)
31004e6
+	grub_free (loaddev);
31004e6
       return;
31004e6
     }
31004e6
 
31004e6
@@ -405,4 +455,6 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
31004e6
 			    ctx.partition_name);
31004e6
   grub_free (ctx.partition_name);
31004e6
   grub_free (dname);
31004e6
+  if (loaddev != boot_location)
31004e6
+    grub_free (loaddev);
31004e6
 }
31004e6
-- 
31004e6
1.8.2.1
31004e6