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