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