Tizen 2.1 base
[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 #if 0
479     strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
480     strncat(osp_ext_share_pkgid_path, "share/", 6);
481     strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
482
483     strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
484     strncat(osp_ext_share2_pkgid_path, "share2/", 7);
485     strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
486
487     strncpy(mount_info[3].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
488     strncpy(mount_info[4].src_path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
489     strncpy(mount_info[5].src_path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
490 #else
491     strncpy(mount_info[1].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
492 #endif
493
494     if (chdir(app_rootpath) != 0)
495     {
496         LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
497         return -1;
498     }
499     LOGI("app_rootpath: %s", app_rootpath);
500
501     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); i++)
502     {
503         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
504         {
505             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
506                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
507
508             int j = 0;
509             for (j = i; j > 0; --j)
510             {
511                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
512             }
513             return -1;
514         }
515     }
516
517     return 0;
518 }
519
520 int
521 do_pre_exe(const char* package_name, const char* bin_path, const char* package_id)
522 {
523         char* app_rootpath = NULL;
524         char osp_app_data_path[PATH_MAX] = {0, };
525         //char internal_installed = 1; // true
526         int mmc_mounted = 0;
527     struct statfs fs;
528
529         /* e.g., app_rootdir is "/opt/apps/com.samsung.basicapp or /opt/osp/applications/[appId] */
530         app_rootpath = get_app_rootpath_from_path(bin_path);
531
532         LOGI("[data_caging] do_pre_exe() was called, package name: %s, \
533             binary path: %s, application root(home) path: %s, package id: %s",
534             package_name, bin_path, app_rootpath, package_id);
535
536         umask(0000);
537
538         // TODO: Check whether the application is installed in internal or external storage.
539         // Check installation position using the input path.
540     //if (internal_installed)
541     //{
542
543     if (!internal_is_mounted(package_id))
544     {
545         if (mount_slp_paths(app_rootpath) != 0)
546             goto ERROR;
547
548         if (mount_osp_internal_paths(app_rootpath, package_id) != 0)
549             goto ERROR;
550     }
551
552     int ret = 0;
553     ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
554     if (ret < 0)
555     {
556         LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
557     }
558     if (mmc_mounted == 1)
559     {
560         LOGI("MMC is mounted.");
561         if (create_osp_external_paths(app_rootpath, package_id) != 0)
562         {
563             goto ERROR;
564         }
565
566         if (!external_is_mounted(package_id))
567         {
568             if (mount_osp_external_paths(app_rootpath, package_id) != 0)
569             {
570                 goto ERROR;
571             }
572         }
573     }
574     /*}
575         else
576         {
577             // TODO mount_external_paths(app_rootpath);
578         }*/
579         LOGI("mount() succeeded.");
580
581         if (chroot(app_rootpath) != 0)
582         {
583                 LOGE("chroot() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
584                 goto ERROR;
585         }
586     if (chdir("/") != 0)
587         {
588                 LOGE("chdir() failed, path: /, errno: %d (%s)", errno, strerror(errno));
589                 goto ERROR;
590         }
591         LOGI("chroot() succeeded.");
592
593         // set current working dir to "/opt/apps/{packageId}/data"
594 #if 0
595         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
596         strncat(osp_app_data_path, "/data", strlen("/data"));
597 #endif
598
599         if (chdir("/data") != 0)
600         {
601                 LOGE("chdir() failed, path: /data, errno: %d (%s)", errno, strerror(errno));
602                 goto ERROR;
603         }
604
605         free(app_rootpath);
606     umask(0022);
607
608         LOGI("[data_caging] do_pre_exec() succeeded.");
609         return 0;
610
611 ERROR:
612     free(app_rootpath);
613     umask(0022);
614
615         LOGI("[data_caging] do_pre_exec() failed.");
616     return -1;
617 }
618
619 int
620 do_pre_exec(const char* package_name, const char* bin_path)
621 {
622         char* app_rootpath = NULL;
623     char app_compat_path[PATH_MAX] = { 0, };
624     const char app_compat_file[] = "/info/compat.info\0";
625     int pathlen = 0;
626     char package_id[_MAX_PACKAGEID_LENGTH + 1] = { 0, };
627     char osp_app_data_path[PATH_MAX] = { 0, };
628     int osp_compat = 0;
629
630     LOGI("do_pre_exec() is called, package_name: %s, bin_path: %s", package_name, bin_path);
631
632         app_rootpath = get_app_rootpath_from_path(bin_path);
633
634         strncpy(app_compat_path, app_rootpath, strlen(app_rootpath));
635         strncat(app_compat_path, app_compat_file, strlen(app_compat_file));
636     if (access(app_compat_path, F_OK) == 0)
637     {
638         osp_compat = 1;
639     }
640
641     // XXX: temp code
642     //if (package_name == NULL)
643     {
644         //LOGI("The package name is empty.");
645         get_package_id_from_app_rootpath(app_rootpath, package_id);
646     }
647 #if 0
648     else
649     {
650         get_package_id_from_package_name(package_name, package_id);
651     }
652 #endif
653     // XXX-end
654
655     LOGI("package name: %s, binary path: %s, package id: %s, OSP compatibility: %d",
656             package_name, bin_path, package_id, osp_compat);
657
658         // FIXME: Temporary code with security risk
659         prctl(PR_SET_KEEPCAPS, 1);
660
661     if (osp_compat == 1)
662     {
663                 free(app_rootpath);
664                 //unshare(CLONE_NEWNS);
665                 return do_pre_exe(package_name, bin_path, package_id);
666     }
667
668     // API version is equal to or greater than Tizen 2.0
669         // Set current working dir to "/opt/apps/{pkgId}/data"
670         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
671         strncat(osp_app_data_path, "/data", strlen("/data"));
672
673         if (chdir(osp_app_data_path) != 0)
674         {
675                 LOGE("chdir() failed, path: %s, errno: %d (%s)", osp_app_data_path, errno, strerror(errno));
676                 goto ERROR;
677         }
678
679         if (link_osp_share_path(app_rootpath, package_id) != 0)
680         {
681                 goto ERROR;
682         }
683
684         LOGI("[data_caging] do_pre_exec() succeeded.");
685         free(app_rootpath);
686         return 0;
687
688 ERROR:
689         free(app_rootpath);
690         return -1;
691 }