summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-04-01 21:16:01 +0200
committerThomas Haller <thaller@redhat.com>2021-04-01 21:16:01 +0200
commitca607d2effe1f8d9a29a9f6792c487aa872fa1a3 (patch)
tree6aca847c301c8b63f346173b92c85c4b45a6e24a
parent24bcb8e3e41219601e8ba7e5f53adb55fbcbc02f (diff)
downloadNetworkManager-ca607d2effe1f8d9a29a9f6792c487aa872fa1a3.tar.gz
example: rework "vpn-import-libnm" example
- add more error handling and free/unref data. - split code in 3 functions: vpn_connection_import(), connection_add() and main(). These steps are mostly independent, and having them in separate functions makes their separation clearer. - handle error from nm_client_add_connection_async() to exit program with non zero exit code.
-rw-r--r--examples/C/glib/vpn-import-libnm.c171
1 files changed, 130 insertions, 41 deletions
diff --git a/examples/C/glib/vpn-import-libnm.c b/examples/C/glib/vpn-import-libnm.c
index 6a563bac2d..55ed5175c1 100644
--- a/examples/C/glib/vpn-import-libnm.c
+++ b/examples/C/glib/vpn-import-libnm.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* The example shows how to import VPN connection from a file.
+ *
* @author: Jagadeesh Kotra <jagadeesh@stdin.top>
*
* Compile with:
@@ -9,66 +10,154 @@
#include <glib.h>
#include <NetworkManager.h>
-#include <stdlib.h>
+
+/*****************************************************************************/
+
+static NMConnection *
+vpn_connection_import(const char *filename)
+{
+ NMConnection *conn = NULL;
+ GSList * plugins;
+ GSList * iter;
+
+ g_print("Try to import file \"%s\"...\n", filename);
+
+ plugins = nm_vpn_plugin_info_list_load();
+
+ for (iter = plugins; iter; iter = iter->next) {
+ GError * error = NULL;
+ NMVpnPluginInfo * plugin = iter->data;
+ NMVpnEditorPlugin *editor;
+ const char * plugin_name = nm_vpn_plugin_info_get_name(plugin);
+
+ g_print("plugin[%s]: trying import...\n", plugin_name);
+
+ editor = nm_vpn_plugin_info_load_editor_plugin(plugin, &error);
+ if (error) {
+ g_print("plugin[%s]: error loading plugin: %s\n", plugin_name, error->message);
+ g_clear_error(&error);
+ continue;
+ }
+
+ conn = nm_vpn_editor_plugin_import(editor, filename, &error);
+ if (error) {
+ g_print("plugin[%s]: error importing file: %s\n", plugin_name, error->message);
+ g_clear_error(&error);
+ continue;
+ }
+
+ if (!nm_connection_normalize(conn, NULL, NULL, &error)) {
+ g_print("plugin[%s]: imported connection invalid: %s\n", plugin_name, error->message);
+ g_clear_error(&error);
+ g_clear_object(&conn);
+ continue;
+ }
+
+ g_print("plugin[%s]: imported connection \"%s\" (%s)\n",
+ plugin_name,
+ nm_connection_get_id(conn),
+ nm_connection_get_uuid(conn));
+ break;
+ }
+ g_slist_free_full(plugins, g_object_unref);
+
+ if (!conn) {
+ g_print("Failure to import the file with any plugin\n");
+ return NULL;
+ }
+
+ return conn;
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ GMainLoop * loop;
+ GError * error;
+ NMRemoteConnection *rconn;
+} RequestData;
static void
-add_cb(NMClient *client, GAsyncResult *result, GMainLoop *loop)
+add_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ RequestData *rdata = user_data;
+
+ rdata->rconn = nm_client_add_connection_finish(NM_CLIENT(source), result, &rdata->error);
+ g_main_loop_quit(rdata->loop);
+}
+
+static NMRemoteConnection *
+connection_add(NMConnection *conn)
{
- GError *err = NULL;
- nm_client_add_connection_finish(client, result, &err);
- if (err != NULL) {
- g_print("Error: %s\n", err->message);
+ GError * error = NULL;
+ NMClient * client;
+ RequestData rdata;
+
+ g_print("Adding connection \"%s\" (%s)\n",
+ nm_connection_get_id(conn),
+ nm_connection_get_uuid(conn));
+
+ client = nm_client_new(NULL, &error);
+ if (!client) {
+ g_print("Failure to connect with NetworkManager: %s\n", error->message);
+ return NULL;
+ }
+
+ g_print("Adding connection \"%s\" (%s)\n",
+ nm_connection_get_id(conn),
+ nm_connection_get_uuid(conn));
+
+ rdata = (RequestData){
+ .loop = g_main_loop_new(NULL, FALSE),
+ .rconn = NULL,
+ .error = NULL,
+ };
+
+ nm_client_add_connection_async(client, conn, TRUE, NULL, add_cb, &rdata);
+
+ g_main_loop_run(rdata.loop);
+
+ g_clear_pointer(&rdata.loop, g_main_loop_unref);
+
+ if (rdata.error != NULL) {
+ g_print("Error: %s\n", rdata.error->message);
+ g_clear_error(&rdata.error);
} else {
- g_print("Connection Added.\n");
+ g_print("Connection successfully added: %s\n", nm_object_get_path(NM_OBJECT(rdata.rconn)));
}
- g_main_loop_quit(loop);
+ g_clear_object(&client);
+
+ return rdata.rconn;
}
+/*****************************************************************************/
+
int
main(int argc, char **argv)
{
- GMainLoop * loop = g_main_loop_new(NULL, FALSE);
- GSList * plugins;
- GSList * iter;
- NMVpnEditorPlugin *editor;
- NMClient * client;
- GError * err = NULL;
- NMConnection * conn = NULL;
+ NMRemoteConnection *rconn;
+ NMConnection * conn;
+ const char * filename;
+ gboolean success;
if (argc < 2) {
g_print("program takes exactly one(1) argument.\n");
- exit(1);
+ return 1;
}
- plugins = nm_vpn_plugin_info_list_load();
- g_assert(plugins != NULL);
+ filename = argv[1];
- for (iter = plugins; iter; iter = iter->next) {
- const char *plugin_name = nm_vpn_plugin_info_get_name(iter->data);
- g_print("Trying Plugin: %s\n", plugin_name);
-
- //try to load plugin
- editor = nm_vpn_plugin_info_load_editor_plugin(iter->data, NULL);
-
- conn = nm_vpn_editor_plugin_import(editor, argv[1], &err);
- if (err != NULL) {
- g_print("Error: %s\n", err->message);
- g_error_free(err);
- err = NULL;
- } else {
- g_print("%s imported with %s plugin.\n", argv[1], plugin_name);
- break;
- }
- }
+ conn = vpn_connection_import(filename);
+ if (!conn)
+ return 1;
- g_slist_free_full(plugins, g_object_unref);
- g_assert(conn != NULL);
+ rconn = connection_add(conn);
- client = nm_client_new(NULL, NULL);
+ success = (rconn != NULL);
- nm_client_add_connection_async(client, conn, TRUE, NULL, (GAsyncReadyCallback) add_cb, loop);
- g_main_loop_run(loop);
+ g_clear_object(&conn);
+ g_clear_object(&rconn);
- return 0;
+ return success ? 0 : 1;
}