]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2009-11-04 Felix Zielcke <fzielcke@z-51.de>
authorFelix Zielcke <fzielcke@z-51.de>
Sun, 8 Nov 2009 00:49:15 +0000 (01:49 +0100)
committerFelix Zielcke <fzielcke@z-51.de>
Sun, 8 Nov 2009 00:49:15 +0000 (01:49 +0100)
* util//grub-mkconfig_lib.in (bindir): New variable.
(grub_mkrelpath): Likewise.
Properly set path variable.  Use ${grub_mkrelpath} instead of
calling it directly.

2009-11-02  Felix Zielcke  <fzielcke@z-51.de>

* util/probe.c (probe): Make the file path relative to its root.
Change a info message to use the GRUB path.  Enable again the
check if we can read the file with GRUB facilities.

2009-11-01  Felix Zielcke  <fzielcke@z-51.de>

* util/grub-mkrelpath.c: New file.
* conf/common.rmk (bin_UTILITIES): Add grub-mkrelpath.
(grub_mkrelpath_SOURCES): New variable.
* include/grub/util/misc.h: New function prototype.
* util/misc.c (make_system_path_relative_to_its_root): New function.

* util/grub-mkconfig_lib.in (make_system_path_relative_to_its_root):
Use grub-mkrelpath.

ChangeLog.mkrelpath [new file with mode: 0644]
conf/common.rmk
include/grub/util/misc.h
util/grub-mkconfig_lib.in
util/grub-mkrelpath.c [new file with mode: 0644]
util/grub-probe.c
util/misc.c

diff --git a/ChangeLog.mkrelpath b/ChangeLog.mkrelpath
new file mode 100644 (file)
index 0000000..e210397
--- /dev/null
@@ -0,0 +1,23 @@
+2009-11-04  Felix Zielcke  <fzielcke@z-51.de>
+
+       * util//grub-mkconfig_lib.in (bindir): New variable.
+       (grub_mkrelpath): Likewise.
+       Properly set path variable.  Use ${grub_mkrelpath} instead of
+       calling it directly.
+
+2009-11-02  Felix Zielcke  <fzielcke@z-51.de>
+
+       * util/probe.c (probe): Make the file path relative to its root.
+       Change a info message to use the GRUB path.  Enable again the
+       check if we can read the file with GRUB facilities.
+
+2009-11-01  Felix Zielcke  <fzielcke@z-51.de>
+
+       * util/grub-mkrelpath.c: New file.
+       * conf/common.rmk (bin_UTILITIES): Add grub-mkrelpath.
+       (grub_mkrelpath_SOURCES): New variable.
+       * include/grub/util/misc.h: New function prototype.
+       * util/misc.c (make_system_path_relative_to_its_root): New function.
+
+       * util/grub-mkconfig_lib.in (make_system_path_relative_to_its_root):
+       Use grub-mkrelpath.
index c1f0bbdcf6a83d4082626da3b6e43b53517edcc2..175611f6207c84770d9e916c8c9439b13e52c2ed 100644 (file)
@@ -57,6 +57,10 @@ grub_mkfont_CFLAGS = $(freetype_cflags)
 grub_mkfont_LDFLAGS = $(freetype_libs)
 endif
 
+# For grub-mkrelpath.
+bin_UTILITIES += grub-mkrelpath
+grub_mkrelpath_SOURCES = util/grub-mkrelpath.c util/misc.c
+
 # For the parser.
 grub_script.tab.c grub_script.tab.h: script/sh/parser.y
        $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/sh/parser.y
index 6a93ab0442bc41971f3ad47af911beb24c7a9a89..d0184d4169595f7d4acf942be77eb56e41e99b65 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
  *
  *  GRUB is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -76,4 +76,7 @@ grub_int64_t grub_util_get_disk_size (char *name);
 
 #endif
 
+
+char *make_system_path_relative_to_its_root (const char *path);
+
 #endif /* ! GRUB_UTIL_MISC_HEADER */
index bb30cc4756ccb9bc192275b5623eab3a1f8ec9a8..5b5dfd42a2628c6fcc02da3a727cad33d5c54a2c 100644 (file)
@@ -20,10 +20,12 @@ prefix=@prefix@
 exec_prefix=@exec_prefix@
 datarootdir=@datarootdir@
 datadir=@datadir@
