Support external MMC path for OSP compatible apps.
[platform/framework/native/env-config.git] / osp-env-config.c
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #ifndef _GNU_SOURCE
19 #define _GNU_SOURCE
20 #endif
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sched.h>
26 #include <sys/mount.h>
27 #include <errno.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <limits.h>
31 #include <sys/prctl.h>
32 #include <sys/vfs.h>
33
34 #include <dlog.h>
35 #include <vconf.h>
36
37 #undef LOG_TAG
38 #define LOG_TAG "ENV_CONFIG"
39
40 #define _MAX_PACKAGEID_LENGTH 10
41 #define _MAX_APIVERSION_LENGTH 3
42
43 static const char* _OSP_HOME_PATH = "/opt/osp/\0"; // /opt/apps/com.samsung.osp
44 static const char* _OSP_COMPAT_SHARED_PATH = "/opt/usr/share/.osp-compat/\0";
45 static const char* _EXT_OSP_HOME_PATH = "/opt/storage/sdcard/osp/\0";
46
47 struct _path_info
48 {
49     char src_path[PATH_MAX];
50     char dest_path[PATH_MAX];
51 };
52
53 struct _dir_info
54 {
55         char path[PATH_MAX];
56         mode_t mode;
57         char app_privilege; // 0: root privilege
58 };
59
60 /*
61  * XXX: The returned app_roodir must be freed in caller.
62  */
63 static char*
64 get_app_rootpath_from_path(const char* bin_path)
65 {
66         char* app_rootpath = NULL;
67         char* delimiter = NULL;
68         size_t length = 0;
69         /* e.g., The specified bin_path is "/opt/apps/com.samsung.basicapp/bin/basicapp" */
70
71         length = strlen(bin_path);
72         app_rootpath = (char *)malloc(length + 1);
73         if(app_rootpath == NULL)
74                 return NULL;
75
76         memset(app_rootpath, '\0', length + 1);
77         strncpy(app_rootpath, bin_path, length);
78
79         LOGI("input bin_path: %s", app_rootpath);
80
81         delimiter = strrchr(app_rootpath, '/');
82         *delimiter = '\0';
83
84         delimiter  = strrchr(app_rootpath, '/');
85         *delimiter = '\0';
86
87         return app_rootpath;
88 }
89
90 static void
91 get_package_id_from_app_rootpath(const char* app_rootpath, char* package_id)
92 {
93         const char* p = NULL;
94         if (strncmp(app_rootpath, "/opt/apps/org.tizen.", 19) == 0)
95         {
96         p = strrchr(app_rootpath, '.') + 1;
97         }
98         else
99         {
100         p = strrchr(app_rootpath, '/') + 1;
101         }
102         strncpy(package_id, p, _MAX_PACKAGEID_LENGTH);
103     package_id[_MAX_PACKAGEID_LENGTH] = '\0';
104     LOGI("package id: %s", package_id);
105 }
106
107 static void
108 get_package_id_from_package_name(const char* package_name, char* package_id)
109 {
110     char* tmpbuf = NULL;
111
112     if (strncmp(package_name, "com", 3) == 0)
113     {   // in case of com.samsung.#osp#[package_id]#[serviceid]
114         tmpbuf = strstr(package_name, "#osp#");
115         if (tmpbuf != NULL)
116         {
117             strncpy(package_id, tmpbuf + 5, _MAX_PACKAGEID_LENGTH);
118         }
119     }
120     else if (strncmp(package_name, "osp", 3) == 0)
121     {   // in case of osp.[package_id].#osp#[serviceid]
122         tmpbuf = strstr(package_name, "osp.");
123         if (tmpbuf != NULL)
124         {
125             strncpy(package_id, tmpbuf + 4, _MAX_PACKAGEID_LENGTH);
126         }
127     }
128         else if (strncmp(package_name, "org.tizen", 9) == 0)
129         {
130                 // in case of org.tizen.[package_id]#[serviceid]
131                 tmpbuf = strstr(package_name, "org.tizen.");
132                 if (tmpbuf != NULL)
133                 {
134                         strncpy(package_id, tmpbuf + 10, _MAX_PACKAGEID_LENGTH);
135                 }
136         }
137     else if (strlen(package_name) == 10)
138     {
139                 strncpy(package_id, package_name, _MAX_PACKAGEID_LENGTH);
140     }
141     else
142     {
143         LOGE("package name is invalid (%s)", package_name);
144     }
145
146     package_id[_MAX_PACKAGEID_LENGTH] = '\0';
147     LOGI("package_id: %s", package_id);
148 }
149
150 static int
151 internal_is_mounted(const char* pkgid)
152 {
153         char mount_flag[64] = { 0, };
154         static const char dir[][64] =
155         {
156                 { "/tmp/osp-compat" },
157                 { "/tmp/osp-compat/mount" },
158                 { "/tmp/osp-compat/mount/internal" }
159         };
160
161         sprintf(mount_flag, "/tmp/osp-compat/mount/internal/%s", pkgid);
162         int res = access(mount_flag, F_OK);
163         if (res == 0)
164         {
165                 LOGI("Intenal path is already mounted.");
166                 return 1;
167         }
168         else if (res == -1 && errno == ENOENT)
169         {
170                 int i = 0;
171                 for (i = 0; i < sizeof(dir)/64; ++i)
172                 {
173                         int res = mkdir(dir[i], 0755);
174                         if (res == -1 && errno != EEXIST)
175                         {
176                                 LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno));
177                                 return 1;
178                         }
179                 }
180
181                 int fd = creat(mount_flag, 0644);
182                 if (fd == -1)
183                 {
184                         LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
185                         return 1;
186                 }
187                 close(fd);
188         }
189         else
190         {
191                 LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
192                 return 1;
193         }
194
195         LOGI("Intenal path mount succeeded.");
196         return 0;
197 }
198
199 static int
200 external_is_mounted(const char* pkgid)
201 {
202         char mount_flag[64] = { 0, };
203         static const char dir[][64] =
204         {
205                 { "/tmp/osp-compat" },
206                 { "/tmp/osp-compat/mount" },
207                 { "/tmp/osp-compat/mount/external" }
208         };
209
210         sprintf(mount_flag, "/tmp/osp-compat/mount/external/%s", pkgid);
211         int res = access(mount_flag, F_OK);
212         if (res == 0)
213         {
214                 LOGI("Extenal path is already mounted.");
215                 return 1;
216         }
217         else if (res == -1 && errno == ENOENT)
218         {
219                 int i = 0;
220                 for (i = 0; i < sizeof(dir)/64; ++i)
221                 {
222                         int res = mkdir(dir[i], 0755);
223                         if (res == -1 && errno != EEXIST)
224                         {
225                                 LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno));
226                                 return 1;
227                         }
228                 }
229
230                 int fd = creat(mount_flag, 0644);
231                 if (fd == -1)
232                 {
233                         LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
234                         return 1;
235                 }
236                 close(fd);
237         }
238         else
239         {
240                 LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
241                 return 1;
242         }
243
244         LOGI("Extenal path mount succeeded.");
245         return 0;
246 }
247
248 static int
249 mount_slp_paths(const char* app_rootpath)
250 {
251     int i = 0;
252     static const struct _path_info mount_info[] = {
253         //{ "/bin",             "./bin" },
254         //{ "/boot",            "./boot" },
255         //{ "/cache",           "./cache" },
256         { "/csa",               "./csa" },
257         { "/dev",               "./dev" },
258         { "/dev/pts",           "./dev/pts" },
259         { "/dev/shm",           "./dev/shm" },
260         { "/etc",               "./etc" },
261         { "/lib",               "./lib" },
262         //{ "/lost+found",      "./lost+found" },
263         { "/media",             "./media" },
264         { "/mnt",               "./mnt" },
265         { "/opt",               "./opt" },
266         { "/opt/usr",           "./opt/usr" },
267         { "/opt/var/kdb/db",    "./opt/var/kdb/db" },
268         { "/opt/storage/sdcard","./opt/storage/sdcard" },
269         //{ "/packaging",       "./packaging" },
270         { "/proc",              "./proc" },
271         { "/sbin",              "./sbin" },
272         { "/srv",               "./srv" },
273         { "/sys",               "./sys" },
274         { "/sys/kernel/debug",  "./sys/kernel/debug" },
275         { "/tmp",               "./tmp" },
276         { "/usr",               "./usr" },
277         { "/var",               "./var" },
278         { "/var/run",           "./var/run" }
279     };
280
281     if (chdir(app_rootpath) != 0)
282     {
283         LOGE("chdir() failed path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
284         return -1;
285     }
286
287     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
288     {
289         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
290         {
291             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
292                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
293
294             int j = 0;
295             for (j = i; j > 0; --j)
296             {
297                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
298             }
299             return -1;
300         }
301     }
302
303     return 0;
304 }
305
306 static int
307 mount_osp_internal_paths(const char* app_rootpath, const char* pkgid)
308 {
309     int i = 0;
310     char osp_share_pkgid_path[PATH_MAX] = {0, };
311     char osp_share2_pkgid_path[PATH_MAX] = {0, };
312     struct _path_info mount_info[] = {
313         { "\0",                    "./data/Share" },
314         { "\0",                    "./data/Share2" },
315         { "/opt/usr/share/.osp-compat/share",  "./Share" },
316         { "/opt/usr/share/.osp-compat/share2", "./Share2" },
317       //{ "/opt/osp/clipboard",    "./Clipboard" },
318       //{ "/opt/osp/partner/npki", "./NPKI" },
319       //{ "/opt/osp/system",       "./System" },
320       //{ "/opt/osp/Tmp",          "./Tmp" },
321         { "/opt/usr/media",        "./Media" }
322     };
323
324     strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
325     strncat(osp_share_pkgid_path, "share/", 6);
326     strncat(osp_share_pkgid_path, pkgid, strlen(pkgid));
327
328     strncpy(osp_share2_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
329     strncat(osp_share2_pkgid_path, "share2/", 7);
330     strncat(osp_share2_pkgid_path, pkgid, strlen(pkgid));
331
332     strncpy(mount_info[0].src_path, osp_share_pkgid_path, strlen(osp_share_pkgid_path));
333     strncpy(mount_info[1].src_path, osp_share2_pkgid_path, strlen(osp_share2_pkgid_path));
334
335     if (chdir(app_rootpath) != 0)
336     {
337         LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
338         return -1;
339     }
340
341     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
342     {
343         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
344         {
345             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
346                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
347
348             int j = 0;
349             for (j = i; j > 0; --j)
350             {
351                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
352             }
353             return -1;
354         }
355     }
356
357     return 0;
358 }
359
360 static int
361 link_osp_share_path(const char* app_rootpath, const char* pkgid)
362 {
363     char osp_app_share_path[PATH_MAX] = {0, };
364     char osp_share_pkgid_path[PATH_MAX] = {0, };
365
366     strncpy(osp_app_share_path, app_rootpath, strlen(app_rootpath));
367     strncat(osp_app_share_path, "/shared/data", 12);
368
369     strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
370     strncat(osp_share_pkgid_path, "share/", 6);
371     strncat(osp_share_pkgid_path, pkgid, strlen(pkgid));
372
373     unlink(osp_share_pkgid_path);
374
375     int ret = symlink(osp_app_share_path, osp_share_pkgid_path);
376     if (ret == -1 && errno != 17) // EEXIST
377     {
378         LOGE("symlink() failed, src path: %s, dest path: %s, errno: %d (%s)",
379                 osp_app_share_path, osp_share_pkgid_path, errno, strerror(errno));
380         return -1;
381     }
382
383     return 0;
384 }
385
386 static int
387 create_osp_external_paths(const char* app_rootpath, const char* pkgid)
388 {
389     char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
390     char osp_ext_apps_pkgid_share_path[PATH_MAX] = {0, };
391     char osp_ext_apps_pkgid_share2_path[PATH_MAX] = {0, };
392     char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
393     char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
394         struct _dir_info external_dirs[] = {
395         { "./HomeExt",           0000, 0},
396         { "./ShareExt",          0000, 0},
397         { "./Share2Ext",         0000, 0},
398         { "/opt/storage/sdcard/osp",            0777,   0 },
399         { "/opt/storage/sdcard/osp/apps",       0777,   0 },
400         { "/opt/storage/sdcard/osp/share",      0777,   0 },
401         { "/opt/storage/sdcard/osp/share2",     0777,   0 },
402         { "\0", 0777, 0},
403         { "\0", 0777, 0},
404         { "\0", 0777, 0},
405         { "\0", 0777, 0},
406         { "\0", 0777, 0},
407         { "/opt/storage/sdcard/Images", 0777,   0 },
408         { "/opt/storage/sdcard/Sounds", 0777,   0 },
409         { "/opt/storage/sdcard/Videos", 0777,   0 },
410       //{ "/opt/storage/sdcard/Themes", 0777,   0 },
411         { "/opt/storage/sdcard/Others", 0777,   0 }
412         };
413     int i = 0;
414
415     strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
416     strncat(osp_ext_apps_pkgid_path, "apps/", 5);
417     strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
418
419     strncpy(osp_ext_apps_pkgid_share_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
420     strncat(osp_ext_apps_pkgid_share_path, "/Share", 6);
421
422     strncpy(osp_ext_apps_pkgid_share2_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
423     strncat(osp_ext_apps_pkgid_share2_path, "/Share2", 7);
424
425     strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
426     strncat(osp_ext_share_pkgid_path, "share/", 6);
427     strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
428
429     strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
430     strncat(osp_ext_share2_pkgid_path, "share2/", 7);
431     strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
432
433     strncpy(external_dirs[7].path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
434     strncpy(external_dirs[8].path, osp_ext_apps_pkgid_share_path, strlen(osp_ext_apps_pkgid_share_path));
435     strncpy(external_dirs[9].path, osp_ext_apps_pkgid_share2_path, strlen(osp_ext_apps_pkgid_share2_path));
436     strncpy(external_dirs[10].path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
437     strncpy(external_dirs[11].path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
438
439     if (chdir(app_rootpath) != 0)
440     {
441         LOGE("chdir() failed (%s), path: %s", strerror(errno), app_rootpath);
442         return -1;
443     }
444
445     for (i = 0; i < sizeof(external_dirs)/sizeof(struct _dir_info); i++)
446     {
447         int ret = mkdir(external_dirs[i].path, external_dirs[i].mode);
448         if (ret == -1 && errno != 17) // EEXIST
449         {
450             LOGE("mkdir() failed, path: %s, errno: %d (%s)", external_dirs[i].path, errno, strerror(errno));
451             return -1;
452         }
453     }
454
455     return 0;
456 }
457
458 static int
459 mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
460 {
461     char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
462     char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
463     char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
464     struct _path_info mount_info[] = {
465         { "/opt/storage/sdcard",  "./Storagecard/Media" },
466         { "/opt/storage/sdcard/osp/share",  "./ShareExt" },
467         { "/opt/storage/sdcard/osp/share2", "./Share2Ext" },
468         { "\0",  "./HomeExt" },
469         { "\0",  "./HomeExt/Share" },
470         { "\0",  "./HomeExt/Share2" },
471     };
472     int i = 0;
473
474     strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
475     strncat(osp_ext_apps_pkgid_path, "apps/", 5);
476     strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
477
478     strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
479     strncat(osp_ext_share_pkgid_path, "share/", 6);
480     strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
481
482     strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
483     strncat(osp_ext_share2_pkgid_path, "share2/", 7);
484     strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
485
486     strncpy(mount_info[3].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
487     strncpy(mount_info[4].src_path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
488     strncpy(mount_info[5].src_path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
489
490     if (chdir(app_rootpath) != 0)
491     {
492         LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
493         return -1;
494     }
495     LOGI("app_rootpath: %s", app_rootpath);
496
497     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); i++)
498     {
499         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
500         {
501             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
502                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
503
504             int j = 0;
505             for (j = i; j > 0; --j)
506             {
507                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
508             }
509             return -1;
510         }
511     }
512
513     return 0;
514 }
515
516 int
517 do_pre_exe(const char* package_name, const char* bin_path, const char* package_id)
518 {
519         char* app_rootpath = NULL;
520         char osp_app_data_path[PATH_MAX] = {0, };
521         //char internal_installed = 1; // true
522         int mmc_mounted = 0;
523     struct statfs fs;
524
525         /* e.g., app_rootdir is "/opt/apps/com.samsung.basicapp or /opt/osp/applications/[appId] */
526         app_rootpath = get_app_rootpath_from_path(bin_path);
527
528         LOGI("[data_caging] do_pre_exe() was called, package name: %s, \
529             binary path: %s, application root(home) path: %s, package id: %s",
530             package_name, bin_path, app_rootpath, package_id);
531
532         umask(0000);
533
534         // TODO: Check whether the application is installed in internal or external storage.
535         // Check installation position using the input path.
536     //if (internal_installed)
537     //{
538
539     if (!internal_is_mounted(package_id))
540     {
541         if (mount_slp_paths(app_rootpath) != 0)
542             goto ERROR;
543
544         if (mount_osp_internal_paths(app_rootpath, package_id) != 0)
545             goto ERROR;
546     }
547
548     int ret = 0;
549     ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
550     if (ret < 0)
551     {
552         LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
553     }
554     if (mmc_mounted == 1)
555     {
556         LOGI("MMC is mounted.");
557         if (create_osp_external_paths(app_rootpath, package_id) != 0)
558         {
559             goto ERROR;
560         }
561
562         if (!external_is_mounted(package_id))
563         {
564             if (mount_osp_external_paths(app_rootpath, package_id) != 0)
565             {
566                 goto ERROR;
567             }
568         }
569     }
570     /*}
571         else
572         {
573             // TODO mount_external_paths(app_rootpath);
574         }*/
575         LOGI("mount() succeeded.");
576
577         if (chroot(app_rootpath) != 0)
578         {
579                 LOGE("chroot() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
580                 goto ERROR;
581         }
582     if (chdir("/") != 0)
583         {
584                 LOGE("chdir() failed, path: /, errno: %d (%s)", errno, strerror(errno));
585                 goto ERROR;
586         }
587         LOGI("chroot() succeeded.");
588
589         // set current working dir to "/opt/apps/{packageId}/data"
590 #if 0
591         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
592         strncat(osp_app_data_path, "/data", strlen("/data"));
593 #endif
594
595         if (chdir("/data") != 0)
596         {
597                 LOGE("chdir() failed, path: /data, errno: %d (%s)", errno, strerror(errno));
598                 goto ERROR;
599         }
600
601         free(app_rootpath);
602     umask(0022);
603
604         LOGI("[data_caging] do_pre_exec() succeeded.");
605         return 0;
606
607 ERROR:
608     free(app_rootpath);
609     umask(0022);
610
611         LOGI("[data_caging] do_pre_exec() failed.");
612     return -1;
613 }
614
615 int
616 do_pre_exec(const char* package_name, const char* bin_path)
617 {
618         char* app_rootpath = NULL;
619     char app_compat_path[PATH_MAX] = { 0, };
620     const char app_compat_file[] = "/info/compat.info\0";
621     int pathlen = 0;
622     char package_id[_MAX_PACKAGEID_LENGTH + 1] = { 0, };
623     char osp_app_data_path[PATH_MAX] = { 0, };
624     int osp_compat = 0;
625
626     LOGI("do_pre_exec() is called, package_name: %s, bin_path: %s", package_name, bin_path);
627
628         app_rootpath = get_app_rootpath_from_path(bin_path);
629
630         strncpy(app_compat_path, app_rootpath, strlen(app_rootpath));
631         strncat(app_compat_path, app_compat_file, strlen(app_compat_file));
632     if (access(app_compat_path, F_OK) == 0)
633     {
634         osp_compat = 1;
635     }
636
637     // XXX: temp code
638     //if (package_name == NULL)
639     {
640         //LOGI("The package name is empty.");
641         get_package_id_from_app_rootpath(app_rootpath, package_id);
642     }
643 #if 0
644     else
645     {
646         get_package_id_from_package_name(package_name, package_id);
647     }
648 #endif
649     // XXX-end
650
651     LOGI("package name: %s, binary path: %s, package id: %s, OSP compatibility: %d",
652             package_name, bin_path, package_id, osp_compat);
653
654         // FIXME: Temporary code with security risk
655         prctl(PR_SET_KEEPCAPS, 1);
656
657     if (osp_compat == 1)
658     {
659                 free(app_rootpath);
660                 //unshare(CLONE_NEWNS);
661                 return do_pre_exe(package_name, bin_path, package_id);
662     }
663
664     // API version is equal to or greater than Tizen 2.0
665         // Set current working dir to "/opt/apps/{pkgId}/data"
666         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
667         strncat(osp_app_data_path, "/data", strlen("/data"));
668
669         if (chdir(osp_app_data_path) != 0)
670         {
671                 LOGE("chdir() failed, path: %s, errno: %d (%s)", osp_app_data_path, errno, strerror(errno));
672                 goto ERROR;
673         }
674
675         if (link_osp_share_path(app_rootpath, package_id) != 0)
676         {
677                 goto ERROR;
678         }
679
680         LOGI("[data_caging] do_pre_exec() succeeded.");
681         free(app_rootpath);
682         return 0;
683
684 ERROR:
685         free(app_rootpath);
686         return -1;
687 }