path.c: group git_path(), git_pathdup() and strbuf_git_path() together
[git] / path.c
1 /*
2  * Utilities for paths and pathnames
3  */
4 #include "cache.h"
5 #include "strbuf.h"
6 #include "string-list.h"
7
8 static int get_st_mode_bits(const char *path, int *mode)
9 {
10         struct stat st;
11         if (lstat(path, &st) < 0)
12                 return -1;
13         *mode = st.st_mode;
14         return 0;
15 }
16
17 static char bad_path[] = "/bad-path/";
18
19 static struct strbuf *get_pathname(void)
20 {
21         static struct strbuf pathname_array[4] = {
22                 STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
23         };
24         static int index;
25         struct strbuf *sb = &pathname_array[3 & ++index];
26         strbuf_reset(sb);
27         return sb;
28 }
29
30 static char *cleanup_path(char *path)
31 {
32         /* Clean it up */
33         if (!memcmp(path, "./", 2)) {
34                 path += 2;
35                 while (*path == '/')
36                         path++;
37         }
38         return path;
39 }
40
41 static void strbuf_cleanup_path(struct strbuf *sb)
42 {
43         char *path = cleanup_path(sb->buf);
44         if (path > sb->buf)
45                 strbuf_remove(sb, 0, path - sb->buf);
46 }
47
48 char *mksnpath(char *buf, size_t n, const char *fmt, ...)
49 {
50         va_list args;
51         unsigned len;
52
53         va_start(args, fmt);
54         len = vsnprintf(buf, n, fmt, args);
55         va_end(args);
56         if (len >= n) {
57                 strlcpy(buf, bad_path, n);
58                 return buf;
59         }
60         return cleanup_path(buf);
61 }
62
63 static void do_git_path(struct strbuf *buf, const char *fmt, va_list args)
64 {
65         const char *git_dir = get_git_dir();
66         strbuf_addstr(buf, git_dir);
67         if (buf->len && !is_dir_sep(buf->buf[buf->len - 1]))
68                 strbuf_addch(buf, '/');
69         strbuf_vaddf(buf, fmt, args);
70         strbuf_cleanup_path(buf);
71 }
72
73 void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
74 {
75         va_list args;
76         va_start(args, fmt);
77         do_git_path(sb, fmt, args);
78         va_end(args);
79 }
80
81 const char *git_path(const char *fmt, ...)
82 {
83         struct strbuf *pathname = get_pathname();
84         va_list args;
85         va_start(args, fmt);
86         do_git_path(pathname, fmt, args);
87         va_end(args);
88         return pathname->buf;
89 }
90
91 char *git_pathdup(const char *fmt, ...)
92 {
93         struct strbuf path = STRBUF_INIT;
94         va_list args;
95         va_start(args, fmt);
96         do_git_path(&path, fmt, args);
97         va_end(args);
98         return strbuf_detach(&path, NULL);
99 }
100
101 char *mkpathdup(const char *fmt, ...)
102 {
103         struct strbuf sb = STRBUF_INIT;
104         va_list args;
105         va_start(args, fmt);
106         strbuf_vaddf(&sb, fmt, args);
107         va_end(args);
108         strbuf_cleanup_path(&sb);
109         return strbuf_detach(&sb, NULL);
110 }
111
112 const char *mkpath(const char *fmt, ...)
113 {
114         va_list args;
115         struct strbuf *pathname = get_pathname();
116         va_start(args, fmt);
117         strbuf_vaddf(pathname, fmt, args);
118         va_end(args);
119         return cleanup_path(pathname->buf);
120 }
121
122 void home_config_paths(char **global, char **xdg, char *file)
123 {
124         char *xdg_home = getenv("XDG_CONFIG_HOME");
125         char *home = getenv("HOME");
126         char *to_free = NULL;
127
128         if (!home) {
129                 if (global)
130                         *global = NULL;
131         } else {
132                 if (!xdg_home) {
133                         to_free = mkpathdup("%s/.config", home);
134                         xdg_home = to_free;
135                 }
136                 if (global)
137                         *global = mkpathdup("%s/.gitconfig", home);
138         }
139
140         if (xdg) {
141                 if (!xdg_home)
142                         *xdg = NULL;
143                 else
144                         *xdg = mkpathdup("%s/git/%s", xdg_home, file);
145         }
146
147         free(to_free);
148 }
149
150 const char *git_path_submodule(const char *path, const char *fmt, ...)
151 {
152         struct strbuf *buf = get_pathname();
153         const char *git_dir;
154         va_list args;
155
156         strbuf_addstr(buf, path);
157         if (buf->len && buf->buf[buf->len - 1] != '/')
158                 strbuf_addch(buf, '/');
159         strbuf_addstr(buf, ".git");
160
161         git_dir = read_gitfile(buf->buf);
162         if (git_dir) {
163                 strbuf_reset(buf);
164                 strbuf_addstr(buf, git_dir);
165         }
166         strbuf_addch(buf, '/');
167
168         va_start(args, fmt);
169         strbuf_vaddf(buf, fmt, args);
170         va_end(args);
171         strbuf_cleanup_path(buf);
172         return buf->buf;
173 }
174
175 int validate_headref(const char *path)
176 {
177         struct stat st;
178         char *buf, buffer[256];
179         unsigned char sha1[20];
180         int fd;
181         ssize_t len;
182
183         if (lstat(path, &st) < 0)
184                 return -1;
185
186         /* Make sure it is a "refs/.." symlink */
187         if (S_ISLNK(st.st_mode)) {
188                 len = readlink(path, buffer, sizeof(buffer)-1);
189                 if (len >= 5 && !memcmp("refs/", buffer, 5))
190                         return 0;
191                 return -1;
192         }
193
194         /*
195          * Anything else, just open it and try to see if it is a symbolic ref.
196          */
197         fd = open(path, O_RDONLY);
198         if (fd < 0)
199                 return -1;
200         len = read_in_full(fd, buffer, sizeof(buffer)-1);
201         close(fd);
202
203         /*
204          * Is it a symbolic ref?
205          */
206         if (len < 4)
207                 return -1;
208         if (!memcmp("ref:", buffer, 4)) {
209                 buf = buffer + 4;
210                 len -= 4;
211                 while (len && isspace(*buf))
212                         buf++, len--;
213                 if (len >= 5 && !memcmp("refs/", buf, 5))
214                         return 0;
215         }
216
217         /*
218          * Is this a detached HEAD?
219          */
220         if (!get_sha1_hex(buffer, sha1))
221                 return 0;
222
223         return -1;
224 }
225
226 static struct passwd *getpw_str(const char *username, size_t len)
227 {
228         struct passwd *pw;
229         char *username_z = xmemdupz(username, len);
230         pw = getpwnam(username_z);
231         free(username_z);
232         return pw;
233 }
234
235 /*
236  * Return a string with ~ and ~user expanded via getpw*.  If buf != NULL,
237  * then it is a newly allocated string. Returns NULL on getpw failure or
238  * if path is NULL.
239  */
240 char *expand_user_path(const char *path)
241 {
242         struct strbuf user_path = STRBUF_INIT;
243         const char *to_copy = path;
244
245         if (path == NULL)
246                 goto return_null;
247         if (path[0] == '~') {
248                 const char *first_slash = strchrnul(path, '/');
249                 const char *username = path + 1;
250                 size_t username_len = first_slash - username;
251                 if (username_len == 0) {
252                         const char *home = getenv("HOME");
253                         if (!home)
254                                 goto return_null;
255                         strbuf_addstr(&user_path, home);
256                 } else {
257                         struct passwd *pw = getpw_str(username, username_len);
258                         if (!pw)
259                                 goto return_null;
260                         strbuf_addstr(&user_path, pw->pw_dir);
261                 }
262                 to_copy = first_slash;
263         }
264         strbuf_addstr(&user_path, to_copy);
265         return strbuf_detach(&user_path, NULL);
266 return_null:
267         strbuf_release(&user_path);
268         return NULL;
269 }
270
271 /*
272  * First, one directory to try is determined by the following algorithm.
273  *
274  * (0) If "strict" is given, the path is used as given and no DWIM is
275  *     done. Otherwise:
276  * (1) "~/path" to mean path under the running user's home directory;
277  * (2) "~user/path" to mean path under named user's home directory;
278  * (3) "relative/path" to mean cwd relative directory; or
279  * (4) "/absolute/path" to mean absolute directory.
280  *
281  * Unless "strict" is given, we try access() for existence of "%s.git/.git",
282  * "%s/.git", "%s.git", "%s" in this order.  The first one that exists is
283  * what we try.
284  *
285  * Second, we try chdir() to that.  Upon failure, we return NULL.
286  *
287  * Then, we try if the current directory is a valid git repository.
288  * Upon failure, we return NULL.
289  *
290  * If all goes well, we return the directory we used to chdir() (but
291  * before ~user is expanded), avoiding getcwd() resolving symbolic
292  * links.  User relative paths are also returned as they are given,
293  * except DWIM suffixing.
294  */
295 const char *enter_repo(const char *path, int strict)
296 {
297         static char used_path[PATH_MAX];
298         static char validated_path[PATH_MAX];
299
300         if (!path)
301                 return NULL;
302
303         if (!strict) {
304                 static const char *suffix[] = {
305                         "/.git", "", ".git/.git", ".git", NULL,
306                 };
307                 const char *gitfile;
308                 int len = strlen(path);
309                 int i;
310                 while ((1 < len) && (path[len-1] == '/'))
311                         len--;
312
313                 if (PATH_MAX <= len)
314                         return NULL;
315                 strncpy(used_path, path, len); used_path[len] = 0 ;
316                 strcpy(validated_path, used_path);
317
318                 if (used_path[0] == '~') {
319                         char *newpath = expand_user_path(used_path);
320                         if (!newpath || (PATH_MAX - 10 < strlen(newpath))) {
321                                 free(newpath);
322                                 return NULL;
323                         }
324                         /*
325                          * Copy back into the static buffer. A pity
326                          * since newpath was not bounded, but other
327                          * branches of the if are limited by PATH_MAX
328                          * anyway.
329                          */
330                         strcpy(used_path, newpath); free(newpath);
331                 }
332                 else if (PATH_MAX - 10 < len)
333                         return NULL;
334                 len = strlen(used_path);
335                 for (i = 0; suffix[i]; i++) {
336                         struct stat st;
337                         strcpy(used_path + len, suffix[i]);
338                         if (!stat(used_path, &st) &&
339                             (S_ISREG(st.st_mode) ||
340                             (S_ISDIR(st.st_mode) && is_git_directory(used_path)))) {
341                                 strcat(validated_path, suffix[i]);
342                                 break;
343                         }
344                 }
345                 if (!suffix[i])
346                         return NULL;
347                 gitfile = read_gitfile(used_path) ;
348                 if (gitfile)
349                         strcpy(used_path, gitfile);
350                 if (chdir(used_path))
351                         return NULL;
352                 path = validated_path;
353         }
354         else if (chdir(path))
355                 return NULL;
356
357         if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 &&
358             validate_headref("HEAD") == 0) {
359                 set_git_dir(".");
360                 check_repository_format();
361                 return path;
362         }
363
364         return NULL;
365 }
366
367 static int calc_shared_perm(int mode)
368 {
369         int tweak;
370
371         if (shared_repository < 0)
372                 tweak = -shared_repository;
373         else
374                 tweak = shared_repository;
375
376         if (!(mode & S_IWUSR))
377                 tweak &= ~0222;
378         if (mode & S_IXUSR)
379                 /* Copy read bits to execute bits */
380                 tweak |= (tweak & 0444) >> 2;
381         if (shared_repository < 0)
382                 mode = (mode & ~0777) | tweak;
383         else
384                 mode |= tweak;
385
386         return mode;
387 }
388
389
390 int adjust_shared_perm(const char *path)
391 {
392         int old_mode, new_mode;
393
394         if (!shared_repository)
395                 return 0;
396         if (get_st_mode_bits(path, &old_mode) < 0)
397                 return -1;
398
399         new_mode = calc_shared_perm(old_mode);
400         if (S_ISDIR(old_mode)) {
401                 /* Copy read bits to execute bits */
402                 new_mode |= (new_mode & 0444) >> 2;
403                 new_mode |= FORCE_DIR_SET_GID;
404         }
405
406         if (((old_mode ^ new_mode) & ~S_IFMT) &&
407                         chmod(path, (new_mode & ~S_IFMT)) < 0)
408                 return -2;
409         return 0;
410 }
411
412 static int have_same_root(const char *path1, const char *path2)
413 {
414         int is_abs1, is_abs2;
415
416         is_abs1 = is_absolute_path(path1);
417         is_abs2 = is_absolute_path(path2);
418         return (is_abs1 && is_abs2 && tolower(path1[0]) == tolower(path2[0])) ||
419                (!is_abs1 && !is_abs2);
420 }
421
422 /*
423  * Give path as relative to prefix.
424  *
425  * The strbuf may or may not be used, so do not assume it contains the
426  * returned path.
427  */
428 const char *relative_path(const char *in, const char *prefix,
429                           struct strbuf *sb)
430 {
431         int in_len = in ? strlen(in) : 0;
432         int prefix_len = prefix ? strlen(prefix) : 0;
433         int in_off = 0;
434         int prefix_off = 0;
435         int i = 0, j = 0;
436
437         if (!in_len)
438                 return "./";
439         else if (!prefix_len)
440                 return in;
441
442         if (have_same_root(in, prefix)) {
443                 /* bypass dos_drive, for "c:" is identical to "C:" */
444                 if (has_dos_drive_prefix(in)) {
445                         i = 2;
446                         j = 2;
447                 }
448         } else {
449                 return in;
450         }
451
452         while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
453                 if (is_dir_sep(prefix[i])) {
454                         while (is_dir_sep(prefix[i]))
455                                 i++;
456                         while (is_dir_sep(in[j]))
457                                 j++;
458                         prefix_off = i;
459                         in_off = j;
460                 } else {
461                         i++;
462                         j++;
463                 }
464         }
465
466         if (
467             /* "prefix" seems like prefix of "in" */
468             i >= prefix_len &&
469             /*
470              * but "/foo" is not a prefix of "/foobar"
471              * (i.e. prefix not end with '/')
472              */
473             prefix_off < prefix_len) {
474                 if (j >= in_len) {
475                         /* in="/a/b", prefix="/a/b" */
476                         in_off = in_len;
477                 } else if (is_dir_sep(in[j])) {
478                         /* in="/a/b/c", prefix="/a/b" */
479                         while (is_dir_sep(in[j]))
480                                 j++;
481                         in_off = j;
482                 } else {
483                         /* in="/a/bbb/c", prefix="/a/b" */
484                         i = prefix_off;
485                 }
486         } else if (
487                    /* "in" is short than "prefix" */
488                    j >= in_len &&
489                    /* "in" not end with '/' */
490                    in_off < in_len) {
491                 if (is_dir_sep(prefix[i])) {
492                         /* in="/a/b", prefix="/a/b/c/" */
493                         while (is_dir_sep(prefix[i]))
494                                 i++;
495                         in_off = in_len;
496                 }
497         }
498         in += in_off;
499         in_len -= in_off;
500
501         if (i >= prefix_len) {
502                 if (!in_len)
503                         return "./";
504                 else
505                         return in;
506         }
507
508         strbuf_reset(sb);
509         strbuf_grow(sb, in_len);
510
511         while (i < prefix_len) {
512                 if (is_dir_sep(prefix[i])) {
513                         strbuf_addstr(sb, "../");
514                         while (is_dir_sep(prefix[i]))
515                                 i++;
516                         continue;
517                 }
518                 i++;
519         }
520         if (!is_dir_sep(prefix[prefix_len - 1]))
521                 strbuf_addstr(sb, "../");
522
523         strbuf_addstr(sb, in);
524
525         return sb->buf;
526 }
527
528 /*
529  * A simpler implementation of relative_path
530  *
531  * Get relative path by removing "prefix" from "in". This function
532  * first appears in v1.5.6-1-g044bbbc, and makes git_dir shorter
533  * to increase performance when traversing the path to work_tree.
534  */
535 const char *remove_leading_path(const char *in, const char *prefix)
536 {
537         static char buf[PATH_MAX + 1];
538         int i = 0, j = 0;
539
540         if (!prefix || !prefix[0])
541                 return in;
542         while (prefix[i]) {
543                 if (is_dir_sep(prefix[i])) {
544                         if (!is_dir_sep(in[j]))
545                                 return in;
546                         while (is_dir_sep(prefix[i]))
547                                 i++;
548                         while (is_dir_sep(in[j]))
549                                 j++;
550                         continue;
551                 } else if (in[j] != prefix[i]) {
552                         return in;
553                 }
554                 i++;
555                 j++;
556         }
557         if (
558             /* "/foo" is a prefix of "/foo" */
559             in[j] &&
560             /* "/foo" is not a prefix of "/foobar" */
561             !is_dir_sep(prefix[i-1]) && !is_dir_sep(in[j])
562            )
563                 return in;
564         while (is_dir_sep(in[j]))
565                 j++;
566         if (!in[j])
567                 strcpy(buf, ".");
568         else
569                 strcpy(buf, in + j);
570         return buf;
571 }
572
573 /*
574  * It is okay if dst == src, but they should not overlap otherwise.
575  *
576  * Performs the following normalizations on src, storing the result in dst:
577  * - Ensures that components are separated by '/' (Windows only)
578  * - Squashes sequences of '/'.
579  * - Removes "." components.
580  * - Removes ".." components, and the components the precede them.
581  * Returns failure (non-zero) if a ".." component appears as first path
582  * component anytime during the normalization. Otherwise, returns success (0).
583  *
584  * Note that this function is purely textual.  It does not follow symlinks,
585  * verify the existence of the path, or make any system calls.
586  *
587  * prefix_len != NULL is for a specific case of prefix_pathspec():
588  * assume that src == dst and src[0..prefix_len-1] is already
589  * normalized, any time "../" eats up to the prefix_len part,
590  * prefix_len is reduced. In the end prefix_len is the remaining
591  * prefix that has not been overridden by user pathspec.
592  */
593 int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
594 {
595         char *dst0;
596
597         if (has_dos_drive_prefix(src)) {
598                 *dst++ = *src++;
599                 *dst++ = *src++;
600         }
601         dst0 = dst;
602
603         if (is_dir_sep(*src)) {
604                 *dst++ = '/';
605                 while (is_dir_sep(*src))
606                         src++;
607         }
608
609         for (;;) {
610                 char c = *src;
611
612                 /*
613                  * A path component that begins with . could be
614                  * special:
615                  * (1) "." and ends   -- ignore and terminate.
616                  * (2) "./"           -- ignore them, eat slash and continue.
617                  * (3) ".." and ends  -- strip one and terminate.
618                  * (4) "../"          -- strip one, eat slash and continue.
619                  */
620                 if (c == '.') {
621                         if (!src[1]) {
622                                 /* (1) */
623                                 src++;
624                         } else if (is_dir_sep(src[1])) {
625                                 /* (2) */
626                                 src += 2;
627                                 while (is_dir_sep(*src))
628                                         src++;
629                                 continue;
630                         } else if (src[1] == '.') {
631                                 if (!src[2]) {
632                                         /* (3) */
633                                         src += 2;
634                                         goto up_one;
635                                 } else if (is_dir_sep(src[2])) {
636                                         /* (4) */
637                                         src += 3;
638                                         while (is_dir_sep(*src))
639                                                 src++;
640                                         goto up_one;
641                                 }
642                         }
643                 }
644
645                 /* copy up to the next '/', and eat all '/' */
646                 while ((c = *src++) != '\0' && !is_dir_sep(c))
647                         *dst++ = c;
648                 if (is_dir_sep(c)) {
649                         *dst++ = '/';
650                         while (is_dir_sep(c))
651                                 c = *src++;
652                         src--;
653                 } else if (!c)
654                         break;
655                 continue;
656
657         up_one:
658                 /*
659                  * dst0..dst is prefix portion, and dst[-1] is '/';
660                  * go up one level.
661                  */
662                 dst--;  /* go to trailing '/' */
663                 if (dst <= dst0)
664                         return -1;
665                 /* Windows: dst[-1] cannot be backslash anymore */
666                 while (dst0 < dst && dst[-1] != '/')
667                         dst--;
668                 if (prefix_len && *prefix_len > dst - dst0)
669                         *prefix_len = dst - dst0;
670         }
671         *dst = '\0';
672         return 0;
673 }
674
675 int normalize_path_copy(char *dst, const char *src)
676 {
677         return normalize_path_copy_len(dst, src, NULL);
678 }
679
680 /*
681  * path = Canonical absolute path
682  * prefixes = string_list containing normalized, absolute paths without
683  * trailing slashes (except for the root directory, which is denoted by "/").
684  *
685  * Determines, for each path in prefixes, whether the "prefix"
686  * is an ancestor directory of path.  Returns the length of the longest
687  * ancestor directory, excluding any trailing slashes, or -1 if no prefix
688  * is an ancestor.  (Note that this means 0 is returned if prefixes is
689  * ["/"].) "/foo" is not considered an ancestor of "/foobar".  Directories
690  * are not considered to be their own ancestors.  path must be in a
691  * canonical form: empty components, or "." or ".." components are not
692  * allowed.
693  */
694 int longest_ancestor_length(const char *path, struct string_list *prefixes)
695 {
696         int i, max_len = -1;
697
698         if (!strcmp(path, "/"))
699                 return -1;
700
701         for (i = 0; i < prefixes->nr; i++) {
702                 const char *ceil = prefixes->items[i].string;
703                 int len = strlen(ceil);
704
705                 if (len == 1 && ceil[0] == '/')
706                         len = 0; /* root matches anything, with length 0 */
707                 else if (!strncmp(path, ceil, len) && path[len] == '/')
708                         ; /* match of length len */
709                 else
710                         continue; /* no match */
711
712                 if (len > max_len)
713                         max_len = len;
714         }
715
716         return max_len;
717 }
718
719 /* strip arbitrary amount of directory separators at end of path */
720 static inline int chomp_trailing_dir_sep(const char *path, int len)
721 {
722         while (len && is_dir_sep(path[len - 1]))
723                 len--;
724         return len;
725 }
726
727 /*
728  * If path ends with suffix (complete path components), returns the
729  * part before suffix (sans trailing directory separators).
730  * Otherwise returns NULL.
731  */
732 char *strip_path_suffix(const char *path, const char *suffix)
733 {
734         int path_len = strlen(path), suffix_len = strlen(suffix);
735
736         while (suffix_len) {
737                 if (!path_len)
738                         return NULL;
739
740                 if (is_dir_sep(path[path_len - 1])) {
741                         if (!is_dir_sep(suffix[suffix_len - 1]))
742                                 return NULL;
743                         path_len = chomp_trailing_dir_sep(path, path_len);
744                         suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
745                 }
746                 else if (path[--path_len] != suffix[--suffix_len])
747                         return NULL;
748         }
749
750         if (path_len && !is_dir_sep(path[path_len - 1]))
751                 return NULL;
752         return xstrndup(path, chomp_trailing_dir_sep(path, path_len));
753 }
754
755 int daemon_avoid_alias(const char *p)
756 {
757         int sl, ndot;
758
759         /*
760          * This resurrects the belts and suspenders paranoia check by HPA
761          * done in <435560F7.4080006@zytor.com> thread, now enter_repo()
762          * does not do getcwd() based path canonicalization.
763          *
764          * sl becomes true immediately after seeing '/' and continues to
765          * be true as long as dots continue after that without intervening
766          * non-dot character.
767          */
768         if (!p || (*p != '/' && *p != '~'))
769                 return -1;
770         sl = 1; ndot = 0;
771         p++;
772
773         while (1) {
774                 char ch = *p++;
775                 if (sl) {
776                         if (ch == '.')
777                                 ndot++;
778                         else if (ch == '/') {
779                                 if (ndot < 3)
780                                         /* reject //, /./ and /../ */
781                                         return -1;
782                                 ndot = 0;
783                         }
784                         else if (ch == 0) {
785                                 if (0 < ndot && ndot < 3)
786                                         /* reject /.$ and /..$ */
787                                         return -1;
788                                 return 0;
789                         }
790                         else
791                                 sl = ndot = 0;
792                 }
793                 else if (ch == 0)
794                         return 0;
795                 else if (ch == '/') {
796                         sl = 1;
797                         ndot = 0;
798                 }
799         }
800 }