Initial commit
[platform/core/uifw/capi-ui-sticker.git] / sticker-parser / sticker-parser.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <unistd.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <dlog.h>
22 #include <glib.h>
23 #include <json-glib/json-glib.h>
24 #include <pkgmgr-info.h>
25 #include <sqlite3.h>
26 #include <tzplatform_config.h>
27 #include <package_manager.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <errno.h>
31 #include <dirent.h>
32 #include <fcntl.h>
33
34 #ifndef EXPORT_API
35 #define EXPORT_API __attribute__((visibility("default")))
36 #endif
37
38 #ifdef LOG_TAG
39 #undef LOG_TAG
40 #endif
41 #define LOG_TAG "STICKER_PARSER"
42
43 #define STICKER_DIRECTORY tzplatform_mkpath(TZ_SYS_SHARE, "sticker-data")
44 #define UIFW_ID           502
45 #define APPFW_ID          301
46 #define MAX_ERROR_BUFFER  256
47
48 static char error_buffer[MAX_ERROR_BUFFER];
49
50 typedef struct metadata {
51     const char *key;
52     const char *value;
53 } metadata;
54
55 static char* __get_string_from_object(JsonObject *object, const char *key)
56 {
57     if (json_object_has_member(object, key) == false)
58         return NULL;
59
60     const char *str = json_object_get_string_member(object, key);
61     if (str != NULL)
62         return strdup(str);
63     else
64         return NULL;
65 }
66
67 static int __get_int_from_object(JsonObject *object, const char *key)
68 {
69     if (json_object_has_member(object, key) == false)
70         return -1;
71
72     int type = json_object_get_int_member(object, key);
73
74     return type;
75 }
76
77 static sqlite3 *__db_open(const char *path)
78 {
79     int ret;
80     sqlite3 *db = NULL;
81     char *err = NULL;
82
83     ret = sqlite3_open(path, &db);
84     if (ret != SQLITE_OK) {
85         LOGE("Failed to open db : %s", sqlite3_errmsg(db));
86         return NULL;
87     }
88
89     ret = sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, &err);
90     if (ret != SQLITE_OK) {
91         LOGE("Failed to turn on foreign keys : %s", err);
92     }
93
94     return db;
95 }
96
97 static int __change_ownership(const char *path, int user, int group)
98 {
99     int ret;
100     uid_t uid = (uid_t)user;
101     gid_t gid = (gid_t)group;
102
103     ret = chown(path, uid, gid);
104     if (ret != 0) {
105         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
106         LOGE("chown() failed : %s", error_buffer);
107     }
108
109     return ret;
110 }
111
112 static int __remove_app_path(char *uri, const char *app_path)
113 {
114     int n = 0;
115     int k = 0;
116     for (int i = 0; uri[i] != '\0'; i++) {
117         if (uri[i] == app_path[n]) {
118             k = i;
119             while (uri[i] == app_path[n]) {
120                 if (app_path[++n] == '\0') {
121                     for(; uri[k + n] != '\0'; k++) {
122                         uri[k] = uri[k + n];
123                     }
124                     uri[k] = '\0';
125                     return 1;
126                 }
127                 i++;
128             }
129             n = 0;
130             i--;
131         }
132     }
133     return 0;
134 }
135
136 static int __mkdirs(const char *path, mode_t mode)
137 {
138     int len = 0;
139     char prev_path[2048];
140     const char *tmp = path;
141
142     if (!path || strlen(path) > 2048)
143         return -1;
144
145     memset(prev_path, '\0', 2048);
146     while ((tmp = strchr(tmp, '/')) != NULL) {
147         len = tmp - path;
148         tmp++;
149
150         if (len == 0)
151             continue;
152
153         strncpy(prev_path, path, len);
154         prev_path[len] = 0x00;
155
156         if (mkdir(prev_path, mode) == -1) {
157             if (errno != EEXIST) {
158                 strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
159                 LOGE("directory create error : %s", error_buffer);
160                 return -1;
161             }
162         } else {
163             if (__change_ownership(prev_path, UIFW_ID, UIFW_ID) != 0)
164                 LOGE("failed to change ownership");
165         }
166     }
167
168     if (mkdir(prev_path, mode) == -1) {
169         if (errno != EEXIST) {
170             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
171             LOGE("directory create error : %s", error_buffer);
172             return -1;
173         }
174     } else {
175         if (__change_ownership(prev_path, UIFW_ID, UIFW_ID) != 0)
176             LOGE("failed to change ownership");
177     }
178     return 0;
179 }
180
181 static int __file_copy(const char *src, const char *dest)
182 {
183     int ret = 0;
184     int fd = -1, n_fd = -1;
185     char buf[4096];
186     int tmp_err = 0;
187     int size;
188
189     memset(buf, '\0', 4096);
190     fd = open(src, O_RDONLY);
191     n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
192
193     if (fd == -1 || n_fd == -1) {
194         tmp_err = errno;
195         ret = -1;
196         goto cleanup;
197     }
198
199     while((size = read(fd, buf, 4096))) {
200         if (size == -1) {
201             if(errno == EINTR)
202                 continue;
203
204             tmp_err = errno;
205             ret = -1;
206             goto cleanup;
207         }
208
209         while(write(n_fd, buf, size) == -1) {
210             if(errno == EINTR) {
211                 continue;
212             } else {
213                 tmp_err = errno;
214                 goto cleanup;
215             }
216         }
217     }
218
219 cleanup:
220     if (fd != -1)
221         close(fd);
222
223     if (n_fd != -1)
224         close(n_fd);
225
226     errno = tmp_err;
227     return ret;
228 }
229
230 static char* __convert_sticker_uri(const char *uri, const char *appid, const char *app_path)
231 {
232     int ret;
233     char *rel_path = strdup(uri);
234
235     __remove_app_path(rel_path, app_path);
236     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(rel_path) + 2;
237     char *new_path = (char *)calloc(len, sizeof(char));
238     if (new_path == NULL) {
239         free(rel_path);
240         rel_path = NULL;
241         return NULL;
242     }
243
244     snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, rel_path);
245
246     if (access(new_path, F_OK) == 0) {
247         LOGE("sticker file already exists");
248         ret = -1;
249         goto cleanup;
250     }
251
252     ret = __mkdirs(new_path, 0755);
253     if (ret != 0) {
254         LOGE("directory create error");
255         goto cleanup;
256     }
257
258     if (__file_copy(uri, new_path) == -1) {
259         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
260         LOGE("failed to copy sticker file : %s", error_buffer);
261         ret = -1;
262         goto cleanup;
263     }
264
265     ret = unlink(uri);
266     if (ret != 0) {
267         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
268         LOGE("failed to remove sticker file : %s", error_buffer);
269     }
270
271     if (__change_ownership(new_path, UIFW_ID, UIFW_ID) != 0)
272         LOGE("failed to change ownership");
273
274 cleanup:
275     free(rel_path);
276     rel_path = NULL;
277
278     if (ret == 0) {
279         return new_path;
280     } else {
281         free(new_path);
282         new_path = NULL;
283         return NULL;
284     }
285 }
286
287 static void __insert_sticker_info(const char *app_id, int type, const char *uri, const char *group, const char *thumbnail, const char *description)
288 {
289     int ret;
290     sqlite3 *db = NULL;
291     sqlite3_stmt *stmt = NULL;
292     const char *db_path;
293
294     db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
295     db = __db_open(db_path);
296     if (!db)
297         return;
298
299     ret = sqlite3_prepare_v2(db, "INSERT INTO sticker_info (app_id, type, uri, thumbnail, description, group_name, date) VALUES (?, ?, ?, ?, ?, ?, DateTime('now','localtime'))",-1, &stmt, NULL);
300     if (ret == SQLITE_OK) {
301         sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
302         sqlite3_bind_int(stmt, 2, type);
303         sqlite3_bind_text(stmt, 3, uri, -1, SQLITE_TRANSIENT);
304         sqlite3_bind_text(stmt, 4, thumbnail, -1, SQLITE_TRANSIENT);
305         sqlite3_bind_text(stmt, 5, description, -1, SQLITE_TRANSIENT);
306         sqlite3_bind_text(stmt, 6, group, -1, SQLITE_TRANSIENT);
307
308         ret = sqlite3_step(stmt);
309         if (ret != SQLITE_OK && ret != SQLITE_DONE)
310             LOGE("sqlite3_step() failed : ret(%d)", ret);
311
312         if (sqlite3_changes(db) == 0)
313             LOGE("No changes to DB");
314
315         sqlite3_finalize(stmt);
316         sqlite3_close(db);
317     } else {
318         LOGE("failed to insert sticker information : %s", sqlite3_errmsg(db));
319         sqlite3_finalize(stmt);
320         sqlite3_close(db);
321     }
322
323     return;
324 }
325
326 static void __insert_sticker_keyword_info(const char *keyword)
327 {
328     int ret;
329     int record_id;
330     sqlite3 *db = NULL;
331     sqlite3_stmt *stmt = NULL;
332     const char *db_path;
333
334     db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
335     db = __db_open(db_path);
336     if (!db)
337         return;
338
339     ret = sqlite3_prepare_v2(db, "SELECT sticker_info_id FROM sticker_info ORDER BY sticker_info_id DESC LIMIT 1", -1, &stmt, NULL);
340     if (ret == SQLITE_OK) {
341         ret = sqlite3_step(stmt);
342         if (ret == SQLITE_ERROR) {
343             LOGE("sqlite3_step() failed : ret(%d)", ret);
344             sqlite3_finalize(stmt);
345             sqlite3_close(db);
346         } else {
347             record_id = sqlite3_column_int(stmt, 0);
348
349             sqlite3_finalize(stmt);
350             stmt = NULL;
351
352             ret = sqlite3_prepare_v2(db, "INSERT INTO sticker_keyword_info (sticker_info_id, keyword) VALUES (?, ?)", -1, &stmt, NULL);
353             if (ret == SQLITE_OK) {
354                 sqlite3_bind_int(stmt, 1, record_id);
355                 sqlite3_bind_text(stmt, 2, keyword, -1, SQLITE_TRANSIENT);
356
357                 ret = sqlite3_step(stmt);
358                 if (ret != SQLITE_OK && ret != SQLITE_DONE)
359                     LOGE("sqlite3_step() failed : ret(%d)", ret);
360
361                 if (sqlite3_changes(db) == 0)
362                     LOGE("No changes to DB");
363
364                 sqlite3_finalize(stmt);
365                 sqlite3_close(db);
366             } else {
367                 LOGE("fail to insert sticker keyword : %s", sqlite3_errmsg(db));
368                 sqlite3_finalize(stmt);
369                 sqlite3_close(db);
370             }
371         }
372     } else {
373         LOGE("fail to insert sticker information : %s", sqlite3_errmsg(db));
374         sqlite3_finalize(stmt);
375         sqlite3_close(db);
376     }
377
378     return;
379 }
380
381 static int __get_sticker_info_from_json(const char *appid, const char *file_path, const char *app_path)
382 {
383     int ret = 1;
384     JsonParser* parser = NULL;
385     GError* err_msg = NULL;
386     char *uri = NULL;
387     char *group = NULL;
388     char *description = NULL;
389     char *thumbnail = NULL;
390     char *uri_path = NULL;
391
392     parser = json_parser_new();
393     json_parser_load_from_file(parser, file_path, &err_msg);
394     if (err_msg) {
395         LOGE("failed to load json file. error message: %s", err_msg->message);
396         ret = 0;
397         goto cleanup;
398     }
399
400     JsonNode *root = json_parser_get_root(parser);
401     if (root == NULL) {
402         LOGE("failed to get root");
403         ret = 0;
404         goto cleanup;
405     }
406
407     JsonObject *root_obj = json_node_get_object(root);
408     if (root_obj == NULL) {
409         LOGE("failed to get object");
410         ret = 0;
411         goto cleanup;
412     }
413
414     JsonArray *sticker_arr = json_object_get_array_member(root_obj, "sticker");
415     if (sticker_arr == NULL) {
416         LOGE("failed to get array member");
417         ret = 0;
418         goto cleanup;
419     }
420
421     int arr_len = json_array_get_length(sticker_arr);
422     for (int i = 0; i < arr_len; i++) {
423         JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
424         if (info_object != NULL) {
425             int type = __get_int_from_object(info_object, "type");
426             if (type < 1)
427                 continue;
428
429             uri = __get_string_from_object(info_object, "uri");
430             if (!uri)
431                 goto free_memory;
432
433             group = __get_string_from_object(info_object, "group");
434             if (!group)
435                 goto free_memory;
436
437             thumbnail = __get_string_from_object(info_object, "thumbnail");
438             description = __get_string_from_object(info_object, "description");
439
440             JsonArray *keyword_arr = json_object_get_array_member(info_object, "keyword");
441             int keyword_arr_len = json_array_get_length(keyword_arr);
442             if (keyword_arr_len < 1)
443                 goto free_memory;
444
445             if (type == 1) {
446                 if (access(uri, F_OK) == 0) {
447                     char *new_uri = __convert_sticker_uri(uri, appid, app_path);
448                     if (!new_uri)
449                         goto free_memory;
450                     __insert_sticker_info(appid, type, new_uri, group, thumbnail, description);
451
452                     if (new_uri) {
453                         free(new_uri);
454                         new_uri = NULL;
455                     }
456                 } else {
457                     int path_len = strlen(app_path) + strlen(uri) + 2;
458                     uri_path = (char *)calloc(path_len, sizeof(char));
459                     if (!uri_path) {
460                         LOGE("failed to alloc memory");
461                         goto free_memory;
462                     }
463
464                     if (uri[0] == '/')
465                         snprintf(uri_path, path_len, "%s%s",app_path, uri);
466                     else
467                         snprintf(uri_path, path_len, "%s%s%s",app_path, "/", uri);
468
469                     if (access(uri_path, F_OK) == 0) {
470                         char *new_uri = __convert_sticker_uri(uri_path, appid, app_path);
471                         if (!new_uri) {
472                             free(uri_path);
473                             uri_path = NULL;
474                             goto free_memory;
475                         }
476                         __insert_sticker_info(appid, type, new_uri, group, thumbnail, description);
477
478                         free(new_uri);
479                         new_uri = NULL;
480
481                         free(uri_path);
482                         uri_path = NULL;
483                     } else {
484                         LOGE("%s does not exist", uri_path);
485                         free(uri_path);
486                         uri_path = NULL;
487                         goto free_memory;
488                     }
489                 }
490             } else {
491                 __insert_sticker_info(appid, type, uri, group, thumbnail, description);
492             }
493
494             for (int j = 0; j < keyword_arr_len; j++) {
495                 __insert_sticker_keyword_info(json_array_get_string_element(keyword_arr, j));
496             }
497
498 free_memory:
499             if (uri) {
500                 free(uri);
501                 uri = NULL;
502             }
503
504             if (group) {
505                 free(group);
506                 group = NULL;
507             }
508
509             if (thumbnail) {
510                 free(thumbnail);
511                 thumbnail = NULL;
512             }
513
514             if (description) {
515                 free(description);
516                 description = NULL;
517             }
518         }
519     }
520
521 cleanup:
522     if (err_msg)
523         g_error_free(err_msg);
524
525     if (parser)
526         g_object_unref(parser);
527
528     return ret;
529 }
530
531 static void __delete_sticker_info(const char *db_path, int record_id)
532 {
533     int ret;
534     sqlite3 *db = NULL;
535     sqlite3_stmt *stmt = NULL;
536
537     db = __db_open(db_path);
538         if (!db)
539             return;
540
541     ret = sqlite3_prepare_v2(db, "DELETE FROM sticker_info WHERE sticker_info_id = ?", -1, &stmt, NULL);
542     if (ret != SQLITE_OK) {
543         LOGE("failed to delete sticker information : %s", sqlite3_errmsg(db));
544         sqlite3_finalize(stmt);
545         sqlite3_close(db);
546         goto cleanup;
547     }
548
549     sqlite3_bind_int(stmt, 1, record_id);
550
551     ret = sqlite3_step(stmt);
552     if (ret != SQLITE_OK && ret != SQLITE_DONE) {
553         LOGE("sqlite3_step() failed : ret(%d)", ret);
554         goto cleanup;
555     }
556
557     if (sqlite3_changes(db) == 0) {
558         LOGE("No changes to DB");
559         goto cleanup;
560     }
561
562     sqlite3_finalize(stmt);
563     sqlite3_close(db);
564     return;
565
566 cleanup:
567     sqlite3_finalize(stmt);
568     sqlite3_close(db);
569     return;
570 }
571
572 static int __remove_directory(const char *path, int is_error_stop)
573 {
574     DIR *dir_ptr = NULL;
575     struct dirent *file = NULL;
576     struct stat buf;
577     char filename[1024];
578
579     memset(filename, '\0', 1024);
580
581     if (__change_ownership(path, APPFW_ID, APPFW_ID) != 0)
582         LOGE("failed to change ownership");
583
584     dir_ptr = opendir(path);
585     if (dir_ptr == NULL)
586         return unlink(path);
587
588     while ((file = readdir(dir_ptr)) != NULL) {
589         if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
590             continue;
591
592         snprintf(filename, strlen(path) + strlen(file->d_name) + 2, "%s/%s", path, file->d_name);
593
594         if (lstat(filename, &buf) == -1)
595             continue;
596
597         if (S_ISDIR(buf.st_mode)) {
598             if (__remove_directory(filename, is_error_stop) == -1 && is_error_stop) {
599                 closedir(dir_ptr);
600                 return -1;
601             }
602         } else if (S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) {
603             if (unlink(filename) == -1 && is_error_stop) {
604                 closedir(dir_ptr);
605                 return -1;
606             }
607         }
608     }
609
610     closedir(dir_ptr);
611     return rmdir(path);
612 }
613
614 EXPORT_API
615 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
616 {
617     LOGD("METADATA INSTALL");
618     LOGD("pkgid: %s, appid: %s", pkgid, appid);
619
620     metadata *md = NULL;
621     GList *md_list = NULL;
622     package_info_h package_info = NULL;
623     char *app_path = NULL;
624     char *file_path = NULL;
625     int ret = 0;
626
627     ret = package_info_create(pkgid, &package_info);
628     if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
629         LOGE("faild to create package_info. ret: %d", ret);
630         goto cleanup;
631     }
632
633     ret = package_info_get_root_path(package_info, &app_path);
634     if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
635         LOGE("faild to create package_info. ret: %d", ret);
636         goto cleanup;
637     }
638
639     for(md_list = g_list_first(list); md_list != NULL; md_list = md_list->next) {
640         md = (metadata *)md_list->data;
641         int path_len = strlen(app_path) + strlen((char *)md->value) + 2;
642         file_path = (char *)calloc(path_len, sizeof(char));
643         if (!file_path) {
644             LOGE("failed to alloc memory");
645             continue;
646         }
647
648         if ((char)md->value[0] == '/')
649             snprintf(file_path, path_len, "%s%s",app_path, (char *)md->value);
650         else
651             snprintf(file_path, path_len, "%s%s%s",app_path, "/", (char *)md->value);
652
653         if (__get_sticker_info_from_json(appid, file_path, app_path) == 0)
654             LOGE("failed to get sticker information [path : %s]", file_path);
655
656         free(file_path);
657         file_path = NULL;
658     }
659
660 cleanup:
661     if (package_info)
662         package_info_destroy(package_info);
663
664     if (app_path) {
665         free(app_path);
666         app_path = NULL;
667     }
668
669     return 0;
670 }
671
672 EXPORT_API
673 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
674 {
675     LOGD("METADATA UNINSTALL");
676     LOGD("pkgid: %s, appid: %s", pkgid, appid);
677
678     int ret;
679     int del_id;
680     sqlite3 *db = NULL;
681     sqlite3_stmt *stmt = NULL;
682     const char *db_path;
683     GList *id_list = NULL;
684
685     db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
686     db = __db_open(db_path);
687     if (!db)
688         return 0;
689
690     ret = sqlite3_prepare_v2(db, "SELECT sticker_info_id from sticker_info WHERE app_id = ?", -1, &stmt, NULL);
691     if (ret == SQLITE_OK) {
692         sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
693         while (sqlite3_step(stmt) == SQLITE_ROW) {
694             const unsigned char *record_id = sqlite3_column_text(stmt, 0);
695             if (record_id)
696                 id_list = g_list_append(id_list, strdup((const char *)record_id));
697         }
698
699         sqlite3_finalize(stmt);
700         sqlite3_close(db);
701
702         for(GList *tmp = g_list_first(id_list); tmp != NULL; tmp = tmp->next) {
703             del_id = atoi((const char*)tmp->data);
704             __delete_sticker_info(db_path, del_id);
705         }
706
707         if (id_list)
708             g_list_free_full(id_list, free);
709     } else {
710         LOGE("failed to get sticker id");
711         sqlite3_finalize(stmt);
712         sqlite3_close(db);
713     }
714
715     return 0;
716 }
717
718 EXPORT_API
719 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
720 {
721     LOGD("METADATA UPGRADE");
722     LOGD("pkgid: %s, appid: %s", pkgid, appid);
723
724     PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
725     PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
726     return 0;
727 }
728
729 EXPORT_API
730 int PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
731 {
732     LOGD("STICKER CATEGORY INSTALL");
733     LOGD("pkgid: %s, appid: %s", pkgid, appid);
734
735     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + 2;
736     char *dir_path = (char *)calloc(len, sizeof(char));
737
738     if (dir_path != NULL) {
739         snprintf(dir_path, len, "%s%s%s", STICKER_DIRECTORY, "/", appid);
740         LOGD("directory path : %s", dir_path);
741
742         if (mkdir(dir_path, 0755) == -1 && errno != EEXIST) {
743             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
744             LOGE("directory create error : %s", error_buffer);
745         } else {
746             if (__change_ownership(dir_path, UIFW_ID, UIFW_ID) != 0)
747                 LOGE("failed to change ownership");
748         }
749
750         free(dir_path);
751         dir_path = NULL;
752     }
753
754     return 0;
755 }
756
757 EXPORT_API
758 int PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
759 {
760     LOGD("STICKER CATEGORY UNINSTALL");
761     LOGD("pkgid: %s, appid: %s", pkgid, appid);
762
763     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + 2;
764     char * dir_path = (char *)calloc(len, sizeof(char));
765
766     if (dir_path != NULL) {
767         snprintf(dir_path, len, "%s%s%s", STICKER_DIRECTORY, "/", appid);
768         LOGD("directory path : %s", dir_path);
769
770         if (__remove_directory(dir_path, 0) < 0) {
771             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
772             LOGE("directory remove error : %s", error_buffer);
773         }
774
775         free(dir_path);
776         dir_path = NULL;
777     }
778
779     return 0;
780 }
781
782 EXPORT_API
783 int PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
784 {
785     LOGD("STICKER CATEGORY UPGRADE");
786     LOGD("pkgid: %s, appid: %s", pkgid, appid);
787
788     PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
789     PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(pkgid, appid, list);
790
791     return 0;
792 }