Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: v1.5.6.4
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 65 lines (56 sloc) 1.347 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
#include "cache.h"

struct pathname {
int len;
char path[PATH_MAX];
};

/* Return matching pathname prefix length, or zero if not matching */
static inline int match_pathname(int len, const char *name, struct pathname *match)
{
int match_len = match->len;
return (len > match_len &&
name[match_len] == '/' &&
!memcmp(name, match->path, match_len)) ? match_len : 0;
}

static inline void set_pathname(int len, const char *name, struct pathname *match)
{
if (len < PATH_MAX) {
match->len = len;
memcpy(match->path, name, len);
match->path[len] = 0;
}
}

int has_symlink_leading_path(int len, const char *name)
{
static struct pathname link, nonlink;
char path[PATH_MAX];
struct stat st;
char *sp;
int known_dir;

/*
* See if the last known symlink cache matches.
*/
if (match_pathname(len, name, &link))
return 1;

/*
* Get rid of the last known directory part
*/
known_dir = match_pathname(len, name, &nonlink);

while ((sp = strchr(name + known_dir + 1, '/')) != NULL) {
int thislen = sp - name ;
memcpy(path, name, thislen);
path[thislen] = 0;

if (lstat(path, &st))
return 0;
if (S_ISDIR(st.st_mode)) {
set_pathname(thislen, path, &nonlink);
known_dir = thislen;
continue;
}
if (S_ISLNK(st.st_mode)) {
set_pathname(thislen, path, &link);
return 1;
}
break;
}
return 0;
}
Something went wrong with that request. Please try again.