89ec0cd8ae13717ca1ebbd894f91fa3b68508aaa
[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 int app2ext_usr_get_app_location(const char *pkgid, uid_t uid)
109 {
110         FILE *fp = NULL;
111         char loopback_device[FILENAME_MAX] = { 0, };
112         char application_path[FILENAME_MAX] = { 0, };
113         char application_mmc_path[FILENAME_MAX] = { 0, };
114         char *encoded_id = NULL;
115
116         /* validate the function parameter received */
117         if (pkgid == NULL) {
118                 _E("invalid func parameters");
119                 return -1;
120         }
121
122         if (_is_global(uid)) {
123                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
124                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
125                 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/%s/.mmc",
126                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
127         } else {
128                 tzplatform_set_user(uid);
129                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
130                         tzplatform_getenv(TZ_USER_APP), pkgid);
131                 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/%s/.mmc",
132                         tzplatform_getenv(TZ_USER_APP), pkgid);
133                 tzplatform_reset_user();
134         }
135         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
136         if (encoded_id == NULL)
137                 return -1;
138
139         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
140                 APP2SD_PATH, encoded_id);
141         free(encoded_id);
142
143         /* check whether application is in external memory or not */
144         fp = fopen(loopback_device, "r");
145         if (fp != NULL) {
146                 fclose(fp);
147                 fp = NULL;
148                 _D("sd card");
149                 return APP2EXT_SD_CARD;
150         }
151
152         /* check whether application is in internal or not */
153         fp = fopen(application_path, "r");
154         if (fp == NULL) {
155                 _D("app_dir_path open failed, " \
156                         "package not installed");
157                 return APP2EXT_NOT_INSTALLED;
158         } else {
159                 fclose(fp);
160                 /* check whether the application is installed in SD card
161                  * but SD card is not present
162                  */
163                 fp = fopen(application_mmc_path, "r");
164                 if (fp == NULL) {
165                         _D("internal mem");
166                         return APP2EXT_INTERNAL_MEM;
167                 } else {
168                         fclose(fp);
169                         _E("app_mmc_internal_path exists, " \
170                                 "error mmc status");
171                         return -1;
172                 }
173         }
174 }
175
176 int app2ext_get_app_location(const char *pkgid)
177 {
178         int ret = 0;
179
180         ret = app2ext_usr_get_app_location(pkgid, getuid());
181
182         return ret;
183 }
184
185 int app2ext_usr_enable_external_pkg(const char *pkgid, uid_t uid)
186 {
187         FILE *fp = NULL;
188         app2ext_handle *handle = NULL;
189         char loopback_device[FILENAME_MAX] = { 0, };
190         char *encoded_id = NULL;
191
192         /* validate the function parameter received */
193         if (pkgid == NULL) {
194                 _E("invalid func parameters");
195                 return -1;
196         }
197
198         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
199         if (encoded_id == NULL)
200                 return -1;
201
202         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
203                 APP2SD_PATH, encoded_id);
204         free(encoded_id);
205
206         /* check whether application is in external memory or not */
207         fp = fopen(loopback_device, "r");
208         if (fp != NULL) {
209                 fclose(fp);
210                 fp = NULL;
211
212                 handle = app2ext_init(APP2EXT_SD_CARD);
213                 if (handle == NULL) {
214                         _E("app2ext init failed");
215                         return -1;
216                 }
217
218                 handle->interface.client_usr_enable(pkgid, uid);
219                 app2ext_deinit(handle);
220         }
221
222         return 0;
223 }
224
225 int app2ext_enable_external_pkg(const char *pkgid)
226 {
227         int ret = 0;
228
229         ret = app2ext_usr_enable_external_pkg(pkgid, getuid());
230
231         return ret;
232 }
233
234 int app2ext_usr_disable_external_pkg(const char *pkgid, uid_t uid)
235 {
236         FILE *fp = NULL;
237         app2ext_handle *handle = NULL;
238         char loopback_device[FILENAME_MAX] = { 0, };
239         char *encoded_id = NULL;
240
241         /* validate the function parameter received */
242         if (pkgid == NULL || uid < 0) {
243                 _E("invalid func parameters");
244                 return -1;
245         }
246
247         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
248         if (encoded_id == NULL)
249                 return -1;
250
251         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
252                 APP2SD_PATH, encoded_id);
253         free(encoded_id);
254
255         /* check whether application is in external memory or not */
256         fp = fopen(loopback_device, "r");
257         if (fp != NULL) {
258                 fclose(fp);
259                 fp = NULL;
260
261                 handle = app2ext_init(APP2EXT_SD_CARD);
262                 if (handle == NULL) {
263                         _E("app2ext init failed");
264                         return -1;
265                 }
266
267                 handle->interface.client_usr_disable(pkgid, uid);
268                 app2ext_deinit(handle);
269         }
270
271         return 0;
272 }
273
274 int app2ext_disable_external_pkg(const char *pkgid)
275 {
276         int ret = 0;
277
278         ret = app2ext_usr_disable_external_pkg(pkgid, getuid());
279
280         return ret;
281 }
282
283 int app2ext_enable_external_full_pkg(void)
284 {
285         int ret = 0;
286         app2ext_handle *handle = NULL;
287
288         if (getuid() >= REGULAR_USER)
289                 return 0;
290
291         handle = app2ext_init(APP2EXT_SD_CARD);
292         if (handle == NULL) {
293                 _E("app2ext init failed");
294                 return -1;
295         }
296
297         ret = handle->interface.client_enable_full_pkg();
298         if (ret != 0)
299                 _E("failed to enable entire pkgs");
300
301         app2ext_deinit(handle);
302
303         return 0;
304 }
305
306 int app2ext_disable_external_full_pkg(void)
307 {
308         int ret = 0;
309         app2ext_handle *handle = NULL;
310
311         if (getuid() >= REGULAR_USER)
312                 return 0;
313
314         handle = app2ext_init(APP2EXT_SD_CARD);
315         if (handle == NULL) {
316                 _E("app2ext init failed");
317                 return -1;
318         }
319
320         ret = handle->interface.client_disable_full_pkg();
321         if (ret != 0)
322                 _E("failed to disable entire pkgs");
323
324         app2ext_deinit(handle);
325
326         return 0;
327 }
328
329 int app2ext_usr_force_clean_pkg(const char *pkgid, uid_t uid)
330 {
331         app2ext_handle *handle = NULL;
332
333         /* validate the function parameter received */
334         if (pkgid == NULL || uid < 0) {
335                 _E("invalid func parameters");
336                 return -1;
337         }
338
339         handle = app2ext_init(APP2EXT_SD_CARD);
340         if (handle == NULL) {
341                 _E("app2ext init failed");
342                 return -1;
343         }
344
345         handle->interface.client_usr_force_clean(pkgid, uid);
346         app2ext_deinit(handle);
347
348         return 0;
349 }
350
351 int app2ext_force_clean_pkg(const char *pkgid)
352 {
353         int ret = 0;
354
355         ret = app2ext_usr_force_clean_pkg(pkgid, getuid());
356
357         return ret;
358 }