4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
24 #include <sys/types.h>
31 struct json_object *pubarr;
32 struct json_object *direct;
33 struct json_object *byapp;
40 struct afapps applications;
43 struct appfwk *appfwk_create()
45 struct appfwk *appfwk = malloc(sizeof * appfwk);
52 appfwk->applications.pubarr = NULL;
53 appfwk->applications.direct = NULL;
54 appfwk->applications.byapp = NULL;
59 void appfwk_addref(struct appfwk *appfwk)
65 void appfwk_unref(struct appfwk *appfwk)
68 if (!--appfwk->refcount) {
69 while (appfwk->nrroots)
70 free(appfwk->roots[--appfwk->nrroots]);
76 int appfwk_add_root(struct appfwk *appfwk, const char *path)
83 /* don't depend on the cwd and unique name */
84 r = realpath(path, NULL);
88 /* avoiding duplications */
90 roots = appfwk->roots;
91 for (i = 0 ; i < n ; i++) {
92 if (!strcmp(r, roots[i])) {
99 roots = realloc(roots, (n + 1) * sizeof(roots[0]));
106 appfwk->roots = roots;
111 static int json_add(struct json_object *obj, const char *key, struct json_object *val)
113 json_object_object_add(obj, key, val);
117 static int json_add_str(struct json_object *obj, const char *key, const char *val)
119 struct json_object *str = json_object_new_string (val ? val : "");
120 return str ? json_add(obj, key, str) : -1;
123 static int json_add_int(struct json_object *obj, const char *key, int val)
125 struct json_object *v = json_object_new_int (val);
126 return v ? json_add(obj, key, v) : -1;
129 static int addapp(struct afapps *apps, const char *path)
131 struct wgt_info *info;
132 const struct wgt_desc *desc;
133 const struct wgt_desc_feature *feat;
134 struct json_object *priv = NULL, *pub, *bya, *plugs, *str;
137 /* connect to the widget */
138 info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0);
141 desc = wgt_info_desc(info);
143 /* create the application id */
144 appid = alloca(2 + strlen(desc->id) + strlen(desc->version));
145 end = stpcpy(appid, desc->id);
147 strcpy(end, desc->version);
149 /* create the application structure */
150 priv = json_object_new_object();
154 pub = json_object_new_object();
158 if (json_add(priv, "public", pub)) {
159 json_object_put(pub);
163 plugs = json_object_new_array();
167 if (json_add(priv, "plugins", plugs)) {
168 json_object_put(plugs);
172 if(json_add_str(pub, "id", appid)
173 || json_add_str(priv, "id", desc->id)
174 || json_add_str(pub, "version", desc->version)
175 || json_add_str(priv, "path", path)
176 || json_add_int(pub, "width", desc->width)
177 || json_add_int(pub, "height", desc->height)
178 || json_add_str(pub, "name", desc->name)
179 || json_add_str(pub, "description", desc->description)
180 || json_add_str(pub, "shortname", desc->name_short)
181 || json_add_str(pub, "author", desc->author))
184 feat = desc->features;
186 static const char prefix[] = FWK_PREFIX_PLUGIN;
187 if (!memcmp(feat->name, prefix, sizeof prefix - 1)) {
188 str = json_object_new_string (feat->name + sizeof prefix - 1);
191 if (json_object_array_add(plugs, str)) {
192 json_object_put(str);
199 /* record the application structure */
200 if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) {
201 bya = json_object_new_object();
204 if (json_add(apps->byapp, desc->id, bya)) {
205 json_object_put(bya);
210 if (json_add(apps->direct, appid, priv))
212 json_object_get(priv);
214 if (json_add(bya, desc->version, priv)) {
215 json_object_put(priv);
219 if (json_object_array_add(apps->pubarr, pub))
222 wgt_info_unref(info);
226 json_object_put(priv);
227 wgt_info_unref(info);
238 static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *))
243 struct dirent entry, *e;
245 /* opens the directory */
246 dir = opendir(data->path);
250 /* prepare appending entry names */
251 beg = data->path + data->length;
254 /* enumerate entries */
255 rc = readdir_r(dir, &entry, &e);
257 if (entry.d_name[0] != '.' || (entry.d_name[1] && (entry.d_name[1] != '.' || entry.d_name[2]))) {
259 end = stpcpy(beg, entry.d_name);
260 data->length = end - data->path;
261 /* call the function */
266 rc = readdir_r(dir, &entry, &e);
272 static int recordapp(struct enumdata *data)
274 return addapp(&data->apps, data->path);
277 /* enumerate the versions */
278 static int enumvers(struct enumdata *data)
280 int rc = enumentries(data, recordapp);
281 return !rc || errno != ENOTDIR ? 0 : rc;
284 /* regenerate the list of applications */
285 int appfwk_update_applications(struct appfwk *af)
288 struct enumdata edata;
289 struct afapps oldapps;
291 /* create the result */
292 edata.apps.pubarr = json_object_new_array();
293 edata.apps.direct = json_object_new_object();
294 edata.apps.byapp = json_object_new_object();
295 if (edata.apps.pubarr == NULL || edata.apps.direct == NULL || edata.apps.byapp == NULL) {
300 for (iroot = 0 ; iroot < af->nrroots ; iroot++) {
301 edata.length = stpcpy(edata.path, af->roots[iroot]) - edata.path;
302 assert(edata.length < sizeof edata.path);
303 /* enumerate the applications */
304 rc = enumentries(&edata, enumvers);
308 /* commit the result */
309 oldapps = af->applications;
310 af->applications = edata.apps;
311 json_object_put(oldapps.pubarr);
312 json_object_put(oldapps.direct);
313 json_object_put(oldapps.byapp);
317 json_object_put(edata.apps.pubarr);
318 json_object_put(edata.apps.direct);
319 json_object_put(edata.apps.byapp);
323 int appfwk_ensure_applications(struct appfwk *af)
325 return af->applications.pubarr ? 0 : appfwk_update_applications(af);
328 /* regenerate the list of applications */
329 struct json_object *appfwk_application_list(struct appfwk *af)
331 return appfwk_ensure_applications(af) ? NULL : af->applications.pubarr;
337 struct appfwk *af = appfwk_create();
338 appfwk_add_root(af,FWK_APP_DIR);
339 appfwk_update_applications(af);
340 printf("array = %s\n", json_object_to_json_string_ext(af->applications.pubarr, 3));
341 printf("direct = %s\n", json_object_to_json_string_ext(af->applications.direct, 3));
342 printf("byapp = %s\n", json_object_to_json_string_ext(af->applications.byapp, 3));