2 * Copyright (C) 2016, 2017 "IoT.bzh"
3 * Author José Bollo <jose.bollo@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #define NO_BINDING_VERBOSE_MACRO
28 #include "afb-api-so.h"
29 #include "afb-api-so-v1.h"
32 int afb_api_so_timeout = 15;
34 void afb_api_so_set_timeout(int to)
36 afb_api_so_timeout = to;
39 static int load_binding(const char *path, int force)
44 // This is a loadable library let's check if it's a binding
46 handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
49 ERROR("binding [%s] not loadable: %s", path, dlerror());
51 INFO("binding [%s] not loadable: %s", path, dlerror());
55 /* retrieves the register function */
56 rc = afb_api_so_v1_add(path, handle);
58 /* error when loading a valid v& binding */
62 /* not a v1 binding */
64 ERROR("binding [%s] is not an AFB binding", path);
66 INFO("binding [%s] is not an AFB binding", path);
78 int afb_api_so_add_binding(const char *path)
80 return load_binding(path, 1);
83 static int adddirs(char path[PATH_MAX], size_t end)
89 /* open the DIR now */
92 ERROR("can't scan binding directory %s, %m", path);
95 INFO("Scanning dir=[%s] for bindings", path);
105 ERROR("read error while scanning directory %.*s: %m", (int)(end - 1), path);
109 len = strlen(dent->d_name);
110 if (len + end >= PATH_MAX) {
111 ERROR("path too long while scanning bindings for %s", dent->d_name);
114 if (dent->d_type == DT_DIR) {
115 /* case of directories */
116 if (dent->d_name[0] == '.') {
119 if (dent->d_name[1] == '.' && len == 2)
122 memcpy(&path[end], dent->d_name, len+1);
123 adddirs(path, end+len);;
124 } else if (dent->d_type == DT_REG) {
126 if (memcmp(&dent->d_name[len - 3], ".so", 4))
128 memcpy(&path[end], dent->d_name, len+1);
129 if (load_binding(path, 0) < 0)
137 int afb_api_so_add_directory(const char *path)
140 char buffer[PATH_MAX];
142 length = strlen(path);
143 if (length >= sizeof(buffer)) {
144 ERROR("path too long %lu [%.99s...]", (unsigned long)length, path);
148 memcpy(buffer, path, length + 1);
149 return adddirs(buffer, length);
152 int afb_api_so_add_path(const char *path)
157 rc = stat(path, &st);
159 ERROR("Invalid binding path [%s]: %m", path);
160 else if (S_ISDIR(st.st_mode))
161 rc = afb_api_so_add_directory(path);
162 else if (strstr(path, ".so"))
163 rc = load_binding(path, 0);
165 INFO("not a binding [%s], skipped", path);
169 int afb_api_so_add_pathset(const char *pathset)
171 static char sep[] = ":";
174 ps = strdupa(pathset);
176 p = strsep(&ps, sep);
179 if (afb_api_so_add_path(p) < 0)