Remove compile warning
[platform/core/appfw/app2sd.git] / plugin / app2sd / src / app2sd_internals.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
27 #include <sys/xattr.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <dirent.h>
34 #include <sys/stat.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <errno.h>
38 #include <openssl/sha.h>
39 #include <fcntl.h>
40 #include <time.h>
41 #include <dlog.h>
42 #include <privilege-control.h>
43 #include <sys/statvfs.h>
44
45 extern int app2sd_force_clean(const char *pkgid);
46
47 /*
48 ########### Internal APIs ##################
49
50 static int _app2sd_setup_path(const char *pkgid, const char *dirpath,
51                 int apppathtype, const char *groupid)
52 {
53         int ret = 0;
54
55         if (groupid == NULL) {
56                 ret = perm_app_setup_path(pkgid, dirpath, apppathtype);
57                 app2ext_print( "[smack] app_setup_path(), result = [%d]", ret);
58         } else {
59                 ret = perm_app_setup_path(pkgid, dirpath, apppathtype, groupid);
60                 app2ext_print( "[smack] app_setup_path(), result = [%d]", ret);
61         }
62
63         return ret;
64 }
65 */
66
67 /*
68 static int _app2sd_apply_app_smack(const char *pkgid, GList* dir_list, const char *groupid)
69 {
70         int ret = APP2EXT_SUCCESS;
71         GList *list = NULL;
72         app2ext_dir_details* dir_detail = NULL;
73         char path[FILENAME_MAX] = { 0, };
74
75         list = g_list_first(dir_list);
76         while (list) {
77                 dir_detail = (app2ext_dir_details *)list->data;
78                 if (dir_detail && dir_detail->name
79                         && dir_detail->type == APP2EXT_DIR_RO) {
80                         snprintf(path, FILENAME_MAX, "%s%s/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
81                         ret = _app2sd_setup_path(pkgid, path, PERM_APP_PATH_ANY_LABEL, groupid);
82                         if (ret) {
83                                 app2ext_print ("App2Sd Error : unable to smack %s\n", path);
84                                 return APP2EXT_ERROR_MOVE;
85                         }
86                 }
87                 list = g_list_next(list);
88         }
89
90         return APP2EXT_SUCCESS;
91 }
92 */
93
94 /*
95 static int _app2sd_apply_mmc_smack(const char *pkgid, GList* dir_list, const char *groupid)
96 {
97         int ret = APP2EXT_SUCCESS;
98         GList *list = NULL;
99         app2ext_dir_details* dir_detail = NULL;
100         char path[FILENAME_MAX] = { 0, };
101
102         list = g_list_first(dir_list);
103         while (list) {
104                 dir_detail = (app2ext_dir_details *)list->data;
105                 if (dir_detail && dir_detail->name
106                         && dir_detail->type == APP2EXT_DIR_RO) {
107                         snprintf(path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
108
109                         ret = _app2sd_setup_path(pkgid, path, PERM_APP_PATH_ANY_LABEL, groupid);
110                         if (ret) {
111                                 app2ext_print ("App2Sd Error : unable to smack %s\n", path);
112                                 return APP2EXT_ERROR_MOVE;
113                         }
114                 }
115                 list = g_list_next(list);
116         }
117
118         return APP2EXT_SUCCESS;
119 }
120 */
121
122 char *_app2sd_find_associated_device_node(const char *pkgid)
123 {
124         char *ret_result = NULL;
125         char delims[] = ":";
126         char *result = NULL;
127         char app_path[FILENAME_MAX] = { '\0' };
128         char dev[FILENAME_MAX] = {0,};
129         char *devnode = NULL;
130         snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
131                  pkgid);
132         app2ext_print("sdcard app_path = (%s)\n", app_path);
133         result = (char *)_app2sd_find_associated_device(app_path);
134         if (result == NULL) {
135                 app2ext_print("App2SD info! there is no the associated File with [%s]\n", pkgid);
136                 return NULL;
137         }
138         /* process the string*/
139         app2ext_print("result = (%s)\n", result);
140         snprintf(dev, FILENAME_MAX-1, "%s", result);
141         if (strstr(dev, "/dev") == NULL) {
142                 app2ext_print("App2SD Error! Unable to find the associated File\n");
143
144                 free(result);
145                 return NULL;
146         } else {
147                 char *saveptr = NULL;
148                 ret_result = strtok_r(dev, delims, &saveptr);
149                 if (ret_result)
150                         devnode = strdup(ret_result);
151         }
152         free(result);
153         return devnode;
154 }
155
156 char *_app2sd_create_loopdevice_node(void)
157 {
158         char *ret_result = NULL;
159         mode_t mode = DIR_PERMS;
160         int count = 0;
161         int ret = APP2EXT_SUCCESS;
162         char *result = NULL;
163         FILE *fp = NULL;
164
165         result = (char *)_app2sd_find_free_device();
166         /* validate the result */
167         if (result == NULL || strstr(result, "/dev") == NULL) {
168                 app2ext_print("No device found, creating device node...\n");
169
170                 if (result) {
171                         free(result);
172                         result = NULL;
173                 }
174                 count = 0;
175                 char dev_path[BUF_SIZE] = { 0, };
176                 snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
177                 while ((fp = fopen(dev_path, "r+")) != NULL) {
178                         count = count + 1;
179                         snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
180                         app2ext_print("next dev path for checking is %s\n",
181                                      dev_path);
182                         fclose(fp);
183                 }
184                 app2ext_print("Device node candidate is %s \n", dev_path);
185                 dev_t dev_node;
186                 dev_node = makedev(DEV_MAJOR, count);
187                 ret = mknod(dev_path, S_IFBLK | mode, dev_node);
188                 if (ret < 0) {
189                         app2ext_print
190                             ("Error while creating the device node: errno is %d\n",
191                              errno);
192                         return NULL;
193                 }
194                 ret_result = (char *)malloc(strlen(dev_path) + 1);
195                 if (ret_result == NULL) {
196                         app2ext_print("Unable to allocate memory\n");
197                         return NULL;
198                 }
199                 memset(ret_result, '\0', strlen(dev_path) + 1);
200                 memcpy(ret_result, dev_path, strlen(dev_path));
201         } else {
202                 ret_result = (char *)malloc(strlen(result) + 1);
203                 if (ret_result == NULL) {
204                         app2ext_print("Malloc failed!\n");
205                         free(result);
206                         result = NULL;
207                         return NULL;
208                 }
209                 memset(ret_result, '\0', strlen(result) + 1);
210                 if (strlen(result) > 0) {
211                         memcpy(ret_result, result, strlen(result) - 1);
212                 }
213                 free(result);
214                 result = NULL;
215
216         }
217         return ret_result;
218 }
219
220 char *_app2sd_do_loopback_encryption_setup(const char *pkgid)
221 {
222         int ret = APP2EXT_SUCCESS;
223         char *passwd = NULL;
224         char app_path[FILENAME_MAX] = { '\0' };
225         char *result = NULL;
226         char *device_node = NULL;
227         if (pkgid == NULL) {
228                 app2ext_print("App2Sd Error: Invalid argument\n");
229                 return NULL;
230         }
231
232         snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
233                  pkgid);
234         /* Get password for loopback encryption */
235         ret = _app2sd_initialize_db();
236         if (ret) {
237                 app2ext_print("\n app2sd db initialize failed");
238                 return NULL;
239         }
240         if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
241                 passwd = (char *)_app2sd_generate_password(pkgid);
242                 if (NULL == passwd) {
243                         app2ext_print
244                             ("App2Sd Error: Unable to generate password\n");
245                         return NULL;
246                 } else {
247                         app2ext_print("Password is %s\n", passwd);
248                         if ((ret = _app2sd_set_password_in_db(pkgid,
249                                         passwd)) < 0) {
250                                 app2ext_print
251                                 ("App2Sd Error: Unable to save password\n");
252                                 free(passwd);
253                                 passwd = NULL;
254                                 return NULL;
255                         }
256                 }
257         }
258
259         /* Get Free device node*/
260         device_node = _app2sd_create_loopdevice_node();
261         if (NULL == device_node) {
262                 free(passwd);
263                 passwd = NULL;
264                 app2ext_print
265                     ("App2Sd Error: Unable to find free loopback node\n");
266                 return NULL;
267         }
268         result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
269         if (result == NULL) {
270                 app2ext_print("App2Sd Error: Encryption failed!\n\n");
271                 free(passwd);
272                 passwd = NULL;
273                 return NULL;
274         } else {
275                 free(result);
276                 result = NULL;
277                 free(passwd);
278                 passwd = NULL;
279                 return device_node;
280         }
281 }
282
283 char *_app2sd_do_loopback_duplicate_encryption_setup(const char *pkgid, const char * dup_appname)
284 {
285         int ret = APP2EXT_SUCCESS;
286         char *passwd = NULL;
287         char app_path[FILENAME_MAX] = { '\0' };
288         char *result = NULL;
289         char *device_node = NULL;
290         if (pkgid == NULL || dup_appname == NULL) {
291                 app2ext_print("App2Sd Error: Invalid argument\n");
292                 return NULL;
293         }
294
295         snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
296                  dup_appname);
297         /* Get password for loopback encryption */
298         ret = _app2sd_initialize_db();
299         if (ret) {
300                 app2ext_print("\n app2sd db initialize failed");
301                 return NULL;
302         }
303         if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
304                 passwd = (char *)_app2sd_generate_password(pkgid);
305                 if (NULL == passwd) {
306                         app2ext_print
307                             ("App2Sd Error: Unable to generate password\n");
308                         return NULL;
309                 } else {
310                         app2ext_print("Password is %s\n", passwd);
311                         if ((ret = _app2sd_set_password_in_db(pkgid,
312                                         passwd)) < 0) {
313                                 app2ext_print
314                                 ("App2Sd Error: Unable to save password\n");
315                                 free(passwd);
316                                 passwd = NULL;
317                                 return NULL;
318                         }
319                 }
320
321         }
322         /* Get Free device node*/
323         device_node = _app2sd_create_loopdevice_node();
324         if (NULL == device_node) {
325                 free(passwd);
326                 passwd = NULL;
327                 app2ext_print
328                     ("App2Sd Error: Unable to find free loopback node\n");
329                 return NULL;
330         }
331         result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
332         if (result == NULL) {
333                 app2ext_print("App2Sd Error: Encryption failed!\n\n");
334                 free(passwd);
335                 passwd = NULL;
336                 return NULL;
337         } else {
338                 if (strlen(result) == 0) {
339                         free(result);
340                         result = NULL;
341                         free(passwd);
342                         passwd = NULL;
343                         return device_node;
344                 } else {
345                         app2ext_print("App2Sd Error: Error is %s\n", result);
346                         free(result);
347                         result = NULL;
348                         free(passwd);
349                         passwd = NULL;
350                         return NULL;
351                 }
352         }
353         return device_node;
354 }
355
356 int _app2sd_remove_loopback_encryption_setup(const char *pkgid)
357 {
358         int ret = APP2EXT_SUCCESS;
359         char *result = NULL;
360         char *dev_node = NULL;
361         if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
362                 app2ext_print("Unable to find the association\n");
363                 ret = APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
364         }
365         result = (char *)_app2sd_detach_loop_device(dev_node);
366         if (result == NULL) {
367                 app2ext_print("App2sd Error: Error in detaching\n");
368                 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
369         } else {
370                 free(result);
371                 result = NULL;
372         }
373         if (dev_node) {
374                 free(dev_node);
375                 dev_node = NULL;
376         }
377         return ret;
378 }
379
380 int _app2sd_remove_all_loopback_encryption_setups(const char *pkgid)
381 {
382         int ret = APP2EXT_SUCCESS;
383         char *result = NULL;
384         char *dev_node = NULL;
385         while(1) {
386                 if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
387                         app2ext_print("finish to find the association\n");
388                         ret = APP2EXT_SUCCESS;
389                         break;
390                 }
391
392                 app2ext_print("find node ::  %s \n", dev_node);
393
394                 result = (char *)_app2sd_detach_loop_device(dev_node);
395                 if (result == NULL) {
396                         app2ext_print("App2sd Error: Error in detaching\n");
397                         ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
398                         break;
399                 } else {
400                         free(result);
401                         result = NULL;
402                 }
403                 if (dev_node) {
404                         free(dev_node);
405                         dev_node = NULL;
406                 }
407         }
408         return ret;
409 }
410
411 int _app2sd_create_loopback_device(const char *pkgid, int size)
412 {
413         int ret = APP2EXT_SUCCESS;
414         char command[FILENAME_MAX] = { 0, };
415         mode_t mode = DIR_PERMS;
416         char external_storage_path[FILENAME_MAX] = { 0, };
417         char buff[BUF_SIZE] = { 0, };
418         char app_path[FILENAME_MAX] = { 0, };
419         FILE *fp = NULL;
420
421         if (NULL == pkgid || size <= 0) {
422                 app2ext_print("App2Sd Error: Invalid argument\n");
423                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
424         }
425         snprintf(command, FILENAME_MAX, "of=%s%s", APP2SD_PATH,
426                  pkgid);
427         snprintf(buff, BUF_SIZE, "count=%d", size);
428         const char *argv1[] =
429             { "dd", "if=/dev/zero", command, "bs=1M", buff, NULL };
430         snprintf(external_storage_path, FILENAME_MAX, "%s",
431                  APP2SD_PATH);
432         ret = mkdir(external_storage_path, mode);
433         if (ret) {
434                 if (errno != EEXIST) {
435                         app2ext_print
436                             ("App2sd Error : Create directory failed, error no is %d\n",
437                              errno);
438                         return APP2EXT_ERROR_CREATE_DIRECTORY;
439                 }
440         }
441         snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
442                  pkgid);
443         if ((fp = fopen(app_path, "r+")) != NULL) {
444                 app2ext_print("Application already exists %s\n", app_path);
445                 fclose(fp);
446                 return APP2EXT_ERROR_PKG_EXISTS;
447         }
448
449         ret = _xsystem(argv1);
450         if (ret) {
451                 app2ext_print("App2Sd Error : command \"%s\" failed \n",
452                              command);
453                 return ret;
454         }
455         return ret;
456 }
457
458 int _app2sd_delete_loopback_device(const char *pkgid)
459 {
460         int ret = APP2EXT_SUCCESS;
461         char loopback_device[FILENAME_MAX] = { 0, };
462
463         snprintf(loopback_device, FILENAME_MAX, "%s%s", APP2SD_PATH,
464                  pkgid);
465
466         ret = unlink(loopback_device);
467         if (ret) {
468                 if (errno == ENOENT) {
469                         app2ext_print("Unable to access file %s\n", loopback_device);
470                 } else {
471                         app2ext_print("Unable to delete %s\n", loopback_device);
472                         return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
473                 }
474         }
475         return ret;
476 }
477
478 int _app2sd_create_file_system(const char *device_path)
479 {
480         int ret = APP2EXT_SUCCESS;
481         FILE *fp = NULL;
482         char err_buf[1024] = {0,};
483
484         if (device_path == NULL) {
485                 app2ext_print("App2Sd Error: invalid param [NULL]\n");
486                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
487         }
488
489         /* Format the filesystem [create a filesystem]*/
490         const char *argv[] = { "/sbin/mkfs.ext4", device_path, NULL };
491         fp = fopen(device_path, "r+");
492         if (fp == NULL) {
493                 strerror_r(errno, err_buf, sizeof(err_buf));
494                 app2ext_print
495                     ("App2sd Error: Unable to access %s [System errono is %d.....%s]\n",
496                      device_path, errno, err_buf);
497                 return APP2EXT_ERROR_ACCESS_FILE;
498         } else {
499                 fclose(fp);
500         }
501         ret = _xsystem(argv);
502         if (ret) {
503                 strerror_r(errno, err_buf, sizeof(err_buf));
504                 app2ext_print
505                     ("App2Sd Error : creating file system failed [System error is %s\n",
506                      err_buf);
507                 return APP2EXT_ERROR_CREATE_FS;
508         }
509         return ret;
510 }
511
512 static int _app2sd_create_dir_with_link(const char *pkgid,
513                                          const char *dir_name)
514 {
515         mode_t mode = DIR_PERMS;
516         int ret = APP2EXT_SUCCESS;
517         char app_dir_mmc_path[FILENAME_MAX] = { 0, };
518         char app_dir_path[FILENAME_MAX] = { 0, };
519         snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH,
520                  pkgid, dir_name);
521         snprintf(app_dir_path, FILENAME_MAX, "%s%s/%s", APP_INSTALLATION_PATH, pkgid,
522                  dir_name);
523
524         ret = mkdir(app_dir_mmc_path, mode);
525         if (ret) {
526                 if (errno != EEXIST) {
527                         app2ext_print
528                             ("App2sd Error : Create directory failed, error no is %d\n",
529                              errno);
530                         return APP2EXT_ERROR_CREATE_DIRECTORY;
531                 }
532         }
533
534         if ((ret = symlink(app_dir_mmc_path, app_dir_path)) < 0) {
535                 if (errno == EEXIST) {
536                         app2ext_print
537                             ("App2sd : File with Symlink name present %s\n",
538                              app_dir_path);
539                 } else {
540                         app2ext_print
541                             ("A2Sd Error : Symbolic link creation failed, error no is %d\n",
542                              errno);
543                         return APP2EXT_ERROR_CREATE_SYMLINK;
544                 }
545         }
546
547         /* TODO */
548         /*
549         ret = _app2sd_setup_path(pkgid, app_dir_path, PERM_APP_PATH_ANY_LABEL, pkgid);
550         if (ret) {
551                 app2ext_print ("App2Sd Error : unable to smack %s\n", app_dir_path);
552                 return APP2EXT_ERROR_MOVE;
553         }
554
555         ret = _app2sd_setup_path(pkgid, app_dir_mmc_path, PERM_APP_PATH_ANY_LABEL, pkgid);
556         if (ret) {
557                 app2ext_print ("App2Sd Error : unable to smack %s\n", app_dir_mmc_path);
558                 return APP2EXT_ERROR_MOVE;
559         }
560         */
561
562         return ret;
563 }
564
565 int _app2sd_create_directory_entry(const char *pkgid, GList* dir_list)
566 {
567         int ret = APP2EXT_SUCCESS;
568         char app_dir_path[FILENAME_MAX] = { 0, };
569         GList *list = NULL;
570         app2ext_dir_details* dir_detail = NULL;
571
572         snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH,
573                  pkgid);
574
575         list = g_list_first(dir_list);
576         while (list) {
577                 dir_detail = (app2ext_dir_details *)list->data;
578                 if (dir_detail && dir_detail->name
579                         && dir_detail->type == APP2EXT_DIR_RO) {
580                         ret = _app2sd_create_dir_with_link(pkgid, dir_detail->name);
581                         if (ret) {
582                                 return ret;
583                         }
584                 }
585                 list = g_list_next(list);
586         }
587         return APP2EXT_SUCCESS;
588 }
589
590
591 /*
592  *
593  * _app2sd_mount_app_content
594  This function is to create the path for mmc and mount the content
595 Example usage: _app2sd_mount_app_content("deb.com.samsung.helloworld","/dev/loop0",MOUNT_TYPE_RD)
596 */
597 int _app2sd_mount_app_content(const char *pkgid, const char *dev,
598                         int mount_type, GList* dir_list, app2sd_cmd cmd)
599 {
600         int ret = APP2EXT_SUCCESS;
601         mode_t mode = DIR_PERMS;
602         char app_dir_path[FILENAME_MAX] = { 0, };
603         char app_dir_mmc_path[FILENAME_MAX] = { 0, };
604         struct timespec time = {
605                 .tv_sec = 0,
606                 .tv_nsec = 1000 * 1000 * 200
607         };
608
609         if (NULL == pkgid || NULL == dev) {
610                 app2ext_print("App2Sd Error : Input param is NULL %s %s \n",
611                              pkgid, dev);
612                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
613         }
614         snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
615         ret = mkdir(app_dir_path, mode);
616         if (ret) {
617                 if (errno != EEXIST) {
618                         app2ext_print
619                             ("App2Sd Error : Create directory failed, error no is %d\n",
620                              errno);
621                         return APP2EXT_ERROR_CREATE_DIRECTORY;
622                 }
623         }
624         snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
625         ret = mkdir(app_dir_mmc_path, mode);
626         if (ret) {
627                 if (errno != EEXIST) {
628                         app2ext_print
629                             ("App2Sd Error : Create directory failed, error no is %d\n",
630                              errno);
631                         return APP2EXT_ERROR_CREATE_DIRECTORY;
632                 }
633         }
634
635         nanosleep(&time, NULL); /* 200ms sleep */
636         app2ext_print ("App2Sd info : give a delay for mount\n");
637
638         switch (mount_type) {
639         case MOUNT_TYPE_RD:
640                 {
641                         if ((ret =
642                              mount(dev, app_dir_mmc_path, FS_TYPE,
643                                    MS_MGC_VAL | MS_RDONLY | MS_NOSUID, NULL)) < 0) {
644                                 app2ext_print
645                                     ("App2Sd Error : Read Only Mount failed [System Erro no is %d], dev is %s path is %s\n",
646                                      errno, dev, app_dir_mmc_path);
647                                 ret = APP2EXT_ERROR_MOUNT;
648                         }
649                         break;
650                 }
651         case MOUNT_TYPE_RW:
652                 {
653                         if ((ret =
654                              mount(dev, app_dir_mmc_path, FS_TYPE, MS_MGC_VAL | MS_NOSUID,
655                                    NULL)) < 0) {
656                                 app2ext_print
657                                     ("App2Sd Error : Read Write Mount failed [System Erro no is %d]\n",
658                                      errno);
659                                 ret = APP2EXT_ERROR_MOUNT;
660                         }
661                         break;
662                 }
663         case MOUNT_TYPE_RW_NOEXEC:
664                 {
665                         if ((ret =
666                              mount(dev, app_dir_mmc_path, FS_TYPE,
667                                    MS_MGC_VAL | MS_NOEXEC | MS_NOSUID, NULL)) < 0) {
668                                 app2ext_print
669                                     ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
670                                      errno);
671                                 ret = APP2EXT_ERROR_MOUNT;
672                         }
673                         break;
674                 }
675         case MOUNT_TYPE_RD_REMOUNT:
676                 {
677                         if ((ret =
678                              mount(dev, app_dir_mmc_path, FS_TYPE,
679                                    MS_MGC_VAL | MS_RDONLY | MS_REMOUNT | MS_NOSUID,
680                                    NULL)) < 0) {
681                                 app2ext_print
682                                     ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
683                                      errno);
684                                 ret = APP2EXT_ERROR_MOUNT;
685                         }
686                         break;
687                 }
688         case MOUNT_TYPE_RW_REMOUNT:
689                 {
690                         if ((ret =
691                              mount(dev, app_dir_mmc_path, FS_TYPE,
692                                    MS_MGC_VAL | MS_REMOUNT | MS_NOSUID, NULL)) < 0) {
693                                 app2ext_print
694                                     ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
695                                      errno);
696                                 ret = APP2EXT_ERROR_MOUNT;
697                         }
698                         break;
699                 }
700
701         default:
702                 {
703                         app2ext_print("App2Sd Error: Invalid mount type\n");
704                         break;
705                 }
706         }
707         if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC || cmd == APP2SD_PRE_UPGRADE) {
708                 ret = _app2sd_create_directory_entry(pkgid, dir_list);
709         }
710         return ret;
711 }
712
713 int _app2sd_unmount_app_content(const char *pkgid)
714 {
715         int ret = APP2EXT_SUCCESS;
716         char app_dir_mmc_path[FILENAME_MAX] = { 0, };
717
718         snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
719         if ((ret = umount(app_dir_mmc_path)) < 0) {
720                 char err_buf[1024] = {0,};
721                 strerror_r(errno, err_buf, sizeof(err_buf));
722                 app2ext_print("Unable to umount the dir %s\n", err_buf);
723         }
724         return ret;
725 }
726
727 static int _app2sd_move_to_archive(const char *src_path, const char *arch_path)
728 {
729         int ret = APP2EXT_SUCCESS;
730
731         ret = _app2sd_copy_dir(src_path, arch_path);
732         if (ret && ret != APP2EXT_ERROR_ACCESS_FILE) {
733                 char err_buf[1024] = {0,};
734                 strerror_r(errno, err_buf, sizeof(err_buf));
735                 app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
736                                 src_path, arch_path, err_buf);
737                 return APP2EXT_ERROR_MOVE;
738         }
739
740         ret = _app2sd_delete_directory((char *)src_path);
741         if (ret && ret != APP2EXT_ERROR_ACCESS_FILE) {
742                 app2ext_print("App2Sd Error : unable to delete %s \n", src_path);
743                 return APP2EXT_ERROR_DELETE_DIRECTORY;
744         }
745
746         return ret;
747 }
748
749 int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
750 {
751         int ret = APP2EXT_SUCCESS;
752         char app_path[FILENAME_MAX] = { 0, };
753         char path[FILENAME_MAX] = { 0, };
754         char app_mmc_path[FILENAME_MAX] = { 0, };
755         char app_archive_path[FILENAME_MAX] = { 0, };
756         char mmc_path[FILENAME_MAX] = { 0, };
757         unsigned long long total_size = 0;
758         int reqd_size = 0;
759         int reqd_disk_size = 0;
760         char *device_node = NULL;
761         char *devi = NULL;
762         mode_t mode = DIR_PERMS;
763         int free_mmc_mem = 0;
764         FILE *fp = NULL;
765         GList *list = NULL;
766         app2ext_dir_details* dir_detail = NULL;
767
768         /* Check whether MMC is present or not */
769         ret = _app2sd_check_mmc_status();
770         if (ret) {
771                 app2ext_print
772                     ("App2Sd Error : MMC not preset OR Not ready %d\n",
773                      ret);
774                 return APP2EXT_ERROR_MMC_STATUS;
775         }
776
777         snprintf(mmc_path, FILENAME_MAX,
778                  "%s%s", APP2SD_PATH, pkgid);
779
780         /* check whether application is in external memory or not */
781         fp = fopen(mmc_path, "r+");
782         if (fp != NULL) {
783                 app2ext_print
784                     ("Already %s entry is present in the SD Card, delete entry and go on without return\n",
785                      pkgid);
786                 fclose(fp);
787                 app2sd_force_clean(pkgid);
788         }
789
790         snprintf(app_mmc_path, FILENAME_MAX,
791                  "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
792         snprintf(app_archive_path, FILENAME_MAX,
793                  "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
794
795         ret = mkdir(app_archive_path, mode);
796         if (ret) {
797                 if (errno != EEXIST) {
798                         app2ext_print
799                             ("App2sd Error: Unable to create directory for archiving, error no is %d\n",
800                              errno);
801                 }
802         }
803
804         list = g_list_first(dir_list);
805         while (list) {
806                 dir_detail = (app2ext_dir_details *)list->data;
807                 if (dir_detail && dir_detail->name
808                         && dir_detail->type == APP2EXT_DIR_RO) {
809                         memset((void *)&app_path, '\0',
810                                FILENAME_MAX);
811                         snprintf(app_path, FILENAME_MAX,
812                                  "%s%s/%s",APP_INSTALLATION_PATH,
813                                  pkgid,
814                                  dir_detail->name);
815                         total_size +=
816                             _app2sd_calculate_dir_size
817                             (app_path);
818                 }
819                 list = g_list_next(list);
820         }
821
822         reqd_size = ((total_size)/( 1024 * 1024)) + 2;
823         reqd_disk_size = reqd_size + ceil(reqd_size * 0.2);
824
825         /* Find avialable free memory in the MMC card */
826         ret =
827             _app2sd_get_available_free_memory
828             (MMC_PATH, &free_mmc_mem);
829         if (ret) {
830                 app2ext_print
831                     ("App2Sd Error : Unable to get available free memory in MMC %d\n",
832                      ret);
833                 return APP2EXT_ERROR_MMC_STATUS;
834         }
835         /* If avaialalbe free memory in MMC is less than required size + 5MB , return error */
836         if (reqd_disk_size > free_mmc_mem) {
837                 app2ext_print
838                     ("App2Sd Error : Insufficient memory in MMC for application installation %d\n",
839                      ret);
840                 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
841         }
842         /* Create a loopback device */
843         ret =
844             _app2sd_create_loopback_device(pkgid, (reqd_disk_size+PKG_BUF_SIZE));
845         if (ret) {
846                 app2ext_print
847                     ("App2Sd Error : loopback node creation failed\n");
848         }
849         /* Perform Loopback encryption setup */
850         device_node =
851             _app2sd_do_loopback_encryption_setup(pkgid);
852         if (!device_node) {
853                 app2ext_print
854                     ("App2Sd Error : losetup failed, device node is %s\n",
855                      device_node);
856                 return APP2EXT_ERROR_DO_LOSETUP;
857         }
858         /* Check whether loopback device is associated with device node or not */
859         devi = _app2sd_find_associated_device_node(pkgid);
860         if (devi == NULL) {
861                 app2ext_print
862                     ("App2Sd Error :  _app2sd_find_associated_device_node  losetup failed\n");
863                 return APP2EXT_ERROR_DO_LOSETUP;
864         } else {
865                 free(devi);
866                 devi = NULL;
867         }
868         /* Format the loopback file system */
869         ret = _app2sd_create_file_system(device_node);
870         if (ret) {
871                 app2ext_print
872                     ("App2Sd Error : create ext4 filesystem failed\n");
873                 return APP2EXT_ERROR_CREATE_FS;
874         }
875         /********Archiving code begin***********/
876         list = g_list_first(dir_list);
877         while (list) {
878                 dir_detail = (app2ext_dir_details *)list->data;
879                 if (dir_detail && dir_detail->name
880                         && dir_detail->type == APP2EXT_DIR_RO) {
881                         snprintf(path, FILENAME_MAX,
882                                  "%s%s/%s",APP_INSTALLATION_PATH,
883                                  pkgid,
884                                  dir_detail->name);
885                         ret =
886                             _app2sd_move_to_archive
887                             (path,
888                              app_archive_path);
889                         if (ret) {
890                                 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
891                                         app2ext_print
892                                             ("App2Sd Error : unable to access %s\n",
893                                              path);
894                                 } else {
895                                         app2ext_print
896                                             ("App2Sd Error : unable to copy from %s to %s \n",
897                                              path,
898                                              app_archive_path);
899                                 }
900                         }
901                 }
902                 list = g_list_next(list);
903         }
904         /********Archiving code ends***********/
905
906         /* mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
907         ret =
908             _app2sd_mount_app_content(pkgid, device_node,
909                                       MOUNT_TYPE_RW, dir_list,
910                                       APP2SD_MOVE_APP_TO_MMC);
911         if (ret) {
912                 return ret;
913         }
914         /********restore Archive begin***********/
915         list = g_list_first(dir_list);
916         while (list) {
917                 dir_detail = (app2ext_dir_details *)list->data;
918                 if (dir_detail && dir_detail->name
919                         && dir_detail->type == APP2EXT_DIR_RO) {
920                         memset((void *)&path, '\0',
921                                FILENAME_MAX);
922                         snprintf(path, FILENAME_MAX,
923                                  "%s%s/.archive/%s",APP_INSTALLATION_PATH,
924                                  pkgid,
925                                  dir_detail->name);
926                         ret =
927                             _app2sd_copy_dir
928                             (path,
929                              app_mmc_path);
930                         if (ret) {
931                                 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
932                                         app2ext_print("App2Sd Error : unable to access %s\n", path);
933                                 } else {
934                                         char err_buf[1024] = {0,};
935                                         strerror_r(errno, err_buf, sizeof(err_buf));
936                                         app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
937                                                         path, app_mmc_path, err_buf);
938                                 }
939                         }
940                         ret =
941                             _app2sd_delete_directory
942                             (path);
943                         if (ret) {
944                                 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
945                                         app2ext_print
946                                             ("App2Sd Error : unable to access %s\n",
947                                              path);
948                                 } else {
949                                         app2ext_print
950                                             ("App2Sd Error : unable to delete %s \n",
951                                              path);
952                                         return
953                                             APP2EXT_ERROR_DELETE_DIRECTORY;
954                                 }
955                         }
956                 }
957                 list = g_list_next(list);
958         }
959
960         ret = _app2sd_delete_directory(app_archive_path);
961         if (ret) {
962                 app2ext_print
963                     ("App2Sd Error : unable to delete %s \n",
964                      app_archive_path);
965         }
966
967         /* TODO */
968         /*
969         ret = _app2sd_apply_mmc_smack(pkgid, dir_list, pkgid);
970         */
971         if (ret) {
972                 app2ext_print("App2Sd Error : unable to apply app smack\n");
973                 return APP2EXT_ERROR_MOVE;
974         }
975
976         /* Restore archive ends */
977         /* Re-mount the loopback encrypted pseudo device on application installation path as with Read Only permission */
978         ret = _app2sd_unmount_app_content(pkgid);
979         if (ret) {
980                 return APP2EXT_ERROR_REMOUNT;
981         }
982         ret =
983             _app2sd_remove_loopback_encryption_setup(pkgid);
984         if (ret) {
985                 app2ext_print
986                     ("App2Sd Error : unable to detach loopback setup for %s\n",
987                      pkgid);
988                 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
989         }
990         return APP2EXT_SUCCESS;
991 }
992
993 int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
994 {
995         int ret = APP2EXT_SUCCESS;
996         mode_t mode = DIR_PERMS;
997         char path[FILENAME_MAX] = { 0, };
998         char app_mmc_path[FILENAME_MAX] = { 0, };
999         char app_path[FILENAME_MAX] = { 0, };
1000         char mmc_path[FILENAME_MAX] = { 0, };
1001         char app_archive_path[FILENAME_MAX] = { 0, };
1002         char *device_node = NULL;
1003         FILE *fp = NULL;
1004         GList *list = NULL;
1005         app2ext_dir_details* dir_detail = NULL;
1006         int reqd_size = 0;
1007         int free_internal_mem = 0;
1008         struct statvfs buf = {0,};
1009         unsigned long long temp = 0;
1010         char err_buf[1024] = {0,};
1011
1012         snprintf(app_mmc_path, FILENAME_MAX,
1013                  "%s%s/.mmc", APP_INSTALLATION_PATH,  pkgid);
1014         snprintf(app_path, FILENAME_MAX, "%s%s/", APP_INSTALLATION_PATH,
1015                  pkgid);
1016         snprintf(app_archive_path, FILENAME_MAX,
1017                  "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
1018         snprintf(mmc_path, FILENAME_MAX,
1019                  "%s%s", APP2SD_PATH, pkgid);
1020
1021         /* Check whether MMC is present or not */
1022         ret = _app2sd_check_mmc_status();
1023         if (ret) {
1024                 app2ext_print
1025                     ("App2Sd Error : MMC not preset OR Not ready %d\n",
1026                      ret);
1027                 return APP2EXT_ERROR_MMC_STATUS;
1028         }
1029
1030         /* check whether application is in external memory or not */
1031         fp = fopen(mmc_path, "r+");
1032         if (fp == NULL) {
1033                 app2ext_print
1034                     ("Application %s is not installed on SD Card\n",
1035                      pkgid);
1036                 return APP2EXT_ERROR_FILE_ABSENT;
1037         } else {
1038                 fclose(fp);
1039                 fp = NULL;
1040         }
1041
1042         memset((void *)&buf, '\0', sizeof(struct statvfs));
1043         ret = statvfs(INTERNAL_STORAGE_PATH, &buf);
1044         if (0 == ret){
1045                 temp = (buf.f_bsize * buf.f_bavail)/(1024*1024);
1046                 free_internal_mem = (int)temp;
1047         }else{
1048                 app2ext_print("App2SD Error: Unable to get internal storage size\n");
1049                 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY; /* TODO: new error no for internal? */
1050         }
1051
1052         /* check app entry is there in sd card or not. */
1053         snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
1054                  pkgid);
1055         app2ext_print("App2Sd Log : Checking path %s\n", app_path);
1056         fp = fopen(app_path, "r+");
1057         if (fp == NULL) {
1058                 app2ext_print
1059                     ("App2SD Error: App Entry is not present in SD Card\n");
1060                 return APP2EXT_ERROR_INVALID_PACKAGE;
1061         }
1062         fclose(fp);
1063         /* Get installed app size*/
1064         temp = _app2sd_calculate_file_size(app_path);
1065         reqd_size = (int)((temp)/(1024 * 1024));
1066         app2ext_print("App2Sd Log : Reqd size is %d\n", reqd_size);
1067
1068         if (reqd_size == 0) {
1069                 app2ext_print
1070                     ("App2SD Error: App Entry is not present in SD Card\n");
1071                 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
1072         }
1073
1074         app2ext_print("Reqd Size: %d MB, free internal mem %d MB\n", reqd_size, free_internal_mem);
1075         /* If avaialalbe free memory in internal storage is less than required size, return error */
1076         if (reqd_size > free_internal_mem) {
1077                 app2ext_print
1078                     ("App2Sd Error : Insufficient memory in internal storage for application installation %d\n",
1079                      ret);
1080                 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY; /* TODO: new error no for internal? */
1081         }
1082         /* Get the associated device node for SD card applicationer */
1083         snprintf(app_path, FILENAME_MAX, "%s%s/", APP_INSTALLATION_PATH,
1084                  pkgid);
1085
1086         device_node =
1087             _app2sd_find_associated_device_node(pkgid);
1088         if (NULL == device_node) {
1089                 /* Do loopback setup */
1090                 device_node =
1091                     _app2sd_do_loopback_encryption_setup
1092                     (pkgid);
1093                 if (device_node == NULL) {
1094                         app2ext_print
1095                             ("App2Sd Error : loopback encryption setup failed\n");
1096                         return APP2EXT_ERROR_DO_LOSETUP;
1097                 }
1098                 /* Do mounting */
1099                 ret =
1100                     _app2sd_mount_app_content(pkgid,
1101                                               device_node,
1102                                               MOUNT_TYPE_RW,
1103                                               dir_list,
1104                                               APP2SD_MOVE_APP_TO_PHONE);
1105                 if (ret) {
1106                         app2ext_print
1107                             ("App2Sd Error : Re-mount failed\n");
1108                         return APP2EXT_ERROR_MOUNT_PATH;
1109                 }
1110         } else {
1111                 /* Do re-mounting */
1112                 ret =
1113                     _app2sd_mount_app_content(pkgid,
1114                                               device_node,
1115                                               MOUNT_TYPE_RW_REMOUNT,
1116                                               dir_list,
1117                                               APP2SD_MOVE_APP_TO_PHONE);
1118                 if (ret) {
1119                         app2ext_print
1120                             ("App2Sd Error : Re-mount failed\n");
1121                         return APP2EXT_ERROR_MOUNT_PATH;
1122                 }
1123         }
1124         ret = mkdir(app_archive_path, mode);
1125         if (ret) {
1126                 app2ext_print
1127                     ("App2Sd Error : unable to create directory%s\n",
1128                      app_archive_path);
1129         }
1130
1131
1132         list = g_list_first(dir_list);
1133         while (list) {
1134                 dir_detail = (app2ext_dir_details *)list->data;
1135                 if (dir_detail && dir_detail->name
1136                         && dir_detail->type == APP2EXT_DIR_RO) {
1137                                 /* Archiving code */
1138                                 memset((void *)&path, '\0',
1139                                        FILENAME_MAX);
1140                                 snprintf(path, FILENAME_MAX,
1141                                          "%s%s/.mmc/%s", APP_INSTALLATION_PATH,
1142                                          pkgid,
1143                                          dir_detail->name);
1144                                 ret =
1145                                     _app2sd_copy_dir
1146                                     (path,
1147                                      app_archive_path);
1148                                 if (ret) {
1149                                         if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1150                                                 app2ext_print("App2Sd Error : unable to access %s\n", path);
1151                                         } else {
1152                                                 strerror_r(errno, err_buf, sizeof(err_buf));
1153                                                 app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
1154                                                                 path, app_archive_path, err_buf);
1155                                         }
1156                                 }
1157
1158                                 /* Delete the symbolic link files [bin, lib, res]*/
1159                                 memset((void *)&path, '\0',
1160                                        FILENAME_MAX);
1161                                 snprintf(path, FILENAME_MAX,
1162                                          "%s%s/%s", APP_INSTALLATION_PATH,
1163                                          pkgid,
1164                                          dir_detail->name);
1165                                 ret = unlink(path);
1166                                 if (ret) {
1167                                         if (errno == ENOENT) {
1168                                                 app2ext_print("App2Sd Error : Directory %s does not exist\n", path);
1169                                         } else {
1170                                                 app2ext_print("App2Sd Error : unable to remove the symbolic link file %s,"
1171                                                                 " it is already unlinked!!!\n", path);
1172                                         }
1173                                 }
1174
1175                                 /* Copy content to destination */
1176                                 memset((void *)&path, '\0',
1177                                        FILENAME_MAX);
1178                                 snprintf(path, FILENAME_MAX,
1179                                         "%s%s/.archive/%s", APP_INSTALLATION_PATH,
1180                                          pkgid, dir_detail->name);
1181                                 ret = _app2sd_copy_dir(path, app_path);
1182                                 if (ret) {
1183                                         if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1184                                                 app2ext_print("App2Sd Error : unable to access %s\n", path);
1185                                         } else {
1186                                                 strerror_r(errno, err_buf, sizeof(err_buf));
1187                                                 app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
1188                                                                 path, app_path, err_buf);
1189                                         }
1190                                 }
1191                 }
1192                 list = g_list_next(list);
1193         }
1194
1195         app2ext_print("App2Sd info : Copying file completed\n");
1196         ret = _app2sd_unmount_app_content(pkgid);
1197         if (ret) {
1198                 app2ext_print
1199                     ("App2Sd Error : unable to unmount SD directory for app %s\n",
1200                      pkgid);
1201                 return APP2EXT_ERROR_UNMOUNT;
1202         }
1203         ret =
1204             _app2sd_remove_loopback_encryption_setup(pkgid);
1205         if (ret) {
1206                 app2ext_print
1207                     ("App2Sd Error : unable to detach loopback setup for %s\n",
1208                      pkgid);
1209                 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
1210         }
1211         ret = _app2sd_delete_loopback_device(pkgid);
1212         if (ret) {
1213                 app2ext_print
1214                     ("App2Sd Error : unable to delete the loopback device for %s\n",
1215                      pkgid);
1216                 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1217         }
1218         ret = _app2sd_delete_directory(app_mmc_path);
1219         if (ret) {
1220                 app2ext_print
1221                     ("App2Sd Error : unable to delete %s \n",
1222                      app_mmc_path);
1223         }
1224         ret = _app2sd_delete_directory(app_archive_path);
1225         if (ret) {
1226                 app2ext_print
1227                     ("App2Sd Error : unable to delete %s \n",
1228                      app_archive_path);
1229         }
1230
1231         /* TODO */
1232         /*
1233         ret = _app2sd_apply_app_smack(pkgid, dir_list, pkgid);
1234         */
1235         if (ret) {
1236                 app2ext_print("App2Sd Error : unable to apply app smack\n");
1237                 return APP2EXT_ERROR_MOVE;
1238         }
1239
1240         return APP2EXT_SUCCESS;
1241 }
1242
1243 int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_list)
1244 {
1245         int ret = APP2EXT_SUCCESS;
1246
1247         /* Check whether MMC is present or not */
1248         ret = _app2sd_check_mmc_status();
1249         if (ret) {
1250                 app2ext_print
1251                     ("App2Sd Error : MMC not preset OR Not ready %d\n",
1252                      ret);
1253                 return APP2EXT_ERROR_MMC_STATUS;
1254         }
1255
1256         switch (move_cmd) {
1257         case APP2EXT_MOVE_TO_EXT:
1258                 {
1259                         ret = _app2sd_move_app_to_external(pkgid, dir_list);
1260                         if (ret) {
1261                                 app2ext_print
1262                                     ("App2Sd Error : move app to external memory failed %d\n",
1263                                      ret);
1264                                 return ret;
1265                         }
1266                         break;
1267                 }
1268         case APP2EXT_MOVE_TO_PHONE:
1269                 {
1270                         ret = _app2sd_move_app_to_internal(pkgid, dir_list);
1271                         if (ret) {
1272                                 app2ext_print
1273                                     ("App2Sd Error : move app to internal memory failed %d\n",
1274                                      ret);
1275                                 return ret;
1276                         }
1277                         break;
1278                 }
1279         default:
1280                 {
1281                         app2ext_print("App2Sd Error : invalid argument\n");
1282                         return APP2EXT_ERROR_INVALID_ARGUMENTS;
1283                 }
1284         }
1285
1286         return ret;
1287
1288 }
1289
1290 int _app2sd_copy_ro_content(const char *src, const char *dest, GList* dir_list)
1291 {
1292         char path[FILENAME_MAX] = { 0, };
1293         int ret =       APP2EXT_SUCCESS;
1294         GList *list = NULL;
1295         app2ext_dir_details* dir_detail = NULL;
1296
1297         list = g_list_first(dir_list);
1298         while (list) {
1299                 dir_detail = (app2ext_dir_details *)list->data;
1300                 if (dir_detail && dir_detail->name
1301                         && dir_detail->type == APP2EXT_DIR_RO) {
1302                         memset((void *)&path, '\0',
1303                                FILENAME_MAX);
1304                         snprintf(path, FILENAME_MAX,
1305                                  "%s/%s", src,
1306                                  dir_detail->name);
1307                         ret =
1308                             _app2sd_copy_dir
1309                             (path,
1310                              dest);
1311                         if (ret) {
1312                                 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1313                                         app2ext_print
1314                                             ("App2Sd Error : unable to access %s\n",
1315                                              path);
1316                                 } else {
1317                                         app2ext_print
1318                                             ("App2Sd Error : unable to copy from %s to %s .....errno is %d\n",
1319                                              path,
1320                                              dest,
1321                                              errno);
1322                                         return
1323                                             APP2EXT_ERROR_MOVE;
1324                                 }
1325                         }
1326                 }
1327                 list = g_list_next(list);
1328         }
1329
1330         return APP2EXT_SUCCESS;
1331 }
1332
1333 int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node, int size)
1334 {
1335         int ret = 0;
1336         char temp_pkgid[FILENAME_MAX] = { 0, };
1337         char *devi = NULL;
1338         int err_res = 0;
1339         char *result = NULL;
1340
1341         /* Create a new loopback device */
1342         snprintf(temp_pkgid, FILENAME_MAX,
1343                  "%s.new", pkgid);
1344         ret = _app2sd_create_loopback_device(temp_pkgid, (size+PKG_BUF_SIZE));
1345         if (ret) {
1346                 app2ext_print("App2Sd Error : Package already present\n");
1347                 return ret;
1348         }
1349         app2ext_print("App2Sd  : _app2sd_create_loopback_device SUCCESS\n");
1350         /* Perform Loopback encryption setup */
1351         dev_node = _app2sd_do_loopback_duplicate_encryption_setup(pkgid, temp_pkgid);
1352         if (!dev_node) {
1353                 app2ext_print("App2Sd Error : losetup failed, device node is %s\n", dev_node);
1354                 _app2sd_delete_loopback_device(pkgid);
1355                 app2ext_print("App2Sd Error : create ext filesystem failed\n");
1356                 return APP2EXT_ERROR_DO_LOSETUP;
1357         }
1358         app2ext_print("App2Sd  : _app2sd_do_loopback_duplicate_encryption_setup SUCCESS\n");
1359         /* Check whether loopback device is associated with device node or not */
1360         devi = _app2sd_find_associated_device_node(temp_pkgid);
1361         if (devi == NULL) {
1362                 app2ext_print("App2Sd Error : finding associated device node failed\n");
1363                 err_res = APP2EXT_ERROR_DO_LOSETUP;
1364                 goto FINISH_OFF;
1365         }
1366         app2ext_print("App2Sd  : _app2sd_find_associated_device_node SUCCESS\n");
1367         /* Format the loopback file system */
1368         ret = _app2sd_create_file_system(dev_node);
1369         if (ret) {
1370                 app2ext_print("App2Sd Error : creating FS failed failed\n");
1371                 err_res = APP2EXT_ERROR_CREATE_FS;
1372                 goto FINISH_OFF;
1373         }
1374         app2ext_print("App2Sd  : _app2sd_create_file_system SUCCESS\n");
1375         /* Do mounting for new dev*/
1376         ret =
1377             _app2sd_mount_app_content(temp_pkgid, dev_node, MOUNT_TYPE_RW,
1378                                 dir_list, APP2SD_PRE_UPGRADE);
1379         if (ret) {
1380                 app2ext_print("App2Sd Error : Re-mount failed\n");
1381                 err_res = APP2EXT_ERROR_MOUNT_PATH;
1382                 goto FINISH_OFF;
1383         }
1384         if (devi) {
1385                 free(devi);
1386                 devi = NULL;
1387         }
1388         return APP2EXT_SUCCESS;
1389
1390 FINISH_OFF:
1391         if (dev_node) {
1392                 result = _app2sd_detach_loop_device(dev_node);
1393                 if (result) {
1394                         free(result);
1395                         result = NULL;
1396                 }
1397                 _app2sd_delete_loopback_device(pkgid);
1398                 free(dev_node);
1399                 dev_node = NULL;
1400         }
1401
1402         if (devi) {
1403                 free(devi);
1404                 devi = NULL;
1405         }
1406         return err_res;
1407 }
1408
1409 int _app2sd_update_loopback_device_size(const char *pkgid,
1410         int size, GList* dir_list)
1411 {
1412         int ret = 0;
1413         char *device_node = NULL;
1414         char *old_device_node = NULL;
1415         int err_res = 0;
1416         char app_mmc_path[FILENAME_MAX] = { 0, };
1417         char app_archive_path[FILENAME_MAX] = { 0, };
1418         char temp_pkgid[FILENAME_MAX] = { 0, };
1419         char app_path[FILENAME_MAX] = { 0, };
1420
1421         snprintf(temp_pkgid, FILENAME_MAX,
1422                  "%s.new", pkgid);
1423
1424         ret = _app2sd_duplicate_device(pkgid, dir_list, device_node, size);
1425         if (ret) {
1426                 app2ext_print("App2Sd Error : Creating duplicate device failed\n");
1427                 return ret;
1428         }
1429
1430         app2ext_print("App2Sd  : _app2sd_mount_app_content SUCCESS\n");
1431         /* check app entry is there in sd card or not. */
1432         snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
1433                  pkgid);
1434
1435         /* Get the associated device node for SD card applicatione */
1436         old_device_node = _app2sd_find_associated_device_node(pkgid);
1437         if (NULL == old_device_node) {
1438                 /* Do loopback setup */
1439                 old_device_node = _app2sd_do_loopback_encryption_setup(pkgid);
1440                 if (old_device_node == NULL) {
1441                         app2ext_print
1442                             ("App2Sd Error : loopback encryption setup failed\n");
1443                         err_res = APP2EXT_ERROR_DO_LOSETUP;
1444                         goto FINISH_OFF;
1445                 }
1446                 /* Do mounting */
1447                 ret =
1448                     _app2sd_mount_app_content(pkgid, old_device_node,
1449                                               MOUNT_TYPE_RW, dir_list,
1450                                               APP2SD_PRE_UPGRADE);
1451                 if (ret) {
1452                         app2ext_print("App2Sd Error : Re-mount failed\n");
1453                         err_res = APP2EXT_ERROR_MOUNT_PATH;
1454                 }
1455         } else {
1456                 /* Do re-mounting */
1457                 ret =
1458                     _app2sd_mount_app_content(pkgid, old_device_node,
1459                                               MOUNT_TYPE_RW_REMOUNT, dir_list,
1460                                               APP2SD_PRE_UPGRADE);
1461                 if (ret) {
1462                         app2ext_print("App2Sd Error : Re-mount failed\n");
1463                         err_res = APP2EXT_ERROR_MOUNT_PATH;
1464                 }
1465         }
1466
1467         snprintf(app_mmc_path, FILENAME_MAX,
1468                  "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
1469         snprintf(app_archive_path, FILENAME_MAX,
1470                 "%s%s/.mmc", APP_INSTALLATION_PATH, temp_pkgid);
1471
1472         ret = _app2sd_copy_ro_content(app_mmc_path, app_archive_path, dir_list);
1473         if (ret) {
1474                 app2ext_print("App2Sd Error : copy ro content  failed\n");
1475                 err_res = ret;
1476         }
1477
1478         ret = _app2sd_unmount_app_content(pkgid);
1479         if (ret) {
1480                 app2ext_print
1481                     ("App2SD Error: Unable to unmount the SD application\n");
1482                 err_res = APP2EXT_ERROR_UNMOUNT;
1483         }
1484         ret = _app2sd_remove_loopback_encryption_setup(pkgid);
1485         if (ret) {
1486                 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1487                 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1488         }
1489         ret = _app2sd_unmount_app_content(temp_pkgid);
1490         if (ret) {
1491                 app2ext_print
1492                     ("App2SD Error: Unable to unmount the SD application\n");
1493                 err_res = APP2EXT_ERROR_UNMOUNT;
1494                 goto FINISH_OFF;
1495         }
1496         ret = _app2sd_remove_loopback_encryption_setup(temp_pkgid);
1497         if (ret) {
1498                 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1499                 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1500                 goto FINISH_OFF;
1501         }
1502         snprintf(app_archive_path, FILENAME_MAX,
1503                 "%s%s", APP2SD_PATH, temp_pkgid);
1504         ret = _app2sd_delete_directory(app_path);
1505         if (ret) {
1506                 app2ext_print
1507                     ("App2Sd Error : unable to delete %s \n",
1508                      app_path);
1509                 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1510                 goto FINISH_OFF;
1511         }
1512         ret = _app2sd_rename_dir(app_archive_path, app_path);
1513         if (ret) {
1514                 app2ext_print
1515                     ("App2Sd Error : unable to rename %s \n",
1516                      app_archive_path);
1517                 err_res = APP2EXT_ERROR_MOVE;
1518                 goto FINISH_OFF;
1519         }
1520         snprintf(app_path, FILENAME_MAX,
1521                 "%s%s", APP_INSTALLATION_PATH, temp_pkgid);
1522         ret = _app2sd_delete_directory(app_path);
1523         if (ret) {
1524                 app2ext_print
1525                     ("App2Sd Error : unable to delete %s \n",
1526                      app_path);
1527                 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1528                 goto FINISH_OFF;
1529         }
1530         return APP2EXT_SUCCESS;
1531
1532 FINISH_OFF:
1533         if (old_device_node) {
1534                 free(old_device_node);
1535                 old_device_node = NULL;
1536         }
1537
1538         ret = _app2sd_remove_loopback_encryption_setup(pkgid);
1539         if (ret) {
1540                 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1541                 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1542         }
1543         return err_res;
1544 }
1545
1546 void _app2sd_make_result_info_file(char *pkgid, int size)
1547 {
1548         int ret = 0;
1549         FILE* file = NULL;
1550         int fd = 0;
1551         char buf[FILENAME_MAX] = {0};
1552         const char* app_info_label = "*";
1553         char info_file[FILENAME_MAX] = {'\0', };
1554
1555         if(pkgid == NULL)
1556                 return;
1557
1558         snprintf(info_file, FILENAME_MAX, "/tmp/%s", pkgid);
1559         app2ext_print("App2SD info : File path = %s\n", info_file);
1560
1561         file = fopen(info_file, "w");
1562         if (file == NULL) {
1563                 app2ext_print("App2SD Error: Couldn't open the file %s \n", info_file);
1564                 return;
1565         }
1566
1567         snprintf(buf, 128, "%d\n", size);
1568         fwrite(buf, 1, strlen(buf), file);
1569
1570         fflush(file);
1571         fd = fileno(file);
1572         fsync(fd);
1573         fclose(file);
1574
1575         if(lsetxattr(info_file, "security.SMACK64", app_info_label, strlen(app_info_label), 0)) {
1576                 app2ext_print("App2SD Error: error(%d) in setting smack label",errno);
1577         }
1578         ret = chmod(info_file, 0777);
1579         if (ret == -1) {
1580                 return;
1581         }
1582
1583         ret = chown(info_file, 5000, 5000);
1584         if (ret == -1) {
1585                 return;
1586         }
1587 }