fix pkg move behavior
[platform/core/appfw/app2sd.git] / src / app2ext_interface.c
1 /*
2  * app2ext
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <errno.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26 #include <dlfcn.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <dirent.h>
31
32 #include "app2ext_interface.h"
33 #include "app2ext_utils.h"
34
35 #define APP2EXT_SD_PLUGIN_PATH  LIBPREFIX "/libapp2sd.so"
36
37 app2ext_handle *app2ext_init(int storage_type)
38 {
39         void *dl_handle = NULL;
40         int (*dl_on_load)(app2ext_interface *) = NULL;
41
42         /* validate the function parameter recieved */
43         if (storage_type < APP2EXT_INTERNAL_MEM ||
44                 storage_type > APP2EXT_CLOUD) {
45                 _E("invalid function arguments");
46                 return NULL;
47         }
48         if (storage_type != APP2EXT_SD_CARD) {
49                 _E("storage type currently not supported");
50                 return NULL;
51         }
52
53         /* allocate memory for app2ext handle*/
54         app2ext_handle *handle = (app2ext_handle *)calloc(1, sizeof(app2ext_handle));
55         if (handle == NULL) {
56                 _E("memory allocation failed");
57                 return NULL;
58         }
59
60         /* load SD plugin*/
61         handle->type = APP2EXT_SD_CARD;
62         dl_handle = dlopen(APP2EXT_SD_PLUGIN_PATH, RTLD_LAZY|RTLD_GLOBAL);
63         if (NULL == dl_handle) {
64                 _E("dlopen(%s) failed", APP2EXT_SD_PLUGIN_PATH);
65                 free(handle);
66                 return NULL;
67         }
68
69         handle->plugin_handle = dl_handle;
70         dl_on_load = dlsym(dl_handle, "app2ext_on_load");
71         if (NULL == dl_on_load) {
72                 _E("cannot find app2ext_on_load symbol in (%s)", APP2EXT_SD_PLUGIN_PATH);
73                 dlclose(dl_handle);
74                 free(handle);
75                 return NULL;
76         }
77
78         /* initialize the SD plugin*/
79         if (!dl_on_load(&(handle->interface))) {
80                 _E("app2ext_on_load() failed in (%s)", APP2EXT_SD_PLUGIN_PATH);
81                 dlclose(dl_handle);
82                 free(handle);
83                 return NULL;
84         }
85
86         _D("plugin(%s) loaded", APP2EXT_SD_PLUGIN_PATH);
87
88         return handle;
89 }
90
91 int app2ext_deinit(app2ext_handle *handle)
92 {
93         /* validate the function parameter recieved */
94         if (handle == NULL || handle->plugin_handle == NULL) {
95                 _E("invalid function arguments");
96                 return -1;
97         }
98
99         /* close the plugin handle*/
100         dlclose(handle->plugin_handle);
101
102         /* free allocated memory during installtion*/
103         free(handle);
104
105         return 0;
106 }
107
108 /* use this api only to check external related file existing,
109  * such as .mmc directory and image file under /sdcard/app2sd.
110  */
111 int app2ext_usr_get_app_location(const char *pkgid, uid_t uid)
112 {
113         FILE *fp = NULL;
114         char loopback_device[FILENAME_MAX] = { 0, };
115         char application_path[FILENAME_MAX] = { 0, };
116         char application_mmc_path[FILENAME_MAX] = { 0, };
117         char *encoded_id = NULL;
118
119         /* validate the function parameter received */
120         if (pkgid == NULL) {
121                 _E("invalid func parameters");
122                 return -1;
123         }
124
125         if (_is_global(uid)) {
126                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
127                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
128                 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/%s/.mmc",
129                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
130         } else {
131                 tzplatform_set_user(uid);
132                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
133                         tzplatform_getenv(TZ_USER_APP), pkgid);
134                 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/%s/.mmc",
135                         tzplatform_getenv(TZ_USER_APP), pkgid);
136                 tzplatform_reset_user();
137         }
138         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
139         if (encoded_id == NULL)
140                 return -1;
141
142         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
143                 APP2SD_PATH, encoded_id);
144         free(encoded_id);
145
146         /* check whether application is in external memory or not */
147         fp = fopen(loopback_device, "r");
148         if (fp != NULL) {
149                 fclose(fp);
150                 fp = NULL;
151                 _D("sd card");
152                 return APP2EXT_SD_CARD;
153         }
154
155         /* check whether application is in internal or not */
156         fp = fopen(application_path, "r");
157         if (fp == NULL) {
158                 _D("app_dir_path open failed, " \
159                         "package not installed");
160                 return APP2EXT_NOT_INSTALLED;
161         } else {
162                 fclose(fp);
163                 /* check whether the application is installed in SD card
164                  * but SD card is not present
165                  */
166                 fp = fopen(application_mmc_path, "r");
167                 if (fp == NULL) {
168                         _D("internal mem");
169                         return APP2EXT_INTERNAL_MEM;
170                 } else {
171                         fclose(fp);
172                         _E("app_mmc_internal_path exists, " \
173                                 "error mmc status");
174                         return -1;
175                 }
176         }
177 }
178
179 int app2ext_get_app_location(const char *pkgid)
180 {
181         int ret = 0;
182
183         ret = app2ext_usr_get_app_location(pkgid, getuid());
184
185         return ret;
186 }
187
188 int app2ext_usr_enable_external_pkg(const char *pkgid, uid_t uid)
189 {
190         FILE *fp = NULL;
191         app2ext_handle *handle = NULL;
192         char loopback_device[FILENAME_MAX] = { 0, };
193         char *encoded_id = NULL;
194
195         /* validate the function parameter received */
196         if (pkgid == NULL) {
197                 _E("invalid func parameters");
198                 return -1;
199         }
200
201         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
202         if (encoded_id == NULL)
203                 return -1;
204
205         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
206                 APP2SD_PATH, encoded_id);
207         free(encoded_id);
208
209         /* check whether application is in external memory or not */
210         fp = fopen(loopback_device, "r");
211         if (fp != NULL) {
212                 fclose(fp);
213                 fp = NULL;
214
215                 handle = app2ext_init(APP2EXT_SD_CARD);
216                 if (handle == NULL) {
217                         _E("app2ext init failed");
218                         return -1;
219                 }
220
221                 handle->interface.client_usr_enable(pkgid, uid);
222                 app2ext_deinit(handle);
223         }
224
225         return 0;
226 }
227
228 int app2ext_enable_external_pkg(const char *pkgid)
229 {
230         int ret = 0;
231
232         ret = app2ext_usr_enable_external_pkg(pkgid, getuid());
233
234         return ret;
235 }
236
237 int app2ext_usr_disable_external_pkg(const char *pkgid, uid_t uid)
238 {
239         FILE *fp = NULL;
240         app2ext_handle *handle = NULL;
241         char loopback_device[FILENAME_MAX] = { 0, };
242         char *encoded_id = NULL;
243
244         /* validate the function parameter received */
245         if (pkgid == NULL) {
246                 _E("invalid func parameters");
247                 return -1;
248         }
249
250         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
251         if (encoded_id == NULL)
252                 return -1;
253
254         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
255                 APP2SD_PATH, encoded_id);
256         free(encoded_id);
257
258         /* check whether application is in external memory or not */
259         fp = fopen(loopback_device, "r");
260         if (fp != NULL) {
261                 fclose(fp);
262                 fp = NULL;
263
264                 handle = app2ext_init(APP2EXT_SD_CARD);
265                 if (handle == NULL) {
266                         _E("app2ext init failed");
267                         return -1;
268                 }
269
270                 handle->interface.client_usr_disable(pkgid, uid);
271                 app2ext_deinit(handle);
272         }
273
274         return 0;
275 }
276
277 int app2ext_disable_external_pkg(const char *pkgid)
278 {
279         int ret = 0;
280
281         ret = app2ext_usr_disable_external_pkg(pkgid, getuid());
282
283         return ret;
284 }
285
286 int app2ext_enable_all_external_pkgs(void)
287 {
288         int ret = 0;
289         app2ext_handle *handle = NULL;
290
291         if (getuid() >= REGULAR_USER)
292                 return 0;
293
294         handle = app2ext_init(APP2EXT_SD_CARD);
295         if (handle == NULL) {
296                 _E("app2ext init failed");
297                 return -1;
298         }
299
300         ret = handle->interface.client_enable_full_pkg();
301         if (ret != 0)
302                 _E("failed to enable entire pkgs");
303
304         app2ext_deinit(handle);
305
306         return 0;
307 }
308
309 int app2ext_disable_all_external_pkgs(void)
310 {
311         int ret = 0;
312         app2ext_handle *handle = NULL;
313
314         if (getuid() >= REGULAR_USER)
315                 return 0;
316
317         handle = app2ext_init(APP2EXT_SD_CARD);
318         if (handle == NULL) {
319                 _E("app2ext init failed");
320                 return -1;
321         }
322
323         ret = handle->interface.client_disable_full_pkg();
324         if (ret != 0)
325                 _E("failed to disable entire pkgs");
326
327         app2ext_deinit(handle);
328
329         return 0;
330 }
331
332 int app2ext_usr_force_clean_pkg(const char *pkgid, uid_t uid)
333 {
334         app2ext_handle *handle = NULL;
335
336         /* validate the function parameter received */
337         if (pkgid == NULL) {
338                 _E("invalid func parameters");
339                 return -1;
340         }
341
342         handle = app2ext_init(APP2EXT_SD_CARD);
343         if (handle == NULL) {
344                 _E("app2ext init failed");
345                 return -1;
346         }
347
348         handle->interface.client_usr_force_clean(pkgid, uid);
349         app2ext_deinit(handle);
350
351         return 0;
352 }
353
354 int app2ext_force_clean_pkg(const char *pkgid)
355 {
356         int ret = 0;
357
358         ret = app2ext_usr_force_clean_pkg(pkgid, getuid());
359
360         return ret;
361 }