remove redundant file open
[framework/osp/loader.git] / osp-system-service-loader / systemservice_loader.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 /**
19  *   @file       systemservice_loader.c
20  *   @brief             This is the implementation for the osp-system-service-loader.
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <dlfcn.h>
26 #include <unistd.h>
27 #include <limits.h>
28 #include <fcntl.h>
29
30 #include <aul.h>
31 #include <dlog.h>
32
33 #undef LOG_TAG
34 #define LOG_TAG "LOADER"
35
36 #define MAX_APPID 20
37 #define MAX_APP_EXECUTABLE_NAME 230
38
39 #define MIN(a,b)  ((a) < (b) ? (a) : (b))
40
41
42 static void
43 print_args(int argc, char* argv[])
44 {
45         const char* p = NULL;
46         int i = 0;
47         for (; i < argc; i++)
48         {
49                 p = argv[i];
50                 LOGI("%dth arg : [%s]", i, p);
51         }
52 }
53
54 static int
55 osp_do_pre_exe(const char* bin_path)
56 {
57         int ret = 0;
58         void* handle = NULL;
59         char* errormsg = 0;
60         int (*do_pre_exec_fn)(const char*, const char*) = NULL;
61
62         handle = dlopen("libosp-env-config.so", RTLD_LAZY | RTLD_LOCAL);
63         if (!handle)
64         {
65                 LOGE("Failed to dlopen libosp-env-config.so (%s)", dlerror());
66                 return -1;
67         }
68         LOGI("dlopen() ok");
69
70         do_pre_exec_fn = (int (*)(const char*, const char*)) dlsym(handle, "do_pre_exec");
71         errormsg = dlerror();
72         if (errormsg != NULL)
73         {
74                 LOGE("Failed to dlsym() (%s)", errormsg);
75                 dlclose(handle);
76                 return -1;
77         }
78         LOGI("dlsym() ok");
79
80         ret = do_pre_exec_fn(NULL, bin_path);
81         if (ret < 0)
82         {
83                 LOGE("Failed to do_pre_exe() (%d)", ret);
84         }
85         LOGI("do_pre_exec() ok");
86
87         dlclose(handle);
88
89         return 0;
90 }
91
92 static int
93 get_appid_executable_name_from_path(const char path[], char appid[], char executable_name[])
94 {
95         // path is ".../[appid]/bin/[executable_name]"
96
97         // Calculate the header
98         const char* p = strrchr(path, '/');
99         if (p == NULL)
100         {
101                 LOGI("Improper path %s", path);
102                 return -1;
103         }
104
105         const int path_len = strlen(path);
106         const int exec_len = strlen(p);
107         if (exec_len <= 0 || exec_len > PATH_MAX || path_len <= 0 || path_len > PATH_MAX)   
108         {   
109                 LOGI("Improper path %s", path);
110                 return -1;
111         }
112
113         strncpy(executable_name, p + 1, exec_len);
114
115 #ifdef _SECURE_LOG
116         LOGI("Exec is %s", executable_name);
117 #endif
118
119         if (path_len < /* '/' */ 1 + 10 + strlen("/bin/") + exec_len)
120         {
121                 LOGI("Improper path %s", path);
122                 return -1;
123         }
124
125         strncpy(appid, p - strlen("bin/") - 10, 10);
126
127         LOGI("PackageId is %s", appid);
128
129         return 1;
130 }
131
132
133 int
134 main(int argc, char* argv[])
135 {
136         void* real_handle = NULL;
137         char* errormsg = 0;
138         char appid[MAX_APPID];
139         char executable_name[MAX_APP_EXECUTABLE_NAME];
140
141         void (*pAppInfoInit)(const char*, const char*, int, char* [], int) = NULL;
142         int (*pRealMain)(int, char* []) = NULL;
143
144         memset(appid, 0, sizeof(appid));
145         memset(executable_name, 0, sizeof(executable_name));
146
147         LOGI("Initializing.");
148         LOGI("argc %d, argv 0x%x.", argc, argv);
149         print_args(argc, argv);
150
151         // convert package path to appId
152         get_appid_executable_name_from_path(argv[0], appid, executable_name);
153         LOGI("Osp appId %s.", appid);
154
155
156         if (getuid() == 0)
157         {
158                 // self caging
159                 osp_do_pre_exe(argv[0]);
160
161                 // do not adjust privilege : root for system services
162         }
163
164
165         // actual loading
166         char buffer[1024];
167
168         snprintf(buffer, 1024, "%s.exe", argv[0]);
169
170
171         real_handle = dlopen(buffer, RTLD_LAZY);
172         if (!real_handle)
173         {
174                 LOGE("Failed to open %s : %s.", buffer, dlerror());
175                 return -1;
176         }
177
178         pAppInfoInit = (void (*)(const char*, const char*, int, char*[], int)) dlsym(real_handle, "InitAppInfo");
179         errormsg = dlerror();
180         if (errormsg != NULL)
181         {
182                 LOGE("Failed to find InitAppInfo() : %s.", errormsg);
183                 dlclose(real_handle);
184                 fprintf(stderr, "executable does not have proper osp library dependency.\n");
185                 return -1;
186         }
187
188         pRealMain = (int (*)(int, char*[])) dlsym(real_handle, "OspMain");
189         errormsg = dlerror();
190         if (errormsg != NULL)
191         {
192                 LOGE("Failed to find OspMain() : %s.", errormsg);
193                 dlclose(real_handle);
194                 return -1;
195         }
196
197         // actual initialization
198         (*pAppInfoInit)(appid, executable_name, argc, argv, -1);
199         (*pRealMain)(argc, argv);
200
201         LOGI("Osp application terminates.");
202
203         //dlclose(real_handle);
204         LOGI("Osp cleanup finished for %s.", argv[0]);
205
206         return 0;
207 }
208