Remove compile warning messages
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_db.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <ctype.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <grp.h>
11 #include <dirent.h>
12 #include <libgen.h>
13
14 #include <sqlite3.h>
15
16 #include <tzplatform_config.h>
17
18 #include "pkgmgr-info.h"
19 #include "pkgmgrinfo_debug.h"
20 #include "pkgmgrinfo_private.h"
21 #include "pkgmgr_parser.h"
22 #include "pkgmgr_parser_db.h"
23
24 typedef int (*sqlite_query_callback)(void *data, int ncols, char **coltxt, char **colname);
25
26 static int _mkdir_for_user(const char* dir, uid_t uid, gid_t gid)
27 {
28         int ret;
29         char *fullpath;
30         char *subpath;
31         char buf[1024];
32         int fd;
33         struct stat sb;
34
35         fullpath = strdup(dir);
36         if (fullpath == NULL)
37                 return -1;
38         subpath = dirname(fullpath);
39         if (strlen(subpath) > 1 && strcmp(subpath, fullpath) != 0) {
40                 ret = _mkdir_for_user(fullpath, uid, gid);
41                 if (ret == -1) {
42                         free(fullpath);
43                         return ret;
44                 }
45         }
46
47         ret = mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
48         if (ret && errno != EEXIST) {
49                 free(fullpath);
50                 return ret;
51         } else if (ret && errno == EEXIST) {
52                 free(fullpath);
53                 return 0;
54         }
55
56         if (getuid() == ROOT_UID) {
57                 fd = open(dir, O_RDONLY);
58                 if (fd == -1) {
59                         _LOGE("FAIL : open %s : %s", dir,
60                                         strerror_r(errno, buf, sizeof(buf)));
61                         free(fullpath);
62                         return -1;
63                 }
64                 ret = fstat(fd, &sb);
65                 if (ret == -1) {
66                         _LOGE("FAIL : fstat %s : %s", dir,
67                                         strerror_r(errno, buf, sizeof(buf)));
68                         close(fd);
69                         free(fullpath);
70                         return -1;
71                 }
72                 if (S_ISLNK(sb.st_mode)) {
73                         _LOGE("FAIL : %s is symlink!", dir);
74                         close(fd);
75                         free(fullpath);
76                         return -1;
77                 }
78                 ret = fchown(fd, uid, gid);
79                 if (ret == -1) {
80                         _LOGE("FAIL : fchown %s %d.%d, because %s", dir, uid,
81                                         gid, strerror_r(errno, buf, sizeof(buf)));
82                         close(fd);
83                         free(fullpath);
84                         return -1;
85                 }
86                 close(fd);
87         }
88
89         free(fullpath);
90
91         return 0;
92 }
93
94 static char *_get_db_path(uid_t uid)
95 {
96         const char *db_path;
97         char path[PATH_MAX];
98
99         db_path = tzplatform_getenv(TZ_SYS_DB);
100         if (db_path == NULL) {
101                 _LOGE("Failed to get TZ_SYS_DB path");
102                 return NULL;
103         }
104
105         if (uid == GLOBAL_USER || uid == ROOT_UID)
106                 return strdup(db_path);
107
108         snprintf(path, sizeof(path), "%s/user/%d", db_path, uid);
109
110         return strdup(path);
111 }
112
113 int _check_create_cert_db(void)
114 {
115         return pkgmgr_parser_initialize_cert_db();
116 }
117
118 static gid_t _get_gid(const char *name)
119 {
120         char buf[BUFSIZE];
121         struct group entry;
122         struct group *ge;
123         int ret;
124
125         ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
126         if (ret || ge == NULL) {
127                 _LOGE("fail to get gid of %s", name);
128                 return -1;
129         }
130
131         return entry.gr_gid;
132 }
133
134 API const char *getIconPath(uid_t uid, bool readonly)
135 {
136         const char *path = NULL;
137         uid_t uid_caller = getuid();
138         gid_t gid = ROOT_UID;
139
140         if (uid != GLOBAL_USER && uid != ROOT_UID) {
141                 _LOGD("not supported target user");
142                 return NULL;
143         }
144
145         if (readonly)
146                 path = tzplatform_mkpath(TZ_SYS_RO_ICONS, "/");
147
148         /* just allow certain users to create the icon directory if needed. */
149         if (path && (uid_caller == ROOT_UID  ||
150                 uid_caller == APPFW_UID || uid_caller == uid))
151                 _mkdir_for_user(path, uid, gid);
152
153         return path;
154 }
155
156 API char *getUserPkgParserDBPath(void)
157 {
158         return getUserPkgParserDBPathUID(_getuid());
159 }
160
161 API char *getUserPkgParserDBPathUID(uid_t uid)
162 {
163         char pkgmgr_parser_db[PATH_MAX];
164         uid_t uid_caller = getuid();
165         gid_t gid = ROOT_UID;
166         char *db_path;
167
168         db_path = _get_db_path(uid);
169         if (db_path == NULL) {
170                 _LOGE("Failed to get db path %d", uid);
171                 return NULL;
172         }
173         snprintf(pkgmgr_parser_db, sizeof(pkgmgr_parser_db),
174                         "%s/.pkgmgr_parser.db", db_path);
175         if (access(db_path, F_OK) != 0) {
176                 if (uid != GLOBAL_USER && uid != ROOT_UID) {
177                         tzplatform_set_user(uid);
178                         gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
179                         tzplatform_reset_user();
180                 }
181                 /* just allow certain users to create the dbspace directory if needed. */
182                 if (uid_caller == ROOT_UID || uid_caller == APPFW_UID ||
183                                 uid_caller == uid)
184                         _mkdir_for_user(db_path, uid, gid);
185         }
186         free(db_path);
187
188         return strdup(pkgmgr_parser_db);
189 }
190
191 API char *getUserPkgCertDBPath(void)
192 {
193         char *db_path;
194         char pkgmgr_cert_db[PATH_MAX];
195
196         db_path = _get_db_path(GLOBAL_USER);
197         snprintf(pkgmgr_cert_db, sizeof(pkgmgr_cert_db),
198                         "%s/.pkgmgr_cert.db", db_path);
199         free(db_path);
200
201         return strdup(pkgmgr_cert_db);
202 }
203
204 API const char *getUserManifestPath(uid_t uid, bool readonly)
205 {
206         const char *path = NULL;
207         uid_t uid_caller = getuid();
208         gid_t gid = ROOT_UID;
209
210         if (uid != GLOBAL_USER && uid != ROOT_UID) {
211                 tzplatform_set_user(uid);
212                 path = tzplatform_mkpath(TZ_USER_PACKAGES, "/");
213                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
214                 tzplatform_reset_user();
215         } else {
216                 if (readonly)
217                         path = tzplatform_mkpath(TZ_SYS_RO_PACKAGES, "/");
218                 else
219                         path = tzplatform_mkpath(TZ_SYS_RW_PACKAGES, "/");
220         }
221
222         /* just allow certain users to create the icon directory if needed. */
223         if (uid_caller == ROOT_UID || uid_caller == APPFW_UID || uid_caller == uid)
224                 _mkdir_for_user(path, uid, gid);
225
226         return path;
227 }
228
229 void _save_column_int(sqlite3_stmt *stmt, int idx, int *i)
230 {
231         *i = sqlite3_column_int(stmt, idx);
232 }
233
234 inline void _save_column_str(sqlite3_stmt *stmt, int idx, char **str)
235 {
236         const char *val;
237
238         val = (const char *)sqlite3_column_text(stmt, idx);
239         if (val)
240                 *str = strdup(val);
241 }
242
243 API int pkgmgrinfo_pkginfo_set_usr_installed_storage(const char *pkgid, INSTALL_LOCATION location, const char *external_pkg_path, uid_t uid)
244 {
245         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
246         int ret = -1;
247         sqlite3 *pkgmgr_parser_db = NULL;
248         char *query = NULL;
249         char *db_path;
250         const char *location_str;
251
252         db_path = getUserPkgParserDBPathUID(uid);
253         if (db_path == NULL) {
254                 _LOGE("Failed to get pkg parser db path - %d", uid);
255                 return PMINFO_R_ERROR;
256         }
257
258         ret = __open_db(db_path, &pkgmgr_parser_db, SQLITE_OPEN_READWRITE);
259         if (ret != SQLITE_OK) {
260                 _LOGE("connect db failed!");
261                 free(db_path);
262                 return PMINFO_R_ERROR;
263         }
264         free(db_path);
265
266         /*Begin transaction*/
267         /* Setting Manifest DB */
268         ret = sqlite3_exec(pkgmgr_parser_db, "BEGIN DEFERRED", NULL, NULL, NULL);
269         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
270         _LOGD("Transaction Begin\n");
271
272         if (location == INSTALL_INTERNAL)
273                 location_str = "installed_internal";
274         else if (location == INSTALL_EXTERNAL)
275                 location_str = "installed_external";
276         else
277                 location_str = "installed_extended";
278         /* pkgcakge_info table */
279         query = sqlite3_mprintf(
280                         "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
281                         location_str, external_pkg_path, pkgid);
282
283         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
284         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
285         sqlite3_free(query);
286
287         /* package_app_info table */
288         query = sqlite3_mprintf(
289                         "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
290                         location_str, external_pkg_path, pkgid);
291
292         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
293         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
294
295         /*Commit transaction*/
296         ret = sqlite3_exec(pkgmgr_parser_db, "COMMIT", NULL, NULL, NULL);
297         if (ret != SQLITE_OK) {
298                 _LOGE("Failed to commit transaction. Rollback now\n");
299                 ret = sqlite3_exec(pkgmgr_parser_db, "ROLLBACK", NULL, NULL, NULL);
300                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
301         }
302         _LOGD("Transaction Commit and End\n");
303
304         ret = PMINFO_R_OK;
305 catch:
306         sqlite3_close_v2(pkgmgr_parser_db);
307         sqlite3_free(query);
308         return ret;
309 }
310
311 API int pkgmgrinfo_pkginfo_set_installed_storage(const char *pkgid, INSTALL_LOCATION location, const char *external_pkg_path)
312 {
313         return pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid, location, external_pkg_path, _getuid());
314 }