fix setting a default font issue in wrong cases
[platform/core/uifw/download-fonts-service.git] / pkgmgr_font / src / font_service_register.c
1 /*
2  * Copyright 2013 Samsung Electronics Co., Ltd
3  *
4  *
5  * Contact: Minsu Seo <minsu15.seo@samsung.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 #include <stdio.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/xattr.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <dirent.h>
26 #include <glib.h>
27 #include <dlog.h>
28 #include <fontconfig/fontconfig.h>
29 #include <Elementary.h>
30 #include <pkgmgr-info.h>
31 #include <pkgmgr_installer_info.h>
32 #include "system_settings.h"
33
34 #define FONT_SERVICE_TAG                "FONT_SERVICE"
35 #define DEBUG_LOG(frmt, args...)                \
36         do { SLOG(LOG_DEBUG,FONT_SERVICE_TAG, "[font_service] %s: "frmt"\n",\
37         __func__, ##args);} while (0)
38 #define DEBUG_WARNING(frmt, args...)            \
39         do { SLOG(LOG_WARN,FONT_SERVICE_TAG, "[font_service] %s: "frmt"\n",\
40         __func__, ##args);} while (0)
41 #define DEBUG_ERROR(frmt, args...)              \
42         do { SLOG(LOG_ERROR,FONT_SERVICE_TAG, "[font_service] %s: "frmt"\n",\
43         __func__, ##args);} while (0)
44
45 static const char *PARENT_PATH = "/opt/share/fonts";
46 static const char *DOWNLOAD_PATH = "/opt/share/fonts/download";
47 static const char *PRELOADED_PATH = "/opt/share/fonts/preloaded";
48
49 #define MAX_FILE_LEN 4096
50 #define APP_OWNER_ID 5001
51 #define APP_GROUP_ID 100
52
53 static int make_dir(const char *path);
54 static int symbolic_link(const char *srcpath, const char *destpath);
55 static int do_install(const char *parent, const char *appid, const char *rootpath, pkgmgrinfo_pkginfo_h handle);
56 static int do_uninstall(const char *deletedir);
57 static int move_file(const char *srcpath, const char *destpath);
58 static const char* check_preloaded(const char *app_root_path);
59 #ifdef CHECK_FAMILY_NAME
60 static int check_family_name(const char *srcpath);
61 #endif
62
63 static const char* check_preloaded(const char *app_root_path)
64 {
65         char tpk_path[MAX_FILE_LEN];
66         char wgt_path[MAX_FILE_LEN];
67
68         sprintf(tpk_path, "%s/preloaded", app_root_path);
69         sprintf(wgt_path, "%s/res/wgt/preloaded", app_root_path);
70
71         if ((access(tpk_path, F_OK) == 0) || (access(wgt_path, F_OK) == 0))
72         {
73                 return PRELOADED_PATH;
74         }
75
76         return DOWNLOAD_PATH;
77 }
78
79 static int make_dir(const char *path)
80 {
81         int ret = 0;
82
83         if (access(path, F_OK) == 0)
84         {
85                 return ret;
86         }
87         else
88         {
89                 ret = mkdir(path, 0755);
90                 if (ret < 0)
91                 {
92                         DEBUG_ERROR("make current directory %s is failed \n",path);
93                         return ret;
94                 }
95
96                 ret = chown(path, getuid(), APP_GROUP_ID);
97                 if (ret < 0)
98                 {
99                         DEBUG_ERROR("chown is failed %s\n",path);
100                         return ret;
101                 }
102
103                 ret = chmod(path, 0755);
104                 if (ret < 0)
105                 {
106                         DEBUG_ERROR("chmod is failed %s\n",path);
107                         rmdir(path);
108                         return ret;
109                 }
110         }
111
112         return ret;
113 }
114
115 static int symbolic_link(const char *srcpath, const char *destpath)
116 {
117         DIR *d;
118         struct dirent *e;
119         int ret = 0;
120
121         d = opendir(srcpath);
122         while ((e = readdir (d)))
123         {
124                 if (e->d_name[0] != '.' && strlen((char *)e->d_name) < MAX_FILE_LEN)
125                 {
126                         char srcdir[MAX_FILE_LEN];
127                         char destdir[MAX_FILE_LEN];
128                         struct stat       statb;
129
130                         if (strlen (srcpath) + strlen ((char *)e->d_name) + 2 >= MAX_FILE_LEN )
131                         {
132                                 DEBUG_ERROR("srcdir length is not available \n");
133                                 goto FAIL;
134                         }
135
136                         if (strlen (destpath) + strlen ((char *)e->d_name) + 2 >= MAX_FILE_LEN )
137                         {
138                                 DEBUG_ERROR("destdir length is not available \n");
139                                 goto FAIL;
140                         }
141
142                         sprintf(srcdir,"%s/%s",srcpath,(char *) e->d_name);
143                         sprintf(destdir,"%s/%s",destpath,(char *) e->d_name);
144                         if (stat (srcdir, &statb) == -1)
145                         {
146                                 DEBUG_ERROR("stat %s is failed \n",srcdir);
147                                 goto FAIL;
148                         }
149
150                         if (S_ISDIR (statb.st_mode))
151                         {
152                                 if (make_dir(destdir)<0)
153                                 {
154                                         DEBUG_ERROR("make current directory %s is failed \n",destdir);
155                                         goto FAIL;
156                                 }
157                                 ret = symbolic_link(srcdir,destdir);
158                                 if (ret < 0)
159                                 {
160                                         DEBUG_ERROR("symlink is failed \n");
161                                         goto FAIL;
162                                 }
163                                 continue;
164                         }
165                         DEBUG_LOG("srcdir =%s\n",(char *) srcdir);
166                         DEBUG_LOG("destdir =%s\n",(char *) destdir);
167                         DEBUG_LOG("file name =%s\n",(char *) e->d_name);
168
169                         ret = symlink((const char *)srcdir,(const char *)destdir);
170                         if (ret < 0)
171                         {
172                                 DEBUG_ERROR("symlink is failed \n");
173                                 goto FAIL;
174                         }
175                 }
176         }
177         closedir (d);
178         return ret;
179
180 FAIL:
181         closedir (d);
182         return -1;
183 }
184
185
186 static int move_file(const char *srcpath, const char *destpath)
187 {
188         DIR *d;
189         struct dirent *e;
190         int ret = 0;
191
192         d = opendir (srcpath);
193         while ((e = readdir (d)))
194         {
195                 if (e->d_name[0] != '.' && strlen((char *)e->d_name) < MAX_FILE_LEN)
196                 {
197                         char srcdir[MAX_FILE_LEN];
198                         char destdir[MAX_FILE_LEN];
199                         struct stat       statb;
200
201                         if (strlen (srcpath) + strlen ((char *)e->d_name) + 2 >= MAX_FILE_LEN )
202                         {
203                                 DEBUG_ERROR("srcdir length is not available \n");
204                                 goto FAIL;
205                         }
206
207                         if (strlen (destpath) + strlen ((char *)e->d_name) + 2 >= MAX_FILE_LEN )
208                         {
209                                 DEBUG_ERROR("destdir length is not available \n");
210                                 goto FAIL;
211                         }
212
213                         sprintf(srcdir,"%s/%s",srcpath,(char *) e->d_name);
214                         sprintf(destdir,"%s/%s",destpath,(char *) e->d_name);
215                         if (stat (srcdir, &statb) == -1)
216                         {
217                                 DEBUG_ERROR("stat %s is failed \n",srcdir);
218                                 goto FAIL;
219                         }
220
221                         if (S_ISDIR (statb.st_mode))
222                         {
223                                 if (make_dir(destdir)<0)
224                                 {
225                                         DEBUG_ERROR("make current directory %s is failed \n",destdir);
226                                         goto FAIL;
227                                 }
228                                 continue;
229                         }
230                         DEBUG_LOG("srcdir =%s\n",(char *) srcdir);
231                         DEBUG_LOG("destdir =%s\n",(char *) destdir);
232                         DEBUG_LOG("file name =%s\n",(char *) e->d_name);
233
234                         ret = rename((const char *)srcdir,(const char *)destdir);
235                         if (ret < 0)
236                         {
237                                 DEBUG_ERROR("symlink is failed \n");
238                                 goto FAIL;
239                         }
240                 }
241         }
242         closedir (d);
243         return ret;
244
245 FAIL:
246         closedir (d);
247         return -1;
248 }
249
250 #ifdef CHECK_FAMILY_NAME
251 static int check_family_name(const char *srcpath)
252 {
253         FcObjectSet *os = NULL;
254         FcFontSet* fs = NULL;
255         FcPattern* pat = NULL;
256         FcConfig* font_config = NULL;
257         bool is_only_one_family = false;
258
259         font_config = FcInitLoadConfigAndFonts();
260
261         if(font_config == NULL) {
262                 DEBUG_ERROR("Failed: FcInitLoadConfigAndFonts");
263                 return -1;
264         }
265
266         pat = FcPatternCreate();
267
268         os = FcObjectSetBuild(FC_FAMILY, FC_FILE, (char *) 0);
269
270         if (os) {
271                 fs = FcFontList(font_config, pat, os);
272                 FcObjectSetDestroy(os);
273                 os = NULL;
274         }
275
276         if (pat) {
277                 FcPatternDestroy(pat);
278                 pat = NULL;
279         }
280
281         if (fs)
282         {
283                 int j;
284                 char* only_one_family = NULL;
285
286                 for (j = 0; j < fs->nfont; j++)
287                 {
288                         FcChar8 *family = NULL;
289                         FcChar8 *file = NULL;
290
291                         if (FcPatternGetString(fs->fonts[j], FC_FILE, 0, &file) == FcResultMatch)
292                         {
293                                 int font_path_len = strlen(srcpath);
294
295                                         /* always shown for src path */
296                                         if (strncmp((const char*)file, srcpath, font_path_len) == 0)
297                                         {
298                                                                 if (FcPatternGetString(fs->fonts[j], FC_FAMILY, 0, &family) != FcResultMatch)
299                                                                 {
300                                                                         DEBUG_ERROR("Family name is invalid");
301                                                                         continue;
302                                                                 }
303                                                                 //DEBUG_ERROR("-------- FOUND FONT - family = %s", (char *)family);
304
305                                                                 // first found family name
306                                                                 if (only_one_family == NULL  && strlen((char *)family) > 0)
307                                                                 {
308                                                                         is_only_one_family = true;
309                                                                         only_one_family = (char *)family;
310                                                                         //DEBUG_ERROR("--------First FOUND FONT - family = %s", only_one_family);
311                                                                 }
312                                                                 else if (only_one_family != NULL  && strlen((char *)family) > 0)// after first
313                                                                 {
314                                                                                 if (strcmp(only_one_family,  (char *)family) != 0)
315                                                                                 {
316                                                                                         DEBUG_ERROR("Not supported various font famliy. only one font famliy. %s %s", only_one_family, (char *)family);
317                                                                                         is_only_one_family = false;
318                                                                                         break;
319                                                                                 }
320                                                                 }
321                                                                 else
322                                                                 {
323                                                                         DEBUG_ERROR("invalid fonts");
324                                                                         break;
325                                                                 }
326                                         }
327                         }
328                 }
329
330                 FcFontSetDestroy(fs);
331                 fs = NULL;
332         }
333
334         FcConfigDestroy(font_config);
335         font_config = NULL;
336
337         if (is_only_one_family == false)
338         {
339                 //DEBUG_ERROR("Not supported various font famliy. only one font famliy");
340                 return -1;
341         }
342
343         return 0;
344 }
345 #endif
346
347 static int do_install(const char *parent, const char *appid, const char *rootpath, pkgmgrinfo_pkginfo_h handle)
348 {
349         char destdir[MAX_FILE_LEN];
350         char path[MAX_FILE_LEN];
351         char *type = NULL;
352         int ret = 0;
353
354         if (strlen (parent) + strlen (appid) + 2 >= MAX_FILE_LEN )
355         {
356                 DEBUG_ERROR("appid length is not available \n");
357                 return -1;
358         }
359
360         sprintf(destdir,"%s/%s",parent,appid);
361         ret = make_dir(destdir);
362         if (ret < 0)
363         {
364                 DEBUG_ERROR("make current directory %s is failed \n", destdir);
365                 goto FAIL;
366         }
367
368         if (strlen (rootpath) + 2 >= MAX_FILE_LEN )
369         {
370                 DEBUG_ERROR("rootpath length is not available \n");
371                 goto FAIL;
372         }
373
374         ret = pkgmgrinfo_pkginfo_get_type(handle, &type);
375         if (ret < 0)
376         {
377                 DEBUG_ERROR("pkgmgrinfo_pkginfo_get_type is failed\n");
378                 goto FAIL;
379         }
380
381         sprintf(path,"%s/shared/res", rootpath);
382
383         if (!strcmp(type,"wgt"))
384         {
385                 char srcpath[MAX_FILE_LEN];
386                 sprintf(srcpath,"%s/res/wgt/shared/res", rootpath);
387                 ret = move_file(srcpath, path);
388         }
389
390         if (ret < 0)
391         {
392                 DEBUG_ERROR("move_file is failed\n");
393                 goto FAIL;
394         }
395
396         ret = symbolic_link(path, destdir);
397
398         if (ret < 0)
399         {
400                 DEBUG_ERROR("install is failed \n", destdir);
401                 goto FAIL;
402         }
403
404 #ifdef CHECK_FAMILY_NAME
405         ret = check_family_name(destdir);
406
407         if (ret < 0)
408         {
409                 DEBUG_ERROR("Invaid font files\n");
410                 goto FAIL;
411         }
412 #endif
413
414         return ret;
415
416 FAIL:
417         do_uninstall(destdir);
418         return -1;
419 }
420
421
422 static int do_uninstall(const char *deletedir)
423 {
424         DIR     *d;
425         struct dirent *e;
426
427         d = opendir(deletedir);
428         while((e = readdir (d)))
429         {
430                 if (e->d_name[0] != '.')
431                 {
432                         char destfile[MAX_FILE_LEN];
433                         struct stat       statb;
434
435                         if (strlen (deletedir) + strlen ((char *) e->d_name) + 2 >= MAX_FILE_LEN )
436                         {
437                                 DEBUG_ERROR("destfile length is not available \n");
438                                 goto FAIL;
439                         }
440
441                         sprintf(destfile,"%s/%s",deletedir,(char *) e->d_name);
442                         if (lstat (destfile, &statb) == -1)
443                         {
444                                 DEBUG_ERROR("lstat %s is failed \n",destfile);
445                                 goto FAIL;
446                         }
447
448                         if (S_ISDIR (statb.st_mode))
449                         {
450                                 if (do_uninstall(destfile)<0)
451                                         goto FAIL;
452                         }
453                         else if (unlink(destfile) < 0)
454                         {
455                                 DEBUG_ERROR("unlink is failed %s\n",destfile);
456                                 goto FAIL;
457                         }
458                         DEBUG_LOG("destfile =%s\n",destfile);
459                 }
460         }
461
462         closedir (d);
463
464         if (rmdir(deletedir) < 0)
465         {
466                 DEBUG_ERROR("rmdir is failed \n");
467                 return -1;
468         }
469
470         DEBUG_LOG("rmdir =%s\n",deletedir);
471         return 0;
472
473 FAIL:
474         closedir (d);
475         return -1;
476 }
477
478
479 int COMMON_PKGMGR_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
480 {
481         int ret;
482         pkgmgrinfo_pkginfo_h handle = NULL;
483         const char *app_root_path = NULL;
484         const char *dest_path = NULL;
485         uid_t uid = 0;
486
487         pkgmgr_installer_info_get_target_uid(&uid);
488         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
489
490         if (ret < 0)
491         {
492                 DEBUG_ERROR("pkgid[%s] handle get fail", pkgid);
493                 return -1;
494         }
495
496         ret = pkgmgrinfo_pkginfo_get_root_path(handle, (char **)&app_root_path);
497         if (ret < 0)
498         {
499                 DEBUG_ERROR("pkgid[%s] path get fail", pkgid);
500                 goto FAIL;
501         }
502
503         if (appid == NULL)
504         {
505                 DEBUG_ERROR("appid is NULL \n");
506                 goto FAIL;
507         }
508
509         ret = make_dir(PARENT_PATH);
510
511         if (ret < 0)
512         {
513                 DEBUG_ERROR("make current directory is failed \n");
514                 goto FAIL;
515         }
516
517         dest_path = check_preloaded(app_root_path);
518
519         if (make_dir(dest_path)<0)
520         {
521                 DEBUG_ERROR("make current directory is failed \n");
522                 return -1;
523         }
524
525         ret = do_install(dest_path,appid, app_root_path, handle);
526         if (ret < 0)
527         {
528                 DEBUG_ERROR("font install is failed \n");
529                 goto FAIL;
530         }
531
532         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
533
534         return ret;
535
536 FAIL:
537         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
538         return -1;
539 }
540
541
542 int COMMON_PKGMGR_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
543 {
544         char deletedir[MAX_FILE_LEN];
545         int ret = 0;
546         pkgmgrinfo_pkginfo_h handle = NULL;
547         const char* app_root_path = NULL;
548         const char* dest_path = NULL;
549         uid_t uid = 0;
550
551         pkgmgr_installer_info_get_target_uid(&uid);
552         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
553
554         if (ret < 0)
555         {
556                 DEBUG_ERROR("pkgid[%s] handle get fail", pkgid);
557                 return -1;
558         }
559
560         ret = pkgmgrinfo_pkginfo_get_root_path(handle, (char **)&app_root_path);
561         if (ret < 0)
562         {
563                 DEBUG_ERROR("pkgid[%s] path get fail", pkgid);
564                 goto FAIL;
565         }
566
567         if (appid == NULL)
568         {
569                 DEBUG_ERROR("appid is NULL \n");
570                 goto FAIL;
571         }
572
573         dest_path = check_preloaded(app_root_path);
574
575         if (strlen (dest_path) + strlen (appid) + 2 >= MAX_FILE_LEN )
576         {
577                 DEBUG_ERROR("appid length is not available \n");
578                 goto FAIL;
579         }
580
581         sprintf(deletedir,"%s/%s", dest_path, appid);
582
583         if (access(deletedir, F_OK) == -1)
584         {
585                 DEBUG_ERROR("dest directory(%s) is not exist: %s\n", deletedir, strerror(errno));
586                 goto FAIL;
587         }
588
589         ret = do_uninstall(deletedir);
590         if (ret < 0)
591         {
592                 DEBUG_ERROR("do_uninstall is failed \n");
593                 goto FAIL;
594         }
595
596         ret = make_dir(PARENT_PATH);
597         if (ret < 0)
598         {
599                 DEBUG_ERROR("make current directory(%s) is failed: %s\n", PARENT_PATH, strerror(errno));
600                 goto FAIL;
601         }
602
603         ret = make_dir(dest_path);
604         if (ret < 0)
605         {
606                 DEBUG_ERROR("make current directory(%s) is failed: %s\n", dest_path, strerror(errno));
607                 goto FAIL;
608         }
609
610         ret = do_install(dest_path, appid, app_root_path, handle);
611         if (ret < 0)
612         {
613                 DEBUG_ERROR("do_install is failed \n");
614                 goto FAIL;
615         }
616
617         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
618         return ret;
619
620 FAIL:
621         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
622         return -1;
623 }
624
625
626
627 int COMMON_PKGMGR_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
628 {
629         char deletedir[MAX_FILE_LEN];
630         FcObjectSet *os = NULL;
631         FcPattern *pat = NULL;
632         FcFontSet *fs = NULL;
633         pkgmgrinfo_pkginfo_h handle = NULL;
634         const char* app_root_path = NULL;
635         const char *dest_path = NULL;
636         int ret, deletedir_len;
637         uid_t uid = 0;
638
639         elm_init(0, NULL);
640
641         if (appid == NULL)
642         {
643                 DEBUG_ERROR("appid is NULL \n");
644                 return -1;
645         }
646
647         pkgmgr_installer_info_get_target_uid(&uid);
648         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
649
650         if (ret < 0)
651         {
652                 DEBUG_ERROR("pkgid[%s] handle get fail", pkgid);
653                 return -1;
654         }
655
656         ret = pkgmgrinfo_pkginfo_get_root_path(handle, (char **)&app_root_path);
657         if (ret < 0)
658         {
659                 DEBUG_ERROR("pkgid[%s] path get fail", pkgid);
660                 goto FAIL;
661         }
662
663         dest_path = check_preloaded(app_root_path);
664
665         if (strlen (dest_path) + strlen (appid) + 2 >= MAX_FILE_LEN )
666         {
667                 DEBUG_ERROR("appid length is not available \n");
668                 goto FAIL;
669         }
670
671         /* It must contain "/" character at end of the delete dir path.
672          * It prevents file path comparing issues when there are many similar path. */
673         sprintf(deletedir,"%s/%s/", dest_path, appid);
674
675         //check if current using font is same with uninstall font
676         deletedir_len = strlen(deletedir);
677
678         pat = FcPatternCreate();
679         if (pat == NULL)
680         {
681                 DEBUG_ERROR("FcPatternCreate is NULL \n");
682                 goto FAIL;
683         }
684
685         char *current_font_name = NULL;
686         ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, &current_font_name);
687         if (ret < 0)
688         {
689                 DEBUG_ERROR("Get current font is failed \n");
690                 goto FAIL;
691         }
692
693         DEBUG_LOG("current_font_name =%s\n",current_font_name);
694
695         FcInitLoadConfigAndFonts();
696         FcPatternAddString (pat, FC_FAMILY,(FcChar8*)current_font_name);
697         os = FcObjectSetBuild(FC_FAMILY, FC_FILE, (char *) 0);
698         fs = FcFontList(NULL, pat, os);
699
700         FcPatternDestroy(pat);
701         free(current_font_name);
702
703         if (fs)
704         {
705                 int j;
706
707                 for (j = 0; j < fs->nfont; j++)
708                 {
709                         FcChar8 *file = NULL;
710                         if (FcPatternGetString(fs->fonts[j], FC_FILE, 0, &file) == FcResultMatch)
711                         {
712                                 DEBUG_LOG("file =%s, deletedir =%s\n", file, deletedir);
713                                 if (strncmp((const char*)file, deletedir, deletedir_len) == 0)
714                                 {
715                                         DEBUG_LOG("change to default font\n");
716                                         char *default_font_name = NULL;
717
718                                         ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_DEFAULT_FONT_TYPE, &default_font_name);
719                                         if (ret < 0)
720                                         {
721                                                 DEBUG_ERROR("Get default font is failed \n");
722                                                 goto FAIL;
723                                         }
724
725                                         DEBUG_LOG("default_font_name = %s \n",default_font_name);
726                                         ret = system_settings_set_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, default_font_name);
727                                         if (ret < 0)
728                                         {
729                                                 DEBUG_ERROR("Set default font is failed ret=%d \n",ret);
730                                                 free(default_font_name);
731                                                 break;
732                                         }
733
734                                         free(default_font_name);
735                                         DEBUG_LOG("success change to default font\n");
736                                         break;
737                                 }
738                         }
739                 }
740         }
741
742         if (access(deletedir, F_OK) == -1)
743         {
744                 DEBUG_ERROR("dest directory(%s) is not exist: %s\n", deletedir, strerror(errno));
745                 goto FAIL;
746         }
747
748         elm_shutdown();
749         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
750
751         return do_uninstall(deletedir);
752
753 FAIL:
754         elm_shutdown();
755         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
756
757         return -1;
758 }
759
760 #if USE_META_DATA
761 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
762 {
763         return COMMON_PKGMGR_PLUGIN_INSTALL(pkgid, appid, list);
764 }
765
766 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
767 {
768         return COMMON_PKGMGR_PLUGIN_UPGRADE(pkgid, appid, list);
769 }
770
771 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
772 {
773         return COMMON_PKGMGR_PLUGIN_UNINSTALL(pkgid, appid, list);
774 }
775 #endif
776
777 int PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
778 {
779         return COMMON_PKGMGR_PLUGIN_INSTALL(pkgid, appid, list);
780 }
781
782 int PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
783 {
784         return COMMON_PKGMGR_PLUGIN_UPGRADE(pkgid, appid, list);
785 }
786
787 int PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
788 {
789         return COMMON_PKGMGR_PLUGIN_UNINSTALL(pkgid, appid, list);
790 }
791
792
793 /* End of a file */