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/* We allow "recursive" symbolic links. Only within reason, though. */ 15#define MAXDEPTH 5 16 17/* 18 * Use this to get the real path, i.e. resolve links. If you want an 19 * absolute path but don't mind links, use absolute_path. 20 * 21 * If path is our buffer, then return path, as it's already what the 22 * user wants. 23 */ 24const char *real_path(const char *path) 25{ 26 static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1]; 27 char cwd[1024] = ""; 28 int buf_index = 1; 29 30 int depth = MAXDEPTH; 31 char *last_elem = NULL; 32 struct stat st; 33 34 /* We've already done it */ 35 if (path == buf || path == next_buf) 36 return path; 37 38 if (!*path) 39 die("The empty string is not a valid path"); 40 41 if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) 42 die ("Too long path: %.*s", 60, path); 43 44 while (depth--) { 45 if (!is_directory(buf)) { 46 char *last_slash = find_last_dir_sep(buf); 47 if (last_slash) { 48 *last_slash = '\0'; 49 last_elem = xstrdup(last_slash + 1); 50 } else { 51 last_elem = xstrdup(buf); 52 *buf = '\0'; 53 } 54 } 55 56 if (*buf) { 57 if (!*cwd && !getcwd(cwd, sizeof(cwd))) 58 die_errno ("Could not get current working directory"); 59 60 if (chdir(buf)) 61 die_errno ("Could not switch to '%s'", buf); 62 } 63 if (!getcwd(buf, PATH_MAX)) 64 die_errno ("Could not get current working directory"); 65 66 if (last_elem) { 67 size_t len = strlen(buf); 68 if (len + strlen(last_elem) + 2 > PATH_MAX) 69 die ("Too long path name: '%s/%s'", 70 buf, last_elem); 71 if (len && !is_dir_sep(buf[len-1])) 72 buf[len++] = '/'; 73 strcpy(buf + len, last_elem); 74 free(last_elem); 75 last_elem = NULL; 76 } 77 78 if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) { 79 ssize_t len = readlink(buf, next_buf, PATH_MAX); 80 if (len < 0) 81 die_errno ("Invalid symlink '%s'", buf); 82 if (PATH_MAX <= len) 83 die("symbolic link too long: %s", buf); 84 next_buf[len] = '\0'; 85 buf = next_buf; 86 buf_index = 1 - buf_index; 87 next_buf = bufs[buf_index]; 88 } else 89 break; 90 } 91 92 if (*cwd && chdir(cwd)) 93 die_errno ("Could not change back to '%s'", cwd); 94 95 return buf; 96} 97 98static const char *get_pwd_cwd(void) 99{ 100 static char cwd[PATH_MAX + 1]; 101 char *pwd; 102 struct stat cwd_stat, pwd_stat; 103 if (getcwd(cwd, PATH_MAX) == NULL) 104 return NULL; 105 pwd = getenv("PWD"); 106 if (pwd && strcmp(pwd, cwd)) { 107 stat(cwd, &cwd_stat); 108 if ((cwd_stat.st_dev || cwd_stat.st_ino) && 109 !stat(pwd, &pwd_stat) && 110 pwd_stat.st_dev == cwd_stat.st_dev && 111 pwd_stat.st_ino == cwd_stat.st_ino) { 112 strlcpy(cwd, pwd, PATH_MAX); 113 } 114 } 115 return cwd; 116} 117 118/* 119 * Use this to get an absolute path from a relative one. If you want 120 * to resolve links, you should use real_path. 121 * 122 * If the path is already absolute, then return path. As the user is 123 * never meant to free the return value, we're safe. 124 */ 125const char *absolute_path(const char *path) 126{ 127 static char buf[PATH_MAX + 1]; 128 129 if (!*path) { 130 die("The empty string is not a valid path"); 131 } else if (is_absolute_path(path)) { 132 if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) 133 die("Too long path: %.*s", 60, path); 134 } else { 135 size_t len; 136 const char *fmt; 137 const char *cwd = get_pwd_cwd(); 138 if (!cwd) 139 die_errno("Cannot determine the current working directory"); 140 len = strlen(cwd); 141 fmt = (len > 0 && is_dir_sep(cwd[len-1])) ? "%s%s" : "%s/%s"; 142 if (snprintf(buf, PATH_MAX, fmt, cwd, path) >= PATH_MAX) 143 die("Too long path: %.*s", 60, path); 144 } 145 return buf; 146} 147 148/* 149 * Unlike prefix_path, this should be used if the named file does 150 * not have to interact with index entry; i.e. name of a random file 151 * on the filesystem. 152 */ 153const char *prefix_filename(const char *pfx, int pfx_len, const char *arg) 154{ 155 static char path[PATH_MAX]; 156#ifndef WIN32 157 if (!pfx_len || is_absolute_path(arg)) 158 return arg; 159 memcpy(path, pfx, pfx_len); 160 strcpy(path + pfx_len, arg); 161#else 162 char *p; 163 /* don't add prefix to absolute paths, but still replace '\' by '/' */ 164 if (is_absolute_path(arg)) 165 pfx_len = 0; 166 else if (pfx_len) 167 memcpy(path, pfx, pfx_len); 168 strcpy(path + pfx_len, arg); 169 for (p = path + pfx_len; *p; p++) 170 if (*p == '\\') 171 *p = '/'; 172#endif 173 return path; 174}