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.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
/*
|
/*
|
||||||
* The example shows how to import VPN connection from a file.
|
* The example shows how to import VPN connection from a file.
|
||||||
|
*
|
||||||
* @author: Jagadeesh Kotra <jagadeesh@stdin.top>
|
* @author: Jagadeesh Kotra <jagadeesh@stdin.top>
|
||||||
*
|
*
|
||||||
* Compile with:
|
* Compile with:
|
||||||
@@ -9,66 +10,154 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <NetworkManager.h>
|
#include <NetworkManager.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static void
|
/*****************************************************************************/
|
||||||
add_cb(NMClient *client, GAsyncResult *result, GMainLoop *loop)
|
|
||||||
|
static NMConnection *
|
||||||
|
vpn_connection_import(const char *filename)
|
||||||
{
|
{
|
||||||
GError *err = NULL;
|
NMConnection *conn = NULL;
|
||||||
nm_client_add_connection_finish(client, result, &err);
|
GSList * plugins;
|
||||||
if (err != NULL) {
|
GSList * iter;
|
||||||
g_print("Error: %s\n", err->message);
|
|
||||||
} else {
|
g_print("Try to import file \"%s\"...\n", filename);
|
||||||
g_print("Connection Added.\n");
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_main_loop_quit(loop);
|
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(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 * 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 successfully added: %s\n", nm_object_get_path(NM_OBJECT(rdata.rconn)));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object(&client);
|
||||||
|
|
||||||
|
return rdata.rconn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
GMainLoop * loop = g_main_loop_new(NULL, FALSE);
|
NMRemoteConnection *rconn;
|
||||||
GSList * plugins;
|
NMConnection * conn;
|
||||||
GSList * iter;
|
const char * filename;
|
||||||
NMVpnEditorPlugin *editor;
|
gboolean success;
|
||||||
NMClient * client;
|
|
||||||
GError * err = NULL;
|
|
||||||
NMConnection * conn = NULL;
|
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
g_print("program takes exactly one(1) argument.\n");
|
g_print("program takes exactly one(1) argument.\n");
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins = nm_vpn_plugin_info_list_load();
|
filename = argv[1];
|
||||||
g_assert(plugins != NULL);
|
|
||||||
|
|
||||||
for (iter = plugins; iter; iter = iter->next) {
|
conn = vpn_connection_import(filename);
|
||||||
const char *plugin_name = nm_vpn_plugin_info_get_name(iter->data);
|
if (!conn)
|
||||||
g_print("Trying Plugin: %s\n", plugin_name);
|
return 1;
|
||||||
|
|
||||||
//try to load plugin
|
rconn = connection_add(conn);
|
||||||
editor = nm_vpn_plugin_info_load_editor_plugin(iter->data, NULL);
|
|
||||||
|
|
||||||
conn = nm_vpn_editor_plugin_import(editor, argv[1], &err);
|
success = (rconn != NULL);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slist_free_full(plugins, g_object_unref);
|
g_clear_object(&conn);
|
||||||
g_assert(conn != NULL);
|
g_clear_object(&rconn);
|
||||||
|
|
||||||
client = nm_client_new(NULL, NULL);
|
return success ? 0 : 1;
|
||||||
|
|
||||||
nm_client_add_connection_async(client, conn, TRUE, NULL, (GAsyncReadyCallback) add_cb, loop);
|
|
||||||
g_main_loop_run(loop);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user