Remove the cache when language change event occurs
[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 <tzplatform_config.h>
15
16 #include "pkgmgr-info.h"
17 #include "pkgmgrinfo_debug.h"
18 #include "pkgmgrinfo_private.h"
19 #include "pkgmgr_parser.h"
20 #include "manager/pkginfo_manager.h"
21
22 typedef int (*sqlite_query_callback)(void *data, int ncols,
23                 char **coltxt, char **colname);
24
25 static int _mkdir_for_user(const char *dir, uid_t uid, gid_t gid)
26 {
27         int ret;
28         char *fullpath;
29         char *subpath;
30         char buf[1024];
31         int fd;
32         struct stat sb;
33
34         fullpath = strdup(dir);
35         if (fullpath == NULL)
36                 return -1;
37         subpath = dirname(fullpath);
38         if (strlen(subpath) > 1 && strcmp(subpath, fullpath) != 0) {
39                 ret = _mkdir_for_user(fullpath, uid, gid);
40                 if (ret == -1) {
41                         free(fullpath);
42                         return ret;
43                 }
44         }
45
46         ret = mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
47         if (ret && errno != EEXIST) {
48                 free(fullpath);
49                 return ret;
50         } else if (ret && errno == EEXIST) {
51                 free(fullpath);
52                 return 0;
53         }
54
55         if (getuid() == ROOT_UID) {
56                 fd = open(dir, O_RDONLY);
57                 if (fd == -1) {
58                         _LOGE("FAIL : open %s : %s", dir,
59                                         strerror_r(errno, buf, sizeof(buf)));
60                         free(fullpath);
61                         return -1;
62                 }
63                 ret = fstat(fd, &sb);
64                 if (ret == -1) {
65                         _LOGE("FAIL : fstat %s : %s", dir,
66                                         strerror_r(errno, buf, sizeof(buf)));
67                         close(fd);
68                         free(fullpath);
69                         return -1;
70                 }
71                 if (S_ISLNK(sb.st_mode)) {
72                         _LOGE("FAIL : %s is symlink!", dir);
73                         close(fd);
74                         free(fullpath);
75                         return -1;
76                 }
77                 ret = fchown(fd, uid, gid);
78                 if (ret == -1) {
79                         _LOGE("FAIL : fchown %s %d.%d, because %s",
80                                         dir, uid, gid,
81                                         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 static gid_t _get_gid(const char *name)
114 {
115         char buf[BUFSIZE];
116         struct group entry;
117         struct group *ge;
118         int ret;
119
120         ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
121         if (ret || ge == NULL) {
122                 _LOGE("fail to get gid of %s", name);
123                 return -1;
124         }
125
126         return entry.gr_gid;
127 }
128
129 API const char *getIconPath(uid_t uid, bool readonly)
130 {
131         const char *path = NULL;
132         uid_t uid_caller = getuid();
133         gid_t gid = ROOT_UID;
134
135         if (uid != GLOBAL_USER && uid != ROOT_UID) {
136                 _LOGD("not supported target user");
137                 return NULL;
138         }
139
140         if (readonly)
141                 path = tzplatform_mkpath(TZ_SYS_RO_ICONS, "/");
142
143         /* just allow certain users to create the icon directory if needed. */
144         if (path && (uid_caller == ROOT_UID  ||
145                 uid_caller == APPFW_UID || uid_caller == uid))
146                 _mkdir_for_user(path, uid, gid);
147
148         return path;
149 }
150
151 API char *getUserPkgParserDBPath(void)
152 {
153         return getUserPkgParserDBPathUID(_getuid());
154 }
155
156 API char *getUserPkgParserDBPathUID(uid_t uid)
157 {
158         char pkgmgr_parser_db[PATH_MAX];
159         uid_t uid_caller = getuid();
160         gid_t gid = ROOT_UID;
161         char *db_path;
162
163         db_path = _get_db_path(uid);
164         if (db_path == NULL) {
165                 _LOGE("Failed to get db path %d", uid);
166                 return NULL;
167         }
168         snprintf(pkgmgr_parser_db, sizeof(pkgmgr_parser_db),
169                         "%s/.pkgmgr_parser.db", db_path);
170         if (access(db_path, F_OK) != 0) {
171                 if (uid != GLOBAL_USER && uid != ROOT_UID) {
172                         tzplatform_set_user(uid);
173                         gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
174                         tzplatform_reset_user();
175                 }
176                 /* just allow certain users to create the dbspace directory if needed. */
177                 if (uid_caller == ROOT_UID || uid_caller == APPFW_UID)
178                         _mkdir_for_user(db_path, uid, gid);
179         }
180         free(db_path);
181
182         return strdup(pkgmgr_parser_db);
183 }
184
185 API char *getUserPkgCertDBPath(void)
186 {
187         char *db_path;
188         char pkgmgr_cert_db[PATH_MAX];
189
190         db_path = _get_db_path(GLOBAL_USER);
191         snprintf(pkgmgr_cert_db, sizeof(pkgmgr_cert_db),
192                         "%s/.pkgmgr_cert.db", db_path);
193         free(db_path);
194
195         return strdup(pkgmgr_cert_db);
196 }
197
198 API const char *getUserManifestPath(uid_t uid, bool readonly)
199 {
200         const char *path = NULL;
201         uid_t uid_caller = getuid();
202         gid_t gid = ROOT_UID;
203
204         if (uid != GLOBAL_USER && uid != ROOT_UID) {
205                 tzplatform_set_user(uid);
206                 path = tzplatform_mkpath(TZ_USER_PACKAGES, "/");
207                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
208                 tzplatform_reset_user();
209         } else {
210                 if (readonly)
211                         path = tzplatform_mkpath(TZ_SYS_RO_PACKAGES, "/");
212                 else
213                         path = tzplatform_mkpath(TZ_SYS_RW_PACKAGES, "/");
214         }
215
216         /* just allow certain users to create the icon directory if needed. */
217         if (uid_caller == ROOT_UID || uid_caller == APPFW_UID ||
218                         uid_caller == uid)
219                 _mkdir_for_user(path, uid, gid);
220
221         return path;
222 }
223
224 API int pkgmgrinfo_pkginfo_set_usr_installed_storage(const char *pkgid,
225                 INSTALL_LOCATION location, const char *external_pkg_path,
226                 uid_t uid)
227 {
228         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
229         return _pkginfo_set_usr_installed_storage(pkgid,
230                         location, external_pkg_path, uid);
231 }
232
233 API int pkgmgrinfo_pkginfo_set_installed_storage(const char *pkgid,
234                 INSTALL_LOCATION location, const char *external_pkg_path)
235 {
236         return pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
237                         location, external_pkg_path, _getuid());
238 }