tizen 2.3 release
[apps/livebox/data-provider-master.git] / src / main.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <sys/signalfd.h>
24 #include <ctype.h>
25
26 #include <systemd/sd-daemon.h>
27
28 #include <Ecore.h>
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <aul.h>
32 #include <vconf.h>
33
34 #include <packet.h>
35 #include <dlog.h>
36
37 #if defined(HAVE_LIVEBOX)
38
39 #include <dynamicbox_service.h>
40 #include <dynamicbox_conf.h>
41
42 #include "slave_life.h"
43 #include "slave_rpc.h"
44 #include "client_life.h"
45 #include "instance.h"
46 #include "buffer_handler.h"
47 #include "script_handler.h"
48 #include "package.h"
49 #include "group.h"
50 #include "dead_monitor.h"
51 #include "io.h"
52 #include "xmonitor.h"
53 #include "server.h"
54 #include "event.h"
55 #include "file_service.h"
56 #include "utility_service.h"
57 #endif
58
59 #include "conf.h"
60 #include "setting.h"
61 #include "util.h"
62 #include "debug.h"
63 #include "critical_log.h"
64 #include "shortcut_service.h"
65 #include "notification_service.h"
66 #include "badge_service.h"
67
68 #if defined(FLOG)
69 #define TMP_LOG_FILE "/tmp/live.log"
70 FILE *__file_log_fp;
71 #endif
72
73 static inline int app_create(void)
74 {
75         int ret;
76
77         if (access(DYNAMICBOX_CONF_LOG_PATH, R_OK | W_OK) != 0) {
78                 if (mkdir(DYNAMICBOX_CONF_LOG_PATH, 0755) < 0) {
79                         ErrPrint("Failed to create %s (%s)\n", DYNAMICBOX_CONF_LOG_PATH, strerror(errno));
80                 }
81         }
82
83         /*!
84          * \note
85          * Dead signal handler has to be initialized before
86          * initate package or client (slave and client).
87          *
88          * Because while creating slaves for packages.
89          * It could be crashed before complete the initation stage.
90          *
91          * Then the dead callback should be invoked to handle it properly.
92          *
93          * To enable the dead signal handler,
94          * dead_init should be done before other components are initiated.
95          */
96         ret = setting_init();
97         if (ret < 0) {
98                 DbgPrint("Setting initialized: %d\n", ret);
99         }
100
101 #if defined(HAVE_LIVEBOX)
102         ret = client_init();
103         if (ret < 0) {
104                 DbgPrint("Client initialized: %d\n", ret);
105         }
106
107         ret = dead_init();
108         if (ret < 0) {
109                 DbgPrint("Dead callback is registered: %d\n", ret);
110         }
111
112         ret = group_init();
113         if (ret < 0) {
114                 DbgPrint("group init: %d\n", ret);
115         }
116
117         ret = io_init();
118         if (ret < 0) {
119                 DbgPrint("Init I/O: %d\n", ret);
120         }
121
122         ret = package_init();
123         if (ret < 0) {
124                 DbgPrint("pkgmgr initialized: %d\n", ret);
125         }
126
127         instance_init();
128
129         ret = xmonitor_init();
130         if (ret < 0) {
131                 DbgPrint("XMonitor init is done: %d\n", ret);
132         }
133
134         ret = buffer_handler_init();
135         if (ret < 0) {
136                 DbgPrint("Buffer handler init is done: %d\n", ret);
137         }
138
139         /*!
140          * \note
141          * After initiate all other sub-systtems,
142          * Enable the server socket.
143          */
144         ret = server_init();
145         if (ret < 0) {
146                 DbgPrint("Server initialized: %d\n", ret);
147         }
148
149         event_init();
150
151         script_init();
152
153         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_FILE)) {
154                 file_service_init();
155         }
156
157         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_UTILITY)) {
158                 utility_service_init();
159         }
160 #endif
161
162         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_SHORTCUT)) {
163                 shortcut_service_init();
164         }
165
166         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_NOTIFICATION)) {
167                 notification_service_init();
168         }
169
170         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_BADGE)) {
171                 badge_service_init();
172         }
173
174         return 0;
175 }
176
177 static inline int app_terminate(void)
178 {
179         int ret;
180
181         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_BADGE)) {
182                 ret = badge_service_fini();
183                 if (ret < 0) {
184                         DbgPrint("badge: %d\n", ret);
185                 }
186         }
187
188         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_NOTIFICATION)) {
189                 ret = notification_service_fini();
190                 if (ret < 0) {
191                         DbgPrint("noti: %d\n", ret);
192                 }
193         }
194
195         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_SHORTCUT)) {
196                 ret = shortcut_service_fini();
197                 if (ret < 0) {
198                         DbgPrint("shortcut: %d\n", ret);
199                 }
200         }
201
202 #if defined(HAVE_LIVEBOX)
203         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_FILE)) {
204                 ret = file_service_fini();
205                 if (ret < 0) {
206                         DbgPrint("Finalize the file service: %d\n", ret);
207                 }
208         }
209
210         ret = server_fini();
211         if (ret < 0) {
212                 DbgPrint("Finalize server: %d\n", ret);
213         }
214
215         ret = dead_fini();
216         if (ret < 0) {
217                 DbgPrint("dead signal handler finalized: %d\n", ret);
218         }
219
220         if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_UTILITY)) {
221                 ret = utility_service_fini();
222                 if (ret < 0) {
223                         DbgPrint("utility: %d\n", ret);
224                 }
225         }
226
227         ret = event_fini();
228         if (ret < 0) {
229                 DbgPrint("event: %d\n", ret);
230         }
231
232         ret = setting_fini();
233         if (ret < 0) {
234                 DbgPrint("Finalize setting : %d\n", ret);
235         }
236
237         ret = instance_fini();
238         if (ret < 0) {
239                 DbgPrint("Finalizing instances: %d\n", ret);
240         }
241
242         ret = package_fini();
243         if (ret < 0) {
244                 DbgPrint("Finalize package info: %d\n", ret);
245         }
246
247         ret = script_fini();
248         if (ret < 0) {
249                 DbgPrint("script: %d\n", ret);
250         }
251
252         ret = buffer_handler_fini();
253         if (ret < 0) {
254                 DbgPrint("buffer handler: %d\n", ret);
255         }
256
257         xmonitor_fini();
258
259         client_fini();
260
261         ret = io_fini();
262         if (ret < 0) {
263                 DbgPrint("IO finalized: %d\n", ret);
264         }
265
266         ret = group_fini();
267         if (ret < 0) {
268                 DbgPrint("Group finalized: %d\n", ret);
269         }
270 #endif
271
272         DbgPrint("Terminated\n");
273         return 0;
274 }
275
276 static Eina_Bool signal_cb(void *data, Ecore_Fd_Handler *handler)
277 {
278         struct signalfd_siginfo fdsi;
279         ssize_t size;
280         int fd;
281
282         fd = ecore_main_fd_handler_fd_get(handler);
283         if (fd < 0) {
284                 ErrPrint("Unable to get FD\n");
285                 ecore_main_fd_handler_del(handler);
286                 return ECORE_CALLBACK_CANCEL;
287         }
288
289         size = read(fd, &fdsi, sizeof(fdsi));
290         if (size != sizeof(fdsi)) {
291                 ErrPrint("Unable to get siginfo: %s\n", strerror(errno));
292                 ecore_main_fd_handler_del(handler);
293                 return ECORE_CALLBACK_CANCEL;
294         }
295
296         if (fdsi.ssi_signo == SIGTERM) {
297                 int cfd;
298
299                 CRITICAL_LOG("Terminated(SIGTERM)\n");
300
301                 cfd = creat("/tmp/.stop.provider", 0644);
302                 if (cfd < 0 || close(cfd) < 0) {
303                         ErrPrint("stop.provider: %s\n", strerror(errno));
304                 }
305
306                 vconf_set_bool(VCONFKEY_MASTER_STARTED, 0);
307                 //exit(0);
308                 ecore_main_loop_quit();
309         } else if (fdsi.ssi_signo == SIGUSR1) {
310                 /*!
311                  * Turn off auto-reactivation
312                  * Terminate all slaves
313                  */
314 #if defined(HAVE_LIVEBOX)
315                 CRITICAL_LOG("USRS1, Deactivate ALL\n");
316                 slave_deactivate_all(0, 1, 1);
317 #endif
318         } else if (fdsi.ssi_signo == SIGUSR2) {
319                 /*!
320                  * Turn on auto-reactivation
321                  * Launch all slaves again
322                  */
323 #if defined(HAVE_LIVEBOX)
324                 CRITICAL_LOG("USR2, Activate ALL\n");
325                 slave_activate_all();
326 #endif
327         } else {
328                 CRITICAL_LOG("Unknown SIG[%d] received\n", fdsi.ssi_signo);
329         }
330
331         return ECORE_CALLBACK_RENEW;
332 }
333
334 int main(int argc, char *argv[])
335 {
336         int ret;
337         int restart_count = 0;
338         sigset_t mask;
339         Ecore_Fd_Handler *signal_handler = NULL;
340
341 #if defined(FLOG)
342         __file_log_fp = fopen(TMP_LOG_FILE, "w+t");
343         if (!__file_log_fp) {
344                 __file_log_fp = fdopen(1, "w+t");
345         }
346 #endif
347
348         /* appcore_agent_terminate */
349         if (ecore_init() <= 0) {
350                 return -EFAULT;
351         }
352
353         if (util_screen_init() <= 0) {
354                 ecore_shutdown();
355                 return -EFAULT;
356         }
357
358         dynamicbox_conf_init();
359         dynamicbox_conf_load();
360
361         /*!
362          * How could we care this return values?
363          * Is there any way to print something on the screen?
364          */
365         ret = critical_log_init(util_basename(argv[0]));
366         if (ret < 0) {
367                 ErrPrint("Failed to init the critical log\n");
368         }
369
370         /*!
371          * \note
372          * Clear old contents files before start the master provider.
373          */
374         (void)util_unlink_files(DYNAMICBOX_CONF_ALWAYS_PATH);
375         (void)util_unlink_files(DYNAMICBOX_CONF_READER_PATH);
376         (void)util_unlink_files(DYNAMICBOX_CONF_IMAGE_PATH);
377         (void)util_unlink_files(DYNAMICBOX_CONF_LOG_PATH);
378
379         if (util_free_space(DYNAMICBOX_CONF_IMAGE_PATH) < DYNAMICBOX_CONF_MINIMUM_SPACE) {
380                 util_remove_emergency_disk();
381                 util_prepare_emergency_disk();
382         }
383
384         util_setup_log_disk();
385
386         sigemptyset(&mask);
387
388         ret = sigaddset(&mask, SIGTERM);
389         if (ret < 0) {
390                 CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
391         }
392
393         ret = sigaddset(&mask, SIGUSR1);
394         if (ret < 0) {
395                 CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
396         }
397
398         ret = sigaddset(&mask, SIGUSR2);
399         if (ret < 0) {
400                 CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
401         }
402
403         ret = sigprocmask(SIG_BLOCK, &mask, NULL);
404         if (ret < 0) {
405                 CRITICAL_LOG("Failed to mask the SIGTERM: %s\n", strerror(errno));
406         }
407
408         ret = signalfd(-1, &mask, 0);
409         if (ret < 0) {
410                 CRITICAL_LOG("Failed to initiate the signalfd: %s\n", strerror(errno));
411         } else {
412                 signal_handler = ecore_main_fd_handler_add(ret, ECORE_FD_READ, signal_cb, NULL, NULL, NULL);
413                 CRITICAL_LOG("Signal handler initiated: %d\n", ret);
414         }
415
416         ecore_app_args_set(argc, (const char **)argv);
417
418 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
419         g_type_init();
420 #endif
421
422         app_create();
423         sd_notify(0, "READY=1");
424
425         vconf_get_int(VCONFKEY_MASTER_RESTART_COUNT, &restart_count);
426         restart_count++;
427         vconf_set_int(VCONFKEY_MASTER_RESTART_COUNT, restart_count);
428
429         vconf_set_bool(VCONFKEY_MASTER_STARTED, 1);
430         ecore_main_loop_begin();
431         vconf_set_bool(VCONFKEY_MASTER_STARTED, 0);
432
433         app_terminate();
434
435         util_screen_fini();
436
437         if (signal_handler) {
438                 ecore_main_fd_handler_del(signal_handler);
439         }
440
441         ecore_shutdown();
442         critical_log_fini();
443
444 #if defined(FLOG)
445         if (__file_log_fp) {
446                 fclose(__file_log_fp);
447         }
448 #endif
449
450         dynamicbox_conf_reset();
451         return 0;
452 }
453
454 /* End of a file */