tizen 2.3.1 release
[framework/appfw/pkgmgr-info.git] / parser / pkgmgr_parser_plugin.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
23 #define _GNU_SOURCE
24
25 #include <dlfcn.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <ctype.h>
31 #include <time.h>
32 #include <string.h>
33 #include <libxml/parser.h>
34 #include <libxml/xmlreader.h>
35 #include <libxml/xmlschemas.h>
36 #include <glib.h>
37 #include <db-util.h>
38
39 #include "pkgmgr_parser_plugin.h"
40 #include "pkgmgr-info.h"
41 #include "pkgmgrinfo_debug.h"
42
43 #ifdef LOG_TAG
44 #undef LOG_TAG
45 #endif
46 #define LOG_TAG "PKGMGR_PLUGIN"
47
48 #define ASCII(s) (const char *)s
49 #define XMLCHAR(s) (const xmlChar *)s
50
51 #define PLLUGIN_LIST "/usr/etc/package-manager/parserlib/pkgmgr_parser_plugin_list.txt"
52
53 #define TOKEN_TYPE_STR  "type="
54 #define TOKEN_NAME_STR  "name="
55 #define TOKEN_FLAG_STR  "flag="
56 #define TOKEN_PATH_STR  "path="
57
58 #define SEPERATOR_START         '"'
59 #define SEPERATOR_END           '"'
60
61 #define PKG_PARSER_CONF_PATH    "/usr/etc/package-manager/parser_path.conf"
62 #define TAG_PARSER_NAME "parserlib:"
63
64 typedef struct pkgmgr_parser_plugin_info_x {
65         manifest_x *mfx;
66         char *pkgid;
67         char *appid;
68         char *filename;
69         char *type;
70         char *name;
71         char *path;
72         char *flag;
73         void *lib_handle;
74         ACTION_TYPE action;
75         int enabled_plugin;
76 } pkgmgr_parser_plugin_info_x;
77
78 #define E_PKGMGR_PARSER_PLUGIN_MAX                                              0xFFFFFFFF
79
80 #define QUERY_CREATE_TABLE_PACKAGE_PLUGIN_INFO "create table if not exists package_plugin_info " \
81         "(pkgid text primary key not null, " \
82         "enabled_plugin INTEGER DEFAULT 0)"
83
84 /*db info*/
85 #define PKGMGR_PARSER_DB_FILE "/opt/dbspace/.pkgmgr_parser.db"
86 sqlite3 *pkgmgr_parser_db;
87
88 typedef struct {
89         char *key;
90         char *value;
91 } __metadata_t;
92
93 typedef struct {
94         char *name;
95 } __category_t;
96
97 static void __str_trim(char *input)
98 {
99         char *trim_str = input;
100
101         if (input == NULL)
102                 return;
103
104         while (*input != 0) {
105                 if (!isspace(*input)) {
106                         *trim_str = *input;
107                         trim_str++;
108                 }
109                 input++;
110         }
111
112         *trim_str = 0;
113         return;
114 }
115
116 static char *__get_parser_plugin_path(const char *type, char *plugin_name)
117 {
118         FILE *fp = NULL;
119         char buffer[1024] = { 0 };
120         char temp_path[1024] = { 0 };
121         char *path = NULL;
122
123         if (type == NULL) {
124                 _LOGE("invalid argument\n");
125                 return NULL;
126         }
127
128         fp = fopen(PKG_PARSER_CONF_PATH, "r");
129         if (fp == NULL) {
130                 _LOGE("no matching backendlib\n");
131                 return NULL;
132         }
133
134         while (fgets(buffer, sizeof(buffer), fp) != NULL) {
135                 if (buffer[0] == '#')
136                         continue;
137
138                 __str_trim(buffer);
139
140                 if ((path = strstr(buffer, plugin_name)) != NULL) {
141                         path = path + strlen(plugin_name);
142                         break;
143                 }
144
145                 memset(buffer, 0x00, 1024);
146         }
147
148         if (fp != NULL)
149                 fclose(fp);
150
151         if (path == NULL) {
152                 _LOGE("no matching backendlib\n");
153                 return NULL;
154         }
155
156         snprintf(temp_path, sizeof(temp_path) - 1, "%slib%s.so", path, type);
157
158         return strdup(temp_path);
159 }
160
161 static void __metadata_parser_clear_dir_list(GList* dir_list)
162 {
163         GList *list = NULL;
164         __metadata_t* detail = NULL;
165
166         if (dir_list) {
167                 list = g_list_first(dir_list);
168                 while (list) {
169                         detail = (__metadata_t *)list->data;
170                         if (detail) {
171                                 FREE_AND_NULL(detail->key);
172                                 FREE_AND_NULL(detail->value);
173                                 FREE_AND_NULL(detail);
174                         }
175                         list = g_list_next(list);
176                 }
177                 g_list_free(dir_list);
178         }
179 }
180
181 static void __category_parser_clear_dir_list(GList* dir_list)
182 {
183         GList *list = NULL;
184         __category_t* detail = NULL;
185
186         if (dir_list) {
187                 list = g_list_first(dir_list);
188                 while (list) {
189                         detail = (__category_t *)list->data;
190                         if (detail) {
191                                 FREE_AND_NULL(detail->name);
192                                 FREE_AND_NULL(detail);
193                         }
194                         list = g_list_next(list);
195                 }
196                 g_list_free(dir_list);
197         }
198 }
199
200 static int __parser_send_tag(void *lib_handle, ACTION_TYPE action, PLUGIN_PROCESS_TYPE process, const char *pkgid)
201 {
202         int ret = -1;
203         int (*plugin_install) (const char *);
204         char *ac = NULL;
205
206         if (process == PLUGIN_PRE_PROCESS) {
207                 switch (action) {
208                 case ACTION_INSTALL:
209                         ac = "PKGMGR_PARSER_PLUGIN_PRE_INSTALL";
210                         break;
211                 case ACTION_UPGRADE:
212                         ac = "PKGMGR_PARSER_PLUGIN_PRE_UPGRADE";
213                         break;
214                 case ACTION_UNINSTALL:
215                         ac = "PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL";
216                         break;
217                 default:
218                         _LOGE("PRE_PROCESS : action type error[%d]\n", action);
219                         return -1;
220                 }
221         } else if (process == PLUGIN_POST_PROCESS) {
222                 switch (action) {
223                 case ACTION_INSTALL:
224                         ac = "PKGMGR_PARSER_PLUGIN_POST_INSTALL";
225                         break;
226                 case ACTION_UPGRADE:
227                         ac = "PKGMGR_PARSER_PLUGIN_POST_UPGRADE";
228                         break;
229                 case ACTION_UNINSTALL:
230                         ac = "PKGMGR_PARSER_PLUGIN_POST_UNINSTALL";
231                         break;
232                 default:
233                         _LOGE("POST_PROCESS : action type error[%d]\n", action);
234                         return -1;
235                 }
236         } else {
237                 _LOGE("process type error[%d]\n", process);
238                 return -1;
239         }
240
241         if ((plugin_install = dlsym(lib_handle, ac)) == NULL || dlerror() != NULL) {
242                 return -1;
243         }
244
245         ret = plugin_install(pkgid);
246         return ret;
247 }
248
249 int __ps_run_parser(xmlDocPtr docPtr, const char *tag,
250                            ACTION_TYPE action, const char *pkgid)
251 {
252         char *lib_path = NULL;
253         void *lib_handle = NULL;
254         int (*plugin_install) (xmlDocPtr, const char *);
255         int ret = -1;
256         char *ac = NULL;
257
258         switch (action) {
259         case ACTION_INSTALL:
260                 ac = "PKGMGR_PARSER_PLUGIN_INSTALL";
261                 break;
262         case ACTION_UPGRADE:
263                 ac = "PKGMGR_PARSER_PLUGIN_UPGRADE";
264                 break;
265         case ACTION_UNINSTALL:
266                 ac = "PKGMGR_PARSER_PLUGIN_UNINSTALL";
267                 break;
268         default:
269                 goto END;
270         }
271
272         lib_path = __get_parser_plugin_path(tag, TAG_PARSER_NAME);
273
274         if (!lib_path) {
275                 goto END;
276         }
277
278         if ((lib_handle = dlopen(lib_path, RTLD_LAZY)) == NULL) {
279                 _LOGE("dlopen is failed lib_path[%s]\n", lib_path);
280                 goto END;
281         }
282         if ((plugin_install =
283                 dlsym(lib_handle, ac)) == NULL || dlerror() != NULL) {
284                 _LOGE("can not find symbol[%s] \n", ac);
285                 goto END;
286         }
287
288         ret = plugin_install(docPtr, pkgid);
289         if (ret < 0)
290                 _LOGD("[pkgid = %s, libpath = %s plugin fail\n", pkgid, lib_path);
291         else
292                 _LOGD("[pkgid = %s, libpath = %s plugin success\n", pkgid, lib_path);
293
294 END:
295         FREE_AND_NULL(lib_path);
296         if (lib_handle)
297                 dlclose(lib_handle);
298         return ret;
299 }
300
301 static int __ps_get_enabled_plugin(const char *pkgid)
302 {
303         char *query = NULL;
304         sqlite3_stmt *stmt = NULL;
305         const char *tail = NULL;
306         int rc = 0;
307         int enabled_plugin = 0;
308
309         query = sqlite3_mprintf("select * from package_plugin_info where pkgid LIKE %Q", pkgid);
310
311         if (SQLITE_OK != sqlite3_prepare(pkgmgr_parser_db, query, strlen(query), &stmt, &tail)) {
312                 _LOGE("sqlite3_prepare error\n");
313                 sqlite3_free(query);
314                 return E_PKGMGR_PARSER_PLUGIN_MAX;
315         }
316
317         rc = sqlite3_step(stmt);
318         if (rc != SQLITE_ROW || rc == SQLITE_DONE) {
319                 _LOGE("No records found");
320                 goto FINISH_OFF;
321         }
322
323         enabled_plugin = (int)sqlite3_column_int(stmt, 1);
324
325 //      _LOGD("enabled_plugin  ===>    %d", enabled_plugin);
326
327         if (SQLITE_OK != sqlite3_finalize(stmt)) {
328                 _LOGE("error : sqlite3_finalize\n");
329                 goto FINISH_OFF;
330         }
331
332         sqlite3_free(query);
333         return enabled_plugin;
334
335 FINISH_OFF:
336         rc = sqlite3_finalize(stmt);
337         if (rc != SQLITE_OK) {
338                 _LOGE(" sqlite3_finalize failed - %d", rc);
339         }
340         sqlite3_free(query);
341         return E_PKGMGR_PARSER_PLUGIN_MAX;
342 }
343
344 static char *__getvalue(const char* pBuf, const char* pKey)
345 {
346         const char* p = NULL;
347         const char* pStart = NULL;
348         const char* pEnd = NULL;
349
350         p = strstr(pBuf, pKey);
351         if (p == NULL)
352                 return NULL;
353
354         pStart = p + strlen(pKey) + 1;
355         pEnd = strchr(pStart, SEPERATOR_END);
356         if (pEnd == NULL)
357                 return NULL;
358
359         size_t len = pEnd - pStart;
360         if (len <= 0)
361                 return NULL;
362
363         char *pRes = (char*)malloc(len + 1);
364         if(pRes == NULL)
365                 return NULL;
366
367         strncpy(pRes, pStart, len);
368         pRes[len] = 0;
369
370         return pRes;
371 }
372
373 static int __get_plugin_info_x(const char*buf, pkgmgr_parser_plugin_info_x *plugin_info)
374 {
375         if (buf[0] == '#')
376                 return -1;
377
378         if (strstr(buf, TOKEN_TYPE_STR) == NULL)
379                 return -1;
380
381         plugin_info->type = __getvalue(buf, TOKEN_TYPE_STR);
382         if (plugin_info->type == NULL)
383                 return -1;
384
385         plugin_info->name = __getvalue(buf, TOKEN_NAME_STR);
386         plugin_info->flag = __getvalue(buf, TOKEN_FLAG_STR);
387         plugin_info->path = __getvalue(buf, TOKEN_PATH_STR);
388
389         return 0;
390 }
391
392 void __clean_plugin_info(pkgmgr_parser_plugin_info_x *plugin_info)
393 {
394         if(plugin_info == NULL)
395                 return;
396
397         FREE_AND_NULL(plugin_info->filename);
398         FREE_AND_NULL(plugin_info->pkgid);
399         FREE_AND_NULL(plugin_info->appid);
400         FREE_AND_NULL(plugin_info);
401         return;
402 }
403
404 static void __check_enabled_plugin(pkgmgr_parser_plugin_info_x *plugin_info)
405 {
406         int enabled_plugin = 0x0000001;
407
408         enabled_plugin = (int)strtol( plugin_info->flag, NULL, 16 );
409
410         _LOGD( "[%s] flag = 0x%x done[action=%d]!! \n", plugin_info->pkgid, enabled_plugin, plugin_info->action);
411
412         plugin_info->enabled_plugin = plugin_info->enabled_plugin | enabled_plugin;
413 }
414
415 static void __run_metadata_parser(pkgmgr_parser_plugin_info_x *plugin_info, GList *md_list, const char *appid)
416 {
417         int (*metadata_parser_plugin) (const char *, const char *, GList *);
418         int ret = -1;
419         char *ac = NULL;
420
421         switch (plugin_info->action) {
422         case ACTION_INSTALL:
423                 ac = "PKGMGR_MDPARSER_PLUGIN_INSTALL";
424                 break;
425         case ACTION_UPGRADE:
426                 ac = "PKGMGR_MDPARSER_PLUGIN_UPGRADE";
427                 break;
428         case ACTION_UNINSTALL:
429                 ac = "PKGMGR_MDPARSER_PLUGIN_UNINSTALL";
430                 break;
431         default:
432                 goto END;
433         }
434
435         if ((metadata_parser_plugin =
436                 dlsym(plugin_info->lib_handle, ac)) == NULL || dlerror() != NULL) {
437                 _LOGE("can not find symbol[%s] \n",ac);
438                 goto END;
439         }
440
441         ret = metadata_parser_plugin(plugin_info->pkgid, appid, md_list);
442         _LOGD("Plugin = %s, appid = %s, result=%d\n", plugin_info->name, appid, ret);
443
444         __check_enabled_plugin(plugin_info);
445
446 END:
447         return;
448 }
449
450 static void __run_category_parser(pkgmgr_parser_plugin_info_x *plugin_info, GList *category_list, const char *appid)
451 {
452         int (*category_parser_plugin) (const char *, const char *, GList *);
453         int ret = -1;
454         char *ac = NULL;
455
456         switch (plugin_info->action) {
457         case ACTION_INSTALL:
458                 ac = "PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL";
459                 break;
460         case ACTION_UPGRADE:
461                 ac = "PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE";
462                 break;
463         case ACTION_UNINSTALL:
464                 ac = "PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL";
465                 break;
466         default:
467                 goto END;
468         }
469
470         if ((category_parser_plugin =
471                 dlsym(plugin_info->lib_handle, ac)) == NULL || dlerror() != NULL) {
472                 _LOGE("can not find symbol[%s] \n",ac);
473                 goto END;
474         }
475
476         ret = category_parser_plugin(plugin_info->pkgid, appid, category_list);
477         _LOGD("Plugin = %s, appid = %s, result=%d\n", plugin_info->name, appid, ret);
478
479         __check_enabled_plugin(plugin_info);
480
481 END:
482         return;
483 }
484
485
486 static void __run_tag_parser(pkgmgr_parser_plugin_info_x *plugin_info, xmlDocPtr docPtr)
487 {
488         int (*plugin_install) (xmlDocPtr, const char *);
489         int ret = -1;
490         char *ac = NULL;
491
492         switch (plugin_info->action) {
493         case ACTION_INSTALL:
494                 ac = "PKGMGR_PARSER_PLUGIN_INSTALL";
495                 break;
496         case ACTION_UPGRADE:
497                 ac = "PKGMGR_PARSER_PLUGIN_UPGRADE";
498                 break;
499         case ACTION_UNINSTALL:
500                 ac = "PKGMGR_PARSER_PLUGIN_UNINSTALL";
501                 break;
502         default:
503                 goto END;
504         }
505
506         if ((plugin_install =
507                 dlsym(plugin_info->lib_handle, ac)) == NULL || dlerror() != NULL) {
508                 _LOGE("can not find symbol[%s] \n", ac);
509                 goto END;
510         }
511
512         ret = plugin_install(docPtr, plugin_info->pkgid);
513         _LOGD("Plugin = %s, appid = %s, result=%d\n", plugin_info->name, plugin_info->pkgid, ret);
514
515         __check_enabled_plugin(plugin_info);
516 END:
517         return;
518 }
519
520 static int __run_tag_parser_prestep(pkgmgr_parser_plugin_info_x *plugin_info, xmlTextReaderPtr reader)
521 {
522         const xmlChar *name;
523
524         if (xmlTextReaderDepth(reader) != 1) {
525                 _LOGE("Node depth is not 1");
526                 goto END;
527         }
528
529         if (xmlTextReaderNodeType(reader) != 1) {
530                 _LOGE("Node type is not 1");
531                 goto END;
532         }
533
534         const xmlChar *value;
535         name = xmlTextReaderConstName(reader);
536         if (name == NULL) {
537                 _LOGE("TEST TEST TES\n");
538                 name = BAD_CAST "--";
539         }
540
541         value = xmlTextReaderConstValue(reader);
542         if (value != NULL) {
543                 if (xmlStrlen(value) > 40) {
544                         _LOGD(" %.40s...", value);
545                 } else {
546                         _LOGD(" %s", value);
547                 }
548         }
549
550         name = xmlTextReaderConstName(reader);
551         if (name == NULL) {
552                 _LOGE("TEST TEST TES\n");
553                 name = BAD_CAST "--";
554         }
555
556         xmlDocPtr docPtr = xmlTextReaderCurrentDoc(reader);
557         xmlDocPtr copyDocPtr = xmlCopyDoc(docPtr, 1);
558         if (copyDocPtr == NULL)
559                 return -1;
560         xmlNode *rootElement = xmlDocGetRootElement(copyDocPtr);
561         if (rootElement == NULL)
562                 return -1;
563         xmlNode *cur_node = xmlFirstElementChild(rootElement);
564         if (cur_node == NULL)
565                 return -1;
566         xmlNode *temp = xmlTextReaderExpand(reader);
567         if (temp == NULL)
568                 return -1;
569         xmlNode *next_node = NULL;
570         while(cur_node != NULL) {
571                 if ( (strcmp(ASCII(temp->name), ASCII(cur_node->name)) == 0) &&
572                         (temp->line == cur_node->line) ) {
573                         break;
574                 }
575                 else {
576                         next_node = xmlNextElementSibling(cur_node);
577                         xmlUnlinkNode(cur_node);
578                         xmlFreeNode(cur_node);
579                         cur_node = next_node;
580                 }
581         }
582         if (cur_node == NULL)
583                 return -1;
584         next_node = xmlNextElementSibling(cur_node);
585         if (next_node) {
586                 cur_node->next = NULL;
587                 next_node->prev = NULL;
588                 xmlFreeNodeList(next_node);
589                 xmlSetTreeDoc(cur_node, copyDocPtr);
590         } else {
591                 xmlSetTreeDoc(cur_node, copyDocPtr);
592         }
593
594         __run_tag_parser(plugin_info, copyDocPtr);
595  END:
596
597         return 0;
598 }
599
600 static void
601 __process_tag_xml(pkgmgr_parser_plugin_info_x *plugin_info, xmlTextReaderPtr reader)
602 {
603         switch (xmlTextReaderNodeType(reader)) {
604         case XML_READER_TYPE_END_ELEMENT:
605                 {
606                         break;
607                 }
608         case XML_READER_TYPE_ELEMENT:
609                 {
610                         // Elements without closing tag don't receive
611                         const xmlChar *elementName =
612                             xmlTextReaderLocalName(reader);
613                         if (elementName == NULL) {
614                                 break;
615                         }
616
617                         if (strcmp(plugin_info->name, ASCII(elementName)) == 0) {
618                                 __run_tag_parser_prestep(plugin_info, reader);
619                         }
620                         if(elementName != NULL){
621                                 xmlFree((void*)elementName);
622                                 elementName = NULL;
623                         }
624                         break;
625                 }
626
627         default:
628                 break;
629         }
630 }
631
632 static void __process_tag_parser(pkgmgr_parser_plugin_info_x *plugin_info)
633 {
634         xmlTextReaderPtr reader;
635         xmlDocPtr docPtr = NULL;
636         int ret = -1;
637
638         if (access(plugin_info->filename, R_OK) != 0) {
639                 __run_tag_parser(plugin_info, NULL);
640         } else {
641                 docPtr = xmlReadFile(plugin_info->filename, NULL, 0);
642                 reader = xmlReaderWalker(docPtr);
643                 if (reader != NULL) {
644                         ret = xmlTextReaderRead(reader);
645                         while (ret == 1) {
646                                 __process_tag_xml(plugin_info, reader);
647                                 ret = xmlTextReaderRead(reader);
648                         }
649                         xmlFreeTextReader(reader);
650
651                         if (ret != 0) {
652                                 _LOGS("%s : failed to parse", plugin_info->filename);
653                         }
654                 } else {
655                         _LOGS("%s : failed to read", plugin_info->filename);
656                 }
657         }
658
659         if(docPtr != NULL){
660                 xmlFreeDoc(docPtr);
661                 docPtr = NULL;
662         }
663 }
664
665 static void __process_category_parser(pkgmgr_parser_plugin_info_x *plugin_info)
666 {
667         int tag_exist = 0;
668         char buffer[1024] = { 0, };
669         category_x *category = NULL;
670         GList *category_list = NULL;
671         __category_t *category_detail = NULL;
672
673         if (plugin_info->mfx == NULL) {
674                 __run_category_parser(plugin_info, NULL, plugin_info->appid);
675                 return;
676         }
677
678         uiapplication_x *up = plugin_info->mfx->uiapplication;
679         while(up != NULL)
680         {
681                 category = up->category;
682                 while (category != NULL)
683                 {
684                         //get glist of category key and value combination
685                         memset(buffer, 0x00, 1024);
686                         snprintf(buffer, 1024, "%s/", plugin_info->name);
687                         if ((category->name) && (strncmp(category->name, plugin_info->name, strlen(plugin_info->name)) == 0)) {
688                                 category_detail = (__category_t*) calloc(1, sizeof(__category_t));
689                                 if (category_detail == NULL) {
690                                         _LOGD("Memory allocation failed\n");
691                                         goto END;
692                                 }
693
694                                 category_detail->name = (char*) calloc(1, sizeof(char)*(strlen(category->name)+2));
695                                 if (category_detail->name == NULL) {
696                                         _LOGD("Memory allocation failed\n");
697                                         FREE_AND_NULL(category_detail);
698                                         goto END;
699                                 }
700                                 snprintf(category_detail->name, (strlen(category->name)+1), "%s", category->name);
701
702                                 category_list = g_list_append(category_list, (gpointer)category_detail);
703                                 tag_exist = 1;
704                         }
705                         category = category->next;
706                 }
707
708                 //send glist to parser when tags for metadata plugin parser exist.
709                 if (tag_exist) {
710                         __run_category_parser(plugin_info, category_list, up->appid);
711                 }
712
713                 __category_parser_clear_dir_list(category_list);
714                 category_list = NULL;
715                 tag_exist = 0;
716                 up = up->next;
717         }
718 END:
719         if (category_list)
720                 __category_parser_clear_dir_list(category_list);
721
722         return;
723 }
724
725 static void __process_metadata_parser(pkgmgr_parser_plugin_info_x *plugin_info)
726 {
727         int tag_exist = 0;
728         char buffer[1024] = { 0, };
729         metadata_x *md = NULL;
730         GList *md_list = NULL;
731         __metadata_t *md_detail = NULL;
732
733         if (plugin_info->mfx == NULL) {
734                 __run_metadata_parser(plugin_info, NULL, plugin_info->appid);
735                 return;
736         }
737
738         uiapplication_x *up = plugin_info->mfx->uiapplication;
739         while(up != NULL)
740         {
741                 md = up->metadata;
742                 while (md != NULL)
743                 {
744                         //get glist of metadata key and value combination
745                         memset(buffer, 0x00, 1024);
746                         snprintf(buffer, 1024, "%s/", plugin_info->name);
747                         if ((md->key && md->value) && (strncmp(md->key, plugin_info->name, strlen(plugin_info->name)) == 0)) {
748                                 md_detail = (__metadata_t*) calloc(1, sizeof(__metadata_t));
749                                 if (md_detail == NULL) {
750                                         _LOGD("Memory allocation failed\n");
751                                         goto END;
752                                 }
753
754                                 md_detail->key = (char*) calloc(1, sizeof(char)*(strlen(md->key)+2));
755                                 if (md_detail->key == NULL) {
756                                         _LOGD("Memory allocation failed\n");
757                                         FREE_AND_NULL(md_detail);
758                                         goto END;
759                                 }
760                                 snprintf(md_detail->key, (strlen(md->key)+1), "%s", md->key);
761
762                                 md_detail->value = (char*) calloc(1, sizeof(char)*(strlen(md->value)+2));
763                                 if (md_detail->value == NULL) {
764                                         _LOGD("Memory allocation failed\n");
765                                         FREE_AND_NULL(md_detail->key);
766                                         FREE_AND_NULL(md_detail);
767                                         goto END;
768                                 }
769                                 snprintf(md_detail->value, (strlen(md->value)+1), "%s", md->value);
770
771                                 md_list = g_list_append(md_list, (gpointer)md_detail);
772                                 tag_exist = 1;
773                         }
774                         md = md->next;
775                 }
776
777                 //send glist to parser when tags for metadata plugin parser exist.
778                 if (tag_exist) {
779                         __run_metadata_parser(plugin_info, md_list, up->appid);
780                 }
781
782                 __metadata_parser_clear_dir_list(md_list);
783                 md_list = NULL;
784                 tag_exist = 0;
785                 up = up->next;
786         }
787
788 END:
789         if(md_list)
790                 __metadata_parser_clear_dir_list(md_list);
791         return;
792 }
793
794 void __process_plugin_db(pkgmgr_parser_plugin_info_x *plugin_info)
795 {
796         char *query  = NULL;
797         char *error_message = NULL;
798
799         query = sqlite3_mprintf("delete from package_plugin_info where pkgid LIKE %Q", plugin_info->pkgid);
800         if (SQLITE_OK == sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, &error_message)) {
801                 _LOGS("pkgid [%s] plugin[0x%x] deleted", plugin_info->pkgid, plugin_info->enabled_plugin);
802         }
803
804         sqlite3_free(query);
805
806         if (plugin_info->action == ACTION_UNINSTALL)
807                 return;
808
809         query = sqlite3_mprintf("insert into package_plugin_info(pkgid,enabled_plugin) values (%Q,'%d')", plugin_info->pkgid, plugin_info->enabled_plugin);
810         if (SQLITE_OK != sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, &error_message)) {
811                 _LOGE("Don't execute query = %s, error message = %s\n", query, error_message);
812                 sqlite3_free(query);
813                 return;
814         }
815
816         sqlite3_free(query);
817         _LOGS("pkgid [%s] plugin[0x%x] inserted", plugin_info->pkgid, plugin_info->enabled_plugin);
818
819         return;
820 }
821
822 static void __process_each_plugin(pkgmgr_parser_plugin_info_x *plugin_info)
823 {
824         int ret = 0;
825
826         plugin_info->lib_handle = dlopen(plugin_info->path, RTLD_LAZY);
827         retm_if(plugin_info->lib_handle == NULL, "dlopen is failed lib_path");
828
829         ret = __parser_send_tag(plugin_info->lib_handle, plugin_info->action, PLUGIN_PRE_PROCESS, plugin_info->pkgid);
830         _LOGS("PLUGIN_PRE_PROCESS : [%s] result=[%d]\n", plugin_info->name, ret);
831
832         if (strcmp(plugin_info->type,PKGMGR_PARSER_PLUGIN_TAG) == 0) {
833                 __process_tag_parser(plugin_info);
834         } else if (strcmp(plugin_info->type,PKGMGR_PARSER_PLUGIN_METADATA) == 0) {
835                 __process_metadata_parser(plugin_info);
836         } else if (strcmp(plugin_info->type,PKGMGR_PARSER_PLUGIN_CATEGORY) == 0) {
837                 __process_category_parser(plugin_info);
838         }
839
840         ret =__parser_send_tag(plugin_info->lib_handle, plugin_info->action, PLUGIN_POST_PROCESS, plugin_info->pkgid);
841         _LOGS("PLUGIN_POST_PROCESS : [%s] result=[%d]\n", plugin_info->name, ret);
842
843         dlclose(plugin_info->lib_handle);
844 }
845
846 void __process_all_plugins(pkgmgr_parser_plugin_info_x *plugin_info)
847 {
848         int ret = 0;
849         FILE *fp = NULL;
850         char buf[PKG_STRING_LEN_MAX] = {0};
851
852         fp = fopen(PLLUGIN_LIST, "r");
853         retm_if(fp == NULL, "Fail get : %s", PLLUGIN_LIST);
854
855         while (fgets(buf, PKG_STRING_LEN_MAX, fp) != NULL) {
856                 __str_trim(buf);
857
858                 ret = __get_plugin_info_x(buf, plugin_info);
859                 if (ret < 0)
860                         continue;
861
862                 __process_each_plugin(plugin_info);
863
864                 memset(buf, 0x00, PKG_STRING_LEN_MAX);
865                 FREE_AND_NULL(plugin_info->type);
866                 FREE_AND_NULL(plugin_info->name);
867                 FREE_AND_NULL(plugin_info->flag);
868                 FREE_AND_NULL(plugin_info->path);
869         }
870
871         if (fp != NULL)
872                 fclose(fp);
873
874         return;
875 }
876
877
878 int _pkgmgr_parser_plugin_open_db()
879 {
880         char *error_message = NULL;
881         int ret;
882         FILE * fp = NULL;
883
884         fp = fopen(PKGMGR_PARSER_DB_FILE, "r");
885         if (fp != NULL) {
886                 fclose(fp);
887                 ret = db_util_open(PKGMGR_PARSER_DB_FILE, &pkgmgr_parser_db, DB_UTIL_REGISTER_HOOK_METHOD);
888                 if (ret != SQLITE_OK) {
889                         _LOGE("package info DB initialization failed\n");
890                         return -1;
891                 }
892                 return 0;
893         }
894
895         ret = db_util_open(PKGMGR_PARSER_DB_FILE, &pkgmgr_parser_db, DB_UTIL_REGISTER_HOOK_METHOD);
896         if (ret != SQLITE_OK) {
897                 _LOGE("package info DB initialization failed\n");
898                 return -1;
899         }
900
901         if (SQLITE_OK != sqlite3_exec(pkgmgr_parser_db, QUERY_CREATE_TABLE_PACKAGE_PLUGIN_INFO, NULL, NULL, &error_message)) {
902                 _LOGE("Don't execute query = %s, error message = %s\n", QUERY_CREATE_TABLE_PACKAGE_PLUGIN_INFO, error_message);
903                 return -1;
904         }
905
906         _LOGE("db_initialize_done\n");
907         return 0;
908 }
909
910
911 void _pkgmgr_parser_plugin_close_db()
912 {
913         sqlite3_close(pkgmgr_parser_db);
914 }
915
916 void _pkgmgr_parser_plugin_process_plugin(manifest_x *mfx, const char *filename, ACTION_TYPE action)
917 {
918         int ret = 0;
919
920         pkgmgr_parser_plugin_info_x *plugin_info = NULL;
921
922         retm_if(mfx == NULL, "manifest pointer is NULL\n");
923         retm_if(filename == NULL, "filename pointer is NULL\n");
924
925         /*initialize plugin_info_x*/
926         plugin_info = malloc(sizeof(pkgmgr_parser_plugin_info_x));
927         retm_if(plugin_info == NULL, "malloc fail");
928
929         memset(plugin_info, '\0', sizeof(pkgmgr_parser_plugin_info_x));
930
931         /*initialize pkgmgr_paser db*/
932         ret = _pkgmgr_parser_plugin_open_db();
933         if (ret < 0)
934                 _LOGE("_pkgmgr_parser_plugin_open_db failed\n");
935
936         /*save plugin_info_x*/
937         plugin_info->mfx = mfx;
938         plugin_info->pkgid = strdup(mfx->package);
939         plugin_info->filename = strdup(filename);
940         plugin_info->action = action;
941
942         /*get plugin list from list-file, and process each plugin*/
943         __process_all_plugins(plugin_info);
944
945         /*update finished info to pkgmgr_parser db*/
946         __process_plugin_db(plugin_info);
947
948         /*close pkgmgr_paser db*/
949         _pkgmgr_parser_plugin_close_db();
950
951         /*clean plugin_info_x*/
952         __clean_plugin_info(plugin_info);
953 }
954
955 void _pkgmgr_parser_plugin_uninstall_plugin(const char *plugin_type, const char *pkgid, const char *appid)
956 {
957         int ret = 0;
958         FILE *fp = NULL;
959         char buf[PKG_STRING_LEN_MAX] = {0};
960
961         int plugin_flag = 0;
962         int enabled_plugin = 0;
963         pkgmgr_parser_plugin_info_x *plugin_info = NULL;
964
965         retm_if(plugin_type == NULL, "plugin_type is null");
966         retm_if(pkgid == NULL, "pkgid is null");
967         retm_if(appid == NULL, "appid is null");
968
969         /*initialize plugin_info_x*/
970         plugin_info = malloc(sizeof(pkgmgr_parser_plugin_info_x));
971         retm_if(plugin_info == NULL, "malloc fail");
972
973         memset(plugin_info, '\0', sizeof(pkgmgr_parser_plugin_info_x));
974
975         /*save plugin_info_x*/
976         enabled_plugin = __ps_get_enabled_plugin(pkgid);
977         plugin_info->pkgid = strdup(pkgid);
978         plugin_info->appid = strdup(appid);
979         plugin_info->action = ACTION_UNINSTALL;
980
981         /*get plugin list from list-file*/
982         fp = fopen(PLLUGIN_LIST, "r");
983
984         if (fp == NULL) {
985                 _LOGE("Fail get : %s", PLLUGIN_LIST);
986                 __clean_plugin_info(plugin_info);
987                 return;
988         }
989
990         while (fgets(buf, PKG_STRING_LEN_MAX, fp) != NULL) {
991                 __str_trim(buf);
992
993                 ret = __get_plugin_info_x(buf, plugin_info);
994                 if (ret < 0)
995                         continue;
996
997                 /*process uninstallation for given plugin type*/
998                 if (strcmp(plugin_info->type, plugin_type) == 0) {
999
1000                         plugin_flag = (int)strtol(plugin_info->flag, NULL, 16);
1001                         
1002                         /*if there is a plugin that is saved in db, it need to uninstall*/
1003                         if (enabled_plugin & plugin_flag) {
1004                                 __process_each_plugin(plugin_info);
1005                         }
1006                 }
1007
1008                 memset(buf, 0x00, PKG_STRING_LEN_MAX);
1009                 FREE_AND_NULL(plugin_info->type);
1010                 FREE_AND_NULL(plugin_info->name);
1011                 FREE_AND_NULL(plugin_info->flag);
1012                 FREE_AND_NULL(plugin_info->path);
1013         }
1014
1015         if (fp != NULL)
1016                 fclose(fp);
1017
1018         /*clean plugin_info_x*/
1019         __clean_plugin_info(plugin_info);
1020
1021         return;
1022 }
1023