apply encoded name to the source file of losetup.
[platform/core/appfw/app2sd.git] / plugin / app2sd / src / app2sd_interface.c
1 /*
2  * app2ext
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Garima Shrivastava<garima.s@samsung.com>
7  *      Jyotsna Dhumale <jyotsna.a@samsung.com>
8  *      Venkatesha Sarpangala <sarpangala.v@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <app2sd_internals.h>
25 #include <app2sd_interface.h>
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/wait.h>
29 #include <pkgmgr-info.h>
30
31 static int __app2sd_create_app2sd_directories(uid_t uid)
32 {
33         int ret = 0;
34         mode_t mode = DIR_PERMS;
35
36         ret = mkdir(APP2SD_PATH, mode);
37         if (ret) {
38                 if (errno != EEXIST) {
39                         _E("create directory failed," \
40                                 " error no is (%d)", errno);
41                         return APP2EXT_ERROR_CREATE_DIRECTORY;
42                 }
43         }
44
45         return APP2EXT_SUCCESS;
46 }
47
48 int app2sd_usr_pre_app_install(const char *pkgid, GList* dir_list, int size, uid_t uid)
49 {
50         int ret = 0;
51         int free_mmc_mem = 0;
52         char *device_node = NULL;
53         char *devi = NULL;
54         char *result = NULL;
55         char application_path[FILENAME_MAX] = { 0, };
56         char loopback_device[FILENAME_MAX] = { 0, };
57         char *encoded_id = NULL;
58         int reqd_disk_size = size + ceil(size * 0.2);
59
60         /* validate the function parameter recieved */
61         if (pkgid == NULL || dir_list == NULL || size <= 0) {
62                 _E("invalid function arguments");
63                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
64         }
65
66         /* check whether MMC is present or not */
67         ret = _app2sd_check_mmc_status();
68         if (ret) {
69                 _E("MMC not preset OR Not ready (%d)", ret);
70                 return APP2EXT_ERROR_MMC_STATUS;
71         }
72
73         /* find available free memory in the MMC card */
74         ret = _app2sd_get_available_free_memory(MMC_PATH, &free_mmc_mem);
75         if (ret) {
76                 _E("unable to get available free memory in MMC (%d)",
77                         ret);
78                 return APP2EXT_ERROR_MMC_STATUS;
79         }
80         _D("size details for application installation:" \
81                 " size=(%d)MB, reqd_disk_size=(%d)MB, free_mmc_size=(%d)MB",
82                 size, reqd_disk_size, free_mmc_mem);
83
84         /* if avaialalbe free memory in MMC is less than required size + 5MB,
85          * return error
86          */
87         if ((reqd_disk_size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
88                 _E("insufficient memory in MMC for"
89                         " application installation (%d)", ret);
90                 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
91         }
92
93         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
94         if (encoded_id == NULL) {
95                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
96         }
97         if (_is_global(uid)) {
98                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
99                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
100                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
101                         APP2SD_PATH, encoded_id);
102         } else {
103                 tzplatform_set_user(uid);
104                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
105                         tzplatform_getenv(TZ_USER_APP), pkgid);
106                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
107                         APP2SD_PATH, encoded_id);
108                 tzplatform_reset_user();
109         }
110         free(encoded_id);
111         _D("application_path = (%s)", application_path);
112         _D("loopback_device = (%s)", loopback_device);
113
114         ret = __app2sd_create_app2sd_directories(uid);
115         if (ret) {
116                 _E("failed to create app2sd dirs");
117                 return ret;
118         }
119
120         /* check same loopback_device existence */
121         result = (char *)_app2sd_find_associated_device(loopback_device);
122         if (result != NULL) {
123                 _E("there is same associated File (%s)", loopback_device);
124                 return APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS;
125         }
126
127         /* create a loopback device */
128         ret = _app2sd_create_loopback_device(pkgid, loopback_device,
129                 (reqd_disk_size + PKG_BUF_SIZE));
130         if (ret) {
131                 _W("package already present, delete app directory");
132                 ret = _app2sd_delete_directory(application_path);
133                 if (ret) {
134                         _E("unable to delete the directory (%s)",
135                                 application_path);
136                         return ret;
137                 }
138         }
139
140         /* perform loopback encryption setup */
141         device_node = _app2sd_do_loopback_encryption_setup(pkgid,
142                 loopback_device, uid);
143         if (!device_node) {
144                 _E("loopback encryption setup failed");
145                 _app2sd_delete_loopback_device(loopback_device);
146                 return APP2EXT_ERROR_DO_LOSETUP;
147         }
148
149         /* check whether loopback device is associated
150          * with device node or not
151          */
152         devi = _app2sd_find_associated_device_node(loopback_device);
153         if (devi == NULL) {
154                 _E("finding associated device node failed");
155                 ret = APP2EXT_ERROR_DO_LOSETUP;
156                 goto FINISH_OFF;
157         }
158
159         /* format the loopback file system */
160         ret = _app2sd_create_file_system(device_node);
161         if (ret) {
162                 _E("creating FS failed failed");
163                 ret = APP2EXT_ERROR_CREATE_FS;
164                 goto FINISH_OFF;
165         }
166
167         /* mount the loopback encrypted pseudo device on application
168          * installation path as with Read Write permission
169          */
170         ret =_app2sd_mount_app_content(application_path, pkgid,
171                 device_node, MOUNT_TYPE_RW, dir_list,
172                 APP2SD_PRE_INSTALL, uid);
173         if (ret) {
174                 _E("mounting dev path to app install path failed");
175                 ret = APP2EXT_ERROR_MOUNT_PATH;
176                 goto FINISH_OFF;
177         }
178
179         /* Success */
180         ret = APP2EXT_SUCCESS;
181         goto END;
182
183 FINISH_OFF:
184         if (device_node) {
185                 result = _app2sd_detach_loop_device(device_node);
186                 if (result) {
187                         free(result);
188                         result = NULL;
189                 }
190                 _app2sd_delete_loopback_device(loopback_device);
191         }
192
193 END:
194         if (device_node) {
195                 free(device_node);
196                 device_node = NULL;
197         }
198
199         if (devi) {
200                 free(devi);
201                 devi = NULL;
202         }
203
204         return ret;
205 }
206
207 int app2sd_usr_post_app_install(const char *pkgid,
208                 app2ext_status install_status, uid_t uid)
209 {
210         char *device_name = NULL;
211         char application_path[FILENAME_MAX] = { 0, };
212         char loopback_device[FILENAME_MAX] = { 0, };
213         char *encoded_id = NULL;
214         int ret = APP2EXT_SUCCESS;
215         int pkgmgr_ret = 0;
216
217         /* validate the function parameter recieved */
218         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
219                 || install_status > APP2EXT_STATUS_SUCCESS) {
220                 _E("invalid func parameters");
221                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
222         }
223
224         /* check whether MMC is present or not */
225         ret = _app2sd_check_mmc_status();
226         if (ret) {
227                 _E("MMC not present OR Not ready (%d)", ret);
228                 return APP2EXT_ERROR_MMC_STATUS;
229         }
230         sync();
231
232         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
233         if (encoded_id == NULL) {
234                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
235         }
236         if (_is_global(uid)) {
237                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
238                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
239                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
240                         APP2SD_PATH, encoded_id);
241         } else {
242                 tzplatform_set_user(uid);
243                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
244                         tzplatform_getenv(TZ_USER_APP), pkgid);
245                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
246                         APP2SD_PATH, encoded_id);
247                 tzplatform_reset_user();
248         }
249         free(encoded_id);
250         _D("application_path = (%s)", application_path);
251         _D("loopback_device = (%s)", loopback_device);
252
253         /* get the associated device node for SD card applicationer */
254         device_name = _app2sd_find_associated_device_node(loopback_device);
255         if (NULL == device_name) {
256                 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
257         }
258
259         ret = _app2sd_unmount_app_content(application_path);
260         if (ret) {
261                 if (device_name) {
262                         free(device_name);
263                         device_name = NULL;
264                 }
265                 _E("unable to unmount the app content (%d)", ret);
266                 return APP2EXT_ERROR_UNMOUNT;
267         }
268
269         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
270         if (ret) {
271                 if (device_name) {
272                         free(device_name);
273                         device_name = NULL;
274                 }
275                 _E("unable to detach the loopback encryption setup" \
276                         " for the application");
277                 return APP2EXT_ERROR_UNMOUNT;
278         }
279
280         if (device_name) {
281                 free(device_name);
282                 device_name = NULL;
283         }
284
285         /* take appropriate action based on
286          * installation status of application package
287          */
288         if (install_status == APP2EXT_STATUS_FAILED) {
289                 /* delete the loopback device from the SD card */
290                 ret = _app2sd_delete_loopback_device(loopback_device);
291                 if (ret) {
292                         _E("unable to delete the loopback device from the SD Card");
293                         return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
294                 }
295                 ret = _app2sd_remove_password_from_db(pkgid);
296
297                 if (ret)
298                         _E("unable to delete the password");
299
300                 ret = _app2sd_delete_directory(application_path);
301
302                 if (ret)
303                         _E("unable to delete the directory (%s)", application_path);
304         } else {
305                 /* if the status is success, then update installed storage
306                  * to pkgmgr_parser db
307                  */
308                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
309                         INSTALL_EXTERNAL, uid);
310                 if (pkgmgr_ret < 0) {
311                         _E("fail to update installed location " \
312                                 "to db[%s, %d] of uid(%d), pkgmgr ret(%d)",
313                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
314                         return APP2EXT_ERROR_PKGMGR_ERROR;
315                 }
316         }
317
318         return ret;
319 }
320
321 int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
322 {
323         int ret = APP2EXT_SUCCESS;
324         char application_path[FILENAME_MAX] = { 0, };
325         char loopback_device[FILENAME_MAX] = { 0, };
326         char *encoded_id = NULL;
327         char *device_node = NULL;
328         char *result = NULL;
329         FILE *fp = NULL;
330
331         /* validate the function parameter recieved */
332         if (pkgid == NULL) {
333                 _E("invalid function arguments to app launch setup");
334                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
335         }
336
337         /* check whether MMC is present or not */
338         ret = _app2sd_check_mmc_status();
339         if (ret) {
340                 _E("MMC not preset OR Not ready (%d)", ret);
341                 return APP2EXT_ERROR_MMC_STATUS;
342         }
343
344         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
345         if (encoded_id == NULL) {
346                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
347         }
348         /* check app entry is there in sd card or not. */
349         if (_is_global(uid)) {
350                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
351                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
352                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
353                         APP2SD_PATH, encoded_id);
354         } else {
355                 tzplatform_set_user(uid);
356                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
357                         tzplatform_getenv(TZ_USER_APP), pkgid);
358                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
359                         APP2SD_PATH, encoded_id);
360                 tzplatform_reset_user();
361         }
362         free(encoded_id);
363         _D("application_path = (%s)", application_path);
364         _D("loopback_device = (%s)", loopback_device);
365
366         fp = fopen(loopback_device, "r+");
367         if (fp == NULL) {
368                 _E("app entry is not present in SD Card");
369                 return APP2EXT_ERROR_INVALID_PACKAGE;
370         }
371         fclose(fp);
372
373         result = (char *)_app2sd_find_associated_device(loopback_device);
374         /* process the string */
375         if ((result != NULL) && strstr(result, "/dev") != NULL) {
376                 _E("already associated");
377                 free(result);
378                 result = NULL;
379                 return APP2EXT_ERROR_ALREADY_MOUNTED;
380         }
381
382         /* do loopback setup */
383         device_node = _app2sd_do_loopback_encryption_setup(pkgid,
384                 loopback_device, uid);
385         if (device_node == NULL) {
386                 _E("loopback encryption setup failed");
387                 return APP2EXT_ERROR_DO_LOSETUP;
388         }
389
390         /* do mounting */
391         ret = _app2sd_mount_app_content(application_path, pkgid,
392                 device_node, MOUNT_TYPE_RD, NULL, APP2SD_APP_LAUNCH, uid);
393         if (ret) {
394                 _E("mount failed");
395                 if (device_node) {
396                         free(device_node);
397                         device_node = NULL;
398                 }
399                 return APP2EXT_ERROR_MOUNT_PATH;
400         }
401
402         if (device_node) {
403                 free(device_node);
404                 device_node = NULL;
405         }
406
407         return ret;
408 }
409
410 int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
411 {
412         int ret = APP2EXT_SUCCESS;
413         char application_path[FILENAME_MAX] = { 0, };
414         char loopback_device[FILENAME_MAX] = { 0, };
415         char *encoded_id = NULL;
416         FILE *fp = NULL;
417
418         /* validate the function parameter recieved */
419         if (pkgid == NULL) {
420                 _E("invalid function arguments to app launch setup");
421                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
422         }
423
424         /* check whether MMC is present or not */
425         ret = _app2sd_check_mmc_status();
426         if (ret) {
427                 _E("MMC not preset OR Not ready (%d)", ret);
428                 return APP2EXT_ERROR_MMC_STATUS;
429         }
430
431         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
432         if (encoded_id == NULL) {
433                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
434         }
435         /* check app entry is there in sd card or not. */
436         if (_is_global(uid)) {
437                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
438                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
439                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
440                         APP2SD_PATH, encoded_id);
441         } else {
442                 tzplatform_set_user(uid);
443                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
444                         tzplatform_getenv(TZ_USER_APP), pkgid);
445                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
446                         APP2SD_PATH, encoded_id);
447                 tzplatform_reset_user();
448         }
449         free(encoded_id);
450         _D("application_path = (%s)", application_path);
451         _D("loopback_device = (%s)", loopback_device);
452
453         fp = fopen(loopback_device, "r+");
454         if (fp == NULL) {
455                 _E("app entry is not present in SD Card");
456                 return APP2EXT_ERROR_INVALID_PACKAGE;
457         }
458         fclose(fp);
459
460         ret = _app2sd_unmount_app_content(application_path);
461         if (ret) {
462                 _E("unable to unmount the SD application");
463                 return APP2EXT_ERROR_UNMOUNT;
464         }
465
466         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
467         if (ret) {
468                 _E("unable to remove loopback setup");
469                 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
470         }
471
472         return ret;
473 }
474
475 int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
476 {
477         int ret = APP2EXT_SUCCESS;
478         char application_path[FILENAME_MAX] = { 0, };
479         char loopback_device[FILENAME_MAX] = { 0, };
480         char *encoded_id = NULL;
481         char *device_node = NULL;
482         FILE *fp = NULL;
483
484         /* validate the function parameter recieved */
485         if (pkgid == NULL) {
486                 _E("invalid function arguments to app launch setup");
487                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
488                 goto END;
489         }
490
491         /* check whether MMC is present or not */
492         ret = _app2sd_check_mmc_status();
493         if (ret) {
494                 _E("MMC not preset OR Not ready (%d)", ret);
495                 ret = APP2EXT_ERROR_MMC_STATUS;
496                 goto END;
497         }
498
499         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
500         if (encoded_id == NULL) {
501                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
502         }
503         if (_is_global(uid)) {
504                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
505                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
506                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
507                         APP2SD_PATH, encoded_id);
508         } else {
509                 tzplatform_set_user(uid);
510                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
511                         tzplatform_getenv(TZ_USER_APP), pkgid);
512                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
513                         APP2SD_PATH, encoded_id);
514                 tzplatform_reset_user();
515         }
516         free(encoded_id);
517         _D("application_path = (%s)", application_path);
518         _D("loopback_device = (%s)", loopback_device);
519
520         /* check app entry is there in sd card or not. */
521         fp = fopen(loopback_device, "r+");
522         if (fp == NULL) {
523                 _E("app entry is not present in SD Card");
524                 ret = APP2EXT_ERROR_INVALID_PACKAGE;
525                 goto END;
526         }
527         fclose(fp);
528
529         /* get the associated device node for SD card applicationer */
530         device_node = _app2sd_find_associated_device_node(loopback_device);
531         if (NULL == device_node) {
532                 /* do loopback setup */
533                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
534                         loopback_device, uid);
535                 if (device_node == NULL) {
536                         _E("loopback encryption setup failed");
537                         ret = APP2EXT_ERROR_DO_LOSETUP;
538                         goto END;
539                 }
540                 /* do mounting */
541                 ret = _app2sd_mount_app_content(application_path, pkgid,
542                         device_node, MOUNT_TYPE_RW, NULL,
543                         APP2SD_PRE_UNINSTALL, uid);
544                 if (ret) {
545                         _E("mount failed");
546                         if (device_node) {
547                                 free(device_node);
548                                 device_node = NULL;
549                         }
550                         ret = APP2EXT_ERROR_MOUNT_PATH;
551                         goto END;
552                 }
553         } else {
554                 /* do re-mounting */
555                 ret = _app2sd_mount_app_content(application_path, pkgid,
556                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
557                         APP2SD_PRE_UNINSTALL, uid);
558                 if (ret) {
559                         _E("remount failed");
560                         if (device_node) {
561                                 free(device_node);
562                                 device_node = NULL;
563                         }
564                         ret = APP2EXT_ERROR_MOUNT_PATH;
565                         goto END;
566                 }
567         }
568         if (device_node) {
569                 free(device_node);
570                 device_node = NULL;
571         }
572
573 END:
574         return ret;
575 }
576
577 int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
578 {
579         char application_path[FILENAME_MAX] = { 0, };
580         char loopback_device[FILENAME_MAX] = { 0, };
581         char *encoded_id = NULL;
582         int ret = APP2EXT_SUCCESS;
583
584         /* validate the function parameter recieved */
585         if (pkgid == NULL) {
586                 _E("invalid function arguments");
587                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
588                 goto END;
589         }
590
591         /* check whether MMC is present or not */
592         ret = _app2sd_check_mmc_status();
593         if (ret) {
594                 _E("MMC not preset OR Not ready (%d)", ret);
595                 ret = APP2EXT_ERROR_MMC_STATUS;
596                 goto END;
597         }
598
599         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
600         if (encoded_id == NULL) {
601                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
602         }
603         if (_is_global(uid)) {
604                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
605                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
606                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
607                         APP2SD_PATH, encoded_id);
608         } else {
609                 tzplatform_set_user(uid);
610                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
611                         tzplatform_getenv(TZ_USER_APP), pkgid);
612                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
613                         APP2SD_PATH, encoded_id);
614                 tzplatform_reset_user();
615         }
616         free(encoded_id);
617         _D("application_path = (%s)", application_path);
618         _D("loopback_device = (%s)", loopback_device);
619
620         /* unmount the loopback encrypted pseudo device from
621          * the application installation path
622          */
623         ret = _app2sd_unmount_app_content(application_path);
624         if (ret) {
625                 _E("unable to unmount the app content (%d)", ret);
626                 ret = APP2EXT_ERROR_UNMOUNT;
627                 goto END;
628         }
629         /* detach the loopback encryption setup for the application */
630         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
631         if (ret) {
632                 _E("unable to Detach the loopback encryption setup" \
633                         " for the application");
634                 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
635                 goto END;
636         }
637
638         /* delete the loopback device from the SD card */
639         ret = _app2sd_delete_loopback_device(loopback_device);
640         if (ret) {
641                 _E("unable to delete the " \
642                         "loopback device from the SD Card");
643                 ret =  APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
644                 goto END;
645         }
646
647         ret = _app2sd_delete_directory(application_path);
648         if (ret) {
649                 _E("unable to delete the directory (%s)",
650                 application_path);
651                 goto END;
652         }
653
654         /* remove encryption password from DB */
655         ret = _app2sd_initialize_db();
656         if (ret) {
657                 _E("app2sd db initialize failed");
658                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
659                 goto END;
660         }
661
662         ret = _app2sd_remove_password_from_db(pkgid);
663         if (ret) {
664                 _E("cannot remove password from db");
665                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
666                 goto END;
667         }
668
669 END:
670         return ret;
671 }
672
673 int app2sd_usr_move_installed_app(const char *pkgid, GList* dir_list,
674                 app2ext_move_type move_type, uid_t uid)
675 {
676         int ret = 0;
677         int pkgmgr_ret = 0;
678
679         /* validate function arguments */
680         if (pkgid == NULL || dir_list == NULL
681                 || move_type < APP2EXT_MOVE_TO_EXT
682                 || move_type > APP2EXT_MOVE_TO_PHONE) {
683                 _E("invalid function arguments");
684                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
685                 goto END;
686         }
687
688         pkgmgrinfo_pkginfo_h info_handle = NULL;
689         pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE;
690         pkgmgr_ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle);
691         if (pkgmgr_ret < 0) {
692                 _E("failed to get pkginfo for pkg(%s), uid(%d), pkgmgr_ret(%d)",
693                         pkgid, uid, pkgmgr_ret);
694         }
695         pkgmgr_ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
696         if (pkgmgr_ret < 0) {
697                 _E("failed to get installed storage for pkg(%s) of uid(%d), pkgmgr_ret(%d)",
698                         pkgid, uid, pkgmgr_ret);
699                 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
700                 goto END;
701         }
702
703         if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE)
704                 || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) {
705                         ret = APP2EXT_ERROR_PKG_EXISTS;
706                         _E("PKG_EXISTS in [%d] STORAGE", storage);
707                         pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
708                         goto END;
709         } else {
710                 _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage);
711         }
712         pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
713
714         ret = _app2sd_usr_move_app(pkgid, move_type, dir_list, uid);
715         if (ret) {
716                 _D("unable to move application");
717                 goto END;
718         }
719
720         /* if move is completed, then update installed storage to pkgmgr_parser db */
721         if (move_type == APP2EXT_MOVE_TO_EXT) {
722                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
723                                 INSTALL_EXTERNAL, uid);
724                 if (pkgmgr_ret < 0) {
725                         _E("failed to update installed location to db " \
726                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
727                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
728                         return APP2EXT_ERROR_PKGMGR_ERROR;
729                 }
730         } else {
731                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
732                                 INSTALL_INTERNAL, uid);
733                 if (pkgmgr_ret < 0) {
734                         _E("failed to update installed location to db " \
735                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
736                                 pkgid, INSTALL_INTERNAL, uid, pkgmgr_ret);
737                         return APP2EXT_ERROR_PKGMGR_ERROR;
738                 }
739         }
740
741 END:
742         _app2sd_make_result_info_file((char*)pkgid, ret, uid);
743
744         return ret;
745 }
746
747 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList* dir_list,
748                 int size, uid_t uid)
749 {
750         int ret = APP2EXT_SUCCESS;
751         char loopback_device[FILENAME_MAX] = { 0, };
752         char application_path[FILENAME_MAX] = { 0, };
753         char temp_uid[32] = { 0, };
754         char *temp_pkgid = NULL;
755         char *temp_loopback_device = NULL;
756         char *temp_application_path = NULL;
757         char *device_node = NULL;
758         char *encoded_id = NULL;
759         char *temp_encoded_id = NULL;
760         int len = 0;
761         unsigned long long curr_size = 0;
762         FILE *fp = NULL;
763         int reqd_disk_size = size + ceil(size * 0.2);
764
765         /* validate function arguments*/
766         if (pkgid == NULL || dir_list == NULL || size<=0) {
767                 _E("invalid function arguments");
768                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
769         }
770
771         /* check whether MMC is present or not */
772         ret = _app2sd_check_mmc_status();
773         if (ret) {
774                 _E("MMC not preset OR Not ready (%d)", ret);
775                 return APP2EXT_ERROR_MMC_STATUS;
776         }
777
778         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
779         if (encoded_id == NULL) {
780                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
781         }
782         if (_is_global(uid)) {
783                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
784                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
785                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
786                         APP2SD_PATH, encoded_id);
787         } else {
788                 tzplatform_set_user(uid);
789                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
790                         tzplatform_getenv(TZ_USER_APP), pkgid);
791                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
792                         APP2SD_PATH, encoded_id);
793                 tzplatform_reset_user();
794         }
795         free(encoded_id);
796         _D("application_path = (%s)", application_path);
797         _D("loopback_device = (%s)", loopback_device);
798
799         /* check app entry is there in sd card or not. */
800         fp = fopen(loopback_device, "r+");
801         if (fp == NULL) {
802                 _E("app entry is not present in SD Card");
803                 return APP2EXT_ERROR_INVALID_PACKAGE;
804         }
805         fclose(fp);
806
807         /* get installed app size*/
808         curr_size = _app2sd_calculate_file_size(loopback_device);
809         curr_size = (curr_size) / (1024 * 1024);
810         if (curr_size == 0) {
811                 _E("app entry is not present in SD Card");
812                 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
813         }
814         if ((int)curr_size < reqd_disk_size) {
815                 len = strlen(pkgid) + strlen(".new");
816                 temp_pkgid = calloc(len + 1, sizeof(char));
817                 if (temp_pkgid == NULL) {
818                         _E("memory alloc failed");
819                         return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
820                 }
821                 snprintf(temp_pkgid, len, "%s.new", pkgid);
822
823                 if (_is_global(uid)) {
824                         len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
825                         temp_application_path = calloc(len + 1, sizeof(char));
826                         if (temp_application_path == NULL) {
827                                 _E("memory alloc failed");
828                                 free(temp_pkgid);
829                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
830                         }
831                         snprintf(temp_application_path, len, "%s/%s",
832                                 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
833
834                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
835                         if (temp_encoded_id == NULL) {
836                                 free(temp_pkgid);
837                                 free(temp_application_path);
838                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
839                         }
840                         len = strlen(APP2SD_PATH) + strlen(temp_encoded_id) + 1;
841                         temp_loopback_device = calloc(len + 1, sizeof(char));
842                         if (temp_loopback_device == NULL) {
843                                 _E("memory alloc failed");
844                                 free(temp_pkgid);
845                                 free(temp_application_path);
846                                 free(temp_encoded_id);
847                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
848                         }
849                         snprintf(temp_loopback_device, len, "%s/%s",
850                                 APP2SD_PATH, temp_encoded_id);
851                         free(temp_encoded_id);
852                 } else {
853                         tzplatform_set_user(uid);
854                         len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
855                         temp_application_path = calloc(len + 1, sizeof(char));
856                         if (temp_application_path == NULL) {
857                                 _E("memory alloc failed");
858                                 free(temp_pkgid);
859                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
860                         }
861                         snprintf(temp_application_path, len, "%s/%s",
862                                 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
863
864                         temp_encoded_id = _app2sd_get_encoded_name((const char*)temp_pkgid, uid);
865                         if (temp_encoded_id == NULL) {
866                                 free(temp_pkgid);
867                                 free(temp_application_path);
868                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
869                         }
870                         snprintf(temp_uid, 32, "%d", uid);
871                         len = strlen(APP2SD_PATH) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
872                         temp_loopback_device = calloc(len + 1, sizeof(char));
873                         if (temp_loopback_device == NULL) {
874                                 _E("memory alloc failed");
875                                 free(temp_pkgid);
876                                 free(temp_application_path);
877                                 free(temp_encoded_id);
878                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
879                         }
880                         snprintf(temp_loopback_device, len, "%s/%s",
881                                 APP2SD_PATH, temp_encoded_id);
882                         free(temp_encoded_id);
883                         tzplatform_reset_user();
884                 }
885                 ret = _app2sd_update_loopback_device_size(pkgid,
886                         loopback_device, application_path, temp_pkgid,
887                         temp_loopback_device, temp_application_path,
888                         reqd_disk_size, dir_list, uid);
889                 free(temp_pkgid);
890                 free(temp_application_path);
891                 free(temp_loopback_device);
892                 if (APP2EXT_SUCCESS != ret) {
893                         _E("failed to update loopback device size");
894                         return ret;
895                 }
896         }
897
898         /* get the associated device node for SD card applicationer */
899         device_node = _app2sd_find_associated_device_node(loopback_device);
900         if (NULL == device_node) {
901                 /* do loopback setup */
902                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
903                         loopback_device, uid);
904                 if (device_node == NULL) {
905                         _E("loopback encryption setup failed");
906                         return APP2EXT_ERROR_DO_LOSETUP;
907                 }
908
909                 /* do mounting */
910                 ret = _app2sd_mount_app_content(application_path, pkgid,
911                         device_node, MOUNT_TYPE_RW, dir_list,
912                         APP2SD_PRE_UPGRADE, uid);
913                 if (ret) {
914                         _E("mount failed");
915                         if (device_node) {
916                                 free(device_node);
917                                 device_node = NULL;
918                         }
919                         return APP2EXT_ERROR_MOUNT_PATH;
920                 }
921         } else {
922                 /* do re-mounting */
923                 ret = _app2sd_mount_app_content(application_path, pkgid,
924                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
925                         APP2SD_PRE_UPGRADE, uid);
926                 if (ret) {
927                         _E("remount failed");
928                         if (device_node) {
929                                 free(device_node);
930                                 device_node = NULL;
931                         }
932                         return APP2EXT_ERROR_MOUNT_PATH;
933                 }
934         }
935
936         if (device_node) {
937                 free(device_node);
938                 device_node = NULL;
939         }
940         return ret;
941 }
942
943 int app2sd_usr_post_app_upgrade(const char *pkgid,
944                 app2ext_status install_status, uid_t uid)
945 {
946         char *device_name = NULL;
947         char loopback_device[FILENAME_MAX] = { 0, };
948         char application_path[FILENAME_MAX] = { 0, };
949         char *encoded_id = NULL;
950         int ret = APP2EXT_SUCCESS;
951
952         /* validate the function parameter recieved */
953         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
954                 || install_status > APP2EXT_STATUS_SUCCESS) {
955                 _E("invalid func parameters");
956                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
957         }
958
959         /* check whether MMC is present or not */
960         ret = _app2sd_check_mmc_status();
961         if (ret) {
962                 _E("MMC not preset OR Not ready (%d)", ret);
963                 return APP2EXT_ERROR_MMC_STATUS;
964         }
965
966         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
967         if (encoded_id == NULL) {
968                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
969         }
970         if (_is_global(uid)) {
971                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
972                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
973                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
974                         APP2SD_PATH, encoded_id);
975         } else {
976                 tzplatform_set_user(uid);
977                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
978                         tzplatform_getenv(TZ_USER_APP), pkgid);
979                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
980                         APP2SD_PATH, encoded_id);
981                 tzplatform_reset_user();
982         }
983         free(encoded_id);
984         _D("application_path = (%s)", application_path);
985         _D("loopback_device = (%s)", loopback_device);
986
987         /* get the associated device node for SD card applicationer */
988         device_name = _app2sd_find_associated_device_node(loopback_device);
989         if (NULL == device_name) {
990                 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
991         }
992
993         ret = _app2sd_unmount_app_content(application_path);
994         if (ret) {
995                 if (device_name) {
996                         free(device_name);
997                         device_name = NULL;
998                 }
999                 _E("unable to unmount the app content (%d)", ret);
1000                 return APP2EXT_ERROR_UNMOUNT;
1001         }
1002
1003         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1004         if (ret) {
1005                 if (device_name) {
1006                         free(device_name);
1007                         device_name = NULL;
1008                 }
1009                 _E("unable to detach the loopback encryption " \
1010                         "setup for the application");
1011                 return APP2EXT_ERROR_UNMOUNT;
1012         }
1013
1014         if (device_name) {
1015                 free(device_name);
1016                 device_name = NULL;
1017         }
1018
1019         return ret;
1020 }
1021
1022 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1023 {
1024         char loopback_device[FILENAME_MAX] = { 0, };
1025         char application_path[FILENAME_MAX] = { 0, };
1026         char *encoded_id = NULL;
1027         int ret = APP2EXT_SUCCESS;
1028
1029         _D("start force_clean [%s]", pkgid);
1030
1031         /* validate the function parameter recieved */
1032         if (pkgid == NULL) {
1033                 _E("invalid func parameters");
1034                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1035         }
1036
1037         sync();
1038
1039         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1040         if (encoded_id == NULL) {
1041                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1042         }
1043         if (_is_global(uid)) {
1044                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1045                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1046                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1047                         APP2SD_PATH, encoded_id);
1048         } else {
1049                 tzplatform_set_user(uid);
1050                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1051                         tzplatform_getenv(TZ_USER_APP), pkgid);
1052                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1053                         APP2SD_PATH, encoded_id);
1054                 tzplatform_reset_user();
1055         }
1056         free(encoded_id);
1057         _D("application_path = (%s)", application_path);
1058         _D("loopback_device = (%s)", loopback_device);
1059
1060         /* unmount the loopback encrypted pseudo device from the application installation path */
1061         ret = _app2sd_unmount_app_content(application_path);
1062         if (ret) {
1063                 _E("unable to unmount the app content (%d)", ret);
1064         }
1065
1066         /* detach the loopback encryption setup for the application */
1067         ret = _app2sd_remove_all_loopback_encryption_setups(pkgid);
1068         if (ret) {
1069                 _E("unable to detach the loopback encryption setup for the application");
1070         }
1071
1072         /* delete the loopback device from the SD card */
1073         ret = _app2sd_delete_loopback_device(loopback_device);
1074         if (ret) {
1075                 _E("unable to detach the loopback encryption setup for the application");
1076         }
1077
1078         /* delete symlink */
1079         _app2sd_delete_symlink(application_path);
1080
1081         /* remove passwrd from DB */
1082         ret = _app2sd_initialize_db();
1083         if (ret) {
1084                 _E("app2sd db initialize failed");
1085         }
1086         ret = _app2sd_remove_password_from_db(pkgid);
1087         if (ret) {
1088                 _E("cannot remove password from db");
1089         }
1090
1091         _D("finish force_clean");
1092
1093         return 0;
1094 }