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