fixed todo merge
[profile/ivi/automotive-message-broker.git] / ambd / main.cpp
1 /*
2 Copyright (C) 2012 Intel Corporation
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #include <iostream>
20 #include <string>
21 #include <getopt.h>
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <pwd.h>
26 #include <grp.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <signal.h>
32 #include <string.h>
33 #include <stdexcept>
34 #include <glib-object.h>
35
36 #ifdef USE_QT_CORE
37
38 #include <QCoreApplication>
39
40 #else 
41
42 #include <glib.h>
43
44 #endif
45
46 #include "pluginloader.h"
47 #include "core.h"
48 #include <debugout.h>
49
50 using namespace std;
51
52 #ifndef USE_QT_CORE
53
54 GMainLoop* mainLoop = nullptr;
55
56 #endif
57
58 void interrupt(int sign)
59 {
60         signal(sign, SIG_IGN);
61         cout<<"Signal caught. Exiting gracefully.\n"<<endl;
62         
63 #ifdef USE_QT_CORE
64         QCoreApplication::exit(0);
65 #else
66         g_main_loop_quit(mainLoop);
67         exit(0);
68 #endif
69 }
70
71 void daemonize();
72
73 void printhelp(const char *argv0);
74
75 static const char shortopts[] = "hvDc:d:";
76
77 static const struct option longopts[] = {
78         { "help", no_argument, NULL, 'h' }, ///< Print the help text
79         { "version", no_argument, NULL, 'v' }, ///< Print the version text
80         { "daemonise", no_argument, NULL, 'D' }, ///< Daemonise
81         { "config", required_argument, NULL, 'c' },
82         { "debug", required_argument, NULL, 'd' },
83         { NULL, 0, NULL, 0 } ///< End
84 };
85
86 int main(int argc, char **argv) 
87 {
88
89         bool isdeamonize=false;
90         int optc;
91         int th = 0;
92         string config="/etc/ambd/config";
93
94         while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
95         {
96                 switch (optc)
97                 {
98                         case 'D':
99                                 isdeamonize = true;
100                                 break;
101                                 
102                         case 'v':
103                                 cout<<PROJECT_NAME<<endl;
104                                 cout<<"Version: "<<PROJECT_VERSION<<endl;
105                                 return (0);
106                                 break;
107                         case 'c':
108                                 cout<<"Config: "<<optarg<<endl;
109                                 config=optarg;
110                                 break;
111                         case 'd':
112                                 th = atoi(optarg);
113                                 DebugOut::setDebugThreshhold(th);
114                                 break;
115                         default:
116                                 cerr<<"Unknown option "<<optc<<endl;
117                                 printhelp(argv[0]);
118                                 return (0);
119                                 break;
120                 }
121         }
122         
123         if(isdeamonize)
124                 daemonize();
125         
126         
127 #ifdef USE_QT_CORE
128
129         QCoreApplication app(argc,argv);
130
131 #else
132
133         mainLoop = g_main_loop_new(NULL, false);
134         
135 #endif
136         
137         g_type_init();
138
139         /* Register signal handler */
140         signal(SIGINT, interrupt);
141         signal(SIGTERM, interrupt);
142         
143         PluginLoader loader(config, new Core());
144         
145         if(!loader.sources().size())
146         {
147                 throw std::runtime_error("No sources present. aborting");
148         }
149         
150         
151         
152 #ifdef USE_QT_CORE
153         
154         app.exec();
155         
156 #else
157         
158         g_main_loop_run(mainLoop);
159         
160 #endif
161         
162         return 0;
163 }
164
165 void daemonize()
166 {
167         int i=0;
168         if(getppid() == 1)
169         {
170                 return; // already a daemon
171         }
172         if((i = fork()) < 0)
173         {
174                 fprintf(stderr, "%s:%s(%d) - fork error: %s", __FILE__, __FUNCTION__, __LINE__, strerror(errno));
175                 exit(1);
176         }
177         if(i > 0)
178         {
179                 exit(0);        // parent exits
180         }       // child (daemon) continues
181         setsid();       // obtain a new process group
182         for(i = getdtablesize(); i >= 0; --i)
183         {
184                 close(i);       // close all descriptors
185         }
186         {       // handle standard I/O
187         i = open("/dev/null", O_RDWR);
188         dup(i);
189         dup(i);
190         }
191         // first instance continues
192 }
193
194 void printhelp(const char *argv0)
195 {
196         printf("Usage: %s [args]\n"
197                    "   [-D|--daemonise]\n"
198                    "   [-v|--version]\n"
199                    "   [-c|--config </path/to/config> \t]\n"
200                    "   [-d|--debug <level (0-5)>\t]\n"
201                    "   [-h|--help]\n"
202                    , argv0);
203 }
204