[Prevent] Logically dead code
[platform/core/telephony/telephony-daemon.git] / src / main.c
1 /*
2  * telephony-daemon
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <pthread.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <dlfcn.h>
28 #include <getopt.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/sysinfo.h>
32
33 #include <glib.h>
34 #include <glib-object.h>
35 #include <dlog.h>
36
37 #include <tcore.h>
38 #include <plugin.h>
39 #include <server.h>
40 #include <util.h>
41 #include <log.h>
42
43 #include "monitor.h"
44
45 #ifndef DAEMON_VERSION
46 #define DAEMON_VERSION "unknown"
47 #endif
48
49 static Server *_server;
50
51 void tcore_log(enum tcore_log_type type, enum tcore_log_priority priority, const char *tag, const char *fmt, ...)
52 {
53         va_list ap;
54         char buf[1024];
55
56         va_start(ap, fmt);
57         vsnprintf(buf, 1023, fmt, ap);
58         va_end(ap);
59
60         __dlog_print(type, priority, tag, buf);
61 }
62
63 static gboolean load_plugins(Server *s, const char *path, int flag_test_load)
64 {
65         const gchar *file;
66         char *filename;
67         GDir *dir;
68         void *handle;
69         GSList *list;
70         struct stat stat_buf;
71         char file_date[27];
72
73         TcorePlugin *p;
74         struct tcore_plugin_define_desc *desc;
75
76         if ((path == NULL) || (s == NULL))
77                 return FALSE;
78
79         dir = g_dir_open(path, 0, NULL);
80         if (dir == NULL)
81                 return FALSE;
82
83         while ((file = g_dir_read_name(dir)) != NULL) {
84                 if (g_str_has_prefix(file, "lib") == TRUE
85                                 || g_str_has_suffix(file, ".so") == FALSE)
86                         continue;
87
88                 filename = g_build_filename(path, file, NULL);
89
90                 handle = dlopen(filename, RTLD_NOW);
91                 if (handle == NULL) {
92                         dbg("fail to load '%s': %s", filename, dlerror());
93                         g_free(filename);
94                         continue;
95                 }
96
97                 if (flag_test_load) {
98                         dbg("success to load '%s'", filename);
99                         dlclose(handle);
100                         g_free(filename);
101                         continue;
102                 }
103
104                 desc = dlsym(handle, "plugin_define_desc");
105                 if (desc == NULL) {
106                         dbg("fail to load symbol: %s", dlerror());
107                         dlclose(handle);
108                         g_free(filename);
109                         continue;
110                 }
111
112                 dbg("%s plugin", desc->name);
113                 dbg(" - path = %s", filename);
114                 dbg(" - version = %d", desc->version);
115                 dbg(" - priority = %d", desc->priority);
116
117                 memset(&stat_buf, 0, sizeof(struct stat));
118                 if (stat(filename, &stat_buf) == 0) {
119                         if (ctime_r(&stat_buf.st_mtime, file_date) != NULL) {
120                                 if (strlen(file_date) > 1)
121                                         file_date[strlen(file_date)-1] = '\0';
122
123                                 dbg(" - date = %s", file_date);
124                         }
125                 }
126
127                 if (desc->load) {
128                         if (desc->load() == FALSE) {
129                                 dbg("false return from load(). skip this plugin");
130                                 dlclose(handle);
131                                 g_free(filename);
132                                 continue;
133                         }
134                 }
135
136                 p = tcore_plugin_new(s, desc, filename, handle);
137                 tcore_server_add_plugin(s, p);
138
139                 dbg("%s added", desc->name);
140                 g_free(filename);
141         }
142         g_dir_close(dir);
143
144         info("plugin load finished");
145
146         list = tcore_server_ref_plugins(s);
147         for (; list; list = list->next) {
148                 p = list->data;
149                 if (p == NULL)
150                         continue;
151
152                 desc = (struct tcore_plugin_define_desc *)tcore_plugin_get_description(p);
153                 if (desc == NULL)
154                         continue;
155
156                 if (desc->init == NULL)
157                         continue;
158
159                 if (desc->init(p) == FALSE) {
160                         dbg("plugin(%s) init failed.", tcore_plugin_get_filename(p));
161                 }
162         }
163
164         info("plugin init finished");
165
166         return TRUE;
167 }
168
169 static void usage(const char *name)
170 {
171         printf("Usage: %s [OPTION]... [PLUGIN_PATH]\n", name);
172         printf("\n");
173         printf("  -T, --testload\t run with plugin load test mode and exit\n");
174         printf("  -h, --help\t\t display this help and exit\n");
175         printf("\n");
176 }
177
178 static void on_signal_usr1(int signo)
179 {
180         if (_server == NULL)
181                 return;
182
183         monitor_server_state(_server);
184 }
185
186 int main(int argc, char *argv[])
187 {
188         struct sigaction sigact_usr1;
189         Server *s;
190         int flag_test_load = 0;
191         int opt;
192         int opt_index;
193         struct option options[] = {
194                         { "help", 0, 0, 0 },
195                         { "testload", 0, &flag_test_load, 1 },
196                         { 0, 0, 0, 0 }
197         };
198         char *plugin_path = "/usr/lib/telephony/plugins/";
199         char *tcore_ver;
200         struct sysinfo info;
201
202         if (sysinfo(&info) == 0) {
203                 info("uptime: %ld secs", info.uptime);
204         }
205
206         info("daemon version: %s", DAEMON_VERSION);
207
208         tcore_ver = tcore_util_get_version();
209         info("libtcore version: %s", tcore_ver);
210         free(tcore_ver);
211
212         sigact_usr1.sa_handler = on_signal_usr1;
213         sigemptyset(&sigact_usr1.sa_mask);
214         sigaddset(&sigact_usr1.sa_mask, SIGUSR1);
215         sigact_usr1.sa_flags = 0;
216
217         if (sigaction(SIGUSR1, &sigact_usr1, NULL) < 0) {
218                 warn("sigaction(SIGUSR1) failed.");
219         }
220
221         while (1) {
222                 opt = getopt_long(argc, argv, "hT", options, &opt_index);
223
224                 if (opt == -1)
225                         break;
226
227                 switch (opt) {
228                         case 0:
229                                 switch (opt_index) {
230                                         case 0: // help
231                                                 usage(argv[0]);
232                                                 return 0;
233                                                 break;
234                                 }
235                                 break;
236
237                         case 'h':
238                                 usage(argv[0]);
239                                 return 0;
240                                 break;
241
242                         case 'T':
243                                 flag_test_load = 1;
244                                 break;
245                 }
246         }
247
248         if (optind < argc)
249                 plugin_path = argv[optind];
250
251         info("plugin_path: [%s]", plugin_path);
252
253 #if !GLIB_CHECK_VERSION(2,35,0)
254         g_type_init();
255 #endif
256 #if !GLIB_CHECK_VERSION (2, 31, 0)
257         g_thread_init(NULL);
258 #endif
259
260         s = tcore_server_new();
261         if (s == NULL) {
262                 err("server_new failed.");
263                 goto end;
264         }
265         _server = s;
266
267         if (load_plugins(s, plugin_path, flag_test_load) == FALSE)
268                 goto free_end;
269
270         if (flag_test_load)
271                 goto free_end;
272
273         info("server mainloop start");
274
275         if (tcore_server_run(s) == FALSE) {
276                 err("server_run failed.");
277         }
278
279         /*
280          * RUNNING
281          */
282
283 free_end:
284         info("server end");
285         tcore_server_free(s);
286
287 end:
288         return EXIT_SUCCESS;
289 }