1#include "cache.h" 2 3/* 4 * Do not use this for inspecting *tracked* content. When path is a 5 * symlink to a directory, we do not want to say it is a directory when 6 * dealing with tracked content in the working tree. 7 */ 8int is_directory(const char *path) 9{ 10 struct stat st; 11 return (!stat(path, &st) && S_ISDIR(st.st_mode)); 12} 13 14/* removes the last path component from 'path' except if 'path' is root */ 15static void strip_last_component(struct strbuf *path) 16{ 17 size_t offset = offset_1st_component(path->buf); 18 size_t len = path->len; 19 20 /* Find start of the last component */ 21 while (offset < len && !is_dir_sep(path->buf[len - 1])) 22 len--; 23 /* Skip sequences of multiple path-separators */ 24 while (offset < len && is_dir_sep(path->buf[len - 1])) 25 len--; 26 27 strbuf_setlen(path, len); 28} 29 30/* get (and remove) the next component in 'remaining' and place it in 'next' */ 31static void get_next_component(struct strbuf *next, struct strbuf *remaining) 32{ 33 char *start = NULL; 34 char *end = NULL; 35 36 strbuf_reset(next); 37 38 /* look for the next component */ 39 /* Skip sequences of multiple path-separators */ 40 for (start = remaining->buf; is_dir_sep(*start); start++) 41 ; /* nothing */ 42 /* Find end of the path component */ 43 for (end = start; *end && !is_dir_sep(*end); end++) 44 ; /* nothing */ 45 46 strbuf_add(next, start, end - start); 47 /* remove the component from 'remaining' */ 48 strbuf_remove(remaining, 0, end - remaining->buf); 49} 50 51/* copies root part from remaining to resolved, canonicalizing it on the way */ 52static void get_root_part(struct strbuf *resolved, struct strbuf *remaining) 53{ 54 int offset = offset_1st_component(remaining->buf); 55 56 strbuf_reset(resolved); 57 strbuf_add(resolved, remaining->buf, offset); 58#ifdef GIT_WINDOWS_NATIVE 59 convert_slashes(resolved->buf); 60#endif 61 strbuf_remove(remaining, 0, offset); 62} 63 64/* We allow "recursive" symbolic links. Only within reason, though. */ 65#ifndef MAXSYMLINKS 66#define MAXSYMLINKS 32 67#endif 68 69/* 70 * Return the real path (i.e., absolute path, with symlinks resolved 71 * and extra slashes removed) equivalent to the specified path. (If 72 * you want an absolute path but don't mind links, use 73 * absolute_path().) Places the resolved realpath in the provided strbuf. 74 * 75 * The directory part of path (i.e., everything up to the last 76 * dir_sep) must denote a valid, existing directory, but the last 77 * component need not exist. If die_on_error is set, then die with an 78 * informative error message if there is a problem. Otherwise, return 79 * NULL on errors (without generating any output). 80 */ 81char *strbuf_realpath(struct strbuf *resolved, const char *path, 82 int die_on_error) 83{ 84 struct strbuf remaining = STRBUF_INIT; 85 struct strbuf next = STRBUF_INIT; 86 struct strbuf symlink = STRBUF_INIT; 87 char *retval = NULL; 88 int num_symlinks = 0; 89 struct stat st; 90 91 if (!*path) { 92 if (die_on_error) 93 die("The empty string is not a valid path"); 94 else 95 goto error_out; 96 } 97 98 strbuf_addstr(&remaining, path); 99 get_root_part(resolved, &remaining); 100 101 if (!resolved->len) { 102 /* relative path; can use CWD as the initial resolved path */ 103 if (strbuf_getcwd(resolved)) { 104 if (die_on_error) 105 die_errno("unable to get current working directory"); 106 else 107 goto error_out; 108 } 109 } 110 111 /* Iterate over the remaining path components */ 112 while (remaining.len > 0) { 113 get_next_component(&next, &remaining); 114 115 if (next.len == 0) { 116 continue; /* empty component */ 117 } else if (next.len == 1 && !strcmp(next.buf, ".")) { 118 continue; /* '.' component */ 119 } else if (next.len == 2 && !strcmp(next.buf, "..")) { 120 /* '..' component; strip the last path component */ 121 strip_last_component(resolved); 122 continue; 123 } 124 125 /* append the next component and resolve resultant path */ 126 if (!is_dir_sep(resolved->buf[resolved->len - 1])) 127 strbuf_addch(resolved, '/'); 128 strbuf_addbuf(resolved, &next); 129 130 if (lstat(resolved->buf, &st)) { 131 /* error out unless this was the last component */ 132 if (errno != ENOENT || remaining.len) { 133 if (die_on_error) 134 die_errno("Invalid path '%s'", 135 resolved->buf); 136 else 137 goto error_out; 138 } 139 } else if (S_ISLNK(st.st_mode)) { 140 ssize_t len; 141 strbuf_reset(&symlink); 142 143 if (num_symlinks++ > MAXSYMLINKS) { 144 if (die_on_error) 145 die("More than %d nested symlinks " 146 "on path '%s'", MAXSYMLINKS, path); 147 else 148 goto error_out; 149 } 150 151 len = strbuf_readlink(&symlink, resolved->buf, 152 st.st_size); 153 if (len < 0) { 154 if (die_on_error) 155 die_errno("Invalid symlink '%s'", 156 resolved->buf); 157 else 158 goto error_out; 159 } 160 161 if (is_absolute_path(symlink.buf)) { 162 /* absolute symlink; set resolved to root */ 163 get_root_part(resolved, &symlink); 164 } else { 165 /* 166 * relative symlink 167 * strip off the last component since it will 168 * be replaced with the contents of the symlink 169 */ 170 strip_last_component(resolved); 171 } 172 173 /* 174 * if there are still remaining components to resolve 175 * then append them to symlink 176 */ 177 if (remaining.len) { 178 strbuf_addch(&symlink, '/'); 179 strbuf_addbuf(&symlink, &remaining); 180 } 181 182 /* 183 * use the symlink as the remaining components that 184 * need to be resloved 185 */ 186 strbuf_swap(&symlink, &remaining); 187 } 188 } 189 190 retval = resolved->buf; 191 192error_out: 193 strbuf_release(&remaining); 194 strbuf_release(&next); 195 strbuf_release(&symlink); 196 197 if (!retval) 198 strbuf_reset(resolved); 199 200 return retval; 201} 202 203const char *real_path(const char *path) 204{ 205 static struct strbuf realpath = STRBUF_INIT; 206 return strbuf_realpath(&realpath, path, 1); 207} 208 209const char *real_path_if_valid(const char *path) 210{ 211 static struct strbuf realpath = STRBUF_INIT; 212 return strbuf_realpath(&realpath, path, 0); 213} 214 215char *real_pathdup(const char *path) 216{ 217 struct strbuf realpath = STRBUF_INIT; 218 char *retval = NULL; 219 220 if (strbuf_realpath(&realpath, path, 0)) 221 retval = strbuf_detach(&realpath, NULL); 222 223 strbuf_release(&realpath); 224 225 return retval; 226} 227 228/* 229 * Use this to get an absolute path from a relative one. If you want 230 * to resolve links, you should use real_path. 231 */ 232const char *absolute_path(const char *path) 233{ 234 static struct strbuf sb = STRBUF_INIT; 235 strbuf_reset(&sb); 236 strbuf_add_absolute_path(&sb, path); 237 return sb.buf; 238} 239 240/* 241 * Unlike prefix_path, this should be used if the named file does 242 * not have to interact with index entry; i.e. name of a random file 243 * on the filesystem. 244 */ 245const char *prefix_filename(const char *pfx, int pfx_len, const char *arg) 246{ 247 static struct strbuf path = STRBUF_INIT; 248#ifndef GIT_WINDOWS_NATIVE 249 if (!pfx_len || is_absolute_path(arg)) 250 return arg; 251 strbuf_reset(&path); 252 strbuf_add(&path, pfx, pfx_len); 253 strbuf_addstr(&path, arg); 254#else 255 /* don't add prefix to absolute paths, but still replace '\' by '/' */ 256 strbuf_reset(&path); 257 if (is_absolute_path(arg)) 258 pfx_len = 0; 259 else if (pfx_len) 260 strbuf_add(&path, pfx, pfx_len); 261 strbuf_addstr(&path, arg); 262 convert_slashes(path.buf + pfx_len); 263#endif 264 return path.buf; 265}