Merge "Add robustness to mkdir" into tizen
[platform/core/appfw/ail.git] / src / ail_desktop.c
1 /*
2  * ail
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23
24 #define _GNU_SOURCE
25 #include <errno.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <time.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <tzplatform_config.h>
34 #include <xdgmime.h>
35
36 #include <vconf.h>
37 #include <glib.h>
38 #include <grp.h>
39 #include <pwd.h>
40
41 #include "ail_private.h"
42 #include "ail_db.h"
43 #include "ail_sql.h"
44 #include "ail.h"
45
46 #define BUFSIZE 4096
47 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
48
49 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
50 #define argsdelimiter   " \t"
51
52 #define SQL_INSERT_LOCALNAME_STR "insert into localname (package, locale, name) values "
53 #define SQL_INSERT_LOCALNAME_STR_LEN (sizeof(SQL_INSERT_LOCALNAME_STR)-1)
54
55 #define SQL_INSERT_LOCALNAME_INIT_STR  SQL_INSERT_LOCALNAME_STR"( ?, ?, ?) "
56
57 #define SQL_LOCALNAME_TRIPLET_STR  ", ( ?, ?, ?)"
58 #define SQL_LOCALNAME_TRIPLET_STR_LEN (sizeof(SQL_LOCALNAME_TRIPLET_STR)-1)
59
60 typedef enum {
61         NOTI_ADD,
62         NOTI_UPDATE,
63         NOTI_REMOVE,
64         NOTI_MAX,
65 } noti_type;
66
67 struct entry_parser {
68         const char *field;
69         ail_error_e (*value_cb)(void *data, char *tag, char *value, uid_t uid);
70 };
71
72 inline static char *_ltrim(char *str)
73 {
74         if (!str) return NULL;
75
76         while (*str == ' ' || *str == '\t' || *str == '\n') str ++;
77
78         return str;
79 }
80
81
82
83 inline static int _rtrim(char *str)
84 {
85         int len;
86
87         len = strlen(str);
88         while (--len >= 0 && (str[len] == ' ' || str[len] == '\n' || str[len] == '\t')) str[len] = '\0';
89
90         return len;
91 }
92
93 struct name_item {
94         char *locale;
95         char *name;
96 };
97
98 typedef struct {
99         const char*     package;
100         char*           exec;
101         char*           name;
102         char*           type;
103         char*           icon;
104         char*           categories;
105         char*           version;
106         char*           mimetype;
107         char*           x_slp_service;
108         char*           x_slp_packagetype;
109         char*           x_slp_packagecategories;
110         char*           x_slp_packageid;
111         char*           x_slp_uri;
112         char*           x_slp_svc;
113         char*           x_slp_exe_path;
114         char*           x_slp_appid;
115         char*           x_slp_pkgid;
116         char*           x_slp_domain;
117         char*           x_slp_submodemainid;
118         char*           x_slp_installedstorage;
119         int             x_slp_baselayoutwidth;
120         int             x_slp_installedtime;
121         int             nodisplay;
122         int             x_slp_taskmanage;
123         int             x_slp_multiple;
124         int             x_slp_removable;
125         int             x_slp_ishorizontalscale;
126         int             x_slp_enabled;
127         int             x_slp_submode;
128         char*           desktop;
129         GSList*         localname;
130 } desktop_info_s;
131
132
133
134 static ail_error_e _read_exec(void *data, char *tag, char *value, uid_t uid)
135 {
136         desktop_info_s *info = data;
137         char *token_exe_path;
138         char *save_ptr;
139         char *temp_exec;
140
141         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
142         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
143
144         SAFE_FREE_AND_STRDUP(value, info->exec);
145         retv_if(!info->exec, AIL_ERROR_OUT_OF_MEMORY);
146
147         temp_exec = strdup(value);
148         if(!temp_exec) {
149                 free(info->exec);
150                 return AIL_ERROR_OUT_OF_MEMORY;
151         }
152
153         token_exe_path = strtok_r(temp_exec, argsdelimiter, &save_ptr);
154
155         info->x_slp_exe_path = strdup(token_exe_path);
156         if(!info->x_slp_exe_path) {
157                 free(info->exec);
158                 info->exec = NULL;
159                 free(temp_exec);
160                 return AIL_ERROR_OUT_OF_MEMORY;
161         }
162
163         free(temp_exec);
164
165         return AIL_ERROR_OK;
166 }
167
168
169
170 static ail_error_e _read_name(void *data, char *tag, char *value, uid_t uid)
171 {
172         desktop_info_s *info = data;
173
174         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
175         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
176         retv_if(0 == strlen(value), AIL_ERROR_FAIL);
177
178         if (tag && strlen(tag) > 0) {
179                 struct name_item *item;
180                 item = (struct name_item *)calloc(1, sizeof(struct name_item));
181                 retv_if (NULL == item, AIL_ERROR_OUT_OF_MEMORY);
182
183                 SAFE_FREE_AND_STRDUP(tag, item->locale);
184                 if(NULL == item->locale) {
185                         _E("(NULL == item->locale) return\n");
186                         free(item);
187                         return AIL_ERROR_OUT_OF_MEMORY;
188                 }
189
190                 SAFE_FREE_AND_STRDUP(value, item->name);
191                 if(NULL == item->name) {
192                         _E("(NULL == item->name) return\n");
193                         free(item->locale);
194                         free(item);
195                         return AIL_ERROR_OUT_OF_MEMORY;
196                 }
197
198                 info->localname = g_slist_append(info->localname, item);
199
200                 return AIL_ERROR_OK;
201         } else {
202                 SAFE_FREE_AND_STRDUP(value, info->name);
203                 retv_if (!info->name, AIL_ERROR_OUT_OF_MEMORY);
204
205                 return AIL_ERROR_OK;
206         }
207 }
208
209
210
211 static ail_error_e _read_type(void *data, char *tag, char *value, uid_t uid)
212 {
213         desktop_info_s *info = data;
214
215         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
216         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
217
218         SAFE_FREE_AND_STRDUP(value, info->type);
219         retv_if (!info->type, AIL_ERROR_OUT_OF_MEMORY);
220
221         return AIL_ERROR_OK;
222 }
223
224
225 static char*
226 _get_package_from_icon(char* icon)
227 {
228         char* package;
229         char* extension;
230
231         retv_if(!icon, NULL);
232
233         package = strdup(icon);
234         retv_if(!package, NULL);
235         extension = rindex(package, '.');
236         if (extension) {
237                 *extension = '\0';
238         } else {
239                 _E("cannot extract from icon [%s] to package.", icon);
240         }
241
242         return package;
243 }
244
245
246 static char*
247 _get_icon_with_path(char* icon, uid_t uid)
248 {
249         retv_if(!icon, NULL);
250
251         if (index(icon, '/') == NULL) {
252                 char* package;
253                 char* theme = NULL;
254                 char* icon_with_path = NULL;
255                 int len;
256                 char *app_path = NULL;
257
258                 package = _get_package_from_icon(icon);
259                 retv_if(!package, NULL);
260
261 /* "db/setting/theme" is not exist */
262 #if 0
263                 theme = vconf_get_str("db/setting/theme");
264                 if (!theme) {
265                         theme = strdup("default");
266                         if(!theme) {
267                                 free(package);
268                                 return NULL;
269                         }
270                 }
271 #else
272                 theme = strdup("default");
273 #endif
274
275                 len = (0x01 << 7) + strlen(icon) + strlen(package) + strlen(theme);
276                 icon_with_path = malloc(len);
277                 if(icon_with_path == NULL) {
278                         _E("icon_with_path == NULL\n");
279                         free(package);
280                         free(theme);
281                         return NULL;
282                 }
283
284                 memset(icon_with_path, 0, len);
285                 if (uid != GLOBAL_USER)
286                         sqlite3_snprintf( len, icon_with_path, "%s%q", ail_get_icon_path(uid), icon);
287                 else
288                         sqlite3_snprintf( len, icon_with_path, "%s/%q/small/%q", ail_get_icon_path(GLOBAL_USER), theme, icon);
289                         
290                 if (access (icon_with_path, F_OK)) {
291                         app_path = tzplatform_getenv(TZ_SYS_RW_APP);
292                         if (app_path)
293                                 sqlite3_snprintf( len, icon_with_path, "%s/%q/res/icons/%q/small/%q",app_path, package, theme, icon);
294                         if (access (icon_with_path, F_OK))
295                                 _E("Cannot find icon path");
296                 }
297                 free(theme);
298                 free(package);
299                 _D("Icon path : %s", icon_with_path);
300                 return icon_with_path;
301         } else {
302                 char* confirmed_icon = NULL;
303
304                 confirmed_icon = strdup(icon);
305                 retv_if(!confirmed_icon, NULL);
306                 return confirmed_icon;
307         }
308 }
309
310
311 static ail_error_e _read_icon(void *data, char *tag, char *value, uid_t uid)
312 {
313         desktop_info_s *info = data;
314
315         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
316         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
317
318         info->icon = _get_icon_with_path(value, uid);
319
320         retv_if (!info->icon, AIL_ERROR_OUT_OF_MEMORY);
321
322         return AIL_ERROR_OK;
323 }
324
325
326
327 static ail_error_e _read_categories(void *data, char *tag, char *value, uid_t uid)
328 {
329         desktop_info_s *info = data;
330
331         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
332         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
333
334         SAFE_FREE_AND_STRDUP(value, info->categories);
335         retv_if (!info->categories, AIL_ERROR_OUT_OF_MEMORY);
336
337         return AIL_ERROR_OK;
338 }
339
340
341
342 static ail_error_e _read_version(void *data, char *tag, char *value, uid_t uid)
343 {
344         desktop_info_s *info = data;
345
346         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
347         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
348
349         SAFE_FREE_AND_STRDUP(value, info->version);
350         retv_if (!info->version, AIL_ERROR_OUT_OF_MEMORY);
351
352         return AIL_ERROR_OK;
353 }
354
355
356
357 static ail_error_e _read_mimetype(void *data, char *tag, char *value, uid_t uid)
358 {
359         desktop_info_s *info = data;
360         int size, total_len = 0;
361         char *mimes_origin, *mimes_changed, *token_unalias, *save_ptr;
362
363         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
364         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
365         retv_if(!strlen(value), AIL_ERROR_FAIL);
366
367         mimes_origin = strdup(value);
368         retv_if(!mimes_origin, AIL_ERROR_OUT_OF_MEMORY);
369
370         size = getpagesize();
371         mimes_changed = calloc(1, size);
372         if(mimes_changed == NULL) {
373                 _E("(mimes_changed == NULL) return\n");
374                 free(mimes_origin);
375                 return AIL_ERROR_OUT_OF_MEMORY;
376         }
377
378         token_unalias = strtok_r(mimes_origin, ";", &save_ptr);
379
380         while (token_unalias) {
381                 int token_len;
382                 const char *token_alias;
383
384                 _rtrim(token_unalias);
385                 token_unalias = _ltrim(token_unalias);
386
387                 token_alias = xdg_mime_unalias_mime_type(token_unalias);
388                 if (!token_alias) continue;
389
390                 token_len = strlen(token_alias);
391                 if (total_len + token_len + (1<<1) >= size) {
392                         char *tmp;
393                         size *= 2;
394                         tmp = realloc(mimes_changed, size);
395                         if(!tmp) {
396                                 free(mimes_changed);
397                                 return AIL_ERROR_OUT_OF_MEMORY;
398                         }
399                         mimes_changed = tmp;
400                 }
401
402                 strncat(mimes_changed, token_alias, size-1);
403                 total_len += token_len;
404
405                 token_unalias = strtok_r(NULL, ";", &save_ptr);
406                 if (token_unalias) {
407                         strncat(mimes_changed, ";", size-strlen(mimes_changed)-1);
408                 }
409         }
410
411         SAFE_FREE(info->mimetype);
412         info->mimetype = mimes_changed;
413
414         return AIL_ERROR_OK;
415 }
416
417
418
419 static ail_error_e _read_nodisplay(void *data, char *tag, char *value, uid_t uid)
420 {
421         desktop_info_s* info = data;
422
423         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
424         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
425
426         info->nodisplay = !strcasecmp(value, "true");
427
428         return AIL_ERROR_OK;
429 }
430
431
432
433 static ail_error_e _read_x_slp_service(void *data, char *tag, char *value, uid_t uid)
434 {
435         desktop_info_s *info = data;
436
437         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
438         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
439
440         SAFE_FREE_AND_STRDUP(value, info->x_slp_service);
441         retv_if(!info->x_slp_service, AIL_ERROR_OUT_OF_MEMORY);
442
443         return AIL_ERROR_OK;
444 }
445
446
447
448 static ail_error_e _read_x_slp_packagetype(void *data, char *tag, char *value, uid_t uid)
449 {
450         desktop_info_s *info = data;
451
452         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
453         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
454
455         SAFE_FREE_AND_STRDUP(value, info->x_slp_packagetype);
456         retv_if(!info->x_slp_packagetype, AIL_ERROR_OUT_OF_MEMORY);
457
458         return AIL_ERROR_OK;
459 }
460
461
462
463 static ail_error_e _read_x_slp_packagecategories(void *data, char *tag, char *value, uid_t uid)
464 {
465         desktop_info_s *info = data;
466
467         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
468         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
469
470         SAFE_FREE_AND_STRDUP(value, info->x_slp_packagecategories);
471         retv_if(!info->x_slp_packagecategories, AIL_ERROR_OUT_OF_MEMORY);
472
473         return AIL_ERROR_OK;
474 }
475
476
477
478 static ail_error_e _read_x_slp_packageid(void *data, char *tag, char *value, uid_t uid)
479 {
480         desktop_info_s *info = data;
481
482         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
483         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
484
485         SAFE_FREE_AND_STRDUP(value, info->x_slp_packageid);
486         retv_if(!info->x_slp_packageid, AIL_ERROR_OUT_OF_MEMORY);
487
488         return AIL_ERROR_OK;
489 }
490
491 static ail_error_e _read_x_slp_submodemainid(void *data, char *tag, char *value, uid_t uid)
492 {
493         desktop_info_s *info = data;
494
495         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
496         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
497
498         SAFE_FREE_AND_STRDUP(value, info->x_slp_submodemainid);
499         retv_if(!info->x_slp_submodemainid, AIL_ERROR_OUT_OF_MEMORY);
500
501         return AIL_ERROR_OK;
502 }
503
504 static ail_error_e _read_x_slp_installedstorage(void *data, char *tag, char *value, uid_t uid)
505 {
506         desktop_info_s *info = data;
507
508         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
509         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
510
511         SAFE_FREE_AND_STRDUP(value, info->x_slp_installedstorage);
512         retv_if(!info->x_slp_installedstorage, AIL_ERROR_OUT_OF_MEMORY);
513
514         return AIL_ERROR_OK;
515 }
516
517 static ail_error_e _read_x_slp_uri(void *data, char *tag, char *value, uid_t uid)
518 {
519         desktop_info_s *info = data;
520
521         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
522         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
523
524         SAFE_FREE_AND_STRDUP(value, info->x_slp_uri);
525         retv_if(!info->x_slp_uri, AIL_ERROR_OUT_OF_MEMORY);
526
527         return AIL_ERROR_OK;
528 }
529
530
531
532 static ail_error_e _read_x_slp_svc(void *data, char *tag, char *value, uid_t uid)
533 {
534         desktop_info_s *info = data;
535
536         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
537         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
538
539         SAFE_FREE_AND_STRDUP(value, info->x_slp_svc);
540         retv_if(!info->x_slp_svc, AIL_ERROR_OUT_OF_MEMORY);
541
542         return AIL_ERROR_OK;
543 }
544
545
546
547 static ail_error_e _read_x_slp_taskmanage(void *data, char *tag, char *value, uid_t uid)
548 {
549         desktop_info_s *info = data;
550
551         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
552         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
553
554         info->x_slp_taskmanage = !strcasecmp(value, "true");
555
556         return AIL_ERROR_OK;
557 }
558
559
560
561 static ail_error_e _read_x_slp_multiple(void *data, char *tag, char *value, uid_t uid)
562 {
563         desktop_info_s *info = data;
564
565         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
566         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
567
568         info->x_slp_multiple = !strcasecmp(value, "true");
569
570         return AIL_ERROR_OK;
571 }
572
573
574
575 static ail_error_e _read_x_slp_removable(void *data, char *tag, char *value, uid_t uid)
576 {
577         desktop_info_s *info = data;
578
579         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
580         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
581
582         info->x_slp_removable = !strcasecmp(value, "true");
583
584         return AIL_ERROR_OK;
585 }
586
587
588 static ail_error_e _read_x_slp_submode(void *data, char *tag, char *value, uid_t uid)
589 {
590         desktop_info_s *info = data;
591
592         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
593         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
594
595         info->x_slp_submode = !strcasecmp(value, "true");
596
597         return AIL_ERROR_OK;
598 }
599
600 static ail_error_e _read_x_slp_appid(void *data, char *tag, char *value, uid_t uid)
601 {
602         desktop_info_s *info = data;
603
604         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
605         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
606
607         SAFE_FREE_AND_STRDUP(value, info->x_slp_appid);
608         retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
609
610         return AIL_ERROR_OK;
611 }
612
613
614 static ail_error_e _read_x_slp_pkgid(void *data, char *tag, char *value, uid_t uid)
615 {
616         desktop_info_s *info = data;
617
618         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
619         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
620
621         SAFE_FREE_AND_STRDUP(value, info->x_slp_pkgid);
622         retv_if(!info->x_slp_pkgid, AIL_ERROR_OUT_OF_MEMORY);
623
624         return AIL_ERROR_OK;
625 }
626
627
628 static ail_error_e _read_x_slp_domain(void *data, char *tag, char *value, uid_t uid)
629 {
630         desktop_info_s *info = data;
631
632         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
633         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
634
635         SAFE_FREE_AND_STRDUP(value, info->x_slp_domain);
636         retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
637
638         return AIL_ERROR_OK;
639 }
640
641
642 static ail_error_e _read_x_slp_enabled(void *data, char *tag, char *value, uid_t uid)
643 {
644         desktop_info_s *info = data;
645
646         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
647         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
648
649         info->x_slp_enabled = !strcasecmp(value, "true");
650
651         return AIL_ERROR_OK;
652 }
653
654
655 static struct entry_parser entry_parsers[] = {
656         {
657                 .field = "exec",
658                 .value_cb = _read_exec,
659         },
660         {
661                 .field = "name",
662                 .value_cb = _read_name,
663         },
664         {
665                 .field = "type",
666                 .value_cb = _read_type,
667         },
668         {
669                 .field = "icon",
670                 .value_cb = _read_icon,
671         },
672         {
673                 .field = "categories",
674                 .value_cb = _read_categories,
675         },
676         {
677                 .field = "version",
678                 .value_cb = _read_version,
679         },
680         {
681                 .field = "mimetype",
682                 .value_cb = _read_mimetype,
683         },
684         {
685                 .field = "x-tizen-service",
686                 .value_cb = _read_x_slp_service,
687         },
688         {
689                 .field = "x-tizen-packagetype",
690                 .value_cb = _read_x_slp_packagetype,
691         },
692         {
693                 .field = "x-tizen-packagecategories",
694                 .value_cb = _read_x_slp_packagecategories,
695         },
696         {
697                 .field = "x-tizen-packageid",
698                 .value_cb = _read_x_slp_packageid,
699         },
700         {
701                 .field = "x-tizen-submodemainid",
702                 .value_cb = _read_x_slp_submodemainid,
703         },
704         {
705                 .field = "x-tizen-installedstorage",
706                 .value_cb = _read_x_slp_installedstorage,
707         },
708         {
709                 .field = "x-tizen-uri",
710                 .value_cb = _read_x_slp_uri,
711         },
712         {
713                 .field = "x-tizen-svc",
714                 .value_cb = _read_x_slp_svc,
715         },
716         {
717                 .field = "nodisplay",
718                 .value_cb = _read_nodisplay,
719         },
720         {
721                 .field = "x-tizen-taskmanage",
722                 .value_cb = _read_x_slp_taskmanage,
723         },
724         {
725                 .field = "x-tizen-enabled",
726                 .value_cb = _read_x_slp_enabled,
727         },
728         {
729                 .field = "x-tizen-submode",
730                 .value_cb = _read_x_slp_submode,
731         },
732         {
733                 .field = "x-tizen-multiple",
734                 .value_cb = _read_x_slp_multiple,
735         },
736         {
737                 .field = "x-tizen-removable",
738                 .value_cb = _read_x_slp_removable,
739         },
740         {
741                 .field = "x-tizen-appid",
742                 .value_cb = _read_x_slp_appid,
743         },
744         {
745                 .field = "x-tizen-pkgid",
746                 .value_cb = _read_x_slp_pkgid,
747         },
748         {
749                 .field = "x-tizen-domain",
750                 .value_cb = _read_x_slp_domain,
751         },
752         {
753                 .field = "x-tizen-enabled",
754                 .value_cb = _read_x_slp_domain,
755         },
756         {
757                 .field = NULL,
758                 .value_cb = NULL,
759         },
760 };
761
762
763
764 /* Utility functions */
765 static int _count_all(uid_t uid)
766 {
767         ail_error_e ret;
768         int count;
769
770         if (uid != GLOBAL_USER)
771                 ret = ail_filter_count_usr_appinfo(NULL, &count, uid);
772         else
773                 ret = ail_filter_count_appinfo(NULL, &count);   
774         if(ret != AIL_ERROR_OK) {
775                 _E("cannot count appinfo");
776                 count = -1;
777         }
778
779         retv_if(ret != AIL_ERROR_OK, -1);
780
781         return count;
782 }
783
784 char *_pkgname_to_desktop(const char *package, uid_t uid)
785 {
786         char *desktop;
787         char *desktop_path;
788         int size;
789
790         retv_if(!package, NULL);
791
792   desktop_path = ail_get_desktop_path(uid);
793
794         size = strlen(desktop_path) + strlen(package) + 10;
795         desktop = malloc(size);
796         retv_if(!desktop, NULL);
797
798   snprintf(desktop, size, "%s/%s.desktop", desktop_path, package);
799
800   _D("uid: %d / desktop: [%s]\n",  uid, desktop);
801
802         return desktop;
803 }
804
805 static inline int _bind_local_info(desktop_info_s* info, sqlite3_stmt * stmt)
806 {
807         int ret = 0;
808         unsigned long i = 0;
809         struct name_item *item;
810         GSList* localname;
811         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
812         retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
813         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
814         localname = info->localname;
815         while (localname) {
816                 item = (struct name_item *)     localname->data;
817                 if (item && item->locale && item->name) {
818                         // Bind values for a triplet : package, locale, name
819                         retv_if(db_bind_text(stmt, i+1, info->package) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
820                         retv_if(db_bind_text(stmt, i+2, item->locale) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
821                         retv_if(db_bind_text(stmt, i+3, item->name) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
822                         i += 3;
823                 }
824                 localname = g_slist_next(localname);
825         }
826         return AIL_ERROR_OK;
827 }
828
829
830 static inline int _len_local_info(desktop_info_s* info)
831 {
832         int len = 0;
833         struct name_item *item;
834         GSList* localname;
835         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
836         if(info->localname)     {
837                 localname = info->localname;
838                 while (localname) {
839                         item = (struct name_item *)     localname->data;
840                         if (item && item->locale && item->name)
841                                 len ++;
842                         localname = g_slist_next(localname);
843                 }
844         }
845         return len;
846 }
847
848
849 static inline int _insert_local_info(desktop_info_s* info, uid_t uid)
850 {
851         int len_query = SQL_INSERT_LOCALNAME_STR_LEN;
852         int nb_locale_args;
853         char *query;
854         int ret = AIL_ERROR_OK;
855         sqlite3_stmt *stmt = NULL;
856         int i = 0;
857         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
858         retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
859
860         nb_locale_args = _len_local_info(info);
861
862         retv_if(!nb_locale_args, AIL_ERROR_INVALID_PARAMETER);
863
864         len_query += SQL_LOCALNAME_TRIPLET_STR_LEN*nb_locale_args +1;
865
866         query = (char *) malloc(len_query);
867         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
868         stpncpy(query, SQL_INSERT_LOCALNAME_INIT_STR, len_query);
869         for (i = 0; i <  nb_locale_args - 1; i++)
870                 strcat(query, SQL_LOCALNAME_TRIPLET_STR);
871
872         do {
873                 if(uid != GLOBAL_USER)
874                         ret = db_prepare_rw(query, &stmt);
875                 else 
876                         ret = db_prepare_globalrw(query, &stmt);
877                 if (ret < 0) break;
878
879                 ret = _bind_local_info(info, stmt);
880                 if (ret < 0) {
881                         _E("Can't bind locale information to this query - %s. ",query);
882                         db_finalize(stmt);
883                         break;
884                 }
885                 ret = db_step(stmt);
886                 if (ret != AIL_ERROR_NO_DATA) {
887                         /* Insert Request doesn't return any data.
888                          * db_step should returns AIL_ERROR_NO_DATA in this case. */
889                         _E("Can't execute this query - %s. ",query);
890                         db_finalize(stmt);
891                         break;
892                 }
893                 ret = db_finalize(stmt);
894         } while(0);
895
896         free(query);
897         return ret;
898 }
899
900 static inline int _strlen_desktop_info(desktop_info_s* info)
901 {
902         int len = 0;
903
904         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
905
906         if (info->package) len += strlen(info->package);
907         if (info->exec) len += strlen(info->exec);
908         if (info->name) len += strlen(info->name);
909         if (info->type) len += strlen(info->type);
910         if (info->icon) len += strlen(info->icon);
911         if (info->categories) len += strlen(info->categories);
912         if (info->version) len += strlen(info->version);
913         if (info->mimetype) len += strlen(info->mimetype);
914         if (info->x_slp_service) len += strlen(info->x_slp_service);
915         if (info->x_slp_packagetype) len += strlen(info->x_slp_packagetype);
916         if (info->x_slp_packagecategories) len += strlen(info->x_slp_packagecategories);
917         if (info->x_slp_packageid) len += strlen(info->x_slp_packageid);
918         if (info->x_slp_uri) len += strlen(info->x_slp_uri);
919         if (info->x_slp_svc) len += strlen(info->x_slp_svc);
920         if (info->x_slp_exe_path) len += strlen(info->x_slp_exe_path);
921         if (info->x_slp_appid) len += strlen(info->x_slp_appid);
922         if (info->desktop) len += strlen(info->desktop);
923         if (info->x_slp_submodemainid) len += strlen(info->x_slp_submodemainid);
924         if (info->x_slp_installedstorage) len += strlen(info->x_slp_installedstorage);
925
926         return len;
927 }
928
929
930 int __is_ail_initdb(void)
931 {
932         if( getenv("AIL_INITDB") || getenv("INITDB") )
933                 return 1;
934         else
935                 return 0;
936 }
937
938 /* Manipulating desktop_info functions */
939 static ail_error_e _init_desktop_info(desktop_info_s *info, const char *package, uid_t uid)
940 {
941         static int is_initdb = -1;
942
943   _D("package - [%s].", package);
944
945         if(is_initdb == -1)
946                 is_initdb = __is_ail_initdb();
947
948         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
949         retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
950
951         /* defaults */
952         info->package = package;
953
954         info->x_slp_taskmanage = 1;
955         info->x_slp_removable = 1;
956         info->x_slp_submode = 0;
957
958         if(is_initdb)
959                 info->x_slp_installedtime = 0;
960         else
961                 info->x_slp_installedtime = time(NULL);
962
963 #ifdef PKGTYPE
964         info->x_slp_packagetype = strdup(PKGTYPE);
965 #else
966         info->x_slp_packagetype = strdup("rpm");
967 #endif
968         retv_if(!info->x_slp_packagetype, AIL_ERROR_OUT_OF_MEMORY);
969
970         info->x_slp_packageid = strdup(package);
971         retv_if(!info->x_slp_packageid, AIL_ERROR_OUT_OF_MEMORY);
972         info->x_slp_appid = strdup(package);
973         retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
974
975         info->x_slp_enabled = 1;
976
977         info->desktop = _pkgname_to_desktop(package, uid);
978         retv_if(!info->desktop, AIL_ERROR_FAIL);
979
980   _D("desktop - [%s].", info->desktop);
981
982         return AIL_ERROR_OK;
983 }
984
985
986
987 static ail_error_e _read_desktop_info(desktop_info_s* info,uid_t uid)
988 {
989         char *line = NULL;
990         FILE *fp;
991         size_t size = 0;
992         ssize_t read;
993
994         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
995
996         fp = fopen(info->desktop, "r");
997         retv_if(!fp, AIL_ERROR_FAIL);
998
999         while ((read = getline(&line, &size, fp)) != -1) {
1000                 int len, idx;
1001                 char *tmp, *field, *field_name, *tag, *value;
1002
1003                 tmp = _ltrim(line);
1004                 if(tmp == NULL) continue;
1005                 if (*tmp == '#') continue;
1006                 if (_rtrim(tmp) <= 0) continue;
1007
1008                 len = strlen(line) + 1;
1009                 field = calloc(1, len);
1010                 field_name = calloc(1, len);
1011                 tag = calloc(1, len);
1012                 value = calloc(1, len);
1013
1014                 if (!field || !field_name || !tag || !value) {
1015                         goto NEXT;
1016                 }
1017
1018                 sscanf(tmp, "%[^=]=%[^\n]", field, value);
1019                 _rtrim(field);
1020                 tmp = _ltrim(value);
1021
1022                 sscanf(field, "%[^[][%[^]]]", field_name, tag);
1023
1024                 if (!field_name || !strlen(field_name)){
1025                         goto NEXT;
1026                 }
1027
1028                 for (idx = 0; entry_parsers[idx].field; idx ++) {
1029                         if (!g_ascii_strcasecmp(entry_parsers[idx].field, field_name) && entry_parsers[idx].value_cb) {
1030                                 if (entry_parsers[idx].value_cb(info, tag, tmp,uid) != AIL_ERROR_OK) {
1031                                         _E("field - [%s] is wrong.", field_name);
1032                                 }
1033                                 break;
1034                         }
1035                 }
1036 NEXT:
1037                 SAFE_FREE(field);
1038                 SAFE_FREE(field_name);
1039                 SAFE_FREE(tag);
1040                 SAFE_FREE(value);
1041         }
1042
1043         _D("Read (%s).", info->package);
1044         fclose(fp);
1045
1046         return AIL_ERROR_OK;
1047 }
1048
1049
1050 static ail_error_e _retrieve_all_column_to_desktop_info(desktop_info_s* info, sqlite3_stmt *stmt)
1051 {
1052         int i, j;
1053         ail_error_e err;
1054         char **values;
1055         char *col;
1056
1057         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1058
1059         values = calloc(NUM_OF_PROP, sizeof(char *));
1060         retv_if(!values, AIL_ERROR_OUT_OF_MEMORY);
1061
1062         for (i = 0; i < NUM_OF_PROP; i++) {
1063                 err = db_column_str(stmt, i, &col);
1064                 if (AIL_ERROR_OK != err)
1065                         break;
1066
1067                 if (!col) {
1068                         values[i] = NULL;
1069                 } else {
1070                         values[i] = strdup(col);
1071                         if (!values[i]) {
1072                                 err = AIL_ERROR_OUT_OF_MEMORY;
1073                                 goto NEXT;
1074                         }
1075                 }
1076         }
1077
1078         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_EXEC_STR], info->exec);
1079         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_NAME_STR], info->name);
1080         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_TYPE_STR], info->type);
1081         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_ICON_STR], info->icon);
1082         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_CATEGORIES_STR], info->categories);
1083         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_VERSION_STR], info->version);
1084         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_MIMETYPE_STR], info->mimetype);
1085         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SERVICE_STR], info->x_slp_service);
1086         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGETYPE_STR], info->x_slp_packagetype);
1087         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGECATEGORIES_STR], info->x_slp_packagecategories);
1088         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGEID_STR], info->x_slp_packageid);
1089         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_URI_STR], info->x_slp_uri);
1090         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SVC_STR], info->x_slp_svc);
1091         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_EXE_PATH], info->x_slp_exe_path);
1092         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_APPID_STR], info->x_slp_appid);
1093         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PKGID_STR], info->x_slp_pkgid);
1094         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_DOMAIN_STR], info->x_slp_domain);
1095         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SUBMODEMAINID_STR], info->x_slp_submodemainid);
1096         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR], info->x_slp_installedstorage);
1097
1098         info->x_slp_installedtime = atoi(values[E_AIL_PROP_X_SLP_INSTALLEDTIME_INT]);
1099
1100         info->nodisplay = atoi(values[E_AIL_PROP_NODISPLAY_BOOL]);
1101         info->x_slp_taskmanage = atoi(values[E_AIL_PROP_X_SLP_TASKMANAGE_BOOL]);
1102         info->x_slp_multiple = atoi(values[E_AIL_PROP_X_SLP_MULTIPLE_BOOL]);
1103         info->x_slp_removable = atoi(values[E_AIL_PROP_X_SLP_REMOVABLE_BOOL]);
1104         info->x_slp_ishorizontalscale = atoi(values[E_AIL_PROP_X_SLP_ISHORIZONTALSCALE_BOOL]);
1105         info->x_slp_enabled = atoi(values[E_AIL_PROP_X_SLP_ENABLED_BOOL]);
1106         info->x_slp_submode = atoi(values[E_AIL_PROP_X_SLP_SUBMODE_BOOL]);
1107
1108         err = AIL_ERROR_OK;
1109
1110 NEXT:
1111         for (j = 0; j < i; ++j) {
1112                 if (values[j])
1113                         free(values[j]);
1114         }
1115         if (values)
1116                 free(values);
1117         return err;
1118 }
1119
1120
1121 static ail_error_e _load_desktop_info(desktop_info_s* info, uid_t uid)
1122 {
1123         ail_error_e ret;
1124         char query[AIL_SQL_QUERY_MAX_LEN];
1125         sqlite3_stmt *stmt = NULL;
1126         char w[AIL_SQL_QUERY_MAX_LEN];
1127
1128         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1129
1130         snprintf(w, sizeof(w), sql_get_filter(E_AIL_PROP_X_SLP_APPID_STR), info->package);
1131
1132         snprintf(query, sizeof(query), "SELECT %s FROM %s WHERE %s",SQL_FLD_APP_INFO, SQL_TBL_APP_INFO, w);
1133
1134         do {
1135                 ret = db_open(DB_OPEN_RO, uid);
1136                 if (ret < 0) break;
1137 //is_admin
1138                 ret = db_prepare(query, &stmt);
1139                 //ret = db_prepare_globalro(query, &stmt);
1140                 if (ret < 0) break;
1141
1142                 ret = db_step(stmt);
1143                 if (ret < 0) {
1144                         db_finalize(stmt);
1145                         break;
1146                 }
1147
1148                 ret = _retrieve_all_column_to_desktop_info(info, stmt);
1149                 if (ret < 0) {
1150                         db_finalize(stmt);
1151                         break;
1152                 }
1153
1154                 ret = db_finalize(stmt);
1155                 if (ret < 0) break;
1156
1157                 return AIL_ERROR_OK;
1158         } while(0);
1159
1160         return ret;
1161 }
1162
1163 static ail_error_e _modify_desktop_info_bool(desktop_info_s* info,
1164                                                   const char *property,
1165                                                   bool value)
1166 {
1167         ail_prop_bool_e prop;
1168         int val;
1169
1170         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1171         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
1172
1173         prop = _ail_convert_to_prop_bool(property);
1174
1175         if (prop < E_AIL_PROP_BOOL_MIN || prop > E_AIL_PROP_BOOL_MAX)
1176                 return AIL_ERROR_INVALID_PARAMETER;
1177
1178         switch (prop) {
1179                 case E_AIL_PROP_X_SLP_ENABLED_BOOL:
1180                         info->x_slp_enabled = (int)value;
1181                         break;
1182                 default:
1183                         return AIL_ERROR_FAIL;
1184         }
1185
1186         return AIL_ERROR_OK;
1187 }
1188
1189
1190 static ail_error_e _modify_desktop_info_str(desktop_info_s* info,
1191                                                   const char *property,
1192                                                   const char *value)
1193 {
1194         ail_prop_bool_e prop;
1195         int val;
1196
1197         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1198         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
1199
1200         prop = _ail_convert_to_prop_str(property);
1201
1202         if (prop < E_AIL_PROP_STR_MIN || prop > E_AIL_PROP_STR_MAX)
1203                 return AIL_ERROR_INVALID_PARAMETER;
1204
1205         switch (prop) {
1206                 case E_AIL_PROP_NAME_STR:
1207                         SAFE_FREE_AND_STRDUP(value, info->name);
1208                         retv_if (!info->name, AIL_ERROR_OUT_OF_MEMORY);
1209                         break;
1210                 case E_AIL_PROP_X_SLP_SVC_STR:
1211                         SAFE_FREE_AND_STRDUP(value, info->x_slp_svc);
1212                         retv_if (!info->x_slp_svc, AIL_ERROR_OUT_OF_MEMORY);
1213                         break;
1214                 case E_AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR:
1215                         SAFE_FREE_AND_STRDUP(value, info->x_slp_installedstorage);
1216                         retv_if (!info->x_slp_installedstorage, AIL_ERROR_OUT_OF_MEMORY);
1217                         break;
1218                 default:
1219                         _E("prop[%d] is not defined\n", prop);
1220                         return AIL_ERROR_FAIL;
1221         }
1222
1223         return AIL_ERROR_OK;
1224 }
1225
1226
1227 static inline void _insert_localname(gpointer data, gpointer user_data, uid_t uid)
1228 {
1229         char query[512];
1230
1231         struct name_item *item = (struct name_item *)data;
1232         desktop_info_s *info = (desktop_info_s *)user_data;
1233
1234         sqlite3_snprintf(sizeof(query), query, "insert into localname (package, locale, name, x_slp_pkgid) "
1235                         "values ('%q', '%q', '%q', '%q');",
1236                         info->package, item->locale, item->name, info->x_slp_pkgid);
1237         if(uid != GLOBAL_USER) {
1238                 if (db_exec_usr_rw(query) < 0)
1239                         _E("Failed to insert local name of package[%s]",info->package);
1240         } else {
1241                 if (db_exec_glo_rw(query) < 0)
1242                         _E("Failed to insert local name of package[%s]",info->package);
1243         }
1244 }
1245
1246 static ail_error_e _insert_desktop_info(desktop_info_s *info, uid_t uid)
1247 {
1248         char *query;
1249         int len;
1250         ail_error_e ret;
1251
1252         len = _strlen_desktop_info(info) + (0x01 << 10);
1253         query = calloc(1, len);
1254         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1255
1256         sqlite3_snprintf(len, query, "insert into app_info ("
1257                 "package, "
1258                 "exec, name, "
1259                 "type, "
1260                 "icon, "
1261                 "categories, "
1262                 "version, "
1263                 "mimetype, "
1264                 "x_slp_service, "
1265                 "x_slp_packagetype, "
1266                 "x_slp_packagecategories, "
1267                 "x_slp_packageid, "
1268                 "x_slp_uri, "
1269                 "x_slp_svc, "
1270                 "x_slp_exe_path, "
1271                 "x_slp_appid, "
1272                 "x_slp_pkgid, "
1273                 "x_slp_domain, "
1274                 "x_slp_submodemainid, "
1275                 "x_slp_installedstorage, "
1276                 "x_slp_baselayoutwidth, "
1277                 "x_slp_installedtime, "
1278                 "nodisplay, "
1279                 "x_slp_taskmanage, "
1280                 "x_slp_multiple, "
1281                 "x_slp_removable, "
1282                 "x_slp_ishorizontalscale, "
1283                 "x_slp_enabled, "
1284                 "x_slp_submode, "
1285                 "desktop) "
1286                 "values "
1287                 "('%q', '%q', '%q', '%q', '%q', "
1288                 "'%q', '%q', '%q', '%q', '%q', "
1289                 "'%q', '%q', '%q', '%q', '%q', "
1290                 "'%q', '%q', '%q', '%q', '%q', "
1291                 "%d, %d, %d, %d, %d, %d, %d,"
1292                 "%d, %d, "
1293                 "'%q');",
1294                 info->package,
1295                 info->exec,
1296                 info->name,
1297                 info->type,
1298                 info->icon,
1299                 info->categories,
1300                 info->version,
1301                 info->mimetype,
1302                 info->x_slp_service,
1303                 info->x_slp_packagetype,
1304                 info->x_slp_packagecategories,
1305                 info->x_slp_packageid,
1306                 info->x_slp_uri,
1307                 info->x_slp_svc,
1308                 info->x_slp_exe_path,
1309                 info->x_slp_appid,
1310                 info->x_slp_pkgid,
1311                 info->x_slp_domain,
1312                 info->x_slp_submodemainid,
1313                 info->x_slp_installedstorage,
1314                 info->x_slp_baselayoutwidth,
1315                 info->x_slp_installedtime,
1316                 info->nodisplay,
1317                 info->x_slp_taskmanage,
1318                 info->x_slp_multiple,
1319                 info->x_slp_removable,
1320                 info->x_slp_ishorizontalscale,
1321                 info->x_slp_enabled,
1322                 info->x_slp_submode,
1323                 info->desktop
1324                 );
1325
1326         ret = db_open(DB_OPEN_RW, uid);
1327         if(ret != AIL_ERROR_OK) {
1328                 _E("(tmp == NULL) return\n");
1329                 free(query);
1330                 return AIL_ERROR_DB_FAILED;
1331         }
1332         if (uid != GLOBAL_USER)
1333                 ret = db_exec_usr_rw(query);
1334         else
1335                 ret = db_exec_glo_rw(query);
1336         
1337         free(query);
1338         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
1339
1340         if (info->localname)
1341                 _insert_local_info(info, uid);
1342
1343         _D("Add (%s).", query);
1344
1345         return AIL_ERROR_OK;
1346 }
1347
1348
1349
1350 static ail_error_e _update_desktop_info(desktop_info_s *info, uid_t uid)
1351 {
1352         char *query;
1353         int len;
1354
1355         retv_if (NULL == info, AIL_ERROR_INVALID_PARAMETER);
1356
1357         if (db_open(DB_OPEN_RW, uid) < 0) {
1358                 return AIL_ERROR_DB_FAILED;
1359         }
1360
1361         len = _strlen_desktop_info(info) + (0x01 << 10);
1362         query = calloc(1, len);
1363         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1364
1365         sqlite3_snprintf ( len, query, "update app_info set "
1366                 "exec='%q', "
1367                 "name='%q', "
1368                 "type='%q', "
1369                 "icon='%q', "
1370                 "categories='%q', "
1371                 "version='%q', "
1372                 "mimetype='%q', "
1373                 "x_slp_service='%q', "
1374                 "x_slp_packagetype='%q', "
1375                 "x_slp_packagecategories='%q', "
1376                 "x_slp_packageid='%q', "
1377                 "x_slp_uri='%q', "
1378                 "x_slp_svc='%q', "
1379                 "x_slp_exe_path='%q', "
1380                 "x_slp_appid='%q', "
1381                 "x_slp_pkgid='%q', "
1382                 "x_slp_domain='%q', "
1383                 "x_slp_submodemainid='%q', "
1384                 "x_slp_installedstorage='%q', "
1385                 "x_slp_baselayoutwidth=%d, "
1386                 "x_slp_installedtime=%d, "
1387                 "nodisplay=%d, "
1388                 "x_slp_taskmanage=%d, "
1389                 "x_slp_multiple=%d, "
1390                 "x_slp_removable=%d, "
1391                 "x_slp_ishorizontalscale=%d, "
1392                 "x_slp_enabled=%d, "
1393                 "x_slp_submode=%d, "
1394                 "desktop='%q'"
1395                 "where package='%q'",
1396                 info->exec,
1397                 info->name,
1398                 info->type,
1399                 info->icon,
1400                 info->categories,
1401                 info->version,
1402                 info->mimetype,
1403                 info->x_slp_service,
1404                 info->x_slp_packagetype,
1405                 info->x_slp_packagecategories,
1406                 info->x_slp_packageid,
1407                 info->x_slp_uri,
1408                 info->x_slp_svc,
1409                 info->x_slp_exe_path,
1410                 info->x_slp_appid,
1411                 info->x_slp_pkgid,
1412                 info->x_slp_domain,
1413                 info->x_slp_submodemainid,
1414                 info->x_slp_installedstorage,
1415                 info->x_slp_baselayoutwidth,
1416                 info->x_slp_installedtime,
1417                 info->nodisplay,
1418                 info->x_slp_taskmanage,
1419                 info->x_slp_multiple,
1420                 info->x_slp_removable,
1421                 info->x_slp_ishorizontalscale,
1422                 info->x_slp_enabled,
1423                 info->x_slp_submode,
1424                 info->desktop,
1425                 info->package);
1426
1427         if(uid != GLOBAL_USER) {
1428                 if (db_exec_usr_rw(query) < 0) {
1429                         free (query);
1430                         return AIL_ERROR_DB_FAILED;
1431                 }
1432         } else {
1433                 if (db_exec_glo_rw(query) < 0) {
1434                         free (query);
1435                         return AIL_ERROR_DB_FAILED;
1436                 }
1437         }
1438         snprintf(query, len, "delete from localname where package = '%s'", info->package);
1439         if (uid != GLOBAL_USER) {
1440                 if (db_exec_usr_rw(query) < 0) {
1441                         free (query);
1442                         return AIL_ERROR_DB_FAILED;
1443                 }
1444         } else {
1445                 if (db_exec_glo_rw(query) < 0) {
1446                         free (query);
1447                         return AIL_ERROR_DB_FAILED;
1448                 }
1449         }
1450         if (info->localname)
1451                 _insert_local_info(info, uid);
1452
1453         _D("Update (%s).", info->package);
1454
1455         free(query);
1456
1457         return AIL_ERROR_OK;
1458 }
1459
1460
1461
1462 static ail_error_e _remove_package(const char* package, uid_t uid)
1463 {
1464         char *query;
1465         int size;
1466
1467         retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
1468
1469         if (db_open(DB_OPEN_RW, uid) < 0) {
1470                 return AIL_ERROR_DB_FAILED;
1471         }
1472
1473         size = strlen(package) + (0x01 << 10);
1474         query = calloc(1, size);
1475         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1476
1477         snprintf(query, size, "delete from app_info where package = '%s'", package);
1478
1479         if(uid != GLOBAL_USER) {
1480                 if (db_exec_usr_rw(query) < 0) {
1481                         free(query);
1482                         return AIL_ERROR_DB_FAILED;
1483                 }
1484         } else {
1485                 if (db_exec_glo_rw(query) < 0) {
1486                         free(query);
1487                         return AIL_ERROR_DB_FAILED;
1488                 }
1489         }
1490         snprintf(query, size, "delete from localname where package = '%s'", package);
1491         _D("query=%s",query);
1492         
1493         if(uid != GLOBAL_USER) {
1494                 if (db_exec_usr_rw(query) < 0) {
1495                         free(query);
1496                         return AIL_ERROR_DB_FAILED;
1497                 }
1498         } else {
1499                 if (db_exec_glo_rw(query) < 0) {
1500                         free(query);
1501                         return AIL_ERROR_DB_FAILED;
1502                 }
1503         }
1504         _D("Remove (%s).", package);
1505         free(query);
1506
1507         return AIL_ERROR_OK;
1508 }
1509
1510 static ail_error_e _clean_pkgid_data(const char* pkgid, uid_t uid)
1511 {
1512         char *query;
1513         int size;
1514
1515         retv_if(!pkgid, AIL_ERROR_INVALID_PARAMETER);
1516
1517         if (db_open(DB_OPEN_RW, uid) ){
1518                 return AIL_ERROR_DB_FAILED;
1519         }
1520
1521         size = strlen(pkgid) + (0x01 << 10);
1522         query = calloc(1, size);
1523         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1524
1525         snprintf(query, size, "delete from app_info where x_slp_pkgid = '%s'", pkgid);
1526
1527         if(uid != GLOBAL_USER) {
1528                 if (db_exec_usr_rw(query) < 0) {
1529                         free(query);
1530                         return AIL_ERROR_DB_FAILED;
1531                 }
1532         } else {
1533                 if (db_exec_glo_rw(query) < 0) {
1534                         free(query);
1535                         return AIL_ERROR_DB_FAILED;
1536                 }
1537         }
1538         snprintf(query, size, "delete from localname where x_slp_pkgid = '%s'", pkgid);
1539         _D("query=%s",query);
1540
1541         if(uid != GLOBAL_USER) {
1542                 if (db_exec_usr_rw(query) < 0) {
1543                         free(query);
1544                         return AIL_ERROR_DB_FAILED;
1545                 }
1546         } else {
1547                 if (db_exec_glo_rw(query) < 0) {
1548                         free(query);
1549                         return AIL_ERROR_DB_FAILED;
1550                 }       
1551         }
1552         _D("Clean pkgid data (%s).", pkgid);
1553         free(query);
1554
1555         return AIL_ERROR_OK;
1556 }
1557
1558 static ail_error_e _send_db_done_noti(noti_type type, const char *package)
1559 {
1560         char *type_string, *noti_string;
1561         int size;
1562
1563         retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
1564
1565         switch (type) {
1566                 case NOTI_ADD:
1567                         type_string = "create";
1568                         break;
1569                 case NOTI_UPDATE:
1570                         type_string = "update";
1571                         break;
1572                 case NOTI_REMOVE:
1573                         type_string = "delete";
1574                         break;
1575                 default:
1576                         return AIL_ERROR_FAIL;
1577         }
1578
1579         size = snprintf(NULL, 0, "%s:%s:%u", type_string, package, getuid());
1580         noti_string = (char*) calloc(size + 1, sizeof(char));
1581         retv_if(!noti_string, AIL_ERROR_OUT_OF_MEMORY);
1582
1583         snprintf(noti_string, size + 1, "%s:%s:%u", type_string, package, getuid());
1584         vconf_set_str(VCONFKEY_AIL_INFO_STATE, noti_string);
1585         vconf_set_str(VCONFKEY_MENUSCREEN_DESKTOP, noti_string); // duplicate, will be removed
1586         _D("Noti : %s", noti_string);
1587
1588         free(noti_string);
1589
1590         return AIL_ERROR_OK;
1591 }
1592
1593
1594 static void inline _name_item_free_func(gpointer data)
1595 {
1596         struct name_item *item = (struct name_item *)data;
1597         if (item){
1598                 SAFE_FREE(item->locale);
1599                 item->locale = NULL;
1600                 SAFE_FREE(item->name);
1601                 item->name = NULL;
1602         }
1603         SAFE_FREE(item);
1604 }
1605
1606 static void _fini_desktop_info(desktop_info_s *info)
1607 {
1608         SAFE_FREE(info->exec);
1609         SAFE_FREE(info->name);
1610         SAFE_FREE(info->type);
1611         SAFE_FREE(info->icon);
1612         SAFE_FREE(info->categories);
1613         SAFE_FREE(info->version);
1614         SAFE_FREE(info->mimetype);
1615         SAFE_FREE(info->x_slp_service);
1616         SAFE_FREE(info->x_slp_packagetype);
1617         SAFE_FREE(info->x_slp_packagecategories);
1618         SAFE_FREE(info->x_slp_packageid);
1619         SAFE_FREE(info->x_slp_uri);
1620         SAFE_FREE(info->x_slp_svc);
1621         SAFE_FREE(info->x_slp_exe_path);
1622         SAFE_FREE(info->x_slp_appid);
1623         SAFE_FREE(info->x_slp_pkgid);
1624         SAFE_FREE(info->x_slp_domain);
1625         SAFE_FREE(info->x_slp_submodemainid);
1626         SAFE_FREE(info->x_slp_installedstorage);
1627         SAFE_FREE(info->desktop);
1628         if (info->localname) {
1629                 g_slist_free_full(info->localname, _name_item_free_func);
1630                 info->localname = NULL;
1631         }
1632
1633         return;
1634 }
1635
1636 static int __is_authorized()
1637 {
1638         uid_t uid = getuid();
1639         if ((uid_t) GLOBAL_USER == uid )
1640                 return 1;
1641         else
1642                 return 0;
1643 }
1644
1645
1646 /* Public functions */
1647 EXPORT_API ail_error_e ail_usr_desktop_add(const char *appid, uid_t uid)
1648 {
1649         desktop_info_s info = {0,};
1650         ail_error_e ret;
1651
1652         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1653
1654         ret = _init_desktop_info(&info, appid, uid);
1655         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1656
1657         ret = _read_desktop_info(&info,uid);
1658         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1659
1660         ret = _insert_desktop_info(&info, uid);
1661         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1662
1663         ret = _send_db_done_noti(NOTI_ADD, appid);
1664         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1665
1666         _fini_desktop_info(&info);
1667
1668         return AIL_ERROR_OK;
1669 }
1670
1671 EXPORT_API ail_error_e ail_desktop_add(const char *appid)
1672 {
1673         return ail_usr_desktop_add(appid,GLOBAL_USER);
1674 }
1675
1676 EXPORT_API ail_error_e ail_usr_desktop_update(const char *appid, uid_t uid)
1677 {
1678         desktop_info_s info = {0,};
1679         ail_error_e ret;
1680
1681         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1682
1683         ret = _init_desktop_info(&info, appid, uid);
1684         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1685
1686         ret = _read_desktop_info(&info,uid);
1687         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1688
1689         ret = _update_desktop_info(&info, uid);
1690         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1691
1692         ret = _send_db_done_noti(NOTI_UPDATE, appid);
1693         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1694
1695         _fini_desktop_info(&info);
1696
1697         return AIL_ERROR_OK;
1698 }
1699
1700 EXPORT_API ail_error_e ail_desktop_update(const char *appid)
1701 {
1702         return ail_usr_desktop_update(appid,GLOBAL_USER);
1703 }
1704
1705
1706 EXPORT_API ail_error_e ail_usr_desktop_remove(const char *appid, uid_t uid)
1707 {
1708         ail_error_e ret;
1709
1710         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1711
1712         ret = _remove_package(appid, uid);
1713         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1714
1715         ret = _send_db_done_noti(NOTI_REMOVE, appid);
1716         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1717
1718         return AIL_ERROR_OK;
1719 }
1720
1721 EXPORT_API ail_error_e ail_desktop_remove(const char *appid)
1722 {
1723         return ail_usr_desktop_remove(appid, GLOBAL_USER);
1724 }
1725
1726
1727 EXPORT_API ail_error_e ail_usr_desktop_clean(const char *pkgid, uid_t uid)
1728 {
1729         ail_error_e ret;
1730
1731         retv_if(!pkgid, AIL_ERROR_INVALID_PARAMETER);
1732
1733         _D("ail_desktop_clean=%s",pkgid);
1734
1735         ret = _clean_pkgid_data(pkgid, uid);
1736         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1737
1738         return AIL_ERROR_OK;
1739 }
1740
1741 EXPORT_API ail_error_e ail_desktop_clean(const char *pkgid)
1742 {
1743         return ail_usr_desktop_clean(pkgid, GLOBAL_USER);
1744 }
1745
1746 EXPORT_API ail_error_e ail_usr_desktop_fota(const char *appid, uid_t uid)
1747 {
1748         desktop_info_s info = {0,};
1749         ail_error_e ret;
1750
1751         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1752
1753         ret = _init_desktop_info(&info, appid, uid);
1754         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1755
1756         ret = _read_desktop_info(&info,uid);
1757         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1758
1759         ret = _insert_desktop_info(&info, uid);
1760         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1761
1762         _fini_desktop_info(&info);
1763
1764         return AIL_ERROR_OK;
1765 }
1766
1767 EXPORT_API ail_error_e ail_desktop_fota(const char *appid)
1768 {
1769         return ail_usr_desktop_fota(appid, GLOBAL_USER);
1770 }
1771
1772
1773 EXPORT_API ail_error_e ail_desktop_appinfo_modify_usr_bool(const char *appid,
1774                                                              const char *property,
1775                                                              bool value,
1776                                                              bool broadcast, uid_t uid)
1777 {
1778         desktop_info_s info = {0,};
1779         ail_error_e ret;
1780
1781         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1782
1783         retv_if(strcmp(property, AIL_PROP_X_SLP_ENABLED_BOOL),
1784                 AIL_ERROR_INVALID_PARAMETER);
1785
1786         ret = _init_desktop_info(&info, appid, uid);
1787         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1788
1789         ret = _load_desktop_info(&info, uid);
1790         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1791
1792         ret = _modify_desktop_info_bool(&info, property, value);
1793         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1794
1795         ret = _update_desktop_info(&info, uid);
1796         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1797
1798         if (broadcast) {
1799                 ret = _send_db_done_noti(NOTI_UPDATE, appid);
1800                 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1801         }
1802
1803         _fini_desktop_info(&info);
1804
1805         return AIL_ERROR_OK;
1806 }
1807
1808 EXPORT_API ail_error_e ail_desktop_appinfo_modify_bool(const char *appid,
1809                                                              const char *property,
1810                                                              bool value,
1811                                                              bool broadcast)
1812 {
1813         return ail_desktop_appinfo_modify_usr_bool(appid, property, value, broadcast,
1814                         GLOBAL_USER);
1815 }
1816
1817
1818 EXPORT_API ail_error_e ail_desktop_appinfo_modify_usr_str(const char *appid, uid_t uid,
1819                                                              const char *property,
1820                                                              const char *value,
1821                                                              bool broadcast)
1822 {
1823         desktop_info_s info = {0,};
1824         ail_error_e ret;
1825
1826         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1827
1828         ret = _init_desktop_info(&info, appid, uid);
1829         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1830
1831         ret = _load_desktop_info(&info, uid);
1832         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1833
1834         _D("info.name [%s], value [%s]", info.name, value);
1835         ret = _modify_desktop_info_str(&info, property, value);
1836         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1837         _D("info.name [%s], value [%s]", info.name, value);
1838
1839         ret = _update_desktop_info(&info, uid);
1840         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1841
1842         if (broadcast) {
1843                 ret = _send_db_done_noti(NOTI_UPDATE, appid);
1844                 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1845         }
1846
1847         _fini_desktop_info(&info);
1848
1849         return AIL_ERROR_OK;
1850 }
1851
1852 EXPORT_API ail_error_e ail_desktop_appinfo_modify_str(const char *appid,
1853                                                              const char *property,
1854                                                              const char *value,
1855                                                              bool broadcast)
1856 {
1857         return ail_desktop_appinfo_modify_usr_str(appid, GLOBAL_USER, property, value,
1858                                 broadcast);
1859 }
1860
1861 // End of File