diff options
author | Jose Bollo <jose.bollo@iot.bzh> | 2018-07-03 15:53:18 +0200 |
---|---|---|
committer | Jose Bollo <jose.bollo@iot.bzh> | 2018-07-03 19:25:38 +0200 |
commit | 4f7f5ae8e1907b23cb74178dea68790a6fa963fe (patch) | |
tree | 372b70876870158114f64396759186ee9dd03168 | |
parent | f645c76e0bfa772aff97141389d45476bf091053 (diff) |
Improve readdirs to follow symbolic links
The use of symbolic links can be helpful in
some cases. That modification takes care of
allowing symbolic links in the exploration
of directories.
Change-Id: I54d9004187ba5942410aca37b890cd4f6925177d
Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/afb-api-so.c | 18 | ||||
-rw-r--r-- | src/locale-root.c | 3 |
2 files changed, 14 insertions, 7 deletions
diff --git a/src/afb-api-so.c b/src/afb-api-so.c index 2b71d92f..87281977 100644 --- a/src/afb-api-so.c +++ b/src/afb-api-so.c @@ -152,6 +152,7 @@ static int adddirs(char path[PATH_MAX], size_t end, struct afb_apiset *declare_s { DIR *dir; struct dirent *dent; + struct stat st; size_t len; int rc = 0; @@ -175,12 +176,19 @@ static int adddirs(char path[PATH_MAX], size_t end, struct afb_apiset *declare_s break; } + /* get the name and inspect dereferenced link instead of the directory entry */ len = strlen(dent->d_name); if (len + end >= PATH_MAX) { - ERROR("path too long while scanning bindings for %s", dent->d_name); + ERROR("path too long while scanning bindings for %.*s%s", (int)end, path, dent->d_name); + continue; + } + memcpy(&path[end], dent->d_name, len+1); + rc = stat(path, &st); + if (rc < 0) { + ERROR("getting status of %s failed: %m", path); continue; } - if (dent->d_type == DT_DIR) { + else if (S_ISDIR(st.st_mode)) { /* case of directories */ if (dent->d_name[0] == '.') { /* @@ -213,7 +221,7 @@ debug file made dlopen crashing. See https://sourceware.org/bugzilla/show_bug.cgi?id=22101 */ #if !defined(AFB_API_SO_ACCEPT_DOT_PREFIXED_DIRS) /* not defined by default */ - continue; /* ignore any directory beginnign with a dot */ + continue; /* ignore any directory beginning with a dot */ #else if (len == 1) continue; /* . */ @@ -230,13 +238,11 @@ See https://sourceware.org/bugzilla/show_bug.cgi?id=22101 #endif #endif } - memcpy(&path[end], dent->d_name, len+1); rc = adddirs(path, end+len, declare_set, call_set, failstops); - } else if (dent->d_type == DT_REG || dent->d_type == DT_LNK) { + } else if (S_ISREG(st.st_mode)) { /* case of files */ if (memcmp(&dent->d_name[len - 3], ".so", 4)) continue; - memcpy(&path[end], dent->d_name, len+1); rc = load_binding(path, 0, declare_set, call_set); } if (rc < 0 && failstops) { diff --git a/src/locale-root.c b/src/locale-root.c index eef2df4c..1d255bf3 100644 --- a/src/locale-root.c +++ b/src/locale-root.c @@ -193,7 +193,8 @@ static int init_container(struct locale_container *container, int dirfd) return -1; break; } - if (dent->d_type == DT_DIR || (dent->d_type == DT_UNKNOWN && fstatat(sfd, dent->d_name, &st, 0) == 0 && S_ISDIR(st.st_mode))) { + rc = fstatat(sfd, dent->d_name, &st, 0); + if (rc == 0 && S_ISDIR(st.st_mode)) { /* directory aka folder */ if (dent->d_name[0] == '.' && (dent->d_name[1] == 0 || (dent->d_name[1] == '.' && dent->d_name[2] == 0))) { /* nothing to do for special directories, basic detection, improves if needed */ |