source: grub-pc/trunk/fuentes/grub-core/osdep/unix/relpath.c @ 22

Last change on this file since 22 was 22, checked in by mabarracus, 4 years ago

updated version and apply net.ifnames=0 into debian/rules

File size: 3.7 KB
Line 
1/*
2 *  GRUB  --  GRand Unified Bootloader
3 *  Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013  Free Software Foundation, Inc.
4 *
5 *  GRUB is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version.
9 *
10 *  GRUB is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <config-util.h>
20#include <config.h>
21
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <unistd.h>
25#include <stdint.h>
26#include <string.h>
27#include <errno.h>
28
29#include <grub/util/misc.h>
30#include <grub/emu/hostdisk.h>
31#include <grub/emu/getroot.h>
32#include <grub/mm.h>
33
34/* This function never prints trailing slashes (so that its output
35   can be appended a slash unconditionally).  */
36char *
37grub_make_system_path_relative_to_its_root (const char *path)
38{
39  struct stat st;
40  char *p, *buf, *buf2, *buf3, *ret;
41  uintptr_t offset = 0;
42  dev_t num;
43  size_t len;
44  char *poolfs = NULL;
45
46  /* canonicalize.  */
47  p = canonicalize_file_name (path);
48  if (p == NULL)
49    grub_util_error (_("failed to get canonical path of `%s'"), path);
50
51#ifdef __linux__
52  ret = grub_make_system_path_relative_to_its_root_os (p);
53  if (ret)
54    return ret;
55#endif
56
57  /* For ZFS sub-pool filesystems.  */
58#ifndef __HAIKU__
59  {
60    char *dummy;
61    grub_find_zpool_from_dir (p, &dummy, &poolfs);
62  }
63#endif
64
65  len = strlen (p) + 1;
66  buf = xstrdup (p);
67  free (p);
68
69  if (stat (buf, &st) < 0)
70    grub_util_error (_("cannot stat `%s': %s"), buf, strerror (errno));
71
72  buf2 = xstrdup (buf);
73  num = st.st_dev;
74
75  /* This loop sets offset to the number of chars of the root
76     directory we're inspecting.  */
77  while (1)
78    {
79      p = strrchr (buf, '/');
80      if (p == NULL)
81        /* This should never happen.  */
82        grub_util_error ("%s",
83                         /* TRANSLATORS: canonical pathname is the
84                            complete one e.g. /etc/fstab. It has
85                            to contain `/' normally, if it doesn't
86                            we're in trouble and throw this error.  */
87                         _("no `/' in canonical filename"));
88      if (p != buf)
89        *p = 0;
90      else
91        *++p = 0;
92
93      if (stat (buf, &st) < 0)
94        grub_util_error (_("cannot stat `%s': %s"), buf, strerror (errno));
95
96      /* buf is another filesystem; we found it.  */
97      if (st.st_dev != num)
98        {
99          /* offset == 0 means path given is the mount point.
100             This works around special-casing of "/" in Un*x.  This function never
101             prints trailing slashes (so that its output can be appended a slash
102             unconditionally).  Each slash in is considered a preceding slash, and
103             therefore the root directory is an empty string.  */
104          if (offset == 0)
105            {
106              free (buf);
107              free (buf2);
108              if (poolfs)
109                return xasprintf ("/%s/@", poolfs);
110              return xstrdup ("");
111            }
112          else
113            break;
114        }
115
116      offset = p - buf;
117      /* offset == 1 means root directory.  */
118      if (offset == 1)
119        {
120          /* Include leading slash.  */
121          offset = 0;
122          break;
123        }
124    }
125  free (buf);
126  buf3 = xstrdup (buf2 + offset);
127  buf2[offset] = 0;
128 
129  free (buf2);
130
131  /* Remove trailing slashes, return empty string if root directory.  */
132  len = strlen (buf3);
133  while (len > 0 && buf3[len - 1] == '/')
134    {
135      buf3[len - 1] = '\0';
136      len--;
137    }
138
139  if (poolfs)
140    {
141      ret = xasprintf ("/%s/@%s", poolfs, buf3);
142      free (buf3);
143    }
144  else
145    ret = buf3;
146
147  return ret;
148}
Note: See TracBrowser for help on using the repository browser.