Fix cppcheck warnings
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_db.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <ctype.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <grp.h>
9 #include <dirent.h>
10 #include <libgen.h>
11
12 #include <sqlite3.h>
13
14 #include <tzplatform_config.h>
15 #include <db-util.h>
16
17 #include "pkgmgr-info.h"
18 #include "pkgmgrinfo_debug.h"
19 #include "pkgmgrinfo_private.h"
20 #include "pkgmgr_parser.h"
21 #include "pkgmgr_parser_internal.h"
22
23 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO \
24         "CREATE TABLE IF NOT EXISTS package_cert_index_info( " \
25         " cert_info TEXT UNIQUE, " \
26         " cert_id INTEGER PRIMARY KEY, " \
27         " cert_ref_count INTEGER NOT NULL)"
28
29 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INFO \
30         "CREATE TABLE IF NOT EXISTS package_cert_info( " \
31         " package TEXT PRIMARY KEY, " \
32         " author_root_cert INTEGER, " \
33         " author_im_cert INTEGER, " \
34         " author_signer_cert INTEGER, " \
35         " dist_root_cert INTEGER, " \
36         " dist_im_cert INTEGER, " \
37         " dist_signer_cert INTEGER, " \
38         " dist2_root_cert INTEGER, " \
39         " dist2_im_cert INTEGER, " \
40         " dist2_signer_cert INTEGER)"
41
42 #define QUERY_CREATE_TRIGGER_DELETE_CERT_INFO \
43         "CREATE TRIGGER IF NOT EXISTS delete_cert_info " \
44         "AFTER DELETE ON package_cert_info " \
45         "BEGIN" \
46         " UPDATE package_cert_index_info SET" \
47         "  cert_ref_count = cert_ref_count - 1" \
48         " WHERE cert_id = OLD.author_root_cert" \
49         "  OR cert_id = OLD.author_im_cert" \
50         "  OR cert_id = OLD.author_signer_cert" \
51         "  OR cert_id = OLD.dist_root_cert" \
52         "  OR cert_id = OLD.dist_im_cert" \
53         "  OR cert_id = OLD.dist_signer_cert" \
54         "  OR cert_id = OLD.dist2_root_cert" \
55         "  OR cert_id = OLD.dist2_im_cert" \
56         "  OR cert_id = OLD.dist2_signer_cert;" \
57         "END;"
58
59 #define QUERY_CREATE_TRIGGER_UPDATE_CERT_INDEX_INFO \
60         "CREATE TRIGGER IF NOT EXISTS update_cert_index_info " \
61         "AFTER UPDATE ON package_cert_index_info " \
62         "WHEN ((SELECT cert_ref_count FROM package_cert_index_info " \
63         "       WHERE cert_id = OLD.cert_id) = 0) "\
64         "BEGIN" \
65         " DELETE FROM package_cert_index_info WHERE cert_id = OLD.cert_id;" \
66         "END;"
67
68 #define QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO_FORMAT \
69         "CREATE TRIGGER IF NOT EXISTS update_%s_info " \
70         "AFTER UPDATE ON package_cert_info " \
71         "WHEN (OLD.%s IS NOT NULL) " \
72         "BEGIN" \
73         " UPDATE package_cert_index_info SET" \
74         "  cert_ref_count = cert_ref_count - 1" \
75         " WHERE cert_id = OLD.%s;" \
76         "END;"
77
78 __thread db_handle manifest_db;
79 __thread db_handle cert_db;
80
81 typedef int (*sqlite_query_callback)(void *data, int ncols, char **coltxt, char **colname);
82
83 static int _mkdir_for_user(const char* dir, uid_t uid, gid_t gid)
84 {
85         int ret;
86         char *fullpath;
87         char *subpath;
88
89         fullpath = strdup(dir);
90         if (fullpath == NULL)
91                 return -1;
92         subpath = dirname(fullpath);
93         if (strlen(subpath) > 1 && strcmp(subpath, fullpath) != 0) {
94                 ret = _mkdir_for_user(fullpath, uid, gid);
95                 if (ret == -1) {
96                         free(fullpath);
97                         return ret;
98                 }
99         }
100
101         ret = mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
102         if (ret && errno != EEXIST) {
103                 free(fullpath);
104                 return ret;
105         } else if (ret && errno == EEXIST) {
106                 free(fullpath);
107                 return 0;
108         }
109
110         if (getuid() == ROOT_UID) {
111                 ret = chown(dir, uid, gid);
112                 if (ret == -1)
113                         _LOGE("FAIL : chown %s %d.%d, because %s", dir, uid,
114                                         gid, strerror(errno));
115         }
116
117         free(fullpath);
118
119         return 0;
120 }
121
122 static const char *_get_db_path(uid_t uid) {
123         const char *db_path = NULL;
124         if (uid != GLOBAL_USER && uid != ROOT_UID) {
125                 tzplatform_set_user(uid);
126                 db_path = tzplatform_getenv(TZ_USER_DB);
127                 tzplatform_reset_user();
128         } else {
129                 db_path = tzplatform_getenv(TZ_SYS_DB);
130         }
131         return db_path;
132 }
133
134 static int __attach_and_create_view(sqlite3 *handle, const char *db, const char *tables[], uid_t uid)
135 {
136         int i;
137         char *err;
138         char query[MAX_QUERY_LEN];
139
140         if (uid != GLOBAL_USER && uid != ROOT_UID) {
141                 snprintf(query, sizeof(query), "ATTACH DATABASE '%s' AS Global", db);
142                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
143                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
144                         sqlite3_free(err);
145                         return SQLITE_ERROR;
146                 }
147         }
148
149         for (i = 0; tables[i]; i++) {
150                 if (uid != GLOBAL_USER && uid != ROOT_UID)
151                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
152                                         FROM (SELECT *,0 AS for_all_users FROM main.'%s' UNION \
153                                         SELECT *,1 AS for_all_users FROM Global.'%s')",
154                                         tables[i], tables[i], tables[i]);
155                 else
156                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
157                                         FROM (SELECT *,1 AS for_all_users FROM main.'%s')",
158                                         tables[i], tables[i]);
159                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
160                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
161                         sqlite3_free(err);
162                 }
163         }
164
165         return SQLITE_OK;
166 }
167
168 static int __exec_db_query(sqlite3 *db, char *query, sqlite_query_callback callback, void *data)
169 {
170         char *error_message = NULL;
171         int ret = sqlite3_exec(db, query, callback, data, &error_message);
172         if (SQLITE_OK != ret) {
173                 _LOGE("Don't execute query = %s error message = %s   ret = %d\n", query,
174                        error_message, ret);
175                 sqlite3_free(error_message);
176                 return -1;
177         }
178         sqlite3_free(error_message);
179         return 0;
180 }
181
182 int _check_create_cert_db(sqlite3 *certdb)
183 {
184         int i;
185         char buf[BUFSIZE];
186         static const char *columns[] = {
187                 "author_root_cert", "author_im_cert", "author_signer_cert",
188                 "dist_root_cert", "dist_im_cert", "dist_signer_cert",
189                 "dist2_root_cert", "dist2_im_cert", "dist2_signer_cert",
190                 NULL};
191         int ret = 0;
192         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO, NULL, NULL);
193         if (ret < 0)
194                 return ret;
195         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INFO, NULL, NULL);
196         if (ret < 0)
197                 return ret;
198         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_DELETE_CERT_INFO, NULL, NULL);
199         if (ret < 0)
200                 return ret;
201         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_UPDATE_CERT_INDEX_INFO, NULL, NULL);
202
203         for (i = 0; columns[i] != NULL; i++) {
204                 snprintf(buf, sizeof(buf),
205                                 QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO_FORMAT,
206                                 columns[i], columns[i], columns[i]);
207                 ret = __exec_db_query(certdb, buf, NULL, NULL);
208                 if (ret < 0)
209                         return ret;
210         }
211         return ret;
212 }
213 static gid_t _get_gid(const char *name)
214 {
215         char buf[BUFSIZE];
216         struct group entry;
217         struct group *ge;
218         int ret;
219
220         ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
221         if (ret || ge == NULL) {
222                 _LOGE("fail to get gid of %s", name);
223                 return -1;
224         }
225
226         return entry.gr_gid;
227 }
228
229 API const char *getIconPath(uid_t uid)
230 {
231         const char *path = NULL;
232         uid_t uid_caller = getuid();
233         gid_t gid = ROOT_UID;
234
235         if (uid != GLOBAL_USER && uid != ROOT_UID) {
236                 tzplatform_set_user(uid);
237                 path = tzplatform_mkpath(TZ_USER_ICONS, "/");
238                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
239                 tzplatform_reset_user();
240         } else {
241                 path = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
242         }
243
244         // just allow certain users to create the icon directory if needed.
245         if (uid_caller == ROOT_UID || uid_caller == uid)
246                 _mkdir_for_user(path, uid, gid);
247
248         return path;
249 }
250
251 API const char *getUserPkgParserDBPath(void)
252 {
253         return getUserPkgParserDBPathUID(GLOBAL_USER);
254 }
255
256 API const char *getUserPkgParserDBPathUID(uid_t uid)
257 {
258         const char *pkgmgr_parser_db = NULL;
259         uid_t uid_caller = getuid();
260         gid_t gid = ROOT_UID;
261
262         if (uid != GLOBAL_USER && uid != ROOT_UID) {
263                 tzplatform_set_user(uid);
264                 pkgmgr_parser_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_parser.db");
265                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
266                 tzplatform_reset_user();
267         } else {
268                 pkgmgr_parser_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db");
269         }
270
271         // just allow certain users to create the dbspace directory if needed.
272         if (uid_caller == ROOT_UID || uid_caller == uid) {
273                 const char *db_path = _get_db_path(uid);
274                 _mkdir_for_user(db_path, uid, gid);
275         }
276
277         return pkgmgr_parser_db;
278 }
279
280 API const char *getUserPkgCertDBPath(void)
281 {
282          return getUserPkgCertDBPathUID(GLOBAL_USER);
283 }
284
285 API const char *getUserPkgCertDBPathUID(uid_t uid)
286 {
287         const char *pkgmgr_cert_db = NULL;
288         uid_t uid_caller = getuid();
289         gid_t gid = ROOT_UID;
290
291         if (uid != GLOBAL_USER && uid != ROOT_UID) {
292                 tzplatform_set_user(uid);
293                 pkgmgr_cert_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_cert.db");
294                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
295                 tzplatform_reset_user();
296         } else {
297                 pkgmgr_cert_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db");
298         }
299
300         // just allow certain users to create the dbspace directory if needed.
301         if (uid_caller == ROOT_UID || uid_caller == uid) {
302                 const char *db_path = _get_db_path(uid);
303                 _mkdir_for_user(db_path, uid, gid);
304         }
305
306         return pkgmgr_cert_db;
307 }
308
309 API const char *getUserDesktopPath(uid_t uid)
310 {
311         const char *path = NULL;
312         uid_t uid_caller = getuid();
313         gid_t gid = ROOT_UID;
314
315         if (uid != GLOBAL_USER && uid != ROOT_UID) {
316                 tzplatform_set_user(uid);
317                 path = tzplatform_mkpath(TZ_USER_DESKTOP, "/");
318                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
319                 tzplatform_reset_user();
320         } else {
321                 path = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
322         }
323
324         // just allow certain users to create the icon directory if needed.
325         if (uid_caller == ROOT_UID || uid_caller == uid)
326                 _mkdir_for_user(path, uid, gid);
327
328         return path;
329 }
330
331 API const char *getUserManifestPath(uid_t uid)
332 {
333         const char *path = NULL;
334         uid_t uid_caller = getuid();
335         gid_t gid = ROOT_UID;
336
337         if (uid != GLOBAL_USER && uid != ROOT_UID) {
338                 tzplatform_set_user(uid);
339                 path = tzplatform_mkpath(TZ_USER_PACKAGES, "/");
340                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
341                 tzplatform_reset_user();
342         } else {
343                 path = tzplatform_mkpath(TZ_SYS_RW_PACKAGES, "/");
344         }
345
346         // just allow certain users to create the icon directory if needed.
347         if (uid_caller == ROOT_UID || uid_caller == uid)
348                 _mkdir_for_user(path, uid, gid);
349
350         return path;
351 }
352
353 int __close_manifest_db(void)
354 {
355         if (manifest_db.ref) {
356                 if (--manifest_db.ref == 0)
357                         sqlite3_close(GET_DB(manifest_db));
358                 return 0;
359         }
360         return -1;
361 }
362
363 static const char *parserdb_tables[] = {
364         "package_app_app_category",
365         "package_app_info",
366         "package_app_app_control",
367         "package_app_localized_info",
368         "package_app_app_metadata",
369         "package_app_share_allowed",
370         "package_app_app_permission",
371         "package_app_share_request",
372         "package_info",
373         "package_app_data_control",
374         "package_localized_info",
375         "package_app_icon_section_info",
376         "package_privilege_info",
377         "package_app_image_info",
378         NULL
379 };
380
381 int __open_manifest_db(uid_t uid, bool readonly)
382 {
383         int ret;
384         const char *user_pkg_parser;
385         int flags;
386
387         if (manifest_db.ref) {
388                 manifest_db.ref ++;
389                 return 0;
390         }
391
392         user_pkg_parser = getUserPkgParserDBPathUID(uid);
393         if (access(user_pkg_parser, F_OK) != 0) {
394                 _LOGE("Manifest DB does not exists !!");
395                 return -1;
396         }
397
398         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
399         ret = db_util_open_with_options(user_pkg_parser, &GET_DB(manifest_db),
400                         flags, NULL);
401         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!\n",
402                         user_pkg_parser);
403         manifest_db.ref++;
404         if (readonly) {
405                 ret = __attach_and_create_view(GET_DB(manifest_db), MANIFEST_DB,
406                                 parserdb_tables, uid);
407                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!\n",
408                                 user_pkg_parser);
409         }
410         return 0;
411 }
412
413 int __close_cert_db(void)
414 {
415         if (cert_db.ref) {
416                 if (--cert_db.ref == 0)
417                         sqlite3_close_v2(GET_DB(cert_db));
418                         return 0;
419         }
420         _LOGE("Certificate DB is already closed !!\n");
421         return -1;
422 }
423
424 static const char *certdb_tables[] = {
425         "package_cert_index_info",
426         "package_cert_info",
427         NULL
428 };
429
430 int __open_cert_db(uid_t uid, bool readonly)
431 {
432         int ret;
433         const char *user_cert_parser;
434         int flags;
435
436         if (cert_db.ref) {
437                 cert_db.ref ++;
438                 return 0;
439         }
440
441         user_cert_parser = getUserPkgCertDBPathUID(uid);
442         if (access(user_cert_parser, F_OK) != 0) {
443                 _LOGE("Cert DB does not exists !!");
444                 return -1;
445         }
446
447         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
448         ret = db_util_open_with_options(user_cert_parser, &GET_DB(cert_db),
449                         flags, NULL);
450         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!",
451                         user_cert_parser);
452         cert_db.ref++;
453         if (readonly) {
454                 ret = __attach_and_create_view(GET_DB(cert_db), CERT_DB,
455                                 certdb_tables, uid);
456                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!",
457                                 user_cert_parser);
458         }
459         return 0;
460 }
461
462 void _save_column_int(sqlite3_stmt *stmt, int idx, int *i)
463 {
464         *i = sqlite3_column_int(stmt, idx);
465 }
466
467 void _save_column_str(sqlite3_stmt *stmt, int idx, const char **str)
468 {
469         const char *val;
470
471         val = (const char *)sqlite3_column_text(stmt, idx);
472         if (val)
473                 *str = strdup(val);
474 }
475
476 API int pkgmgrinfo_pkginfo_set_state_enabled(const char *pkgid, bool enabled)
477 {
478         /* Should be implemented later */
479         return 0;
480 }
481
482 API int pkgmgrinfo_appinfo_set_usr_state_enabled(const char *appid, bool enabled, uid_t uid)
483 {
484         int ret;
485         char query[MAX_QUERY_LEN] = {'\0'};
486         char *error_message;
487
488         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
489
490         /* Open db.*/
491         ret = __open_manifest_db(uid, false);
492         if (ret != SQLITE_OK) {
493                 _LOGE("connect db [%s] failed!\n", getUserPkgParserDBPathUID(uid));
494                 return PMINFO_R_ERROR;
495         }
496
497         /*Begin transaction*/
498         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
499         if (ret != SQLITE_OK) {
500                 _LOGE("Failed to begin transaction\n");
501                 __close_manifest_db();
502                 return PMINFO_R_ERROR;
503         }
504         _LOGD("Transaction Begin\n");
505
506         memset(query, '\0', MAX_QUERY_LEN);
507         snprintf(query, MAX_QUERY_LEN,
508                 "update package_app_info set app_enabled='%s' where app_id='%s'", enabled?"true":"false", appid);
509
510         if (SQLITE_OK !=
511             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
512                 _LOGE("Don't execute query = %s error message = %s\n", query,
513                        error_message);
514                 sqlite3_free(error_message);
515                 return PMINFO_R_ERROR;
516         }
517         sqlite3_free(error_message);
518
519         /*Commit transaction*/
520         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
521         if (ret != SQLITE_OK) {
522                 _LOGE("Failed to commit transaction. Rollback now\n");
523                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
524                 __close_manifest_db();
525                 return PMINFO_R_ERROR;
526         }
527         _LOGD("Transaction Commit and End\n");
528         __close_manifest_db();
529         return PMINFO_R_OK;
530 }
531
532 API int pkgmgrinfo_appinfo_set_state_enabled(const char *appid, bool enabled)
533 {
534         return pkgmgrinfo_appinfo_set_usr_state_enabled(appid, enabled, GLOBAL_USER);
535 }
536
537 API int pkgmgrinfo_appinfo_set_usr_default_label(const char *appid, const char *label, uid_t uid)
538 {
539         int ret;
540         char query[MAX_QUERY_LEN] = {'\0'};
541         char *error_message;
542
543         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
544
545         ret = __open_manifest_db(uid, false);
546         if (ret == -1) {
547                 _LOGE("Fail to open manifest DB\n");
548                 return PMINFO_R_ERROR;
549         }
550
551         /*Begin transaction*/
552         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
553         if (ret != SQLITE_OK) {
554                 _LOGE("Failed to begin transaction\n");
555                 __close_manifest_db();
556                 return PMINFO_R_ERROR;
557         }
558         _LOGD("Transaction Begin\n");
559
560         memset(query, '\0', MAX_QUERY_LEN);
561         snprintf(query, MAX_QUERY_LEN,
562                 "update package_app_localized_info set app_label='%s' where app_id='%s' and app_locale='No Locale'", label, appid);
563
564         if (SQLITE_OK !=
565             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
566                 _LOGE("Don't execute query = %s error message = %s\n", query,
567                        error_message);
568                 sqlite3_free(error_message);
569                 return PMINFO_R_ERROR;
570         }
571
572         /*Commit transaction*/
573         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
574         if (ret != SQLITE_OK) {
575                 _LOGE("Failed to commit transaction. Rollback now\n");
576                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
577                 __close_manifest_db();
578                 return PMINFO_R_ERROR;
579         }
580         _LOGD("Transaction Commit and End\n");
581         __close_manifest_db();
582         return PMINFO_R_OK;
583 }
584
585 API int pkgmgrinfo_appinfo_set_default_label(const char *appid, const char *label)
586 {
587         return pkgmgrinfo_appinfo_set_usr_default_label(appid, label, GLOBAL_USER);
588 }
589
590 API int pkgmgrinfo_appinfo_set_usr_guestmode_visibility(pkgmgrinfo_appinfo_h handle, uid_t uid, bool status)
591 {
592         const char *val;
593         int ret;
594         char query[MAX_QUERY_LEN] = {'\0'};
595         char *errmsg;
596         sqlite3 *pkgmgr_parser_db;
597
598         retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL\n");
599
600         pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
601         val = info->app_info->guestmode_visibility;
602         if (val) {
603                 ret = db_util_open_with_options(getUserPkgParserDBPathUID(uid), &pkgmgr_parser_db,
604                                 SQLITE_OPEN_READWRITE, NULL);
605                 if (ret != SQLITE_OK) {
606                         _LOGE("DB Open Failed\n");
607                         return PMINFO_R_ERROR;
608                 }
609
610                 /*TODO: Write to DB here*/
611                 if (status == true)
612                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'true' where app_id = '%s'", (char *)info->app_info->appid);
613                 else
614                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'false' where app_id = '%s'", (char *)info->app_info->appid);
615
616                 ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, &errmsg);
617                 sqlite3_close(pkgmgr_parser_db);
618                 if (ret != SQLITE_OK) {
619                         _LOGE("DB update [%s] failed, error message = %s\n", query, errmsg);
620                         free(errmsg);
621                         return PMINFO_R_ERROR;
622                 }
623         }
624         return PMINFO_R_OK;
625 }
626
627 API int pkgmgrinfo_appinfo_set_guestmode_visibility(pkgmgrinfo_appinfo_h handle, bool status)
628 {
629         return pkgmgrinfo_appinfo_set_usr_guestmode_visibility(handle, GLOBAL_USER, status);
630 }
631
632 API int pkgmgrinfo_pkginfo_set_usr_installed_storage(const char *pkgid, INSTALL_LOCATION location, uid_t uid)
633 {
634         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
635         int ret = -1;
636         sqlite3 *pkgmgr_parser_db = NULL;
637         char *query = NULL;
638
639         ret = db_util_open_with_options(getUserPkgParserDBPathUID(uid), &pkgmgr_parser_db,
640                         SQLITE_OPEN_READWRITE, NULL);
641         retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db failed!");
642
643         /*Begin transaction*/
644         // Setting Manifest DB
645         ret = sqlite3_exec(pkgmgr_parser_db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
646         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
647         _LOGD("Transaction Begin\n");
648
649         // pkgcakge_info table
650         query = sqlite3_mprintf("update package_info set installed_storage=%Q where package=%Q", location?"installed_external":"installed_internal", pkgid);
651
652         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
653         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
654         sqlite3_free(query);
655
656         // package_app_info table
657         query = sqlite3_mprintf("update package_app_info set app_installed_storage=%Q where package=%Q", location?"installed_external":"installed_internal", pkgid);
658
659         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
660         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
661
662         /*Commit transaction*/
663         ret = sqlite3_exec(pkgmgr_parser_db, "COMMIT", NULL, NULL, NULL);
664         if (ret != SQLITE_OK) {
665                 _LOGE("Failed to commit transaction. Rollback now\n");
666                 ret = sqlite3_exec(pkgmgr_parser_db, "ROLLBACK", NULL, NULL, NULL);
667                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
668         }
669         _LOGD("Transaction Commit and End\n");
670
671         ret = PMINFO_R_OK;
672 catch:
673         sqlite3_close(pkgmgr_parser_db);
674         sqlite3_free(query);
675         return ret;
676 }
677
678 API int pkgmgrinfo_pkginfo_set_installed_storage(const char *pkgid, INSTALL_LOCATION location)
679 {
680         return pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid, location, GLOBAL_USER);
681 }