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