* 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.
--- /dev/null
+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.
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
/*
* 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
#endif
+
+char *make_system_path_relative_to_its_root (const char *path);
+
#endif /* ! GRUB_UTIL_MISC_HEADER */
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 ()
{
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*)
--- /dev/null
+/* 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;
+}
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);
/* 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);
if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size))
grub_util_error ("files differ");
}
-#endif
printf ("%s\n", fs->name);
}
#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>
}
#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;
+}