Merge branch 'maint'
[git] / symlinks.c
1 #include "cache.h"
2
3 int has_symlink_leading_path(const char *name, char *last_symlink)
4 {
5         char path[PATH_MAX];
6         const char *sp, *ep;
7         char *dp;
8
9         sp = name;
10         dp = path;
11
12         if (last_symlink && *last_symlink) {
13                 size_t last_len = strlen(last_symlink);
14                 size_t len = strlen(name);
15                 if (last_len < len &&
16                     !strncmp(name, last_symlink, last_len) &&
17                     name[last_len] == '/')
18                         return 1;
19                 *last_symlink = '\0';
20         }
21
22         while (1) {
23                 size_t len;
24                 struct stat st;
25
26                 ep = strchr(sp, '/');
27                 if (!ep)
28                         break;
29                 len = ep - sp;
30                 if (PATH_MAX <= dp + len - path + 2)
31                         return 0; /* new name is longer than that??? */
32                 memcpy(dp, sp, len);
33                 dp[len] = 0;
34
35                 if (lstat(path, &st))
36                         return 0;
37                 if (S_ISLNK(st.st_mode)) {
38                         if (last_symlink)
39                                 strcpy(last_symlink, path);
40                         return 1;
41                 }
42
43                 dp[len++] = '/';
44                 dp = dp + len;
45                 sp = ep + 1;
46         }
47         return 0;
48 }