Rewrite legacy app handler's command-line to use D-Bus
[profile/ivi/node-startup-controller.git] / legacy-app-handler / main.c
1 /* vi:set et ai sw=2 sts=2 ts=2: */
2 /* -
3  * Copyright (c) 2012 GENIVI.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #ifdef HAVE_STDLIB_H
15 #include <stdlib.h>
16 #endif
17
18 #include <glib.h>
19 #include <gio/gio.h>
20
21 #include <dlt/dlt.h>
22
23 #include <legacy-app-handler/la-handler-application.h>
24 #include <legacy-app-handler/la-handler-dbus.h>
25 #include <legacy-app-handler/la-handler-service.h>
26
27
28
29 DLT_DECLARE_CONTEXT (la_handler_context);
30
31
32
33 static void
34 dlt_cleanup (void)
35 {
36   DLT_UNREGISTER_CONTEXT (la_handler_context);
37   DLT_UNREGISTER_APP ();
38 }
39
40
41
42 static gboolean
43 handle_command_line (int              argc,
44                      char           **argv,
45                      GDBusConnection *connection)
46 {
47   GOptionContext *context = g_option_context_new (NULL);
48   LAHandler      *legacy_app_handler;
49   gboolean        do_register = FALSE;
50   gboolean        do_deregister = FALSE;
51   GError         *error = NULL;
52   gchar          *unit = NULL;
53   gchar          *log_message = NULL;
54   gchar          *mode = NULL;
55   gint            timeout = 0;
56
57   GOptionEntry entries[] = {
58     {"deregister",    0, 0, G_OPTION_ARG_NONE,   &do_deregister, NULL, NULL},
59     {"register",      0, 0, G_OPTION_ARG_NONE,   &do_register,   NULL, NULL},
60     {"unit",          0, 0, G_OPTION_ARG_STRING, &unit,          NULL, NULL},
61     {"timeout",       0, 0, G_OPTION_ARG_INT,    &timeout,       NULL, NULL},
62     {"shutdown-mode", 0, 0, G_OPTION_ARG_STRING, &mode,          NULL, NULL},
63     {NULL},
64   };
65
66   /* set up the option context */
67   g_option_context_set_help_enabled (context, FALSE);
68   g_option_context_add_main_entries (context, entries, NULL);
69
70   /* parse the arguments into argument data */
71   if (!g_option_context_parse (context, &argc, &argv, &error) || error != NULL)
72     {
73       /* an error occurred */
74       log_message =
75         g_strdup_printf ("Error occurred parsing arguments: %s\n", error->message);
76       DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
77
78       g_error_free (error);
79       g_free (log_message);
80
81       return FALSE;
82     }
83   else if (do_register && !do_deregister)
84     {
85       if (unit == NULL || *unit == '\0' || timeout < 0)
86         {
87           /* register was called incorrectly */
88           log_message =
89             g_strdup_printf ("Invalid arguments for --register. A unit must be specified"
90                              " and the timeout must be positive.");
91           DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
92
93           g_free (log_message);
94
95           return FALSE;
96         }
97
98       /* get a legacy app handler interface */
99       legacy_app_handler =
100         la_handler_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
101                                    "org.genivi.LegacyAppHandler1",
102                                    "/org/genivi/LegacyAppHandler1", NULL, &error);
103       if (error != NULL)
104         {
105           /* failed to connect to the legacy app handler */
106           log_message =
107             g_strdup_printf ("Error occurred connecting to legacy app handler "
108                              "interface: %s", error->message);
109           DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
110
111           g_free (log_message);
112           g_error_free (error);
113
114           return FALSE;
115         }
116
117       /* call the legacy app handler's Register() method */
118       la_handler_call_register_sync (legacy_app_handler, unit,
119                                      mode ? mode : "normal", (guint) timeout, NULL,
120                                      &error);
121       if (error != NULL)
122         {
123           /* failed to register the legacy app */
124           log_message = g_strdup_printf ("Error occurred registering legacy app: %s",
125                                          error->message);
126           DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
127
128           g_object_unref (legacy_app_handler);
129           g_free (log_message);
130           g_error_free (error);
131
132           return FALSE;
133         }
134
135       g_object_unref (legacy_app_handler);
136
137       return TRUE;
138
139     }
140   else if (do_deregister && !do_register)
141     {
142       if (unit == NULL || *unit == '\0')
143         {
144           /* deregister was called incorrectly */
145           log_message =
146             g_strdup_printf ("Invalid arguments for --deregister. A unit must be "
147                              "specified.");
148           DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
149
150           g_free (log_message);
151
152           return FALSE;
153         }
154
155       /* get a legacy app handler interface */
156       legacy_app_handler =
157         la_handler_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
158                                    "org.genivi.LegacyAppHandler1",
159                                    "/org/genivi/LegacyAppHandler1", NULL, &error);
160       if (error != NULL)
161         {
162           log_message =
163             g_strdup_printf ("Error occurred connecting to legacy app handler "
164                              "interface: %s", error->message);
165           DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
166
167           g_free (log_message);
168           g_error_free (error);
169
170           return FALSE;
171         }
172
173       /* call the legacy app handler's Deregister() method */
174       la_handler_call_deregister_sync (legacy_app_handler, unit, NULL, &error);
175       if (error != NULL)
176         {
177           log_message = g_strdup_printf ("Error occurred deregistering legacy "
178                                          "app: %s", error->message);
179           DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
180
181           g_object_unref (legacy_app_handler);
182           g_free (log_message);
183           g_error_free (error);
184
185           return FALSE;
186         }
187
188       g_object_unref (legacy_app_handler);
189
190       return TRUE;
191     }
192   else if (do_register && do_deregister)
193     {
194       log_message =
195         g_strdup_printf ("Invalid arguments. Please choose either --register or "
196                          "--deregister.");
197         DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
198
199         g_free (log_message);
200
201         return FALSE;
202     }
203   else
204     {
205         DLT_LOG (la_handler_context, DLT_LOG_ERROR,
206                  DLT_STRING ("No arguments recognised"));
207         return FALSE;
208     }
209 }
210
211
212
213 int
214 main (int    argc,
215       char **argv)
216 {
217   LAHandlerApplication *application;
218   LAHandlerService     *service;
219   GDBusConnection      *connection;
220   gboolean              is_remote;
221   GError               *error = NULL;
222   gchar                *log_text;
223   int                   exit_status;
224
225   /* check if this program execution is meant as a remote application.
226    * if it is a remote application, then it will be called with command-line arguments. */
227   is_remote = (argc > 1) ? TRUE : FALSE;
228
229   /* register the application and context in DLT */
230   if (!is_remote)
231     {
232       DLT_REGISTER_APP ("BMGR", "GENIVI Boot Manager");
233       DLT_REGISTER_CONTEXT (la_handler_context, "LAH",
234                             "Context of the legacy application handler that hooks legacy "
235                             "applications up with the shutdown concept of the Node State "
236                             "Manager");
237       atexit (dlt_cleanup);
238     }
239
240   /* initialize the GType type system */
241   g_type_init ();
242
243   /* attempt to connect to D-Bus */
244   connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
245   if (connection == NULL || error != NULL || !G_IS_DBUS_CONNECTION (connection))
246     {
247       log_text = g_strdup_printf ("Failed to connect to D-Bus: %s", error->message);
248       DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text));
249
250       /* clean up */
251       g_free (log_text);
252       g_error_free (error);
253
254       return EXIT_FAILURE;
255     }
256
257   if (is_remote)
258     {
259       if (!handle_command_line (argc, argv, connection))
260         exit_status = EXIT_FAILURE;
261       else
262         exit_status = EXIT_SUCCESS;
263     }
264   else
265     {
266       /* instantiate the LegacyAppHandler service implementation */
267       service = la_handler_service_new (connection);
268       if (!la_handler_service_start (service, &error))
269         {
270           log_text = g_strdup_printf ("Failed to start the legacy app handler service: %s",
271                                       error->message);
272           DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text));
273
274           /* clean up */
275           g_free (log_text);
276           g_error_free (error);
277           g_object_unref (service);
278           g_object_unref (connection);
279
280           return EXIT_FAILURE;
281         }
282
283       /* create and run the main application */
284       application =
285         la_handler_application_new (service, G_APPLICATION_IS_SERVICE);
286
287       exit_status = g_application_run (G_APPLICATION (application), argc, argv);
288       g_object_unref (application);
289
290       /* release allocated objects */
291       g_object_unref (service);
292     }
293
294   g_object_unref (connection);
295
296   return exit_status;
297 }