+bindir=@bindir@
 sbindir=@sbindir@
 pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
 
 grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}`
 
 grub_warn ()
 {
@@ -32,49 +34,7 @@ grub_warn ()
 
 make_system_path_relative_to_its_root ()
 {
-  path=$1
-  # abort if file doesn't exist
-  if test -e $path ; then : ;else
-    return 1
-  fi
-
-  # canonicalize
-  if path=`readlink -f $path` ; then : ; else
-    return 1
-  fi
-
-  # if not a directory, climb up to the directory containing it
-  if test -d $path ; then
-    dir=$path
-  else
-    dir=`echo $path | sed -e "s,/[^/]*$,,g"`
-  fi
-
-  num=`stat -c %d $dir`
-
-  # this loop sets $dir to the root directory of the filesystem we're inspecting
-  while : ; do
-    parent=`readlink -f $dir/..`
-    if [ "x`stat -c %d $parent`" = "x$num" ] ; then : ; else
-      # $parent is another filesystem; we found it.
-      break
-    fi
-    if [ "x$dir" = "x/" ] ; then
-      # / is our root.
-      break
-    fi
-    dir=$parent
-  done
-
-  # This function never prints trailing slashes (so that its output can be
-  # appended a slash unconditionally).  Each slash in $dir is considered a
-  # preceding slash, and therefore the root directory is an empty string.
-  if [ "$dir" = "/" ] ; then
-    dir=""
-  fi
-
-  # XXX: This fails if $dir contains ','.
-  path=`echo "$path" | sed -e "s,^$dir,,g"` || return 1
+  path="`${grub_mkrelpath} $1`"
 
   case "`uname 2>/dev/null`" in
     CYGWIN*)
diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c
new file mode 100644 (file)
index 0000000..3deb4c4
--- /dev/null
@@ -0,0 +1,99 @@
+/* grub-mkrelpath.c - make a system path relative to its root */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/util/misc.h>
+#include <getopt.h>
+
+static struct option options[] =
+  {
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-mkrelpath --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-mkrelpath [OPTIONS] PATH\n\
+\n\
+Make a system path relative to it's root.\n\
+\n\
+Options:\n\
+  -h, --help                display this message and exit\n\
+  -V, --version             print version information and exit\n\
+\n\
+Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *argument, *relpath;
+
+  progname = "grub-mkrelpath";
+
+  /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "hV", options, 0);
+
+      if (c == -1)
+       break;
+      else
+       switch (c)
+         {
+         case 'h':
+           usage (0);
+           break;
+
+         case 'V':
+           printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+           return 0;
+
+         default:
+           usage (1);
+           break;
+         }
+    }
+
+  if (optind >= argc)
+    {
+      fprintf (stderr, "No path is specified.\n");
+      usage (1);
+    }
+
+  if (optind + 1 != argc)
+    {
+      fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]);
+      usage (1);
+    }
+
+  argument = argv[optind];
+
+  relpath = make_system_path_relative_to_its_root (argument);
+  printf ("%s\n", relpath);
+  free (relpath);
+
+  return 0;
+}
index 4e3f96451222cf955afad6c76a8ed90ee2af73ff..051a38c72d42ef175f6fd6000959dcbbad772068 100644 (file)
@@ -235,9 +235,6 @@ probe (const char *path, char *device_name)
 
   if (print == PRINT_FS)
     {
-      /* FIXME: `path' can't be used to read a file via GRUB facilities,
-         because it's not relative to its root.  */
-#if 0
       struct stat st;
 
       stat (path, &st);
@@ -247,11 +244,14 @@ probe (const char *path, char *device_name)
          /* Regular file.  Verify that we can read it properly.  */
 
          grub_file_t file;
+         char *rel_path;
          grub_util_info ("reading %s via OS facilities", path);
          filebuf_via_sys = grub_util_read_image (path);
 
-         grub_util_info ("reading %s via GRUB facilities", path);
-         asprintf (&grub_path, "(%s)%s", drive_name, path);
+         rel_path = make_system_path_relative_to_its_root (path);
+         asprintf (&grub_path, "(%s)%s", drive_name, rel_path);
+         free (rel_path);
+         grub_util_info ("reading %s via GRUB facilities", grub_path);
          file = grub_file_open (grub_path);
          filebuf_via_grub = xmalloc (file->size);
          grub_file_read (file, filebuf_via_grub, file->size);
@@ -261,7 +261,6 @@ probe (const char *path, char *device_name)
          if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size))
            grub_util_error ("files differ");
        }
-#endif
 
       printf ("%s\n", fs->name);
     }
index 37e75311e54e7c44b604a09294b7e23c48b9702f..e4d68e33fe098b5901b4d7688c50ce49743fa098 100644 (file)
 
 #include <config.h>
 
+#include <errno.h>
 #include <setjmp.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -449,3 +451,82 @@ fail:
 }
 
 #endif /* __MINGW32__ */
+
+/* This function never prints trailing slashes (so that its output
+   can be appended a slash unconditionally).  */
+char *
+make_system_path_relative_to_its_root (const char *path)
+{
+  struct stat st;
+  char *p, *buf, *buf2, *buf3;
+  uintptr_t offset = 0;
+  dev_t num;
+  size_t len;
+
+  /* canonicalize.  */
+  p = realpath (path, NULL);
+
+  if (p == NULL)
+    {
+      if (errno != EINVAL)
+       grub_util_error ("failed to get realpath of %s", path);
+      else
+       grub_util_error ("realpath not supporting (path, NULL)");
+    }
+  len = strlen (p) + 1;
+  buf = strdup (p);
+  free (p);
+
+  if (stat (buf, &st) < 0)
+    grub_util_error ("can not stat %s: %s", buf, strerror (errno));
+
+  buf2 = strdup (buf);
+  num = st.st_dev;
+
+  /* This loop sets offset to the number of chars of the root
+     directory we're inspecting.  */
+  while (1)
+    {
+      p = strrchr (buf, '/');
+      if (p == NULL)
+       /* This should never happen.  */
+       grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)");
+      if (p != buf)
+       *p = 0;
+      else
+       *++p = 0;
+
+      if (stat (buf, &st) < 0)
+       grub_util_error ("can not stat %s: %s", buf, strerror (errno));
+
+      /* buf is another filesystem; we found it.  */
+      if (st.st_dev != num)
+       break;
+
+      offset = p - buf;
+      /* offset == 1 means root directory.  */
+      if (offset == 1)
+       {
+         free (buf);
+         len = strlen (buf2);
+         while (buf2[len - 1] == '/' && len > 1)
+           {
+             buf2[len - 1] = '\0';
+             len--;
+           }
+         return buf2;
+       }
+    }
+  free (buf);
+  buf3 = strdup (buf2 + offset);
+  free (buf2);
+
+  len = strlen (buf3);
+  while (buf2[len - 1] == '/' && len > 1)
+    {
+      buf2[len - 1] = '\0';
+      len--;
+    }
+
+  return buf3;
+}