change functions for thread-safe
[platform/core/appfw/pkgmgr-info.git] / parser / pkgmgr_parser.c
1 /*
2  * pkgmgr-info
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>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22 #define _GNU_SOURCE
23 #include <dlfcn.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <ctype.h>
29 #include <time.h>
30 #include <string.h>
31 #include <libxml/parser.h>
32 #include <libxml/xmlreader.h>
33 #include <libxml/xmlschemas.h>
34 #include <vconf.h>
35 #include <glib.h>
36 #include <grp.h>
37
38 #include "pkgmgr-info.h"
39 #include "pkgmgrinfo_basic.h"
40 #include "pkgmgrinfo_debug.h"
41
42 #include "pkgmgr_parser.h"
43 #include "pkgmgr_parser_internal.h"
44 #include "pkgmgr_parser_db.h"
45
46 #ifdef LOG_TAG
47 #undef LOG_TAG
48 #endif
49 #define LOG_TAG "PKGMGR_PARSER"
50
51 #define ASCII(s) (char *)s
52 #define XMLCHAR(s) (const xmlChar *)s
53
54 //#define METADATA_PARSER_LIST SYSCONFDIR "/package-manager/parserlib/metadata/metadata_parser_list.txt"
55 #define METADATA_PARSER_LIST SYSCONFDIR "/package-manager/parserlib/metadata/mdparser_list.txt"
56 #define METADATA_PARSER_NAME    "metadataparser:"
57
58 #define CATEGORY_PARSER_LIST SYSCONFDIR "/package-manager/parserlib/category/category_parser_list.txt"
59 #define CATEGORY_PARSER_NAME    "categoryparser:"
60
61 #define TAG_PARSER_LIST SYSCONFDIR "/package-manager/parserlib/tag_parser_list.txt"
62 #define TAG_PARSER_NAME "parserlib:"
63
64 #define PKG_TAG_LEN_MAX 128
65 #define OWNER_ROOT 0
66 #define BUFSIZE 4096
67 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
68
69 /* plugin process_type */
70 typedef enum {
71         PLUGIN_PRE_PROCESS = 0,
72         PLUGIN_POST_PROCESS
73 } PLUGIN_PROCESS_TYPE;
74
75 const char *package;
76
77 static int __ps_process_label(xmlTextReaderPtr reader, label_x *label);
78 static int __ps_process_privilege(xmlTextReaderPtr reader, char **privilege);
79 static int __ps_process_privileges(xmlTextReaderPtr reader, GList **privileges);
80 static int __ps_process_allowed(xmlTextReaderPtr reader, char **allowed);
81 static int __ps_process_condition(xmlTextReaderPtr reader, char **condition);
82 static int __ps_process_notification(xmlTextReaderPtr reader, notification_x *notifiation);
83 static int __ps_process_category(xmlTextReaderPtr reader, char **category);
84 static int __ps_process_metadata(xmlTextReaderPtr reader, metadata_x *metadata);
85 static int __ps_process_permission(xmlTextReaderPtr reader, permission_x *permission);
86 static int __ps_process_compatibility(xmlTextReaderPtr reader, compatibility_x *compatibility);
87 static int __ps_process_request(xmlTextReaderPtr reader, char **request);
88 static int __ps_process_define(xmlTextReaderPtr reader, define_x *define);
89 static int __ps_process_launchconditions(xmlTextReaderPtr reader, GList **launchconditions);
90 static int __ps_process_datashare(xmlTextReaderPtr reader, datashare_x *datashare);
91 static int __ps_process_icon(xmlTextReaderPtr reader, icon_x *icon, uid_t uid);
92 static int __ps_process_author(xmlTextReaderPtr reader, author_x *author);
93 static int __ps_process_description(xmlTextReaderPtr reader, description_x *description);
94 static int __ps_process_license(xmlTextReaderPtr reader, license_x *license);
95 static int __ps_process_appcontrol(xmlTextReaderPtr reader, GList **appcontrol);
96 static int __ps_process_datacontrol(xmlTextReaderPtr reader, datacontrol_x *datacontrol);
97 static int __ps_process_application(xmlTextReaderPtr reader, application_x *application, int type, uid_t uid);
98 static int __next_child_element(xmlTextReaderPtr reader, int depth);
99 static int __start_process(xmlTextReaderPtr reader, manifest_x * mfx, uid_t uid);
100 static int __process_manifest(xmlTextReaderPtr reader, manifest_x * mfx, uid_t uid);
101 static void __str_trim(char *input);
102 static char *__get_parser_plugin(const char *type);
103 static int __ps_run_parser(xmlDocPtr docPtr, const char *tag, ACTION_TYPE action, const char *pkgid);
104 API int __is_admin();
105
106 static void __save_xml_attribute(xmlTextReaderPtr reader, char *attribute, char **xml_attribute, char *default_value)
107 {
108         xmlChar *attrib_val = xmlTextReaderGetAttribute(reader, XMLCHAR(attribute));
109         if (attrib_val) {
110                 *xml_attribute = strdup((const char *)attrib_val);
111                 xmlFree(attrib_val);
112         } else {
113                 if (default_value != NULL) {
114                         *xml_attribute = strdup(default_value);
115                 }
116         }
117 }
118
119 static void __save_xml_lang(xmlTextReaderPtr reader, char **xml_attribute)
120 {
121         const xmlChar *attrib_val = xmlTextReaderConstXmlLang(reader);
122         if (attrib_val != NULL)
123                 *xml_attribute = strdup(ASCII(attrib_val));
124         else
125                 *xml_attribute = strdup(DEFAULT_LOCALE);
126 }
127
128 static void __save_xml_value(xmlTextReaderPtr reader, char **xml_attribute)
129 {
130         xmlTextReaderRead(reader);
131         const xmlChar *attrib_val = xmlTextReaderConstValue(reader);
132
133         if (attrib_val)
134                 *xml_attribute = strdup((const char *)attrib_val);
135 }
136
137 static void __save_xml_installed_time(manifest_x *mfx)
138 {
139         char buf[PKG_STRING_LEN_MAX] = {'\0'};
140         char *val = NULL;
141         time_t current_time;
142         time(&current_time);
143         snprintf(buf, PKG_STRING_LEN_MAX - 1, "%d", (int)current_time);
144         val = strndup(buf, PKG_STRING_LEN_MAX - 1);
145         mfx->installed_time = val;
146 }
147
148 static void __save_xml_root_path(manifest_x *mfx, uid_t uid)
149 {
150         char root[PKG_STRING_LEN_MAX] = { '\0' };
151         const char *path;
152
153         if (mfx->root_path)
154                 return;
155
156         tzplatform_set_user(uid);
157         path = tzplatform_getenv((uid == OWNER_ROOT || uid == GLOBAL_USER) ? TZ_SYS_RO_APP : TZ_USER_APP);
158         snprintf(root, PKG_STRING_LEN_MAX - 1, "%s/%s", path, mfx->package);
159
160         mfx->root_path = strdup(root);
161
162         tzplatform_reset_user();
163 }
164
165 static void __save_xml_default_value(manifest_x * mfx)
166 {
167         mfx->preload = strdup("False");
168         mfx->removable = strdup("True");
169         mfx->readonly = strdup("False");
170         mfx->update = strdup("False");
171         mfx->system = strdup("False");
172         mfx->installed_storage= strdup("installed_internal");
173         package = mfx->package;
174 }
175
176 void *__open_lib_handle(char *tag)
177 {
178         char *lib_path = NULL;
179         void *lib_handle = NULL;
180
181         lib_path = __get_parser_plugin(tag);
182         retvm_if(!lib_path, NULL, "lib_path get fail");
183
184         lib_handle = dlopen(lib_path, RTLD_LAZY);
185         retvm_if(lib_handle == NULL, NULL, "dlopen is failed lib_path[%s]", lib_path);
186
187         return lib_handle;
188 }
189
190 void __close_lib_handle(void *lib_handle)
191 {
192         dlclose(lib_handle);
193 }
194
195 static void __str_trim(char *input)
196 {
197         char *trim_str = input;
198
199         if (input == NULL)
200                 return;
201
202         while (*input != 0) {
203                 if (!isspace(*input)) {
204                         *trim_str = *input;
205                         trim_str++;
206                 }
207                 input++;
208         }
209
210         *trim_str = 0;
211         return;
212 }
213
214 API int __is_admin()
215 {
216         uid_t uid = getuid();
217         if ((uid_t) 0 == uid )
218                 return 1;
219         else
220                 return 0;
221 }
222
223
224
225 static char * __get_tag_by_key(char *md_key)
226 {
227         char *md_tag = NULL;
228
229         if (md_key == NULL) {
230                 _LOGD("md_key is NULL\n");
231                 return NULL;
232         }
233
234         md_tag = strrchr(md_key, 47) + 1;
235
236
237         return strdup(md_tag);
238 }
239
240 static char *__get_metadata_parser_plugin(const char *type)
241 {
242         FILE *fp = NULL;
243         char buffer[1024] = { 0 };
244         char temp_path[1024] = { 0 };
245         char *path = NULL;
246
247         if (type == NULL) {
248                 _LOGE("invalid argument\n");
249                 return NULL;
250         }
251
252         fp = fopen(PKG_PARSER_CONF_PATH, "r");
253         if (fp == NULL) {
254                 _LOGE("no matching metadata parser\n");
255                 return NULL;
256         }
257
258         while (fgets(buffer, sizeof(buffer), fp) != NULL) {
259                 if (buffer[0] == '#')
260                         continue;
261
262                 __str_trim(buffer);
263
264                 if ((path = strstr(buffer, METADATA_PARSER_NAME)) != NULL) {
265                         path = path + strlen(METADATA_PARSER_NAME);
266
267                         break;
268                 }
269
270                 memset(buffer, 0x00, 1024);
271         }
272
273         if (fp != NULL)
274                 fclose(fp);
275
276         if (path == NULL) {
277                 _LOGE("no matching [%s] [%s]\n", METADATA_PARSER_NAME,type);
278                 return NULL;
279         }
280
281         snprintf(temp_path, sizeof(temp_path) - 1, "%slib%s.so", path, type);
282
283         return strdup(temp_path);
284 }
285
286 static char *__get_category_parser_plugin(const char *type)
287 {
288         FILE *fp = NULL;
289         char buffer[1024] = { 0 };
290         char temp_path[1024] = { 0 };
291         char *path = NULL;
292
293         if (type == NULL) {
294                 _LOGE("invalid argument\n");
295                 return NULL;
296         }
297
298         fp = fopen(PKG_PARSER_CONF_PATH, "r");
299         if (fp == NULL) {
300                 _LOGE("no matching metadata parser\n");
301                 return NULL;
302         }
303
304         while (fgets(buffer, sizeof(buffer), fp) != NULL) {
305                 if (buffer[0] == '#')
306                         continue;
307
308                 __str_trim(buffer);
309
310                 if ((path = strstr(buffer, CATEGORY_PARSER_NAME)) != NULL) {
311                         path = path + strlen(CATEGORY_PARSER_NAME);
312
313                         break;
314                 }
315
316                 memset(buffer, 0x00, 1024);
317         }
318
319         if (fp != NULL)
320                 fclose(fp);
321
322         if (path == NULL) {
323                 _LOGE("no matching [%s] [%s]\n", CATEGORY_PARSER_NAME,type);
324                 return NULL;
325         }
326
327         snprintf(temp_path, sizeof(temp_path) - 1, "%slib%s.so", path, type);
328
329         return strdup(temp_path);
330 }
331
332 static char *__get_parser_plugin(const char *type)
333 {
334         FILE *fp = NULL;
335         char buffer[1024] = { 0 };
336         char temp_path[1024] = { 0 };
337         char *path = NULL;
338
339         if (type == NULL) {
340                 _LOGE("invalid argument\n");
341                 return NULL;
342         }
343
344         fp = fopen(PKG_PARSER_CONF_PATH, "r");
345         if (fp == NULL) {
346                 _LOGE("no matching backendlib\n");
347                 return NULL;
348         }
349
350         while (fgets(buffer, sizeof(buffer), fp) != NULL) {
351                 if (buffer[0] == '#')
352                         continue;
353
354                 __str_trim(buffer);
355
356                 if ((path = strstr(buffer, PKG_PARSERLIB)) != NULL) {
357                         path = path + strlen(PKG_PARSERLIB);
358                         break;
359                 }
360
361                 memset(buffer, 0x00, 1024);
362         }
363
364         if (fp != NULL)
365                 fclose(fp);
366
367         if (path == NULL) {
368                 _LOGE("no matching backendlib\n");
369                 return NULL;
370         }
371
372         snprintf(temp_path, sizeof(temp_path) - 1, "%slib%s.so", path, type);
373
374         return strdup(temp_path);
375 }
376
377 static int __ps_run_tag_parser(void *lib_handle, xmlDocPtr docPtr, const char *tag,
378                            ACTION_TYPE action, const char *pkgid)
379 {
380         int (*plugin_install) (xmlDocPtr, const char *);
381         int ret = -1;
382         char *ac = NULL;
383
384         switch (action) {
385         case ACTION_INSTALL:
386                 ac = "PKGMGR_PARSER_PLUGIN_INSTALL";
387                 break;
388         case ACTION_UPGRADE:
389                 ac = "PKGMGR_PARSER_PLUGIN_UPGRADE";
390                 break;
391         case ACTION_UNINSTALL:
392                 ac = "PKGMGR_PARSER_PLUGIN_UNINSTALL";
393                 break;
394         default:
395                 goto END;
396         }
397
398         if ((plugin_install =
399                 dlsym(lib_handle, ac)) == NULL || dlerror() != NULL) {
400                 _LOGE("can not find symbol[%s] \n", ac);
401                 goto END;
402         }
403
404         ret = plugin_install(docPtr, pkgid);
405         _LOGD("tag parser[%s, %s] ACTION_TYPE[%d] result[%d]\n", pkgid, tag, action, ret);
406
407 END:
408         return ret;
409 }
410
411 static int __ps_run_metadata_parser(GList *md_list, const char *tag,
412                                 ACTION_TYPE action, const char *pkgid, const char *appid)
413 {
414         char *lib_path = NULL;
415         void *lib_handle = NULL;
416         int (*metadata_parser_plugin) (const char *, const char *, GList *);
417         int ret = -1;
418         char *ac = NULL;
419
420         switch (action) {
421         case ACTION_INSTALL:
422                 ac = "PKGMGR_MDPARSER_PLUGIN_INSTALL";
423                 break;
424         case ACTION_UPGRADE:
425                 ac = "PKGMGR_MDPARSER_PLUGIN_UPGRADE";
426                 break;
427         case ACTION_UNINSTALL:
428                 ac = "PKGMGR_MDPARSER_PLUGIN_UNINSTALL";
429                 break;
430         default:
431                 goto END;
432         }
433
434         lib_path = __get_metadata_parser_plugin(tag);
435         if (!lib_path) {
436                 _LOGE("get %s parser fail\n", tag);
437                 goto END;
438         }
439
440         if ((lib_handle = dlopen(lib_path, RTLD_LAZY)) == NULL) {
441                 _LOGE("dlopen is failed lib_path[%s]\n", lib_path);
442                 goto END;
443         }
444
445         if ((metadata_parser_plugin =
446                 dlsym(lib_handle, ac)) == NULL || dlerror() != NULL) {
447                 _LOGE("can not find symbol[%s] \n",ac);
448                 goto END;
449         }
450
451         ret = metadata_parser_plugin(pkgid, appid, md_list);
452         if (ret < 0)
453                 _LOGD("[appid = %s, libpath = %s plugin fail\n", appid, lib_path);
454         else
455                 _LOGD("[appid = %s, libpath = %s plugin success\n", appid, lib_path);
456
457 END:
458         if (lib_path)
459                 free(lib_path);
460         if (lib_handle)
461                 dlclose(lib_handle);
462         return ret;
463 }
464
465 static int __ps_run_category_parser(GList *category_list, const char *tag,
466                                 ACTION_TYPE action, const char *pkgid, const char *appid)
467 {
468         char *lib_path = NULL;
469         void *lib_handle = NULL;
470         int (*category_parser_plugin) (const char *, const char *, GList *);
471         int ret = -1;
472         char *ac = NULL;
473
474         switch (action) {
475         case ACTION_INSTALL:
476                 ac = "PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL";
477                 break;
478         case ACTION_UPGRADE:
479                 ac = "PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE";
480                 break;
481         case ACTION_UNINSTALL:
482                 ac = "PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL";
483                 break;
484         default:
485                 goto END;
486         }
487
488         lib_path = __get_category_parser_plugin(tag);
489         if (!lib_path) {
490                 _LOGE("get %s parser fail\n", tag);
491                 goto END;
492         }
493
494         if ((lib_handle = dlopen(lib_path, RTLD_LAZY)) == NULL) {
495                 _LOGE("dlopen is failed lib_path[%s]\n", lib_path);
496                 goto END;
497         }
498
499         if ((category_parser_plugin =
500                 dlsym(lib_handle, ac)) == NULL || dlerror() != NULL) {
501                 _LOGE("can not find symbol[%s] \n",ac);
502                 goto END;
503         }
504
505         ret = category_parser_plugin(pkgid, appid, category_list);
506         if (ret < 0)
507                 _LOGD("[appid = %s, libpath = %s plugin fail\n", appid, lib_path);
508         else
509                 _LOGD("[appid = %s, libpath = %s plugin success\n", appid, lib_path);
510
511 END:
512         if (lib_path)
513                 free(lib_path);
514         if (lib_handle)
515                 dlclose(lib_handle);
516         return ret;
517 }
518
519 static int __ps_run_parser(xmlDocPtr docPtr, const char *tag,
520                            ACTION_TYPE action, const char *pkgid)
521 {
522         char *lib_path = NULL;
523         void *lib_handle = NULL;
524         int (*plugin_install) (xmlDocPtr, const char *);
525         int ret = -1;
526         char *ac = NULL;
527
528         switch (action) {
529         case ACTION_INSTALL:
530                 ac = "PKGMGR_PARSER_PLUGIN_INSTALL";
531                 break;
532         case ACTION_UPGRADE:
533                 ac = "PKGMGR_PARSER_PLUGIN_UPGRADE";
534                 break;
535         case ACTION_UNINSTALL:
536                 ac = "PKGMGR_PARSER_PLUGIN_UNINSTALL";
537                 break;
538         default:
539                 goto END;
540         }
541
542         lib_path = __get_parser_plugin(tag);
543         if (!lib_path) {
544                 goto END;
545         }
546
547         if ((lib_handle = dlopen(lib_path, RTLD_LAZY)) == NULL) {
548                 _LOGE("dlopen is failed lib_path[%s]\n", lib_path);
549                 goto END;
550         }
551         if ((plugin_install =
552                 dlsym(lib_handle, ac)) == NULL || dlerror() != NULL) {
553                 _LOGE("can not find symbol[%s] \n", ac);
554                 goto END;
555         }
556
557         ret = plugin_install(docPtr, pkgid);
558         if (ret < 0)
559                 _LOGD("[pkgid = %s, libpath = %s plugin fail\n", pkgid, lib_path);
560         else
561                 _LOGD("[pkgid = %s, libpath = %s plugin success\n", pkgid, lib_path);
562
563 END:
564         if (lib_path)
565                 free(lib_path);
566         if (lib_handle)
567                 dlclose(lib_handle);
568         return ret;
569 }
570
571 static void __metadata_parser_clear_dir_list(GList* dir_list)
572 {
573         GList *list = NULL;
574         __metadata_t* detail = NULL;
575
576         if (dir_list) {
577                 list = g_list_first(dir_list);
578                 while (list) {
579                         detail = (__metadata_t *)list->data;
580                         if (detail) {
581                                 if (detail->key)
582                                         free((void *)detail->key);
583                                 if (detail->value)
584                                         free((void *)detail->value);
585                                 free(detail);
586                         }
587                         list = g_list_next(list);
588                 }
589                 g_list_free(dir_list);
590         }
591 }
592
593 static void __category_parser_clear_dir_list(GList* dir_list)
594 {
595         GList *list = NULL;
596         __category_t* detail = NULL;
597
598         if (dir_list) {
599                 list = g_list_first(dir_list);
600                 while (list) {
601                         detail = (__category_t *)list->data;
602                         if (detail) {
603                                 if (detail->name)
604                                         free((void *)detail->name);
605
606                                 free(detail);
607                         }
608                         list = g_list_next(list);
609                 }
610                 g_list_free(dir_list);
611         }
612 }
613
614 static int __run_tag_parser_prestep(void *lib_handle, xmlTextReaderPtr reader, ACTION_TYPE action, const char *pkgid)
615 {
616         int ret = -1;
617         const xmlChar *name;
618
619         if (xmlTextReaderDepth(reader) != 1) {
620                 _LOGE("Node depth is not 1");
621                 goto END;
622         }
623
624         if (xmlTextReaderNodeType(reader) != 1) {
625                 _LOGE("Node type is not 1");
626                 goto END;
627         }
628
629         const xmlChar *value;
630         name = xmlTextReaderConstName(reader);
631         if (name == NULL) {
632                 _LOGE("TEST TEST TES\n");
633                 name = BAD_CAST "--";
634         }
635
636         value = xmlTextReaderConstValue(reader);
637         if (value != NULL) {
638                 if (xmlStrlen(value) > 40) {
639                         _LOGD(" %.40s...", value);
640                 } else {
641                         _LOGD(" %s", value);
642                 }
643         }
644
645         name = xmlTextReaderConstName(reader);
646         if (name == NULL) {
647                 _LOGE("TEST TEST TES\n");
648                 name = BAD_CAST "--";
649         }
650
651         xmlDocPtr docPtr = xmlTextReaderCurrentDoc(reader);
652         xmlDocPtr copyDocPtr = xmlCopyDoc(docPtr, 1);
653         if (copyDocPtr == NULL)
654                 return -1;
655         xmlNode *rootElement = xmlDocGetRootElement(copyDocPtr);
656         if (rootElement == NULL)
657                 return -1;
658         xmlNode *cur_node = xmlFirstElementChild(rootElement);
659         if (cur_node == NULL)
660                 return -1;
661         xmlNode *temp = xmlTextReaderExpand(reader);
662         if (temp == NULL)
663                 return -1;
664         xmlNode *next_node = NULL;
665         while(cur_node != NULL) {
666                 if ( (strcmp(ASCII(temp->name), ASCII(cur_node->name)) == 0) &&
667                         (temp->line == cur_node->line) ) {
668                         break;
669                 }
670                 else {
671                         next_node = xmlNextElementSibling(cur_node);
672                         xmlUnlinkNode(cur_node);
673                         xmlFreeNode(cur_node);
674                         cur_node = next_node;
675                 }
676         }
677         if (cur_node == NULL)
678                 return -1;
679         next_node = xmlNextElementSibling(cur_node);
680         if (next_node) {
681                 cur_node->next = NULL;
682                 next_node->prev = NULL;
683                 xmlFreeNodeList(next_node);
684                 xmlSetTreeDoc(cur_node, copyDocPtr);
685         } else {
686                 xmlSetTreeDoc(cur_node, copyDocPtr);
687         }
688
689         ret = __ps_run_tag_parser(lib_handle, copyDocPtr, ASCII(name), action, pkgid);
690  END:
691
692         return ret;
693 }
694
695 static int __run_metadata_parser_prestep (manifest_x *mfx, char *md_key, ACTION_TYPE action)
696 {
697         int ret = -1;
698         int tag_exist = 0;
699         char buffer[1024] = { 0, };
700         GList *app_tmp;
701         application_x *app;
702         GList *md_tmp = NULL;
703         metadata_x *md;
704         char *md_tag = NULL;
705
706         GList *md_list = NULL;
707         __metadata_t *md_detail = NULL;
708
709         md_tag = __get_tag_by_key(md_key);
710         if (md_tag == NULL) {
711                 _LOGD("md_tag is NULL\n");
712                 return -1;
713         }
714
715         for (app_tmp = mfx->application; app_tmp; app_tmp = app_tmp->next) {
716                 app = (application_x *)app_tmp->data;
717                 if (app == NULL)
718                         continue;
719                 for (md_tmp = app->metadata; md_tmp; md_tmp = md_tmp->next) {
720                         md = (metadata_x *)md_tmp->data;
721                         if (md == NULL)
722                                 continue;
723                         //get glist of metadata key and value combination
724                         memset(buffer, 0x00, 1024);
725                         snprintf(buffer, 1024, "%s/", md_key);
726                         if ((md->key && md->value) && (strncmp(md->key, md_key, strlen(md_key)) == 0) && (strncmp(buffer, md->key, strlen(buffer)) == 0)) {
727                                 md_detail = (__metadata_t*) calloc(1, sizeof(__metadata_t));
728                                 if (md_detail == NULL) {
729                                         _LOGD("Memory allocation failed\n");
730                                         goto END;
731                                 }
732
733                                 md_detail->key = strdup(md->key);
734                                 if (md_detail->key == NULL) {
735                                         _LOGD("Memory allocation failed\n");
736                                         free(md_detail);
737                                         goto END;
738                                 }
739
740                                 md_detail->value = strdup(md->value);
741                                 if (md_detail->value == NULL) {
742                                         _LOGD("Memory allocation failed\n");
743                                         free((void *)md_detail->key);
744                                         free(md_detail);
745                                         goto END;
746                                 }
747
748                                 md_list = g_list_append(md_list, (gpointer)md_detail);
749                                 tag_exist = 1;
750                         }
751                 }
752
753                 //send glist to parser when tags for metadata plugin parser exist.
754                 if (tag_exist) {
755                         ret = __ps_run_metadata_parser(md_list, md_tag, action, mfx->package, app->appid);
756                         if (ret < 0){
757                                 _LOGD("metadata_parser failed[%d] for tag[%s]\n", ret, md_tag);
758                         }
759                         else{
760                                 _LOGD("metadata_parser success for tag[%s]\n", md_tag);
761                         }
762                 }
763                 __metadata_parser_clear_dir_list(md_list);
764                 md_list = NULL;
765                 tag_exist = 0;
766         }
767
768         return 0;
769 END:
770         __metadata_parser_clear_dir_list(md_list);
771
772         if (md_tag)
773                 free(md_tag);
774
775         return ret;
776 }
777
778 static int __run_category_parser_prestep (manifest_x *mfx, char *category_key, ACTION_TYPE action)
779 {
780         int ret = -1;
781         int tag_exist = 0;
782         char buffer[1024] = { 0, };
783         GList *app_tmp;
784         application_x *app;
785         GList *category_tmp;
786         const char *category;
787         char *category_tag = NULL;
788
789         GList *category_list = NULL;
790         __category_t *category_detail = NULL;
791
792         category_tag = __get_tag_by_key(category_key);
793         if (category_tag == NULL) {
794                 _LOGD("md_tag is NULL\n");
795                 return -1;
796         }
797
798         for (app_tmp = mfx->application; app_tmp; app_tmp = app_tmp->next) {
799                 app = (application_x *)app_tmp->data;
800                 if (app == NULL)
801                         continue;
802                 for (category_tmp = app->category; category_tmp; category_tmp = category_tmp->next) {
803                         category = (const char *)category_tmp->data;
804                         //get glist of category key and value combination
805                         memset(buffer, 0x00, 1024);
806                         snprintf(buffer, 1024, "%s/", category_key);
807                         if ((category) && (strncmp(category, category_key, strlen(category_key)) == 0)) {
808                                 category_detail = (__category_t*) calloc(1, sizeof(__category_t));
809                                 if (category_detail == NULL) {
810                                         _LOGD("Memory allocation failed\n");
811                                         goto END;
812                                 }
813
814                                 category_detail->name = strdup(category);
815                                 if (category_detail->name == NULL) {
816                                         _LOGD("Memory allocation failed\n");
817                                         free(category_detail);
818                                         goto END;
819                                 }
820
821                                 category_list = g_list_append(category_list, (gpointer)category_detail);
822                                 tag_exist = 1;
823                         }
824                 }
825
826                 //send glist to parser when tags for metadata plugin parser exist.
827                 if (tag_exist) {
828                         ret = __ps_run_category_parser(category_list, category_tag, action, mfx->package, app->appid);
829                         if (ret < 0)
830                                 _LOGD("category_parser failed[%d] for tag[%s]\n", ret, category_tag);
831                         else
832                                 _LOGD("category_parser success for tag[%s]\n", category_tag);
833                 }
834                 __category_parser_clear_dir_list(category_list);
835                 category_list = NULL;
836                 tag_exist = 0;
837         }
838
839         return 0;
840 END:
841         __category_parser_clear_dir_list(category_list);
842
843         if (category_tag)
844                 free(category_tag);
845
846         return ret;
847 }
848
849 static void __process_tag(void *lib_handle, xmlTextReaderPtr reader, ACTION_TYPE action, char *tag, const char *pkgid)
850 {
851         switch (xmlTextReaderNodeType(reader)) {
852         case XML_READER_TYPE_END_ELEMENT:
853                 {
854                         break;
855                 }
856         case XML_READER_TYPE_ELEMENT:
857                 {
858                         // Elements without closing tag don't receive
859                         const xmlChar *elementName =
860                             xmlTextReaderLocalName(reader);
861                         if (elementName == NULL) {
862                                 break;
863                         }
864
865                         if (strcmp(tag, ASCII(elementName)) == 0) {
866                                 _LOGD("find : tag[%s] ACTION_TYPE[%d] pkg[%s]\n", tag, action, pkgid);
867                                 __run_tag_parser_prestep(lib_handle, reader, action, pkgid);
868                                 break;
869                         }
870                         break;
871                 }
872
873         default:
874                 break;
875         }
876 }
877
878 static int __parser_send_tag(void *lib_handle, ACTION_TYPE action, PLUGIN_PROCESS_TYPE process, const char *pkgid)
879 {
880         int (*plugin_install) (const char *);
881         int ret = -1;
882         char *ac = NULL;
883
884         if (process == PLUGIN_PRE_PROCESS) {
885                 switch (action) {
886                 case ACTION_INSTALL:
887                         ac = "PKGMGR_PARSER_PLUGIN_PRE_INSTALL";
888                         break;
889                 case ACTION_UPGRADE:
890                         ac = "PKGMGR_PARSER_PLUGIN_PRE_UPGRADE";
891                         break;
892                 case ACTION_UNINSTALL:
893                         ac = "PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL";
894                         break;
895                 default:
896                         return -1;
897                 }
898         } else if (process == PLUGIN_POST_PROCESS) {
899                 switch (action) {
900                 case ACTION_INSTALL:
901                         ac = "PKGMGR_PARSER_PLUGIN_POST_INSTALL";
902                         break;
903                 case ACTION_UPGRADE:
904                         ac = "PKGMGR_PARSER_PLUGIN_POST_UPGRADE";
905                         break;
906                 case ACTION_UNINSTALL:
907                         ac = "PKGMGR_PARSER_PLUGIN_POST_UNINSTALL";
908                         break;
909                 default:
910                         return -1;
911                 }
912         } else
913                 return -1;
914
915         if ((plugin_install =
916                 dlsym(lib_handle, ac)) == NULL || dlerror() != NULL) {
917                 return -1;
918         }
919
920         ret = plugin_install(pkgid);
921         return ret;
922 }
923
924 static int __next_child_element(xmlTextReaderPtr reader, int depth)
925 {
926         int ret = xmlTextReaderRead(reader);
927         int cur = xmlTextReaderDepth(reader);
928         while (ret == 1) {
929
930                 switch (xmlTextReaderNodeType(reader)) {
931                 case XML_READER_TYPE_ELEMENT:
932                         if (cur == depth + 1)
933                                 return 1;
934                         break;
935                 case XML_READER_TYPE_TEXT:
936                         /*text is handled by each function separately*/
937                         if (cur == depth + 1)
938                                 return 0;
939                         break;
940                 case XML_READER_TYPE_END_ELEMENT:
941                         if (cur == depth)
942                                 return 0;
943                         break;
944                 default:
945                         if (cur <= depth)
946                                 return 0;
947                         break;
948                 }
949                 ret = xmlTextReaderRead(reader);
950                 cur = xmlTextReaderDepth(reader);
951         }
952         return ret;
953 }
954 int __ps_process_tag_parser(manifest_x *mfx, const char *filename, ACTION_TYPE action)
955 {
956         xmlTextReaderPtr reader;
957         xmlDocPtr docPtr;
958         int ret = -1;
959         FILE *fp = NULL;
960         void *lib_handle = NULL;
961         char tag[PKG_STRING_LEN_MAX] = { 0 };
962
963         fp = fopen(TAG_PARSER_LIST, "r");
964         retvm_if(fp == NULL, PMINFO_R_ERROR, "no preload list");
965
966         while (fgets(tag, sizeof(tag), fp) != NULL) {
967                 __str_trim(tag);
968
969                 lib_handle = __open_lib_handle(tag);
970                 if (lib_handle == NULL)
971                         continue;
972
973                 ret = __parser_send_tag(lib_handle, action, PLUGIN_PRE_PROCESS, mfx->package);
974                 _LOGD("PLUGIN_PRE_PROCESS[%s, %s] ACTION_TYPE[%d] result[%d]\n", mfx->package, tag, action, ret);
975
976                 docPtr = xmlReadFile(filename, NULL, 0);
977                 reader = xmlReaderWalker(docPtr);
978                 if (reader != NULL) {
979                         ret = xmlTextReaderRead(reader);
980                         while (ret == 1) {
981                                 __process_tag(lib_handle, reader, action, tag, mfx->package);
982                                 ret = xmlTextReaderRead(reader);
983                         }
984                         xmlFreeTextReader(reader);
985
986                         if (ret != 0) {
987                                 _LOGD("%s : failed to parse", filename);
988                         }
989                 } else {
990                         _LOGD("Unable to open %s", filename);
991                 }
992
993                 ret = __parser_send_tag(lib_handle, action, PLUGIN_POST_PROCESS, mfx->package);
994                 _LOGD("PLUGIN_POST_PROCESS[%s, %s] ACTION_TYPE[%d] result[%d]\n", mfx->package, tag, action, ret);
995
996                 __close_lib_handle(lib_handle);
997
998                 memset(tag, 0x00, sizeof(tag));
999         }
1000
1001         if (fp != NULL)
1002                 fclose(fp);
1003
1004         return 0;
1005 }
1006
1007 int __ps_process_metadata_parser(manifest_x *mfx, ACTION_TYPE action)
1008 {
1009         fprintf(stdout,"__ps_process_metadata_parser\n");
1010         int ret = 0;
1011         FILE *fp = NULL;
1012         char md_key[PKG_STRING_LEN_MAX] = { 0 };
1013
1014         fp = fopen(METADATA_PARSER_LIST, "r");
1015         if (fp == NULL) {
1016                 _LOGD("no preload list\n");
1017                 return -1;
1018         }
1019
1020         while (fgets(md_key, sizeof(md_key), fp) != NULL) {
1021                 __str_trim(md_key);
1022                 ret = __run_metadata_parser_prestep(mfx, md_key, action);
1023                 if (ret < 0)
1024                         break;
1025         }
1026
1027         if (fp != NULL)
1028                 fclose(fp);
1029
1030         return ret;
1031 }
1032
1033 int __ps_process_category_parser(manifest_x *mfx, ACTION_TYPE action)
1034 {
1035         int ret = 0;
1036         FILE *fp = NULL;
1037         char category_key[PKG_STRING_LEN_MAX] = { 0 };
1038
1039         fp = fopen(CATEGORY_PARSER_LIST, "r");
1040         if (fp == NULL) {
1041                 _LOGD("no category parser list\n");
1042                 return -1;
1043         }
1044
1045         while (fgets(category_key, sizeof(category_key), fp) != NULL) {
1046                 __str_trim(category_key);
1047                 ret = __run_category_parser_prestep(mfx, category_key, action);
1048                 if (ret < 0)
1049                         break;
1050         }
1051
1052         if (fp != NULL)
1053                 fclose(fp);
1054
1055         return ret;
1056 }
1057
1058 static int __ps_process_allowed(xmlTextReaderPtr reader, char **allowed)
1059 {
1060         __save_xml_value(reader, allowed);
1061         return 0;
1062 }
1063
1064 static int __ps_process_condition(xmlTextReaderPtr reader, char **condition)
1065 {
1066         __save_xml_attribute(reader, "name", condition, NULL);
1067         return 0;
1068 }
1069
1070 static int __ps_process_notification(xmlTextReaderPtr reader, notification_x *notification)
1071 {
1072         __save_xml_attribute(reader, "name", &notification->name, NULL);
1073         __save_xml_value(reader, &notification->text);
1074         return 0;
1075 }
1076
1077 static int __ps_process_category(xmlTextReaderPtr reader, char **category)
1078 {
1079         __save_xml_attribute(reader, "name", category, NULL);
1080         return 0;
1081 }
1082
1083 static int __ps_process_privilege(xmlTextReaderPtr reader, char **privilege)
1084 {
1085         __save_xml_value(reader, privilege);
1086         return 0;
1087 }
1088
1089 static int __ps_process_metadata(xmlTextReaderPtr reader, metadata_x *metadata)
1090 {
1091         __save_xml_attribute(reader, "key", &metadata->key, NULL);
1092         __save_xml_attribute(reader, "value", &metadata->value, NULL);
1093         return 0;
1094 }
1095
1096 static int __ps_process_permission(xmlTextReaderPtr reader, permission_x *permission)
1097 {
1098         __save_xml_attribute(reader, "type", &permission->type, NULL);
1099         __save_xml_value(reader, &permission->value);
1100         return 0;
1101 }
1102
1103 static int __ps_process_compatibility(xmlTextReaderPtr reader, compatibility_x *compatibility)
1104 {
1105         __save_xml_attribute(reader, "name", &compatibility->name, NULL);
1106         __save_xml_value(reader, &compatibility->text);
1107         return 0;
1108 }
1109
1110 static int __ps_process_request(xmlTextReaderPtr reader, char **request)
1111 {
1112         __save_xml_value(reader, request);
1113         return 0;
1114 }
1115
1116 static int __ps_process_define(xmlTextReaderPtr reader, define_x *define)
1117 {
1118         const xmlChar *node;
1119         int ret = -1;
1120         int depth = -1;
1121         char *val;
1122
1123         __save_xml_attribute(reader, "path", &define->path, NULL);
1124
1125         depth = xmlTextReaderDepth(reader);
1126         while ((ret = __next_child_element(reader, depth))) {
1127                 node = xmlTextReaderConstName(reader);
1128                 if (!node) {
1129                         _LOGD("xmlTextReaderConstName value is NULL\n");
1130                         return -1;
1131                 }
1132
1133                 if (!strcmp(ASCII(node), "allowed")) {
1134                         val = NULL;
1135                         ret = __ps_process_allowed(reader, &val);
1136                         if (val)
1137                                 define->allowed = g_list_append(define->allowed, (gpointer)val);
1138                 } else if (!strcmp(ASCII(node), "request")) {
1139                         val = NULL;
1140                         ret = __ps_process_request(reader, &val);
1141                         if (val)
1142                                 define->request = g_list_append(define->request, (gpointer)val);
1143                 } else {
1144                         return -1;
1145                 }
1146                 if (ret < 0) {
1147                         _LOGD("Processing define failed\n");
1148                         return ret;
1149                 }
1150         }
1151         return ret;
1152 }
1153
1154 struct appcontrol_data {
1155         GList *operations;
1156         GList *uris;
1157         GList *mimes;
1158         GList *appcontrols;
1159         char operation[BUFSIZE];
1160         char uri[BUFSIZE];
1161         char mime[BUFSIZE];
1162 };
1163
1164 static void __ps_process_mime(gpointer data, gpointer user_data)
1165 {
1166         char *mime = (char *)data;
1167         struct appcontrol_data *ad = (struct appcontrol_data *)user_data;
1168         appcontrol_x *appcontrol;
1169
1170         snprintf(ad->mime, sizeof(ad->mime), "%s", mime);
1171
1172         appcontrol = calloc(1, sizeof(appcontrol_x));
1173         if (strlen(ad->operation))
1174                 appcontrol->operation = strdup(ad->operation);
1175         if (strlen(ad->uri))
1176                 appcontrol->uri = strdup(ad->uri);
1177         appcontrol->mime = strdup(ad->mime);
1178         ad->appcontrols = g_list_append(ad->appcontrols, appcontrol);
1179 }
1180
1181 static void __ps_process_uri(gpointer data, gpointer user_data)
1182 {
1183         char *uri = (char *)data;
1184         struct appcontrol_data *ad = (struct appcontrol_data *)user_data;
1185         appcontrol_x *appcontrol;
1186
1187         snprintf(ad->uri, sizeof(ad->uri), "%s", uri);
1188
1189         if (ad->mimes != NULL) {
1190                 g_list_foreach(ad->mimes, __ps_process_mime, user_data);
1191         } else {
1192                 appcontrol = calloc(1, sizeof(appcontrol_x));
1193                 if (strlen(ad->operation))
1194                         appcontrol->operation = strdup(ad->operation);
1195                 appcontrol->uri = strdup(ad->uri);
1196                 ad->appcontrols = g_list_append(ad->appcontrols, appcontrol);
1197         }
1198 }
1199
1200 static void __ps_process_operation(gpointer data, gpointer user_data)
1201 {
1202         char *operation = (char *)data;
1203         struct appcontrol_data *ad = (struct appcontrol_data *)user_data;
1204         appcontrol_x *appcontrol;
1205
1206         snprintf(ad->operation, sizeof(ad->operation), "%s", operation);
1207
1208         if (ad->uris != NULL) {
1209                 g_list_foreach(ad->uris, __ps_process_uri, user_data);
1210         } else if (ad->mimes != NULL) {
1211                 g_list_foreach(ad->mimes, __ps_process_mime, user_data);
1212         } else {
1213                 appcontrol = calloc(1, sizeof(appcontrol_x));
1214                 appcontrol->operation = strdup(ad->operation);
1215                 ad->appcontrols = g_list_append(ad->appcontrols, appcontrol);
1216         }
1217 }
1218
1219 static GList *__make_appcontrol_list(GList *operations, GList *uris, GList *mimes)
1220 {
1221         struct appcontrol_data ad = {0, };
1222
1223         ad.operations = operations;
1224         ad.uris = uris;
1225         ad.mimes = mimes;
1226
1227         if (ad.operations == NULL)
1228                 return NULL;
1229
1230         g_list_foreach(ad.operations, __ps_process_operation, (gpointer)&ad);
1231
1232         return ad.appcontrols;
1233 }
1234
1235 static int __ps_process_appcontrol(xmlTextReaderPtr reader, GList **appcontrol)
1236 {
1237         const xmlChar *node;
1238         int ret = -1;
1239         int depth = -1;
1240         char *val;
1241         GList *operations = NULL;
1242         GList *uris = NULL;
1243         GList *mimes = NULL;
1244         GList *result;
1245
1246         depth = xmlTextReaderDepth(reader);
1247         while ((ret = __next_child_element(reader, depth)) > 0) {
1248                 node = xmlTextReaderConstName(reader);
1249                 if (!node) {
1250                         _LOGD("xmlTextReaderConstName value is NULL\n");
1251                         return -1;
1252                 }
1253
1254                 val = NULL;
1255                 if (!strcmp(ASCII(node), "operation")) {
1256                         __save_xml_attribute(reader, "name", &val, NULL);
1257                         if (val)
1258                                 operations = g_list_append(operations, (gpointer)val);
1259                         _LOGD("operation processing\n");
1260                 } else if (!strcmp(ASCII(node), "uri")) {
1261                         __save_xml_attribute(reader, "name", &val, NULL);
1262                         if (val)
1263                                 uris = g_list_append(uris, (gpointer)val);
1264                         _LOGD("uri processing\n");
1265                 } else if (!strcmp(ASCII(node), "mime")) {
1266                         __save_xml_attribute(reader, "name", &val, NULL);
1267                         if (val)
1268                                 mimes = g_list_append(mimes, (gpointer)val);
1269                         _LOGD("mime processing\n");
1270                 } else if (!strcmp(ASCII(node), "subapp")) {
1271                         continue;
1272                 } else {
1273                         ret = -1;
1274                 }
1275         }
1276
1277         if (ret < 0) {
1278                 _LOGD("Processing appcontrol failed\n");
1279                 g_list_free_full(operations, free);
1280                 g_list_free_full(uris, free);
1281                 g_list_free_full(mimes, free);
1282                 return ret;
1283         }
1284
1285         result = __make_appcontrol_list(operations, uris, mimes);
1286         if (result)
1287                 *appcontrol = g_list_concat(*appcontrol, result);
1288         else
1289                 ret = -1;
1290
1291         g_list_free_full(operations, free);
1292         g_list_free_full(uris, free);
1293         g_list_free_full(mimes, free);
1294
1295         return ret;
1296 }
1297
1298 static int __ps_process_privileges(xmlTextReaderPtr reader, GList **privileges)
1299 {
1300         const xmlChar *node;
1301         int ret = -1;
1302         int depth = -1;
1303         char *val;
1304
1305         depth = xmlTextReaderDepth(reader);
1306         while ((ret = __next_child_element(reader, depth))) {
1307                 node = xmlTextReaderConstName(reader);
1308                 if (!node) {
1309                         _LOGD("xmlTextReaderConstName value is NULL\n");
1310                         return -1;
1311                 }
1312
1313                 if (strcmp(ASCII(node), "privilege") == 0) {
1314                         val = NULL;
1315                         ret = __ps_process_privilege(reader, &val);
1316                         if (val)
1317                                 *privileges = g_list_append(*privileges, (gpointer)val);
1318                 } else
1319                         return -1;
1320                 if (ret < 0) {
1321                         _LOGD("Processing privileges failed\n");
1322                         return ret;
1323                 }
1324         }
1325         return ret;
1326 }
1327
1328 static int __ps_process_launchconditions(xmlTextReaderPtr reader, GList **launchconditions)
1329 {
1330         const xmlChar *node;
1331         int ret = -1;
1332         int depth = -1;
1333         char *val;
1334
1335         depth = xmlTextReaderDepth(reader);
1336         while ((ret = __next_child_element(reader, depth))) {
1337                 node = xmlTextReaderConstName(reader);
1338                 if (!node) {
1339                         _LOGD("xmlTextReaderConstName value is NULL\n");
1340                         return -1;
1341                 }
1342
1343                 if (strcmp(ASCII(node), "condition") == 0) {
1344                         val = NULL;
1345                         ret = __ps_process_condition(reader, &val);
1346                         if (val)
1347                                 *launchconditions = g_list_append(*launchconditions, (gpointer)val);
1348                 } else
1349                         return -1;
1350                 if (ret < 0) {
1351                         _LOGD("Processing launchconditions failed\n");
1352                         return ret;
1353                 }
1354         }
1355
1356         return ret;
1357 }
1358
1359 static int __ps_process_datashare(xmlTextReaderPtr reader, datashare_x *datashare)
1360 {
1361         const xmlChar *node;
1362         int ret = -1;
1363         int depth = -1;
1364         char *val;
1365         depth = xmlTextReaderDepth(reader);
1366         while ((ret = __next_child_element(reader, depth))) {
1367                 node = xmlTextReaderConstName(reader);
1368                 if (!node) {
1369                         _LOGD("xmlTextReaderConstName value is NULL\n");
1370                         return -1;
1371                 }
1372
1373                 if (!strcmp(ASCII(node), "define")) {
1374                         define_x *define = calloc(1, sizeof(define_x));
1375                         if (define == NULL) {
1376                                 _LOGD("Malloc Failed\n");
1377                                 return -1;
1378                         }
1379                         datashare->define = g_list_append(datashare->define, define);
1380                         ret = __ps_process_define(reader, define);
1381                 } else if (!strcmp(ASCII(node), "request")) {
1382                         val = NULL;
1383                         ret = __ps_process_request(reader, &val);
1384                         if (val)
1385                                 datashare->request = g_list_append(datashare->request, (gpointer)val);
1386                 } else
1387                         return -1;
1388                 if (ret < 0) {
1389                         _LOGD("Processing data-share failed\n");
1390                         return ret;
1391                 }
1392         }
1393         return ret;
1394 }
1395
1396 static char *__get_icon_with_path(const char *icon, uid_t uid)
1397 {
1398         char icon_with_path[BUFSIZE];
1399         const char *app_path;
1400
1401         if (!icon || !package)
1402                 return NULL;
1403
1404         /* just use absolute path */
1405         if (index(icon, '/'))
1406                 return strdup(icon);
1407
1408         do {
1409                 snprintf(icon_with_path, sizeof(icon_with_path), "%s%s",
1410                                 getIconPath(uid, true), icon);
1411                 if (access(icon_with_path, F_OK) == 0)
1412                         break;
1413
1414                 snprintf(icon_with_path, sizeof(icon_with_path), "%s%s",
1415                                 getIconPath(uid, false), icon);
1416                 if (access(icon_with_path, F_OK) == 0)
1417                         break;
1418
1419                 /* for backward compatibility (.../default/small/...)
1420                  * this should be removed
1421                  */
1422                 snprintf(icon_with_path, sizeof(icon_with_path),
1423                                 "%sdefault/small/%s",
1424                                 getIconPath(uid, true), icon);
1425                 if (access(icon_with_path, F_OK) == 0)
1426                         break;
1427
1428                 snprintf(icon_with_path, sizeof(icon_with_path),
1429                                 "%sdefault/small/%s",
1430                                 getIconPath(uid, false), icon);
1431                 if (access(icon_with_path, F_OK) == 0)
1432                         break;
1433
1434                 /* If doesn't exist in case of Global app,
1435                  * try to get icon directly into app's directory
1436                  */
1437                 if (uid == GLOBAL_USER || uid == OWNER_ROOT) {
1438                         app_path = tzplatform_getenv(TZ_SYS_RO_APP);
1439
1440                         snprintf(icon_with_path, sizeof(icon_with_path),
1441                                 "%s/%s/%s", app_path, package, icon);
1442                         if (access(icon_with_path, F_OK) == 0)
1443                                 break;
1444
1445                         app_path = tzplatform_getenv(TZ_SYS_RW_APP);
1446
1447                         snprintf(icon_with_path, sizeof(icon_with_path),
1448                                 "%s/%s/%s", app_path, package, icon);
1449                         if (access(icon_with_path, F_OK) == 0)
1450                                 break;
1451                 } else {
1452                         tzplatform_set_user(uid);
1453                         app_path = tzplatform_getenv(TZ_USER_APP);
1454                         tzplatform_reset_user();
1455
1456                         snprintf(icon_with_path, sizeof(icon_with_path),
1457                                 "%s/%s/%s", app_path, package, icon);
1458                         if (access(icon_with_path, F_OK) == 0)
1459                                 break;
1460                 }
1461
1462                 /* some preload package has icons at below path */
1463                 snprintf(icon_with_path, sizeof(icon_with_path),
1464                                 "%s/%s/res/icons/%s", app_path, package, icon);
1465                 if (access(icon_with_path, F_OK) == 0)
1466                         break;
1467
1468                 /* since 2.3 tpk package */
1469                 snprintf(icon_with_path, sizeof(icon_with_path),
1470                                 "%s/%s/shared/res/%s", app_path, package, icon);
1471                 if (access(icon_with_path, F_OK) == 0)
1472                         break;
1473
1474                 _LOGE("cannot find icon path for [%s]", icon);
1475                 return NULL;
1476         } while (0);
1477
1478         _LOGD("Icon path : %s ---> %s", icon, icon_with_path);
1479
1480         return strdup(icon_with_path);
1481 }
1482
1483 static void __ps_process_tag(manifest_x * mfx, char *const tagv[])
1484 {
1485         int i = 0;
1486         char delims[] = "=";
1487         char *ret_result = NULL;
1488         char *tag = NULL;
1489         char *ptr = NULL;
1490
1491         if (tagv == NULL)
1492                 return;
1493
1494         for (tag = strdup(tagv[0]); tag != NULL; ) {
1495                 ret_result = strtok_r(tag, delims, &ptr);
1496
1497                 /*check tag :  preload */
1498                 if (strcmp(ret_result, "preload") == 0) {
1499                         ret_result = strtok_r(NULL, delims, &ptr);
1500                         if (strcmp(ret_result, "true") == 0) {
1501                                 free((void *)mfx->preload);
1502                                 mfx->preload = strdup("true");
1503                         } else if (strcmp(ret_result, "false") == 0) {
1504                                 free((void *)mfx->preload);
1505                                 mfx->preload = strdup("false");
1506                         }
1507                 /*check tag :  removable*/
1508                 } else if (strcmp(ret_result, "removable") == 0) {
1509                         ret_result = strtok_r(NULL, delims, &ptr);
1510                         if (strcmp(ret_result, "true") == 0){
1511                                 free((void *)mfx->removable);
1512                                 mfx->removable = strdup("true");
1513                         } else if (strcmp(ret_result, "false") == 0) {
1514                                 free((void *)mfx->removable);
1515                                 mfx->removable = strdup("false");
1516                         }
1517                 /*check tag :  not matched*/
1518                 } else
1519                         _LOGD("tag process [%s]is not defined\n", ret_result);
1520
1521                 free(tag);
1522
1523                 /*check next value*/
1524                 if (tagv[++i] != NULL)
1525                         tag = strdup(tagv[i]);
1526                 else {
1527                         _LOGD("tag process success...\n");
1528                         return;
1529                 }
1530         }
1531 }
1532
1533 static int __ps_process_icon(xmlTextReaderPtr reader, icon_x *icon, uid_t uid)
1534 {
1535         __save_xml_attribute(reader, "section", &icon->section, NULL);
1536         __save_xml_attribute(reader, "size", &icon->size, NULL);
1537         __save_xml_attribute(reader, "resolution", &icon->resolution, NULL);
1538         __save_xml_lang(reader, &icon->lang);
1539
1540         xmlTextReaderRead(reader);
1541         char *text  = ASCII(xmlTextReaderValue(reader));
1542         if (text) {
1543                 icon->text = __get_icon_with_path(text, uid);
1544                 free(text);
1545         }
1546
1547         return 0;
1548 }
1549
1550 static int __ps_process_image(xmlTextReaderPtr reader, image_x *image)
1551 {
1552         __save_xml_attribute(reader, "section", &image->section, NULL);
1553         __save_xml_lang(reader, &image->lang);
1554         __save_xml_value(reader, &image->text);
1555         return 0;
1556 }
1557
1558 static int __ps_process_label(xmlTextReaderPtr reader, label_x *label)
1559 {
1560         __save_xml_attribute(reader, "name", &label->name, NULL);
1561         __save_xml_lang(reader, &label->lang);
1562         __save_xml_value(reader, &label->text);
1563         return 0;
1564
1565 }
1566
1567 static int __ps_process_author(xmlTextReaderPtr reader, author_x *author)
1568 {
1569         __save_xml_attribute(reader, "email", &author->email, NULL);
1570         __save_xml_attribute(reader, "href", &author->href, NULL);
1571         __save_xml_value(reader, &author->text);
1572         return 0;
1573 }
1574
1575 static int __ps_process_description(xmlTextReaderPtr reader, description_x *description)
1576 {
1577         __save_xml_lang(reader, &description->lang);
1578         __save_xml_value(reader, &description->text);
1579         return 0;
1580 }
1581
1582 static int __ps_process_license(xmlTextReaderPtr reader, license_x *license)
1583 {
1584         __save_xml_lang(reader, &license->lang);
1585         __save_xml_value(reader, &license->text);
1586         return 0;
1587 }
1588
1589 static int __ps_process_datacontrol(xmlTextReaderPtr reader, datacontrol_x *datacontrol)
1590 {
1591         __save_xml_attribute(reader, "providerid", &datacontrol->providerid, NULL);
1592         __save_xml_attribute(reader, "access", &datacontrol->access, NULL);
1593         __save_xml_attribute(reader, "type", &datacontrol->type, NULL);
1594         return 0;
1595 }
1596
1597 static int __ps_process_splashscreen(xmlTextReaderPtr reader, splashscreen_x *splashscreen)
1598 {
1599         __save_xml_attribute(reader, "src", &splashscreen->src, NULL);
1600         __save_xml_attribute(reader, "type", &splashscreen->type, NULL);
1601         __save_xml_attribute(reader, "dpi", &splashscreen->dpi, NULL);
1602         __save_xml_attribute(reader, "orientation", &splashscreen->orientation, NULL);
1603         __save_xml_attribute(reader, "indicator-display", &splashscreen->indicatordisplay, NULL);
1604         __save_xml_attribute(reader, "app-control-operation", &splashscreen->operation, NULL);
1605         return 0;
1606 }
1607
1608 static int __ps_process_splashscreens(xmlTextReaderPtr reader, GList **splashscreens)
1609 {
1610         const xmlChar *node;
1611         int ret = -1;
1612         int depth = -1;
1613         splashscreen_x *splashscreen;
1614
1615         depth = xmlTextReaderDepth(reader);
1616         while ((ret = __next_child_element(reader, depth))) {
1617                 node = xmlTextReaderConstName(reader);
1618                 if (!node) {
1619                         _LOGD("xmlTextReaderConstName value is NULL\n");
1620                         return -1;
1621                 }
1622
1623                 if (strcmp(ASCII(node), "splash-screen") == 0) {
1624                         splashscreen = calloc(1, sizeof(splashscreen_x));
1625                         if (splashscreen == NULL) {
1626                                 _LOGD("Malloc Failed\n");
1627                                 return -1;
1628                         }
1629                         *splashscreens = g_list_append(*splashscreens, splashscreen);
1630                         ret = __ps_process_splashscreen(reader, splashscreen);
1631                 } else {
1632                         return -1;
1633                 }
1634
1635                 if (ret < 0) {
1636                         _LOGD("Processing splash-screen failed\n");
1637                         return ret;
1638                 }
1639         }
1640         return 0;
1641 }
1642
1643 static int __ps_process_application(xmlTextReaderPtr reader, application_x *application, int type, uid_t uid)
1644 {
1645         const xmlChar *node;
1646         int ret = -1;
1647         int depth = -1;
1648         char *val;
1649
1650         __save_xml_attribute(reader, "appid", &application->appid, NULL);
1651         retvm_if(application->appid == NULL, PM_PARSER_R_ERROR, "appid cant be NULL, appid field is mandatory\n");
1652         __save_xml_attribute(reader, "exec", &application->exec, NULL);
1653         __save_xml_attribute(reader, "nodisplay", &application->nodisplay, "false");
1654         __save_xml_attribute(reader, "multiple", &application->multiple, "false");
1655         __save_xml_attribute(reader, "type", &application->type, NULL);
1656         __save_xml_attribute(reader, "categories", &application->categories, NULL);
1657         __save_xml_attribute(reader, "extraid", &application->extraid, NULL);
1658         __save_xml_attribute(reader, "taskmanage", &application->taskmanage, "true");
1659         __save_xml_attribute(reader, "enabled", &application->enabled, "true");
1660         __save_xml_attribute(reader, "hw-acceleration", &application->hwacceleration, "default");
1661         __save_xml_attribute(reader, "screen-reader", &application->screenreader, "use-system-setting");
1662         __save_xml_attribute(reader, "mainapp", &application->mainapp, "false");
1663         __save_xml_attribute(reader, "recentimage", &application->recentimage, "false");
1664         __save_xml_attribute(reader, "launchcondition", &application->launchcondition, "false");
1665         __save_xml_attribute(reader, "indicatordisplay", &application->indicatordisplay, "true");
1666         __save_xml_attribute(reader, "portrait-effectimage", &application->portraitimg, NULL);
1667         __save_xml_attribute(reader, "landscape-effectimage", &application->landscapeimg, NULL);
1668         __save_xml_attribute(reader, "guestmode-visibility", &application->guestmode_visibility, "true");
1669         __save_xml_attribute(reader, "permission-type", &application->permission_type, "normal");
1670         __save_xml_attribute(reader, "component-type", &application->component_type, type == PMINFO_UI_APP ? "uiapp" : type == PMINFO_SVC_APP ? "svcapp" : "widgetapp");
1671         /*component_type has "svcapp" or "uiapp", if it is not, parsing manifest is fail*/
1672         retvm_if(((strcmp(application->component_type, "svcapp") != 0) && (strcmp(application->component_type, "uiapp") != 0) && (strcmp(application->component_type, "widgetapp") != 0)), PM_PARSER_R_ERROR, "invalid component_type[%s]", application->component_type);
1673         __save_xml_attribute(reader, "submode", &application->submode, "false");
1674         __save_xml_attribute(reader, "submode-mainid", &application->submode_mainid, NULL);
1675         __save_xml_attribute(reader, "process-pool", &application->process_pool, "false");
1676         __save_xml_attribute(reader, "launch_mode", &application->launch_mode, "caller");
1677         __save_xml_attribute(reader, "ui-gadget", &application->ui_gadget, "false");
1678         __save_xml_attribute(reader, "auto-restart", &application->autorestart, "false");
1679         __save_xml_attribute(reader, "on-boot", &application->onboot, "false");
1680
1681         application->package= strdup(package);
1682         /* overwrite some attributes if the app is widgetapp */
1683         if (type == PMINFO_WIDGET_APP || type == PMINFO_WATCH_APP) {
1684                 free((void *)application->nodisplay);
1685                 application->nodisplay = strdup("true");
1686                 free((void *)application->multiple);
1687                 application->multiple = strdup("true");
1688                 free((void *)application->type);
1689                 application->type = strdup("capp");
1690                 free((void *)application->taskmanage);
1691                 application->taskmanage = strdup("false");
1692                 free((void *)application->indicatordisplay);
1693                 application->indicatordisplay = strdup("false");
1694         }
1695
1696         depth = xmlTextReaderDepth(reader);
1697         while ((ret = __next_child_element(reader, depth))) {
1698                 node = xmlTextReaderConstName(reader);
1699                 if (!node) {
1700                         _LOGD("xmlTextReaderConstName value is NULL\n");
1701                         return -1;
1702                 }
1703                 if (!strcmp(ASCII(node), "label")) {
1704                         label_x *label = calloc(1, sizeof(label_x));
1705                         if (label == NULL) {
1706                                 _LOGD("Malloc Failed\n");
1707                                 return -1;
1708                         }
1709                         application->label = g_list_append(application->label, label);
1710                         ret = __ps_process_label(reader, label);
1711                 } else if (!strcmp(ASCII(node), "icon")) {
1712                         icon_x *icon = calloc(1, sizeof(icon_x));
1713                         if (icon == NULL) {
1714                                 _LOGD("Malloc Failed\n");
1715                                 return -1;
1716                         }
1717                         application->icon = g_list_append(application->icon, icon);
1718                         ret = __ps_process_icon(reader, icon, uid);
1719                 } else if (!strcmp(ASCII(node), "image")) {
1720                         image_x *image = calloc(1, sizeof(image_x));
1721                         if (image == NULL) {
1722                                 _LOGD("Malloc Failed\n");
1723                                 return -1;
1724                         }
1725                         application->image = g_list_append(application->image, image);
1726                         ret = __ps_process_image(reader, image);
1727                 } else if (!strcmp(ASCII(node), "category")) {
1728                         val = NULL;
1729                         ret = __ps_process_category(reader, &val);
1730                         if (val)
1731                                 application->category = g_list_append(application->category, (gpointer)val);
1732                 } else if (!strcmp(ASCII(node), "metadata")) {
1733                         metadata_x *metadata = calloc(1, sizeof(metadata_x));
1734                         if (metadata == NULL) {
1735                                 _LOGD("Malloc Failed\n");
1736                                 return -1;
1737                         }
1738                         application->metadata = g_list_append(application->metadata, metadata);
1739                         ret = __ps_process_metadata(reader, metadata);
1740                 } else if (!strcmp(ASCII(node), "permission")) {
1741                         permission_x *permission = calloc(1, sizeof(permission_x));
1742                         if (permission == NULL) {
1743                                 _LOGD("Malloc Failed\n");
1744                                 return -1;
1745                         }
1746                         application->permission = g_list_append(application->permission, permission);
1747                         ret = __ps_process_permission(reader, permission);
1748                 } else if (!strcmp(ASCII(node), "app-control")) {
1749                         ret = __ps_process_appcontrol(reader, &application->appcontrol);
1750                 } else if (!strcmp(ASCII(node), "application-service")) {
1751                         ret = __ps_process_appcontrol(reader, &application->appcontrol);
1752                 } else if (!strcmp(ASCII(node), "data-share")) {
1753                         datashare_x *datashare = calloc(1, sizeof(datashare_x));
1754                         if (datashare == NULL) {
1755                                 _LOGD("Malloc Failed\n");
1756                                 return -1;
1757                         }
1758                         application->datashare = g_list_append(application->datashare, datashare);
1759                         ret = __ps_process_datashare(reader, datashare);
1760                 } else if (!strcmp(ASCII(node), "launch-conditions")) {
1761                         ret = __ps_process_launchconditions(reader, &application->launchconditions);
1762                 } else if (!strcmp(ASCII(node), "notification")) {
1763                         notification_x *notification = calloc(1, sizeof(notification_x));
1764                         if (notification == NULL) {
1765                                 _LOGD("Malloc Failed\n");
1766                                 return -1;
1767                         }
1768                         application->notification = g_list_append(application->notification, notification);
1769                         ret = __ps_process_notification(reader, notification);
1770                 } else if (!strcmp(ASCII(node), "datacontrol")) {
1771                         datacontrol_x *datacontrol = calloc(1, sizeof(datacontrol_x));
1772                         if (datacontrol == NULL) {
1773                                 _LOGD("Malloc Failed\n");
1774                                 return -1;
1775                         }
1776                         application->datacontrol = g_list_append(application->datacontrol, datacontrol);
1777                         ret = __ps_process_datacontrol(reader, datacontrol);
1778                 } else if (!strcmp(ASCII(node), "splash-screens") == 0) {
1779                         ret = __ps_process_splashscreens(reader, &application->splashscreens);
1780                 } else
1781                         continue;
1782                 if (ret < 0) {
1783                         _LOGD("Processing application failed\n");
1784                         return ret;
1785                 }
1786         }
1787
1788         return ret;
1789 }
1790
1791 static int __start_process(xmlTextReaderPtr reader, manifest_x * mfx, uid_t uid)
1792 {
1793         _LOGD("__start_process\n");
1794         const xmlChar *node;
1795         int ret = -1;
1796         int depth = -1;
1797
1798         depth = xmlTextReaderDepth(reader);
1799         while ((ret = __next_child_element(reader, depth))) {
1800                 node = xmlTextReaderConstName(reader);
1801                 if (!node) {
1802                         _LOGD("xmlTextReaderConstName value is NULL\n");
1803                         return -1;
1804                 }
1805
1806                 if (!strcmp(ASCII(node), "label")) {
1807                         label_x *label = calloc(1, sizeof(label_x));
1808                         if (label == NULL) {
1809                                 _LOGD("Malloc Failed\n");
1810                                 return -1;
1811                         }
1812                         mfx->label = g_list_append(mfx->label, label);
1813                         ret = __ps_process_label(reader, label);
1814                 } else if (!strcmp(ASCII(node), "author")) {
1815                         author_x *author = calloc(1, sizeof(author_x));
1816                         if (author == NULL) {
1817                                 _LOGD("Malloc Failed\n");
1818                                 return -1;
1819                         }
1820                         mfx->author = g_list_append(mfx->author, author);
1821                         ret = __ps_process_author(reader, author);
1822                 } else if (!strcmp(ASCII(node), "description")) {
1823                         description_x *description = calloc(1, sizeof(description_x));
1824                         if (description == NULL) {
1825                                 _LOGD("Malloc Failed\n");
1826                                 return -1;
1827                         }
1828                         mfx->description = g_list_append(mfx->description, description);
1829                         ret = __ps_process_description(reader, description);
1830                 } else if (!strcmp(ASCII(node), "license")) {
1831                         license_x *license = calloc(1, sizeof(license_x));
1832                         if (license == NULL) {
1833                                 _LOGD("Malloc Failed\n");
1834                                 return -1;
1835                         }
1836                         mfx->license = g_list_append(mfx->license, license);
1837                         ret = __ps_process_license(reader, license);
1838                 } else if (!strcmp(ASCII(node), "privileges")) {
1839                         ret = __ps_process_privileges(reader, &mfx->privileges);
1840                 } else if (!strcmp(ASCII(node), "ui-application")) {
1841                         application_x *application = calloc(1, sizeof(application_x));
1842                         if (application == NULL) {
1843                                 _LOGD("Malloc Failed\n");
1844                                 return -1;
1845                         }
1846                         mfx->application = g_list_append(mfx->application, application);
1847                         ret = __ps_process_application(reader, application, PMINFO_UI_APP, uid);
1848                 } else if (!strcmp(ASCII(node), "service-application")) {
1849                         application_x *application = calloc(1, sizeof(application_x));
1850                         if (application == NULL) {
1851                                 _LOGD("Malloc Failed\n");
1852                                 return -1;
1853                         }
1854                         mfx->application = g_list_append(mfx->application, application);
1855                         ret = __ps_process_application(reader, application, PMINFO_SVC_APP, uid);
1856                 } else if (!strcmp(ASCII(node), "widget-application")) {
1857                         application_x *application = calloc(1, sizeof(application_x));
1858                         if (application == NULL) {
1859                                 _LOGD("Malloc Failed\n");
1860                                 return -1;
1861                         }
1862                         mfx->application = g_list_append(mfx->application, application);
1863                         ret = __ps_process_application(reader, application, PMINFO_WIDGET_APP, uid);
1864                 } else if (!strcmp(ASCII(node), "watch-application")) {
1865                         application_x *application = calloc(1, sizeof(application_x));
1866                         if (application == NULL) {
1867                                 _LOGD("Malloc Failed\n");
1868                                 return -1;
1869                         }
1870                         mfx->application = g_list_append(mfx->application, application);
1871                         ret = __ps_process_application(reader, application, PMINFO_WATCH_APP, uid);
1872                 } else if (!strcmp(ASCII(node), "icon")) {
1873                         icon_x *icon = calloc(1, sizeof(icon_x));
1874                         if (icon == NULL) {
1875                                 _LOGD("Malloc Failed\n");
1876                                 return -1;
1877                         }
1878                         mfx->icon = g_list_append(mfx->icon, icon);
1879                         ret = __ps_process_icon(reader, icon, uid);
1880                 } else if (!strcmp(ASCII(node), "compatibility")) {
1881                         compatibility_x *compatibility = calloc(1, sizeof(compatibility_x));
1882                         if (compatibility == NULL) {
1883                                 _LOGD("Malloc Failed\n");
1884                                 return -1;
1885                         }
1886                         mfx->compatibility = g_list_append(mfx->compatibility, compatibility);
1887                         ret = __ps_process_compatibility(reader, compatibility);
1888                 } else if (!strcmp(ASCII(node), "shortcut-list")) {
1889                         continue;
1890                 } else if (!strcmp(ASCII(node), "livebox")) {
1891                         continue;
1892                 } else if (!strcmp(ASCII(node), "account")) {
1893                         continue;
1894                 } else if (!strcmp(ASCII(node), "notifications")) {
1895                         continue;
1896                 } else if (!strcmp(ASCII(node), "ime")) {
1897                         continue;
1898                 } else if (!strcmp(ASCII(node), "feature")) {
1899                         continue;
1900                 } else {
1901                         _LOGI("Unknown element: %s", ASCII(node));
1902                         continue;
1903                 }
1904
1905                 if (ret < 0) {
1906                         _LOGD("Processing manifest failed\n");
1907                         return ret;
1908                 }
1909         }
1910         return ret;
1911 }
1912
1913 static int __process_manifest(xmlTextReaderPtr reader, manifest_x *mfx, uid_t uid)
1914 {
1915         const xmlChar *node;
1916         int ret = -1;
1917
1918         if ((ret = __next_child_element(reader, -1))) {
1919                 node = xmlTextReaderConstName(reader);
1920                 if (!node) {
1921                         _LOGD("xmlTextReaderConstName value is NULL\n");
1922                         return -1;
1923                 }
1924
1925                 if (!strcmp(ASCII(node), "manifest")) {
1926                         __save_xml_attribute(reader, "xmlns", &mfx->ns, NULL);
1927                         __save_xml_attribute(reader, "package", &mfx->package, NULL);
1928                         retvm_if(mfx->package == NULL, PM_PARSER_R_ERROR, "package cant be NULL, package field is mandatory\n");
1929                         __save_xml_attribute(reader, "version", &mfx->version, NULL);
1930                         __save_xml_attribute(reader, "size", &mfx->package_size, NULL);
1931                         __save_xml_attribute(reader, "install-location", &mfx->installlocation, "internal-only");
1932                         __save_xml_attribute(reader, "type", &mfx->type, "tpk");
1933                         __save_xml_attribute(reader, "root_path", &mfx->root_path, NULL);
1934                         __save_xml_attribute(reader, "csc_path", &mfx->csc_path, NULL);
1935                         __save_xml_attribute(reader, "appsetting", &mfx->appsetting, "false");
1936                         __save_xml_attribute(reader, "storeclient-id", &mfx->storeclient_id, NULL);
1937                         __save_xml_attribute(reader, "nodisplay-setting", &mfx->nodisplay_setting, "false");
1938                         __save_xml_attribute(reader, "url", &mfx->package_url, NULL);
1939                         __save_xml_attribute(reader, "api-version", &mfx->api_version, NULL);
1940                         __save_xml_attribute(reader, "support-disable", &mfx->support_disable, "false");
1941
1942                         __save_xml_installed_time(mfx);
1943                         __save_xml_root_path(mfx, uid);
1944                         /*Assign default values. If required it will be overwritten in __add_preload_info()*/
1945                         __save_xml_default_value(mfx);
1946
1947                         ret = __start_process(reader, mfx, uid);
1948                 } else {
1949                         _LOGD("No Manifest element found\n");
1950                         return -1;
1951                 }
1952         }
1953         return ret;
1954 }
1955
1956 #define LIBAPPSVC_PATH LIB_PATH "/libappsvc.so.0"
1957
1958 static int __ps_remove_appsvc_db(manifest_x *mfx, uid_t uid)
1959 {
1960         void *lib_handle = NULL;
1961         int (*appsvc_operation) (const char *, uid_t);
1962         int ret = 0;
1963         GList *tmp;
1964         application_x *application;
1965
1966         if ((lib_handle = dlopen(LIBAPPSVC_PATH, RTLD_LAZY)) == NULL) {
1967                 _LOGE("dlopen is failed LIBAPPSVC_PATH[%s]\n", LIBAPPSVC_PATH);
1968                 goto END;
1969         }
1970
1971         if ((appsvc_operation =
1972                  dlsym(lib_handle, "appsvc_unset_defapp")) == NULL || dlerror() != NULL) {
1973                 _LOGE("can not find symbol \n");
1974                 goto END;
1975         }
1976
1977         for (tmp = mfx->application; tmp; tmp = tmp->next) {
1978                 application = (application_x *)tmp->data;
1979                 if (application == NULL)
1980                         continue;
1981                 ret = appsvc_operation(application->appid, uid);
1982                 if (ret <0)
1983                         _LOGE("can not operation  symbol \n");
1984         }
1985
1986 END:
1987         if (lib_handle)
1988                 dlclose(lib_handle);
1989
1990         return ret;
1991 }
1992
1993 static int __check_preload_updated(manifest_x * mfx, const char *manifest, uid_t uid)
1994 {
1995         if (!strstr(manifest, getUserManifestPath(uid,
1996                 strcmp(mfx->preload, "true") == 0))) {
1997                 /* if downloaded app is updated, then update tag set true*/
1998                 if (mfx->update)
1999                         free((void *)mfx->update);
2000                 mfx->update = strdup("true");
2001         }
2002
2003         return 0;
2004 }
2005
2006 API int pkgmgr_parser_create_desktop_file(manifest_x *mfx)
2007 {
2008         /* desktop file is no longer used */
2009         return 0;
2010 }
2011
2012 API int pkgmgr_parser_create_usr_desktop_file(manifest_x *mfx, uid_t uid)
2013 {
2014         /* desktop file is no longer used */
2015         return 0;
2016 }
2017
2018
2019 API void pkgmgr_parser_free_manifest_xml(manifest_x *mfx)
2020 {
2021         pkgmgrinfo_basic_free_package((package_x *)mfx);
2022 }
2023
2024 API manifest_x *pkgmgr_parser_process_manifest_xml(const char *manifest)
2025 {
2026         _LOGD("parsing start pkgmgr_parser_process_manifest_xml\n");
2027         xmlTextReaderPtr reader;
2028         manifest_x *mfx = NULL;
2029
2030         reader = xmlReaderForFile(manifest, NULL, 0);
2031         if (reader) {
2032                 mfx = malloc(sizeof(manifest_x));
2033                 if (mfx) {
2034                         memset(mfx, '\0', sizeof(manifest_x));
2035                         if (__process_manifest(reader, mfx, GLOBAL_USER) < 0) {
2036                                 _LOGD("Parsing Failed\n");
2037                                 pkgmgr_parser_free_manifest_xml(mfx);
2038                                 mfx = NULL;
2039                         } else
2040                                 _LOGD("Parsing Success\n");
2041                 } else {
2042                         _LOGD("Memory allocation error\n");
2043                 }
2044                 xmlFreeTextReader(reader);
2045         } else {
2046                 _LOGD("Unable to create xml reader\n");
2047         }
2048         return mfx;
2049 }
2050
2051
2052 API manifest_x *pkgmgr_parser_usr_process_manifest_xml(const char *manifest, uid_t uid)
2053 {
2054         _LOGD("parsing start pkgmgr_parser_usr_process_manifest_xml\n");
2055         xmlTextReaderPtr reader;
2056         manifest_x *mfx = NULL;
2057
2058         reader = xmlReaderForFile(manifest, NULL, 0);
2059         if (reader) {
2060                 mfx = malloc(sizeof(manifest_x));
2061                 if (mfx) {
2062                         memset(mfx, '\0', sizeof(manifest_x));
2063                         if (__process_manifest(reader, mfx, uid) < 0) {
2064                                 _LOGD("Parsing Failed\n");
2065                                 pkgmgr_parser_free_manifest_xml(mfx);
2066                                 mfx = NULL;
2067                         } else
2068                                 _LOGD("Parsing Success\n");
2069                 } else {
2070                         _LOGD("Memory allocation error\n");
2071                 }
2072                 xmlFreeTextReader(reader);
2073         } else {
2074                 _LOGD("Unable to create xml reader\n");
2075         }
2076         return mfx;
2077 }
2078
2079 API int pkgmgr_parser_usr_update_tep(const char *pkgid, const char *tep_path, uid_t uid)
2080 {
2081         return pkgmgr_parser_update_tep_info_in_usr_db(pkgid, tep_path, uid);
2082 }
2083
2084 API int pkgmgr_parser_update_tep(const char *pkgid, const char *tep_path)
2085 {
2086         return pkgmgr_parser_update_tep_info_in_db(pkgid, tep_path);
2087 }
2088
2089 API int pkgmgr_parser_parse_manifest_for_installation(const char *manifest, char *const tagv[])
2090 {
2091         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2092         _LOGD("parsing manifest for installation: %s\n", manifest);
2093
2094         manifest_x *mfx = NULL;
2095         int ret = -1;
2096
2097         xmlInitParser();
2098         mfx = pkgmgr_parser_process_manifest_xml(manifest);
2099         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2100
2101         _LOGD("Parsing Finished\n");
2102
2103         __ps_process_tag(mfx, tagv);
2104
2105         ret = pkgmgr_parser_insert_manifest_info_in_db(mfx);
2106         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2107
2108         _LOGD("DB Insert Success\n");
2109
2110         __ps_process_tag_parser(mfx, manifest, ACTION_INSTALL);
2111         ret = __ps_process_metadata_parser(mfx, ACTION_INSTALL);
2112         if (ret == -1)
2113                 _LOGD("Creating metadata parser failed\n");
2114
2115         ret = __ps_process_category_parser(mfx, ACTION_INSTALL);
2116         if (ret == -1)
2117                 _LOGD("Creating category parser failed\n");
2118
2119         pkgmgr_parser_free_manifest_xml(mfx);
2120         _LOGD("Free Done\n");
2121         xmlCleanupParser();
2122
2123         return PMINFO_R_OK;
2124 }
2125 API int pkgmgr_parser_parse_usr_manifest_for_installation(const char *manifest, uid_t uid, char *const tagv[])
2126 {
2127         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2128         _LOGD("parsing manifest for installation: %s\n", manifest);
2129         manifest_x *mfx = NULL;
2130         int ret = -1;
2131
2132         xmlInitParser();
2133         mfx = pkgmgr_parser_usr_process_manifest_xml(manifest, uid);
2134         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2135
2136         _LOGD("Parsing Finished\n");
2137
2138         __ps_process_tag(mfx, tagv);
2139
2140         ret = pkgmgr_parser_insert_manifest_info_in_usr_db(mfx, uid);
2141         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2142
2143         _LOGD("DB Insert Success\n");
2144
2145         __ps_process_tag_parser(mfx, manifest, ACTION_INSTALL);
2146         ret = __ps_process_metadata_parser(mfx, ACTION_INSTALL);
2147         if (ret == -1)
2148                 _LOGD("Creating metadata parser failed\n");
2149         ret = __ps_process_category_parser(mfx, ACTION_INSTALL);
2150         if (ret == -1)
2151                 _LOGD("Creating category parser failed\n");
2152
2153         pkgmgr_parser_free_manifest_xml(mfx);
2154         _LOGD("Free Done\n");
2155         xmlCleanupParser();
2156
2157         return PMINFO_R_OK;
2158 }
2159
2160 API int pkgmgr_parser_process_manifest_x_for_installation(manifest_x* mfx, const char *manifest) {
2161         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2162         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2163         _LOGD("processing manifest_x for installation: %s\n", manifest);
2164         int ret = -1;
2165
2166         xmlInitParser();
2167
2168         _LOGD("Added preload infomation\n");
2169
2170         ret = pkgmgr_parser_insert_manifest_info_in_db(mfx);
2171         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2172         _LOGD("DB Insert Success\n");
2173         xmlCleanupParser();
2174
2175         return PMINFO_R_OK;
2176 }
2177
2178 API int pkgmgr_parser_process_usr_manifest_x_for_installation(manifest_x* mfx, const char *manifest, uid_t uid) {
2179         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2180         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2181         _LOGD("processing manifest_x for installation: %s\n", manifest);
2182         int ret = -1;
2183
2184         xmlInitParser();
2185         ret = pkgmgr_parser_insert_manifest_info_in_usr_db(mfx, uid);
2186         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2187         _LOGD("DB Insert Success\n");
2188         xmlCleanupParser();
2189         return PMINFO_R_OK;
2190 }
2191
2192 API int pkgmgr_parser_parse_manifest_for_upgrade(const char *manifest, char *const tagv[])
2193 {
2194         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2195         _LOGD("pkgmgr_parser_parse_manifest_for_upgrade  parsing manifest for upgradation: %s\n", manifest);
2196         manifest_x *mfx = NULL;
2197         int ret = -1;
2198         bool preload = false;
2199         bool system = false;
2200         char *csc_path = NULL;
2201         pkgmgrinfo_pkginfo_h handle = NULL;
2202
2203         xmlInitParser();
2204         mfx = pkgmgr_parser_process_manifest_xml(manifest);
2205         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2206
2207         _LOGD("Parsing Finished\n");
2208         __check_preload_updated(mfx, manifest, GLOBAL_USER);
2209
2210         ret = pkgmgrinfo_pkginfo_get_pkginfo(mfx->package, &handle);
2211         if (ret != PMINFO_R_OK)
2212                 _LOGD("pkgmgrinfo_pkginfo_get_pkginfo failed\n");
2213         ret = pkgmgrinfo_pkginfo_is_preload(handle, &preload);
2214         if (ret != PMINFO_R_OK)
2215                 _LOGD("pkgmgrinfo_pkginfo_is_preload failed\n");
2216
2217         if (preload) {
2218                 free((void *)mfx->preload);
2219                 mfx->preload = strdup("true");
2220         }
2221
2222         ret = pkgmgrinfo_pkginfo_is_system(handle, &system);
2223         if (ret != PMINFO_R_OK)
2224                 _LOGD("pkgmgrinfo_pkginfo_is_system failed\n");
2225         if (system) {
2226                 free((void *)mfx->system);
2227                 mfx->system = strdup("true");
2228         }
2229
2230         ret = pkgmgrinfo_pkginfo_get_csc_path(handle, &csc_path);
2231         if (ret != PMINFO_R_OK)
2232                 _LOGD("pkgmgrinfo_pkginfo_get_csc_path failed\n");
2233
2234         if (csc_path != NULL) {
2235                 if (mfx->csc_path)
2236                         free((void *)mfx->csc_path);
2237                 mfx->csc_path = strdup(csc_path);
2238         }
2239
2240         ret = pkgmgr_parser_update_manifest_info_in_db(mfx);
2241         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2242
2243         _LOGD("DB Update Success\n");
2244
2245         __ps_process_tag_parser(mfx, manifest, ACTION_UPGRADE);
2246         ret = __ps_process_metadata_parser(mfx, ACTION_UPGRADE);
2247         if (ret == -1){
2248                 _LOGD("Upgrade metadata parser failed\n");
2249         }
2250         ret = __ps_process_category_parser(mfx, ACTION_UPGRADE);
2251         if (ret == -1)
2252                 _LOGD("Creating category parser failed\n");
2253         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2254         pkgmgr_parser_free_manifest_xml(mfx);
2255         _LOGD("Free Done\n");
2256         xmlCleanupParser();
2257
2258         return PMINFO_R_OK;
2259 }
2260
2261 API int pkgmgr_parser_parse_usr_manifest_for_upgrade(const char *manifest, uid_t uid, char *const tagv[])
2262 {
2263         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2264         _LOGD(" pkgmgr_parser_parse_usr_manifest_for_upgrade parsing manifest for upgradation: %s\n", manifest);
2265         manifest_x *mfx = NULL;
2266         int ret = -1;
2267         bool preload = false;
2268         bool system = false;
2269         char *csc_path = NULL;
2270         pkgmgrinfo_pkginfo_h handle = NULL;
2271
2272         xmlInitParser();
2273         mfx = pkgmgr_parser_usr_process_manifest_xml(manifest, uid);
2274         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2275
2276         _LOGD("Parsing Finished\n");
2277         __check_preload_updated(mfx, manifest, uid);
2278
2279         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(mfx->package, uid, &handle);
2280         if (ret != PMINFO_R_OK)
2281                 _LOGD("pkgmgrinfo_pkginfo_get_pkginfo failed\n");
2282         ret = pkgmgrinfo_pkginfo_is_preload(handle, &preload);
2283         if (ret != PMINFO_R_OK)
2284                 _LOGD("pkgmgrinfo_pkginfo_is_preload failed\n");
2285
2286         if (preload) {
2287                 free((void *)mfx->preload);
2288                 mfx->preload = strdup("true");
2289         }
2290
2291         ret = pkgmgrinfo_pkginfo_is_system(handle, &system);
2292         if (ret != PMINFO_R_OK)
2293                 _LOGD("pkgmgrinfo_pkginfo_is_system failed\n");
2294
2295         if (system) {
2296                 free((void *)mfx->system);
2297                 mfx->system = strdup("true");
2298         }
2299
2300         ret = pkgmgrinfo_pkginfo_get_csc_path(handle, &csc_path);
2301         if (ret != PMINFO_R_OK)
2302                 _LOGD("pkgmgrinfo_pkginfo_get_csc_path failed\n");
2303         if (csc_path != NULL) {
2304                 if (mfx->csc_path)
2305                         free((void *)mfx->csc_path);
2306                 mfx->csc_path = strdup(csc_path);
2307         }
2308
2309         ret = pkgmgr_parser_update_manifest_info_in_usr_db(mfx, uid);
2310         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2311         _LOGD("DB Update Success\n");
2312
2313         __ps_process_tag_parser(mfx, manifest, ACTION_UPGRADE);
2314         ret = __ps_process_metadata_parser(mfx, ACTION_UPGRADE);
2315         if (ret == -1)
2316                 _LOGD("Upgrade metadata parser failed\n");
2317         ret = __ps_process_category_parser(mfx, ACTION_UPGRADE);
2318         if (ret == -1)
2319                 _LOGD("Creating category parser failed\n");
2320         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2321         pkgmgr_parser_free_manifest_xml(mfx);
2322         _LOGD("Free Done\n");
2323         xmlCleanupParser();
2324
2325         return PMINFO_R_OK;
2326 }
2327
2328 API int pkgmgr_parser_process_manifest_x_for_upgrade(manifest_x* mfx, const char *manifest) {
2329         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2330         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2331         _LOGD("pkgmgr_parser_process_manifest_x_for_upgrade  parsing manifest for upgradation: %s\n", manifest);
2332         int ret = -1;
2333         bool system = false;
2334         char *csc_path = NULL;
2335         pkgmgrinfo_pkginfo_h handle = NULL;
2336
2337         xmlInitParser();
2338
2339         ret = pkgmgrinfo_pkginfo_get_pkginfo(mfx->package, &handle);
2340         if (ret != PMINFO_R_OK)
2341                 _LOGD("pkgmgrinfo_pkginfo_get_pkginfo failed\n");
2342
2343         ret = pkgmgrinfo_pkginfo_is_system(handle, &system);
2344         if (ret != PMINFO_R_OK)
2345                 _LOGD("pkgmgrinfo_pkginfo_is_system failed\n");
2346         if (system) {
2347                 free((void *)mfx->system);
2348                 mfx->system = strdup("true");
2349         }
2350
2351         ret = pkgmgrinfo_pkginfo_get_csc_path(handle, &csc_path);
2352         if (ret != PMINFO_R_OK)
2353                 _LOGD("pkgmgrinfo_pkginfo_get_csc_path failed\n");
2354
2355         if (csc_path != NULL) {
2356                 if (mfx->csc_path)
2357                         free((void *)mfx->csc_path);
2358                 mfx->csc_path = strdup(csc_path);
2359         }
2360
2361         ret = pkgmgr_parser_update_manifest_info_in_db(mfx);
2362         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2363         _LOGD("DB Update Success\n");
2364         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2365         xmlCleanupParser();
2366
2367         return PMINFO_R_OK;
2368 }
2369
2370 API int pkgmgr_parser_process_usr_manifest_x_for_upgrade(manifest_x* mfx, const char *manifest, uid_t uid) {
2371         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2372         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2373         _LOGD(" pkgmgr_parser_process_usr_manifest_x_for_upgrade parsing manifest for upgradation: %s\n", manifest);
2374         int ret = -1;
2375         pkgmgrinfo_pkginfo_h handle = NULL;
2376
2377         xmlInitParser();
2378
2379         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(mfx->package, uid, &handle);
2380         if (ret != PMINFO_R_OK)
2381                 _LOGD("pkgmgrinfo_pkginfo_get_pkginfo failed\n");
2382
2383         ret = pkgmgr_parser_update_manifest_info_in_usr_db(mfx, uid);
2384         retvm_if(ret == PMINFO_R_ERROR, PMINFO_R_ERROR, "DB Insert failed");
2385         _LOGD("DB Update Success\n");
2386         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2387         xmlCleanupParser();
2388
2389         return PMINFO_R_OK;
2390 }
2391
2392 API int pkgmgr_parser_parse_manifest_for_uninstallation(const char *manifest, char *const tagv[])
2393 {
2394         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2395         _LOGD("parsing manifest for uninstallation: %s\n", manifest);
2396
2397         manifest_x *mfx = NULL;
2398         int ret = -1;
2399         xmlInitParser();
2400         mfx = pkgmgr_parser_process_manifest_xml(manifest);
2401         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2402
2403         _LOGD("Parsing Finished\n");
2404
2405         __ps_process_tag_parser(mfx, manifest, ACTION_UNINSTALL);
2406
2407         ret = __ps_process_metadata_parser(mfx, ACTION_UNINSTALL);
2408         if (ret == -1)
2409                 _LOGD("Removing metadata parser failed\n");
2410
2411         ret = __ps_process_category_parser(mfx, ACTION_UNINSTALL);
2412         if (ret == -1)
2413                 _LOGD("Creating category parser failed\n");
2414
2415         ret = pkgmgr_parser_delete_manifest_info_from_db(mfx);
2416         if (ret == -1)
2417                 _LOGD("DB Delete failed\n");
2418         else
2419                 _LOGD("DB Delete Success\n");
2420
2421         pkgmgr_parser_free_manifest_xml(mfx);
2422         _LOGD("Free Done\n");
2423         xmlCleanupParser();
2424
2425         return PMINFO_R_OK;
2426 }
2427
2428
2429 API int pkgmgr_parser_parse_usr_manifest_for_uninstallation(const char *manifest, uid_t uid, char *const tagv[])
2430 {
2431         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2432         _LOGD("parsing manifest for uninstallation: %s\n", manifest);
2433
2434         manifest_x *mfx = NULL;
2435         int ret = -1;
2436         xmlInitParser();
2437         mfx = pkgmgr_parser_usr_process_manifest_xml(manifest, uid);
2438         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2439
2440         _LOGD("Parsing Finished\n");
2441
2442         __ps_process_tag_parser(mfx, manifest, ACTION_UNINSTALL);
2443
2444         ret = __ps_process_metadata_parser(mfx, ACTION_UNINSTALL);
2445         if (ret == -1)
2446                 _LOGD("Removing metadata parser failed\n");
2447
2448         ret = __ps_process_category_parser(mfx, ACTION_UNINSTALL);
2449         if (ret == -1)
2450                 _LOGD("Creating category parser failed\n");
2451
2452         ret = pkgmgr_parser_delete_manifest_info_from_usr_db(mfx, uid);
2453         if (ret == -1)
2454                 _LOGD("DB Delete failed\n");
2455         else
2456                 _LOGD("DB Delete Success\n");
2457
2458         ret = __ps_remove_appsvc_db(mfx, uid);
2459         if (ret == -1)
2460                 _LOGD("Removing appsvc_db failed\n");
2461         else
2462                 _LOGD("Removing appsvc_db Success\n");
2463
2464         pkgmgr_parser_free_manifest_xml(mfx);
2465         _LOGD("Free Done\n");
2466         xmlCleanupParser();
2467
2468         return PMINFO_R_OK;
2469 }
2470
2471 API int pkgmgr_parser_process_manifest_x_for_uninstallation(manifest_x* mfx, const char *manifest) {
2472         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2473         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2474         _LOGD("processing manifest_x for uninstallation: %s\n", manifest);
2475
2476         int ret = -1;
2477         xmlInitParser();
2478         ret = pkgmgr_parser_delete_manifest_info_from_db(mfx);
2479         if (ret == -1)
2480                 _LOGD("DB Delete failed\n");
2481         else
2482                 _LOGD("DB Delete Success\n");
2483         xmlCleanupParser();
2484
2485         return PMINFO_R_OK;
2486 }
2487
2488 API int pkgmgr_parser_process_usr_manifest_x_for_uninstallation(manifest_x* mfx, const char *manifest, uid_t uid) {
2489         retvm_if(mfx == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2490         retvm_if(manifest == NULL, PMINFO_R_ERROR, "argument supplied is NULL");
2491         _LOGD("processing manifest_x for uninstallation: %s\n", manifest);
2492
2493         int ret = -1;
2494         xmlInitParser();
2495
2496         ret = pkgmgr_parser_delete_manifest_info_from_usr_db(mfx, uid);
2497         if (ret == -1)
2498                 _LOGD("DB Delete failed\n");
2499         else
2500                 _LOGD("DB Delete Success\n");
2501
2502         ret = __ps_remove_appsvc_db(mfx, uid);
2503         if (ret == -1)
2504                 _LOGD("Removing appsvc_db failed\n");
2505         else
2506                 _LOGD("Removing appsvc_db Success\n");
2507         xmlCleanupParser();
2508
2509         return PMINFO_R_OK;
2510 }
2511
2512 API int pkgmgr_parser_parse_manifest_for_preload()
2513 {
2514         return pkgmgr_parser_update_preload_info_in_db();
2515 }
2516
2517 API int pkgmgr_parser_parse_usr_manifest_for_preload(uid_t uid)
2518 {
2519         return pkgmgr_parser_update_preload_info_in_usr_db(uid);
2520 }
2521
2522 API int pkgmgr_parser_run_parser_for_installation(xmlDocPtr docPtr, const char *tag, const char *pkgid)
2523 {
2524         return __ps_run_parser(docPtr, tag, ACTION_INSTALL, pkgid);
2525 }
2526
2527 API int pkgmgr_parser_run_parser_for_upgrade(xmlDocPtr docPtr, const char *tag, const char *pkgid)
2528 {
2529         return __ps_run_parser(docPtr, tag, ACTION_UPGRADE, pkgid);
2530 }
2531
2532 API int pkgmgr_parser_run_parser_for_uninstallation(xmlDocPtr docPtr, const char *tag, const char *pkgid)
2533 {
2534         return __ps_run_parser(docPtr, tag, ACTION_UNINSTALL, pkgid);
2535 }
2536
2537 #define SCHEMA_FILE SYSCONFDIR "/package-manager/preload/manifest.xsd"
2538 #if 1
2539 API int pkgmgr_parser_check_manifest_validation(const char *manifest)
2540 {
2541         if (manifest == NULL) {
2542                 _LOGE("manifest file is NULL\n");
2543                 return PMINFO_R_EINVAL;
2544         }
2545         int ret = -1;
2546         xmlSchemaParserCtxtPtr ctx;
2547         xmlSchemaValidCtxtPtr vctx;
2548         xmlSchemaPtr xschema;
2549         ctx = xmlSchemaNewParserCtxt(SCHEMA_FILE);
2550         if (ctx == NULL) {
2551                 _LOGE("xmlSchemaNewParserCtxt() Failed\n");
2552                 return PMINFO_R_ERROR;
2553         }
2554         xschema = xmlSchemaParse(ctx);
2555         if (xschema == NULL) {
2556                 _LOGE("xmlSchemaParse() Failed\n");
2557                 return PMINFO_R_ERROR;
2558         }
2559         vctx = xmlSchemaNewValidCtxt(xschema);
2560         if (vctx == NULL) {
2561                 _LOGE("xmlSchemaNewValidCtxt() Failed\n");
2562                 return PMINFO_R_ERROR;
2563         }
2564         xmlSchemaSetValidErrors(vctx, (xmlSchemaValidityErrorFunc) fprintf, (xmlSchemaValidityWarningFunc) fprintf, stderr);
2565         ret = xmlSchemaValidateFile(vctx, manifest, 0);
2566         if (ret == -1) {
2567                 _LOGE("xmlSchemaValidateFile() failed\n");
2568                 return PMINFO_R_ERROR;
2569         } else if (ret == 0) {
2570                 _LOGD("Manifest is Valid\n");
2571                 return PMINFO_R_OK;
2572         } else {
2573                 _LOGE("Manifest Validation Failed with error code %d\n", ret);
2574                 return PMINFO_R_ERROR;
2575         }
2576         return PMINFO_R_OK;
2577 }
2578
2579 #else
2580 API int pkgmgr_parser_check_manifest_validation(const char *manifest)
2581 {
2582         int err = 0;
2583         int status = 0;
2584         pid_t pid;
2585
2586         pid = fork();
2587
2588         switch (pid) {
2589         case -1:
2590                 _LOGE("fork failed\n");
2591                 return -1;
2592         case 0:
2593                 /* child */
2594                 {
2595                         int dev_null_fd = open ("/dev/null", O_RDWR);
2596                         if (dev_null_fd >= 0)
2597                         {
2598                                 dup2 (dev_null_fd, 0);/*stdin*/
2599                                 dup2 (dev_null_fd, 1);/*stdout*/
2600                                 dup2 (dev_null_fd, 2);/*stderr*/
2601                         }
2602
2603                         if (execl("/usr/bin/xmllint", "xmllint", manifest, "--schema",
2604                                 SCHEMA_FILE, NULL) < 0) {
2605                                 _LOGE("execl error\n");
2606                         }
2607
2608                         _exit(100);
2609                 }
2610         default:
2611                 /* parent */
2612                 break;
2613         }
2614
2615         while ((err = waitpid(pid, &status, WNOHANG)) != pid) {
2616                 if (err < 0) {
2617                         if (errno == EINTR)
2618                                 continue;
2619                         _LOGE("waitpid failed\n");
2620                         return -1;
2621                 }
2622         }
2623
2624
2625         if(WIFEXITED(status) && !WEXITSTATUS(status))
2626                 return 0;
2627         else
2628                 return -1;
2629 }
2630 #endif