Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 118 lines (102 sloc) 2.844 kb
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
1 #include "cache.h"
2
90b4a71 Junio C Hamano is_directory(): a generic helper function
gitster authored
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 */
8 int is_directory(const char *path)
9 {
10 struct stat st;
11 return (!stat(path, &st) && S_ISDIR(st.st_mode));
12 }
13
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
14 /* We allow "recursive" symbolic links. Only within reason, though. */
15 #define MAXDEPTH 5
16
17 const char *make_absolute_path(const char *path)
18 {
19 static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1];
20 char cwd[1024] = "";
1630726 Brandon Casey abspath.c: move declaration of 'len' into inner block and use appropriat...
drafnel authored
21 int buf_index = 1;
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
22
23 int depth = MAXDEPTH;
24 char *last_elem = NULL;
25 struct stat st;
26
27 if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
28 die ("Too long path: %.*s", 60, path);
29
30 while (depth--) {
90b4a71 Junio C Hamano is_directory(): a generic helper function
gitster authored
31 if (!is_directory(buf)) {
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
32 char *last_slash = strrchr(buf, '/');
33 if (last_slash) {
34 *last_slash = '\0';
35 last_elem = xstrdup(last_slash + 1);
36 } else {
37 last_elem = xstrdup(buf);
38 *buf = '\0';
39 }
40 }
41
42 if (*buf) {
43 if (!*cwd && !getcwd(cwd, sizeof(cwd)))
0721c31 trast Use die_errno() instead of die() when checking syscalls
trast authored
44 die_errno ("Could not get current working directory");
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
45
46 if (chdir(buf))
0721c31 trast Use die_errno() instead of die() when checking syscalls
trast authored
47 die_errno ("Could not switch to '%s'", buf);
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
48 }
49 if (!getcwd(buf, PATH_MAX))
0721c31 trast Use die_errno() instead of die() when checking syscalls
trast authored
50 die_errno ("Could not get current working directory");
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
51
52 if (last_elem) {
1630726 Brandon Casey abspath.c: move declaration of 'len' into inner block and use appropriat...
drafnel authored
53 size_t len = strlen(buf);
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
54 if (len + strlen(last_elem) + 2 > PATH_MAX)
55 die ("Too long path name: '%s/%s'",
56 buf, last_elem);
57 buf[len] = '/';
58 strcpy(buf + len + 1, last_elem);
59 free(last_elem);
60 last_elem = NULL;
61 }
62
63 if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
1630726 Brandon Casey abspath.c: move declaration of 'len' into inner block and use appropriat...
drafnel authored
64 ssize_t len = readlink(buf, next_buf, PATH_MAX);
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
65 if (len < 0)
0721c31 trast Use die_errno() instead of die() when checking syscalls
trast authored
66 die_errno ("Invalid symlink '%s'", buf);
737e31a Junio C Hamano make_absolute_path(): check bounds when seeing an overlong symlink
gitster authored
67 if (PATH_MAX <= len)
68 die("symbolic link too long: %s", buf);
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
69 next_buf[len] = '\0';
70 buf = next_buf;
71 buf_index = 1 - buf_index;
72 next_buf = bufs[buf_index];
73 } else
74 break;
75 }
76
77 if (*cwd && chdir(cwd))
0721c31 trast Use die_errno() instead of die() when checking syscalls
trast authored
78 die_errno ("Could not change back to '%s'", cwd);
5b8e6f8 Dmitry Potapov shrink git-shell by avoiding redundant dependencies
dmpot authored
79
80 return buf;
81 }
10c4c88 Allow add_path() to add non-existent directories to the path
Johannes Sixt authored
82
83 static const char *get_pwd_cwd(void)
84 {
85 static char cwd[PATH_MAX + 1];
86 char *pwd;
87 struct stat cwd_stat, pwd_stat;
88 if (getcwd(cwd, PATH_MAX) == NULL)
89 return NULL;
90 pwd = getenv("PWD");
91 if (pwd && strcmp(pwd, cwd)) {
92 stat(cwd, &cwd_stat);
93 if (!stat(pwd, &pwd_stat) &&
94 pwd_stat.st_dev == cwd_stat.st_dev &&
95 pwd_stat.st_ino == cwd_stat.st_ino) {
96 strlcpy(cwd, pwd, PATH_MAX);
97 }
98 }
99 return cwd;
100 }
101
102 const char *make_nonrelative_path(const char *path)
103 {
104 static char buf[PATH_MAX + 1];
105
106 if (is_absolute_path(path)) {
107 if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
108 die("Too long path: %.*s", 60, path);
109 } else {
110 const char *cwd = get_pwd_cwd();
111 if (!cwd)
0721c31 trast Use die_errno() instead of die() when checking syscalls
trast authored
112 die_errno("Cannot determine the current working directory");
10c4c88 Allow add_path() to add non-existent directories to the path
Johannes Sixt authored
113 if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
114 die("Too long path: %.*s", 60, path);
115 }
116 return buf;
117 }
Something went wrong with that request. Please try again.