4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
26 #include <sys/types.h>
34 struct json_object *pubarr;
35 struct json_object *direct;
36 struct json_object *byapp;
43 struct afapps applications;
46 struct af_db *af_db_create()
48 struct af_db *afdb = malloc(sizeof * afdb);
55 afdb->applications.pubarr = NULL;
56 afdb->applications.direct = NULL;
57 afdb->applications.byapp = NULL;
62 void af_db_addref(struct af_db *afdb)
68 void af_db_unref(struct af_db *afdb)
71 if (!--afdb->refcount) {
72 json_object_put(afdb->applications.pubarr);
73 json_object_put(afdb->applications.direct);
74 json_object_put(afdb->applications.byapp);
76 free(afdb->roots[--afdb->nrroots]);
82 int af_db_add_root(struct af_db *afdb, const char *path)
89 /* don't depend on the cwd and unique name */
90 r = realpath(path, NULL);
94 /* avoiding duplications */
97 for (i = 0 ; i < n ; i++) {
98 if (!strcmp(r, roots[i])) {
105 roots = realloc(roots, (n + 1) * sizeof(roots[0]));
117 static int json_add(struct json_object *obj, const char *key, struct json_object *val)
119 json_object_object_add(obj, key, val);
123 static int json_add_str(struct json_object *obj, const char *key, const char *val)
125 struct json_object *str = json_object_new_string (val ? val : "");
126 return str ? json_add(obj, key, str) : -1;
129 static int json_add_int(struct json_object *obj, const char *key, int val)
131 struct json_object *v = json_object_new_int (val);
132 return v ? json_add(obj, key, v) : -1;
135 static int addapp(struct afapps *apps, const char *path)
137 struct wgt_info *info;
138 const struct wgt_desc *desc;
139 const struct wgt_desc_feature *feat;
140 struct json_object *priv = NULL, *pub, *bya, *plugs, *str;
143 /* connect to the widget */
144 info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0);
147 desc = wgt_info_desc(info);
149 /* create the application id */
150 appid = alloca(2 + strlen(desc->id) + strlen(desc->version));
151 end = stpcpy(appid, desc->id);
153 strcpy(end, desc->version);
155 /* create the application structure */
156 priv = json_object_new_object();
160 pub = json_object_new_object();
164 if (json_add(priv, "public", pub)) {
165 json_object_put(pub);
169 plugs = json_object_new_array();
173 if (json_add(priv, "plugins", plugs)) {
174 json_object_put(plugs);
178 if(json_add_str(priv, "id", desc->id)
179 || json_add_str(priv, "path", path)
180 || json_add_str(priv, "content", desc->content_src)
181 || json_add_str(priv, "type", desc->content_type)
182 || json_add_str(pub, "id", appid)
183 || json_add_str(pub, "version", desc->version)
184 || json_add_int(pub, "width", desc->width)
185 || json_add_int(pub, "height", desc->height)
186 || json_add_str(pub, "name", desc->name)
187 || json_add_str(pub, "description", desc->description)
188 || json_add_str(pub, "shortname", desc->name_short)
189 || json_add_str(pub, "author", desc->author))
192 feat = desc->features;
194 static const char prefix[] = FWK_PREFIX_PLUGIN;
195 if (!memcmp(feat->name, prefix, sizeof prefix - 1)) {
196 str = json_object_new_string (feat->name + sizeof prefix - 1);
199 if (json_object_array_add(plugs, str)) {
200 json_object_put(str);
207 /* record the application structure */
208 if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) {
209 bya = json_object_new_object();
212 if (json_add(apps->byapp, desc->id, bya)) {
213 json_object_put(bya);
218 if (json_add(apps->direct, appid, priv))
220 json_object_get(priv);
222 if (json_add(bya, desc->version, priv)) {
223 json_object_put(priv);
227 if (json_object_array_add(apps->pubarr, pub))
230 wgt_info_unref(info);
234 json_object_put(priv);
235 wgt_info_unref(info);
246 static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *))
251 struct dirent entry, *e;
253 /* opens the directory */
254 dir = opendir(data->path);
258 /* prepare appending entry names */
259 beg = data->path + data->length;
262 /* enumerate entries */
263 rc = readdir_r(dir, &entry, &e);
265 if (entry.d_name[0] != '.' || (entry.d_name[1] && (entry.d_name[1] != '.' || entry.d_name[2]))) {
267 end = stpcpy(beg, entry.d_name);
268 data->length = end - data->path;
269 /* call the function */
274 rc = readdir_r(dir, &entry, &e);
280 static int recordapp(struct enumdata *data)
282 return addapp(&data->apps, data->path);
285 /* enumerate the versions */
286 static int enumvers(struct enumdata *data)
288 int rc = enumentries(data, recordapp);
289 return !rc || errno != ENOTDIR ? 0 : rc;
292 /* regenerate the list of applications */
293 int af_db_update_applications(struct af_db *afdb)
296 struct enumdata edata;
297 struct afapps oldapps;
299 /* create the result */
300 edata.apps.pubarr = json_object_new_array();
301 edata.apps.direct = json_object_new_object();
302 edata.apps.byapp = json_object_new_object();
303 if (edata.apps.pubarr == NULL || edata.apps.direct == NULL || edata.apps.byapp == NULL) {
308 for (iroot = 0 ; iroot < afdb->nrroots ; iroot++) {
309 edata.length = stpcpy(edata.path, afdb->roots[iroot]) - edata.path;
310 assert(edata.length < sizeof edata.path);
311 /* enumerate the applications */
312 rc = enumentries(&edata, enumvers);
316 /* commit the result */
317 oldapps = afdb->applications;
318 afdb->applications = edata.apps;
319 json_object_put(oldapps.pubarr);
320 json_object_put(oldapps.direct);
321 json_object_put(oldapps.byapp);
325 json_object_put(edata.apps.pubarr);
326 json_object_put(edata.apps.direct);
327 json_object_put(edata.apps.byapp);
331 int af_db_ensure_applications(struct af_db *afdb)
333 return afdb->applications.pubarr ? 0 : af_db_update_applications(afdb);
336 struct json_object *af_db_application_list(struct af_db *afdb)
338 return af_db_ensure_applications(afdb) ? NULL : afdb->applications.pubarr;
341 struct json_object *af_db_get_application(struct af_db *afdb, const char *id)
343 struct json_object *result;
344 if (!af_db_ensure_applications(afdb) && json_object_object_get_ex(afdb->applications.direct, id, &result))
349 struct json_object *af_db_get_application_public(struct af_db *afdb, const char *id)
351 struct json_object *result = af_db_get_application(afdb, id);
352 return result && json_object_object_get_ex(result, "public", &result) ? result : NULL;
358 #if defined(TESTAPPFWK)
362 struct af_db *afdb = af_db_create();
363 af_db_add_root(afdb,FWK_APP_DIR);
364 af_db_update_applications(afdb);
365 printf("array = %s\n", json_object_to_json_string_ext(afdb->applications.pubarr, 3));
366 printf("direct = %s\n", json_object_to_json_string_ext(afdb->applications.direct, 3));
367 printf("byapp = %s\n", json_object_to_json_string_ext(afdb->applications.byapp, 3));