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