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