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