rpm  5.2.1
About: RPM is a powerful and mature command-line driven package management system capable of installing, uninstalling, verifying, querying, and updating Unix software packages ("no longer Linux-centric"). Hint: The RPM homepage may offer newer releases (but in rpm format).
  Fossies Dox: rpm-5.2.1.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

realpath.c
Go to the documentation of this file.
1 /*
2  * realpath.c -- canonicalize pathname by removing symlinks
3  * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Library Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This program 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 Library Public License for more details.
14  */
15 
16 #include "system.h"
17 
18 #ifndef STDC_HEADERS
19 extern int errno;
20 #endif
21 
22 #ifndef PATH_MAX
23 #ifdef _POSIX_VERSION
24 #define PATH_MAX _POSIX_PATH_MAX
25 #else
26 #ifdef MAXPATHLEN
27 #define PATH_MAX MAXPATHLEN
28 #else
29 #define PATH_MAX 1024
30 #endif
31 #endif
32 #endif
33 
34 #define MAX_READLINKS 32
35 
36 #ifdef __STDC__
37 char *realpath(const char *path, char resolved_path [])
38 #else
39 char *realpath(path, resolved_path)
40 const char *path;
41 char resolved_path [];
42 #endif
43 {
44  char copy_path[PATH_MAX];
45  char link_path[PATH_MAX];
46  char *new_path = resolved_path;
47  char *max_path;
48  int readlinks = 0;
49  int n;
50 
51  /* Make a copy of the source path since we may need to modify it. */
52  strcpy(copy_path, path);
53  path = copy_path;
54  max_path = copy_path + PATH_MAX - 2;
55  /* If it's a relative pathname use getwd for starters. */
56  if (*path != '/') {
57 #ifdef HAVE_GETCWD
58  getcwd(new_path, PATH_MAX - 1);
59 #else
60  getwd(new_path);
61 #endif
62  new_path += strlen(new_path);
63  if (new_path[-1] != '/')
64  *new_path++ = '/';
65  }
66  else {
67  *new_path++ = '/';
68  path++;
69  }
70  /* Expand each slash-separated pathname component. */
71  while (*path != '\0') {
72  /* Ignore stray "/". */
73  if (*path == '/') {
74  path++;
75  continue;
76  }
77  if (*path == '.') {
78  /* Ignore ".". */
79  if (path[1] == '\0' || path[1] == '/') {
80  path++;
81  continue;
82  }
83  if (path[1] == '.') {
84  if (path[2] == '\0' || path[2] == '/') {
85  path += 2;
86  /* Ignore ".." at root. */
87  if (new_path == resolved_path + 1)
88  continue;
89  /* Handle ".." by backing up. */
90  while ((--new_path)[-1] != '/')
91  ;
92  continue;
93  }
94  }
95  }
96  /* Safely copy the next pathname component. */
97  while (*path != '\0' && *path != '/') {
98  if (path > max_path) {
100  return NULL;
101  }
102  *new_path++ = *path++;
103  }
104 #ifdef S_IFLNK
105  /* Protect against infinite loops. */
106  if (readlinks++ > MAX_READLINKS) {
107  errno = ELOOP;
108  return NULL;
109  }
110  /* See if latest pathname component is a symlink. */
111  *new_path = '\0';
112  n = readlink(resolved_path, link_path, PATH_MAX - 1);
113  if (n < 0) {
114  /* EINVAL means the file exists but isn't a symlink. */
115  if (errno != EINVAL)
116  return NULL;
117  }
118  else {
119  /* Note: readlink doesn't add the null byte. */
120  link_path[n] = '\0';
121  if (*link_path == '/')
122  /* Start over for an absolute symlink. */
123  new_path = resolved_path;
124  else
125  /* Otherwise back up over this component. */
126  while (*(--new_path) != '/')
127  ;
128  /* Safe sex check. */
129  if (strlen(path) + n >= PATH_MAX) {
131  return NULL;
132  }
133  /* Insert symlink contents into path. */
134  strcat(link_path, path);
135  strcpy(copy_path, link_path);
136  path = copy_path;
137  }
138 #endif /* S_IFLNK */
139  *new_path++ = '/';
140  }
141  /* Delete trailing slash but don't whomp a lone slash. */
142  if (new_path != resolved_path + 1 && new_path[-1] == '/')
143  new_path--;
144  /* Make sure it's null terminated. */
145  *new_path = '\0';
146  return resolved_path;
147 }
NULL
#define NULL
Definition: defines.h:250
PATH_MAX
#define PATH_MAX
Definition: realpath.c:29
ELOOP
#define ELOOP
Definition: errno.h:127
strcat
#define strcat(a, b)
Definition: brew_db.h:76
realpath
char * realpath(char *path, resolved_path) const
Definition: realpath.c:39
strcpy
#define strcpy(a, b)
Definition: brew_db.h:79
MAX_READLINKS
#define MAX_READLINKS
Definition: realpath.c:34
getcwd
#define getcwd
Definition: clib_port.h:184
errno
int errno
Definition: k_standard.c:57
EINVAL
#define EINVAL
Definition: errno.h:70
strlen
int strlen()
ENAMETOOLONG
#define ENAMETOOLONG
Definition: errno.h:129
getwd
char * getwd()
n
print Counter Value is $counter n
Definition: simple_counter.php:11