d39d5517232ce213f47de995c68f26ba8951e34f
[framework/osp/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         { "/smack",             "./smack" },
273         { "/srv",               "./srv" },
274         { "/sys",               "./sys" },
275         { "/sys/kernel/debug",  "./sys/kernel/debug" },
276         { "/tmp",               "./tmp" },
277         { "/usr",               "./usr" },
278         { "/var",               "./var" },
279         { "/var/run",           "./var/run" }
280     };
281
282     if (chdir(app_rootpath) != 0)
283     {
284         LOGE("chdir() failed path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
285         return -1;
286     }
287
288     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
289     {
290         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
291         {
292             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
293                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
294
295             int j = 0;
296             for (j = i; j > 0; --j)
297             {
298                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
299             }
300             return -1;
301         }
302     }
303
304     return 0;
305 }
306
307 static int
308 mount_osp_internal_paths(const char* app_rootpath, const char* pkgid)
309 {
310     int i = 0;
311     char osp_share_pkgid_path[PATH_MAX] = {0, };
312     char osp_share2_pkgid_path[PATH_MAX] = {0, };
313     struct _path_info mount_info[] = {
314         { "\0",                    "./data/Share" },
315         { "\0",                    "./data/Share2" },
316         { "/opt/usr/share/.osp-compat/share",  "./Share" },
317         { "/opt/usr/share/.osp-compat/share2", "./Share2" },
318       //{ "/opt/osp/clipboard",    "./Clipboard" },
319       //{ "/opt/osp/partner/npki", "./NPKI" },
320       //{ "/opt/osp/system",       "./System" },
321       //{ "/opt/osp/Tmp",          "./Tmp" },
322         { "/opt/usr/media",        "./Media" }
323     };
324
325     strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
326     strncat(osp_share_pkgid_path, "share/", 6);
327     strncat(osp_share_pkgid_path, pkgid, strlen(pkgid));
328
329     strncpy(osp_share2_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
330     strncat(osp_share2_pkgid_path, "share2/", 7);
331     strncat(osp_share2_pkgid_path, pkgid, strlen(pkgid));
332
333     strncpy(mount_info[0].src_path, osp_share_pkgid_path, strlen(osp_share_pkgid_path));
334     strncpy(mount_info[1].src_path, osp_share2_pkgid_path, strlen(osp_share2_pkgid_path));
335
336     if (chdir(app_rootpath) != 0)
337     {
338         LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
339         return -1;
340     }
341
342     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
343     {
344         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
345         {
346             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
347                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
348
349             int j = 0;
350             for (j = i; j > 0; --j)
351             {
352                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
353             }
354             return -1;
355         }
356     }
357
358     return 0;
359 }
360
361 static int
362 link_osp_share_path(const char* app_rootpath, const char* pkgid)
363 {
364     char osp_app_share_path[PATH_MAX] = { 0, };
365     char osp_app_share2_path[PATH_MAX] = { 0, };
366     char osp_share_pkgid_path[PATH_MAX] = { 0, };
367     char osp_share2_pkgid_path[PATH_MAX] = { 0, };
368
369     strncpy(osp_app_share_path, app_rootpath, strlen(app_rootpath));
370     strncat(osp_app_share_path, "/shared/data", 12);
371
372     strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
373     strncat(osp_share_pkgid_path, "share/", 6);
374     strncat(osp_share_pkgid_path, pkgid, strlen(pkgid));
375
376     strncpy(osp_app_share2_path, app_rootpath, strlen(app_rootpath));
377     strncat(osp_app_share2_path, "/shared/trusted", 15);
378
379     strncpy(osp_share2_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
380     strncat(osp_share2_pkgid_path, "share2/", 7);
381     strncat(osp_share2_pkgid_path, pkgid, strlen(pkgid));
382
383     unlink(osp_share_pkgid_path);
384     unlink(osp_share2_pkgid_path);
385
386     int ret = symlink(osp_app_share_path, osp_share_pkgid_path);
387     if (ret == -1 && errno != EEXIST)
388     {
389         LOGE("symlink() failed, src path: %s, dest path: %s, errno: %d (%s)",
390                 osp_app_share_path, osp_share_pkgid_path, errno, strerror(errno));
391         return -1;
392     }
393
394     ret = symlink(osp_app_share2_path, osp_share2_pkgid_path);
395     if (ret == -1 && errno != EEXIST)
396     {
397         LOGE("symlink() failed, src path: %s, dest path: %s, errno: %d (%s)",
398                 osp_app_share2_path, osp_share2_pkgid_path, errno, strerror(errno));
399         return -1;
400     }
401
402     return 0;
403 }
404
405 static int
406 create_osp_external_paths(const char* app_rootpath, const char* pkgid)
407 {
408     char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
409     char osp_ext_apps_pkgid_share_path[PATH_MAX] = {0, };
410     char osp_ext_apps_pkgid_share2_path[PATH_MAX] = {0, };
411     char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
412     char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
413         struct _dir_info external_dirs[] = {
414         { "./HomeExt",           0000, 0},
415         { "./ShareExt",          0000, 0},
416         { "./Share2Ext",         0000, 0},
417         { "/opt/storage/sdcard/osp",            0777,   0 },
418         { "/opt/storage/sdcard/osp/apps",       0777,   0 },
419         { "/opt/storage/sdcard/osp/share",      0777,   0 },
420         { "/opt/storage/sdcard/osp/share2",     0777,   0 },
421         { "\0", 0777, 0},
422         { "\0", 0777, 0},
423         { "\0", 0777, 0},
424         { "\0", 0777, 0},
425         { "\0", 0777, 0},
426         { "/opt/storage/sdcard/Images", 0777,   0 },
427         { "/opt/storage/sdcard/Sounds", 0777,   0 },
428         { "/opt/storage/sdcard/Videos", 0777,   0 },
429       //{ "/opt/storage/sdcard/Themes", 0777,   0 },
430         { "/opt/storage/sdcard/Others", 0777,   0 }
431         };
432     int i = 0;
433
434     strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
435     strncat(osp_ext_apps_pkgid_path, "apps/", 5);
436     strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
437
438     strncpy(osp_ext_apps_pkgid_share_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
439     strncat(osp_ext_apps_pkgid_share_path, "/Share", 6);
440
441     strncpy(osp_ext_apps_pkgid_share2_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
442     strncat(osp_ext_apps_pkgid_share2_path, "/Share2", 7);
443
444     strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
445     strncat(osp_ext_share_pkgid_path, "share/", 6);
446     strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
447
448     strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
449     strncat(osp_ext_share2_pkgid_path, "share2/", 7);
450     strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
451
452     strncpy(external_dirs[7].path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
453     strncpy(external_dirs[8].path, osp_ext_apps_pkgid_share_path, strlen(osp_ext_apps_pkgid_share_path));
454     strncpy(external_dirs[9].path, osp_ext_apps_pkgid_share2_path, strlen(osp_ext_apps_pkgid_share2_path));
455     strncpy(external_dirs[10].path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
456     strncpy(external_dirs[11].path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
457
458     if (chdir(app_rootpath) != 0)
459     {
460         LOGE("chdir() failed (%s), path: %s", strerror(errno), app_rootpath);
461         return -1;
462     }
463
464     for (i = 0; i < sizeof(external_dirs)/sizeof(struct _dir_info); i++)
465     {
466         int ret = mkdir(external_dirs[i].path, external_dirs[i].mode);
467         if (ret == -1 && errno != 17) // EEXIST
468         {
469             LOGE("mkdir() failed, path: %s, errno: %d (%s)", external_dirs[i].path, errno, strerror(errno));
470             return -1;
471         }
472     }
473
474     return 0;
475 }
476
477 static int
478 mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
479 {
480     char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
481     char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
482     char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
483     struct _path_info mount_info[] = {
484         { "/opt/storage/sdcard",  "./Storagecard/Media" },
485         { "/opt/storage/sdcard/osp/share",  "./ShareExt" },
486         { "/opt/storage/sdcard/osp/share2", "./Share2Ext" },
487         { "\0",  "./HomeExt" },
488         { "\0",  "./HomeExt/Share" },
489         { "\0",  "./HomeExt/Share2" },
490     };
491     int i = 0;
492
493     strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
494     strncat(osp_ext_apps_pkgid_path, "apps/", 5);
495     strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
496
497     strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
498     strncat(osp_ext_share_pkgid_path, "share/", 6);
499     strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
500
501     strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
502     strncat(osp_ext_share2_pkgid_path, "share2/", 7);
503     strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
504
505     strncpy(mount_info[3].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
506     strncpy(mount_info[4].src_path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
507     strncpy(mount_info[5].src_path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
508
509     if (chdir(app_rootpath) != 0)
510     {
511         LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
512         return -1;
513     }
514     LOGI("app_rootpath: %s", app_rootpath);
515
516     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); i++)
517     {
518         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
519         {
520             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
521                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
522
523             int j = 0;
524             for (j = i; j > 0; --j)
525             {
526                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
527             }
528             return -1;
529         }
530     }
531
532     return 0;
533 }
534
535 int
536 do_pre_exe(const char* package_name, const char* bin_path, const char* package_id)
537 {
538         char* app_rootpath = NULL;
539         char osp_app_data_path[PATH_MAX] = {0, };
540         //char internal_installed = 1; // true
541         int mmc_mounted = 0;
542     struct statfs fs;
543
544         /* e.g., app_rootdir is "/opt/apps/com.samsung.basicapp or /opt/osp/applications/[appId] */
545         app_rootpath = get_app_rootpath_from_path(bin_path);
546
547         LOGI("[data_caging] do_pre_exe() was called, package name: %s, \
548             binary path: %s, application root(home) path: %s, package id: %s",
549             package_name, bin_path, app_rootpath, package_id);
550
551         umask(0000);
552
553         // TODO: Check whether the application is installed in internal or external storage.
554         // Check installation position using the input path.
555     //if (internal_installed)
556     //{
557
558     if (!internal_is_mounted(package_id))
559     {
560         if (mount_slp_paths(app_rootpath) != 0)
561             goto ERROR;
562
563         if (mount_osp_internal_paths(app_rootpath, package_id) != 0)
564             goto ERROR;
565     }
566
567     int ret = 0;
568     ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
569     if (ret < 0)
570     {
571         LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
572     }
573     if (mmc_mounted == 1)
574     {
575         LOGI("MMC is mounted.");
576         if (create_osp_external_paths(app_rootpath, package_id) != 0)
577         {
578             goto ERROR;
579         }
580
581         if (!external_is_mounted(package_id))
582         {
583             if (mount_osp_external_paths(app_rootpath, package_id) != 0)
584             {
585                 goto ERROR;
586             }
587         }
588     }
589     /*}
590         else
591         {
592             // TODO mount_external_paths(app_rootpath);
593         }*/
594         LOGI("mount() succeeded.");
595
596         if (chroot(app_rootpath) != 0)
597         {
598                 LOGE("chroot() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
599                 goto ERROR;
600         }
601     if (chdir("/") != 0)
602         {
603                 LOGE("chdir() failed, path: /, errno: %d (%s)", errno, strerror(errno));
604                 goto ERROR;
605         }
606         LOGI("chroot() succeeded.");
607
608         // set current working dir to "/opt/apps/{packageId}/data"
609 #if 0
610         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
611         strncat(osp_app_data_path, "/data", strlen("/data"));
612 #endif
613
614         if (chdir("/data") != 0)
615         {
616                 LOGE("chdir() failed, path: /data, errno: %d (%s)", errno, strerror(errno));
617                 goto ERROR;
618         }
619
620         free(app_rootpath);
621     umask(0022);
622
623         LOGI("[data_caging] do_pre_exec() succeeded.");
624         return 0;
625
626 ERROR:
627     free(app_rootpath);
628     umask(0022);
629
630         LOGI("[data_caging] do_pre_exec() failed.");
631     return -1;
632 }
633
634 int
635 do_pre_exec(const char* package_name, const char* bin_path)
636 {
637         char* app_rootpath = NULL;
638     char app_compat_path[PATH_MAX] = { 0, };
639     const char app_compat_file[] = "/info/compat.info\0";
640     int pathlen = 0;
641     char package_id[_MAX_PACKAGEID_LENGTH + 1] = { 0, };
642     char osp_app_data_path[PATH_MAX] = { 0, };
643     int osp_compat = 0;
644
645     LOGI("do_pre_exec() is called, package_name: %s, bin_path: %s", package_name, bin_path);
646
647         app_rootpath = get_app_rootpath_from_path(bin_path);
648
649         strncpy(app_compat_path, app_rootpath, strlen(app_rootpath));
650         strncat(app_compat_path, app_compat_file, strlen(app_compat_file));
651     if (access(app_compat_path, F_OK) == 0)
652     {
653         osp_compat = 1;
654     }
655
656     // XXX: temp code
657     //if (package_name == NULL)
658     {
659         //LOGI("The package name is empty.");
660         get_package_id_from_app_rootpath(app_rootpath, package_id);
661     }
662 #if 0
663     else
664     {
665         get_package_id_from_package_name(package_name, package_id);
666     }
667 #endif
668     // XXX-end
669
670     LOGI("package name: %s, binary path: %s, package id: %s, OSP compatibility: %d",
671             package_name, bin_path, package_id, osp_compat);
672
673         // FIXME: Temporary code with security risk
674         prctl(PR_SET_KEEPCAPS, 1);
675
676     if (osp_compat == 1)
677     {
678                 free(app_rootpath);
679                 //unshare(CLONE_NEWNS);
680                 return do_pre_exe(package_name, bin_path, package_id);
681     }
682
683     // API version is equal to or greater than Tizen 2.0
684         // Set current working dir to "/opt/apps/{pkgId}/data"
685         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
686         strncat(osp_app_data_path, "/data", strlen("/data"));
687
688         if (chdir(osp_app_data_path) != 0)
689         {
690                 LOGE("chdir() failed, path: %s, errno: %d (%s)", osp_app_data_path, errno, strerror(errno));
691                 goto ERROR;
692         }
693
694         if (link_osp_share_path(app_rootpath, package_id) != 0)
695         {
696                 goto ERROR;
697         }
698
699         LOGI("[data_caging] do_pre_exec() succeeded.");
700         free(app_rootpath);
701         return 0;
702
703 ERROR:
704         free(app_rootpath);
705         return -1;
706 }