Add .changes file
[profile/ivi/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
30 #include <glib.h>
31 #include <glib-object.h>
32
33 #include <tcore.h>
34 #include <plugin.h>
35 #include <server.h>
36
37 #include "monitor.h"
38
39 static Server *_server;
40
41 static gboolean load_plugins(Server *s, const char *path, int flag_test_load)
42 {
43         const gchar *file;
44         char *filename;
45         GDir *dir;
46         void *handle;
47         GSList *list;
48
49         TcorePlugin *p;
50         struct tcore_plugin_define_desc *desc;
51
52         dir = g_dir_open(path, 0, NULL);
53         if (!dir)
54                 return FALSE;
55
56         while ((file = g_dir_read_name(dir)) != NULL) {
57                 if (g_str_has_prefix(file, "lib") == TRUE || g_str_has_suffix(file, ".so") == FALSE)
58                         continue;
59
60                 filename = g_build_filename(path, file, NULL);
61
62                 handle = dlopen(filename, RTLD_NOW);
63                 if (handle == NULL) {
64                         dbg("fail to load '%s': %s", filename, dlerror());
65                         g_free(filename);
66                         continue;
67                 }
68
69                 if (flag_test_load) {
70                         dbg("success to load '%s'", filename);
71                         dlclose(handle);
72                         g_free(filename);
73                         continue;
74                 }
75
76                 desc = dlsym(handle, "plugin_define_desc");
77                 if (!desc) {
78                         dbg("fail to load symbol: %s", dlerror());
79                         dlclose(handle);
80                         g_free(filename);
81                         continue;
82                 }
83
84                 if (desc->load) {
85                         if (desc->load() == FALSE) {
86                                 dbg("false return from load(). skip this plugin");
87                                 dlclose(handle);
88                                 g_free(filename);
89                                 continue;
90                         }
91                 }
92
93                 p = tcore_plugin_new(s, desc, filename, handle);
94                 tcore_server_add_plugin(s, p);
95
96                 dbg("plugin(%s) added", filename);
97                 g_free(filename);
98         }
99         g_dir_close(dir);
100
101         list = tcore_server_ref_plugins(s);
102         for (; list; list = list->next) {
103                 p = list->data;
104                 if (!p)
105                         continue;
106
107                 desc = (struct tcore_plugin_define_desc *)tcore_plugin_get_description(p);
108                 if (!desc)
109                         continue;
110
111                 if (!desc->init)
112                         continue;
113
114                 if (!desc->init(p)) {
115                         dbg("plugin(%s) init failed.", tcore_plugin_get_filename(p));
116                 }
117         }
118
119         return TRUE;
120 }
121
122 static void usage(const char *name)
123 {
124         printf("Usage: %s [OPTION]... [PLUGIN_PATH]\n", name);
125         printf("\n");
126         printf("  -T, --testload\t run with plugin load test mode and exit\n");
127         printf("  -h, --help\t\t display this help and exit\n");
128         printf("\n");
129 }
130
131 static void on_signal_usr1(int signo)
132 {
133         if (!_server)
134                 return;
135
136         monitor_server_state(_server);
137 }
138
139 int main(int argc, char *argv[])
140 {
141         struct sigaction sigact_usr1;
142         Server *s;
143         int flag_test_load=0;
144         int opt;
145         int opt_index;
146         struct option options[] = {
147                         { "help", 0, 0, 0 },
148                         { "testload", 0, &flag_test_load, 1 },
149                         { 0, 0, 0, 0 }
150         };
151         char *plugin_path = "/usr/lib/telephony/plugins/";
152
153         sigact_usr1.sa_handler = on_signal_usr1;
154         sigemptyset(&sigact_usr1.sa_mask);
155         sigaddset(&sigact_usr1.sa_mask, SIGUSR1);
156         sigact_usr1.sa_flags = 0;
157
158         if (sigaction(SIGUSR1, &sigact_usr1, NULL) < 0) {
159                 warn("sigaction(SIGUSR1) failed.");
160         }
161
162
163         while (1) {
164                 opt = getopt_long(argc, argv, "hT", options, &opt_index);
165
166                 if (-1 == opt)
167                         break;
168
169                 switch (opt) {
170                         case 0:
171                                 switch (opt_index) {
172                                         case 0: // help
173                                                 usage(argv[0]);
174                                                 return 0;
175                                                 break;
176                                 }
177                                 break;
178
179                         case 'h':
180                                 usage(argv[0]);
181                                 return 0;
182                                 break;
183
184                         case 'T':
185                                 flag_test_load = 1;
186                                 break;
187                 }
188         }
189
190         if (optind < argc) {
191                 plugin_path = argv[optind];
192         }
193
194         dbg("plugin_path: [%s]", plugin_path);
195         dbg("flag[test_load]: %d", flag_test_load);
196
197         g_type_init();
198 #if !GLIB_CHECK_VERSION (2, 31, 0)
199         g_thread_init(NULL);
200 #endif
201
202         s = tcore_server_new();
203         if (!s) {
204                 err("server_new failed.");
205                 goto end;
206         }
207         _server = s;
208
209         if (!load_plugins(s, plugin_path, flag_test_load)) {
210                 goto free_end;
211         }
212
213         if (flag_test_load)
214                 goto free_end;
215
216         if (tcore_server_run(s) == FALSE) {
217                 err("server_run failed.");
218                 goto free_end;
219         }
220
221         /*
222          * RUNNING
223          */
224
225 free_end:
226         dbg("exit!");
227         tcore_server_free(s);
228
229 end:
230         return EXIT_SUCCESS;
231 }