~ubuntu-branches/ubuntu/wily/man-db/wily-proposed

« back to all changes in this revision

Viewing changes to gnulib/lib/canonicalize.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2013-06-24 11:34:02 UTC
  • mfrom: (1.2.13)
  • Revision ID: package-import@ubuntu.com-20130624113402-6xdn53l2p9qu8yus
Tags: 2.6.4-1
* New upstream release:
  - Document default section list in manual pages (closes: #611007).
  - Quieten most warnings from compiling Gnulib (closes: #668429).
  - The MANLESS environment variable is now treated as if it were a
    default value for the -r option to man: occurrences of the text
    "$MAN_PN" are expanded, and explicitly using the -r option overrides
    the default (closes: #690831).
* Use 'set -e' rather than '#! /bin/sh -e' in maintainer scripts.
* Remove maintainer script support for direct upgrades from pre-etch
  (three releases before current stable).
* Breaks/Replaces manpages-zh (<< 1.5.2-1.1); man-db now ships zh_CN
  translations formerly included there.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Return the canonical absolute name of a given file.
2
 
   Copyright (C) 1996-2012 Free Software Foundation, Inc.
 
2
   Copyright (C) 1996-2013 Free Software Foundation, Inc.
3
3
 
4
4
   This program is free software: you can redistribute it and/or modify
5
5
   it under the terms of the GNU General Public License as published by
30
30
#include "pathmax.h"
31
31
#include "xalloc.h"
32
32
#include "xgetcwd.h"
 
33
#include "dosname.h"
33
34
 
34
35
#define MULTIPLE_BITS_SET(i) (((i) & ((i) - 1)) != 0)
35
36
 
43
44
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
44
45
#endif
45
46
 
 
47
#if ISSLASH ('\\')
 
48
# define SLASHES "/\\"
 
49
#else
 
50
# define SLASHES "/"
 
51
#endif
 
52
 
46
53
#if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS)      \
47
54
      || GNULIB_CANONICALIZE_LGPL)
48
55
/* Return the canonical absolute name of file NAME.  A canonical name
99
106
  Hash_table *ht = NULL;
100
107
  int saved_errno;
101
108
  int can_flags = can_mode & ~CAN_MODE_MASK;
 
109
  bool logical = can_flags & CAN_NOLINKS;
 
110
  size_t prefix_len;
 
111
 
102
112
  can_mode &= CAN_MODE_MASK;
103
 
  bool logical = can_flags & CAN_NOLINKS;
104
 
  /* Perhaps in future we might support CAN_NOALLOC with CAN_NOLINKS.  */
105
113
 
106
114
  if (MULTIPLE_BITS_SET (can_mode))
107
115
    {
121
129
      return NULL;
122
130
    }
123
131
 
124
 
  if (name[0] != '/')
 
132
  /* This is always zero for Posix hosts, but can be 2 for MS-Windows
 
133
     and MS-DOS X:/foo/bar file names.  */
 
134
  prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
 
135
 
 
136
  if (!IS_ABSOLUTE_FILE_NAME (name))
125
137
    {
126
138
      rname = xgetcwd ();
127
139
      if (!rname)
138
150
        {
139
151
          rname_limit = dest;
140
152
        }
 
153
      start = name;
 
154
      prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
141
155
    }
142
156
  else
143
157
    {
144
158
      rname = xmalloc (PATH_MAX);
145
159
      rname_limit = rname + PATH_MAX;
146
 
      rname[0] = '/';
147
 
      dest = rname + 1;
 
160
      dest = rname;
 
161
      if (prefix_len)
 
162
        {
 
163
          memcpy (rname, name, prefix_len);
 
164
          dest += prefix_len;
 
165
        }
 
166
      *dest++ = '/';
148
167
      if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
149
168
        {
150
 
          if (name[1] == '/' && name[2] != '/')
 
169
          if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
151
170
            *dest++ = '/';
152
171
          *dest = '\0';
153
172
        }
 
173
      start = name + prefix_len;
154
174
    }
155
175
 
156
 
  for (start = name; *start; start = end)
 
176
  for ( ; *start; start = end)
157
177
    {
158
178
      /* Skip sequence of multiple file name separators.  */
159
 
      while (*start == '/')
 
179
      while (ISSLASH (*start))
160
180
        ++start;
161
181
 
162
182
      /* Find end of component.  */
163
 
      for (end = start; *end && *end != '/'; ++end)
 
183
      for (end = start; *end && !ISSLASH (*end); ++end)
164
184
        /* Nothing.  */;
165
185
 
166
186
      if (end - start == 0)
170
190
      else if (end - start == 2 && start[0] == '.' && start[1] == '.')
171
191
        {
172
192
          /* Back up to previous component, ignore if at root already.  */
173
 
          if (dest > rname + 1)
174
 
            while ((--dest)[-1] != '/');
 
193
          if (dest > rname + prefix_len + 1)
 
194
            for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
 
195
              continue;
175
196
          if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
176
 
              && *dest == '/' && dest[1] != '/')
 
197
              && !prefix_len && ISSLASH (*dest) && !ISSLASH (dest[1]))
177
198
            dest++;
178
199
        }
179
200
      else
180
201
        {
181
202
          struct stat st;
182
203
 
183
 
          if (dest[-1] != '/')
 
204
          if (!ISSLASH (dest[-1]))
184
205
            *dest++ = '/';
185
206
 
186
207
          if (dest + (end - start) >= rname_limit)
216
237
                goto error;
217
238
              if (can_mode == CAN_ALL_BUT_LAST)
218
239
                {
219
 
                  if (end[strspn (end, "/")] || saved_errno != ENOENT)
 
240
                  if (end[strspn (end, SLASHES)] || saved_errno != ENOENT)
220
241
                    goto error;
221
242
                  continue;
222
243
                }
268
289
              memmove (&extra_buf[n], end, len + 1);
269
290
              name = end = memcpy (extra_buf, buf, n);
270
291
 
271
 
              if (buf[0] == '/')
 
292
              if (IS_ABSOLUTE_FILE_NAME (buf))
272
293
                {
273
 
                  dest = rname + 1;     /* It's an absolute symlink */
 
294
                  size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
 
295
 
 
296
                  if (pfxlen)
 
297
                    memcpy (rname, buf, pfxlen);
 
298
                  dest = rname + pfxlen;
 
299
                  *dest++ = '/'; /* It's an absolute symlink */
274
300
                  if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
275
301
                    {
276
 
                      if (buf[1] == '/' && buf[2] != '/')
 
302
                      if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
277
303
                        *dest++ = '/';
278
304
                      *dest = '\0';
279
305
                    }
 
306
                  /* Install the new prefix to be in effect hereafter.  */
 
307
                  prefix_len = pfxlen;
280
308
                }
281
309
              else
282
310
                {
283
311
                  /* Back up to previous component, ignore if at root
284
312
                     already: */
285
 
                  if (dest > rname + 1)
286
 
                    while ((--dest)[-1] != '/');
 
313
                  if (dest > rname + prefix_len + 1)
 
314
                    for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
 
315
                      continue;
287
316
                  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
288
 
                      && *dest == '/' && dest[1] != '/')
 
317
                      && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
289
318
                    dest++;
290
319
                }
291
320
 
301
330
            }
302
331
        }
303
332
    }
304
 
  if (dest > rname + 1 && dest[-1] == '/')
 
333
  if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1]))
305
334
    --dest;
306
 
  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
307
 
      && *dest == '/' && dest[1] != '/')
 
335
  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len
 
336
      && ISSLASH (*dest) && !ISSLASH (dest[1]))
308
337
    dest++;
309
338
  *dest = '\0';
310
339
  if (rname_limit != dest + 1)