Improve readdirs to follow symbolic links 71/14971/1
authorJose Bollo <jose.bollo@iot.bzh>
Tue, 3 Jul 2018 13:53:18 +0000 (15:53 +0200)
committerJose Bollo <jose.bollo@iot.bzh>
Tue, 3 Jul 2018 17:25:38 +0000 (19:25 +0200)
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>
src/afb-api-so.c
src/locale-root.c

index 2b71d92..8728197 100644 (file)
@@ -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) {
index eef2df4..1d255bf 100644 (file)
@@ -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 */