Files
ModemManager/cli/mmcli.c
Aleksander Morgado 16f2b7bdb8 cli: specify common options in a new group
Actions on modems from specific interfaces, like 3GPP, will also need the modem
to be specified.

The new 'Common' option group will handle all options to specify objects.
2012-03-15 14:14:36 +01:00

270 lines
7.2 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* mmcli -- Control modem status & access information from the command line
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2011 Aleksander Morgado <aleksander@gnu.org>
* Copyright (C) 2011 Google, Inc.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <glib.h>
#include <gio/gio.h>
#include <libmm-glib.h>
#include "mmcli.h"
#include "mmcli-common.h"
#define PROGRAM_NAME "mmcli"
#define PROGRAM_VERSION PACKAGE_VERSION
/* Globals */
static GMainLoop *loop;
static GCancellable *cancellable;
/* Context */
static gboolean verbose_flag;
static gboolean version_flag;
static gboolean async_flag;
static GOptionEntry main_entries[] = {
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_flag,
"Run action with verbose logs",
NULL
},
{ "version", 'V', 0, G_OPTION_ARG_NONE, &version_flag,
"Print version",
NULL
},
{ "async", 'a', 0, G_OPTION_ARG_NONE, &async_flag,
"Use asynchronous methods",
NULL
},
{ NULL }
};
static void
signals_handler (int signum)
{
if (cancellable) {
/* Ignore consecutive requests of cancellation */
if (!g_cancellable_is_cancelled (cancellable)) {
g_printerr ("%s\n",
"cancelling the operation...");
g_cancellable_cancel (cancellable);
}
return;
}
if (loop &&
g_main_loop_is_running (loop)) {
g_printerr ("%s\n",
"cancelling the main loop...");
g_main_loop_quit (loop);
}
}
static void
log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
const gchar *log_level_str;
time_t now;
gchar time_str[64];
struct tm *local_time;
now = time ((time_t *) NULL);
local_time = localtime (&now);
strftime (time_str, 64, "%d %b %Y, %H:%M:%S", local_time);
switch (log_level) {
case G_LOG_LEVEL_WARNING:
log_level_str = "-Warning **";
break;
case G_LOG_LEVEL_CRITICAL:
case G_LOG_FLAG_FATAL:
case G_LOG_LEVEL_ERROR:
log_level_str = "-Error **";
break;
case G_LOG_LEVEL_DEBUG:
log_level_str = "[Debug]";
break;
default:
log_level_str = "";
break;
}
g_print ("[%s] %s %s\n", time_str, log_level_str, message);
}
static void
print_version_and_exit (void)
{
g_print ("\n"
PROGRAM_NAME " " PROGRAM_VERSION "\n"
"Copyright (2011) Aleksander Morgado\n"
"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n"
"\n");
exit (EXIT_SUCCESS);
}
void
mmcli_async_operation_done (void)
{
if (cancellable) {
g_object_unref (cancellable);
cancellable = NULL;
}
g_main_loop_quit (loop);
}
void
mmcli_force_async_operation (void)
{
if (!async_flag) {
g_debug ("Forcing request to be run asynchronously");
async_flag = TRUE;
}
}
void
mmcli_force_sync_operation (void)
{
if (async_flag) {
g_debug ("Ignoring request to run asynchronously");
async_flag = FALSE;
}
}
gint
main (gint argc, gchar **argv)
{
GDBusConnection *connection;
GOptionContext *context;
GError *error = NULL;
setlocale (LC_ALL, "");
g_type_init ();
/* Setup option context, process it and destroy it */
context = g_option_context_new ("- Control and monitor the ModemManager");
g_option_context_add_group (context,
mmcli_manager_get_option_group ());
g_option_context_add_group (context,
mmcli_get_common_option_group ());
g_option_context_add_group (context,
mmcli_modem_get_option_group ());
g_option_context_add_group (context,
mmcli_bearer_get_option_group ());
g_option_context_add_main_entries (context, main_entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
if (version_flag)
print_version_and_exit ();
if (verbose_flag)
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, log_handler, NULL);
/* Setup signals */
signal (SIGINT, signals_handler);
signal (SIGHUP, signals_handler);
signal (SIGTERM, signals_handler);
/* Setup dbus connection to use */
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (!connection) {
g_printerr ("error: couldn't get bus: %s\n",
error ? error->message : "unknown error");
exit (EXIT_FAILURE);
}
/* Create requirements for async options */
cancellable = g_cancellable_new ();
loop = g_main_loop_new (NULL, FALSE);
/* Manager options? */
if (mmcli_manager_options_enabled ()) {
/* Ensure options from different groups are not enabled */
if (mmcli_modem_options_enabled ()) {
g_printerr ("error: cannot use manager and modem options "
"at the same time\n");
exit (EXIT_FAILURE);
}
if (async_flag)
mmcli_manager_run_asynchronous (connection, cancellable);
else
mmcli_manager_run_synchronous (connection);
}
/* Bearer options? */
else if (mmcli_bearer_options_enabled ()) {
if (async_flag)
mmcli_bearer_run_asynchronous (connection, cancellable);
else
mmcli_bearer_run_synchronous (connection);
}
/* Modem options?
* NOTE: let this check be always the last one, as other groups also need
* having a modem specified, and therefore if -m is set, modem options
* are always enabled. */
else if (mmcli_modem_options_enabled ()) {
if (async_flag)
mmcli_modem_run_asynchronous (connection, cancellable);
else
mmcli_modem_run_synchronous (connection);
}
/* No options? */
else {
g_printerr ("error: no actions specified\n");
exit (EXIT_FAILURE);
}
/* Run loop only in async operations */
if (async_flag)
g_main_loop_run (loop);
if (mmcli_manager_options_enabled ()) {
mmcli_manager_shutdown ();
} else if (mmcli_modem_options_enabled ()) {
mmcli_modem_shutdown ();
} else if (mmcli_bearer_options_enabled ()) {
mmcli_bearer_shutdown ();
}
if (cancellable)
g_object_unref (cancellable);
g_main_loop_unref (loop);
g_object_unref (connection);
return EXIT_SUCCESS;
}