settings/ifupdown: use c-list for data structure of ifupdown parser

We already have a linked-list implementation. Use it.
This commit is contained in:
Thomas Haller
2018-08-25 14:08:20 +02:00
parent 70350bb621
commit fe018a7e81
5 changed files with 113 additions and 126 deletions

View File

@@ -32,12 +32,6 @@
#include "nm-utils.h" #include "nm-utils.h"
struct _if_parser {
if_block* first;
if_block* last;
if_data* last_data;
};
/*****************************************************************************/ /*****************************************************************************/
static void _ifparser_source (if_parser *parser, const char *path, const char *en_dir, int quiet, int dir); static void _ifparser_source (if_parser *parser, const char *path, const char *en_dir, int quiet, int dir);
@@ -47,45 +41,39 @@ static void _ifparser_source (if_parser *parser, const char *path, const char *e
static void static void
add_block (if_parser *parser, const char *type, const char* name) add_block (if_parser *parser, const char *type, const char* name)
{ {
if_block *ret = g_slice_new0 (struct _if_block); if_block *ifb;
ret->name = g_strdup (name);
ret->type = g_strdup (type); ifb = g_slice_new (if_block);
if (parser->first == NULL) ifb->name = g_strdup (name);
parser->first = parser->last = ret; ifb->type = g_strdup (type);
else { c_list_init (&ifb->data_lst_head);
parser->last->next = ret; c_list_link_tail (&parser->block_lst_head, &ifb->block_lst);
parser->last = ret;
}
parser->last_data = NULL;
} }
static void static void
add_data (if_parser *parser, const char *key, const char *data) add_data (if_parser *parser, const char *key, const char *data)
{ {
if_data *ret; if_block *last_block;
if_data *ifd;
char *idx; char *idx;
last_block = c_list_last_entry (&parser->block_lst_head, if_block, block_lst);
/* Check if there is a block where we can attach our data */ /* Check if there is a block where we can attach our data */
if (parser->first == NULL) if (!last_block)
return; return;
ret = g_slice_new0 (struct _if_data); ifd = g_slice_new (if_data);
ret->key = g_strdup (key); ifd->key = g_strdup (key);
ifd->data = g_strdup (data);
/* Normalize keys. Convert '_' to '-', as ifupdown accepts both variants. /* Normalize keys. Convert '_' to '-', as ifupdown accepts both variants.
* When querying keys via ifparser_getkey(), use '-'. */ * When querying keys via ifparser_getkey(), use '-'. */
while ((idx = strrchr (ret->key, '_'))) { idx = ifd->key;
*idx = '-'; while ((idx = strchr (idx, '_')))
} *(idx++) = '-';
ret->data = g_strdup (data);
if (parser->last->info == NULL) { c_list_link_tail (&last_block->data_lst_head, &ifd->data_lst);
parser->last->info = ret;
parser->last_data = ret;
} else {
parser->last_data->next = ret;
parser->last_data = parser->last_data->next;
}
} }
/* join values in src with spaces into dst; dst needs to be large enough */ /* join values in src with spaces into dst; dst needs to be large enough */
@@ -309,7 +297,8 @@ ifparser_parse (const char *eni_file, int quiet)
{ {
if_parser *parser; if_parser *parser;
parser = g_slice_new0 (if_parser); parser = g_slice_new (if_parser);
c_list_init (&parser->block_lst_head);
_recursive_ifparser (parser, eni_file, quiet); _recursive_ifparser (parser, eni_file, quiet);
return parser; return parser;
} }
@@ -317,61 +306,68 @@ ifparser_parse (const char *eni_file, int quiet)
static void static void
_destroy_data (if_data *ifd) _destroy_data (if_data *ifd)
{ {
if (ifd == NULL) c_list_unlink_stale (&ifd->data_lst);
return;
_destroy_data (ifd->next);
g_free (ifd->key); g_free (ifd->key);
g_free (ifd->data); g_free (ifd->data);
g_slice_free (struct _if_data, ifd); g_slice_free (if_data, ifd);
return;
} }
static void static void
_destroy_block (if_block* ifb) _destroy_block (if_block* ifb)
{ {
if (ifb == NULL) if_data *ifd;
return;
_destroy_block (ifb->next); while ((ifd = c_list_first_entry (&ifb->data_lst_head, if_data, data_lst)))
_destroy_data (ifb->info); _destroy_data (ifd);
c_list_unlink_stale (&ifb->block_lst);
g_free (ifb->name); g_free (ifb->name);
g_free (ifb->type); g_free (ifb->type);
g_slice_free (struct _if_block, ifb); g_slice_free (if_block, ifb);
return;
} }
void void
ifparser_destroy (if_parser *parser) ifparser_destroy (if_parser *parser)
{ {
_destroy_block (parser->first); if_block *ifb;
while ((ifb = c_list_first_entry (&parser->block_lst_head, if_block, block_lst)))
_destroy_block (ifb);
g_slice_free (if_parser, parser); g_slice_free (if_parser, parser);
} }
if_block *ifparser_getfirst (if_parser *parser) if_block *
ifparser_getfirst (if_parser *parser)
{ {
return parser->first; return c_list_first_entry (&parser->block_lst_head, if_block, block_lst);
} }
int ifparser_get_num_blocks (if_parser *parser) guint
ifparser_get_num_blocks (if_parser *parser)
{ {
int i = 0; return c_list_length (&parser->block_lst_head);
if_block *iter = parser->first;
while (iter) {
i++;
iter = iter->next;
}
return i;
} }
if_block * if_block *
ifparser_getif (if_parser *parser, const char* iface) ifparser_getif (if_parser *parser, const char* iface)
{ {
if_block *curr = parser->first; if_block *ifb;
while (curr != NULL) {
if ( nm_streq (curr->type, "iface") c_list_for_each_entry (ifb, &parser->block_lst_head, block_lst) {
&& nm_streq (curr->name, iface)) if ( nm_streq (ifb->type, "iface")
return curr; && nm_streq (ifb->name, iface))
curr = curr->next; return ifb;
}
return NULL;
}
static if_data *
ifparser_findkey (if_block* iface, const char *key)
{
if_data *ifd;
c_list_for_each_entry (ifd, &iface->data_lst_head, data_lst) {
if (nm_streq (ifd->key, key))
return ifd;
} }
return NULL; return NULL;
} }
@@ -379,37 +375,20 @@ ifparser_getif (if_parser *parser, const char* iface)
const char * const char *
ifparser_getkey (if_block* iface, const char *key) ifparser_getkey (if_block* iface, const char *key)
{ {
if_data *curr = iface->info; if_data *ifd;
while (curr != NULL) {
if (nm_streq (curr->key, key)) ifd = ifparser_findkey (iface, key);
return curr->data; return ifd ? ifd->data : NULL;
curr = curr->next;
}
return NULL;
} }
gboolean gboolean
ifparser_haskey (if_block* iface, const char *key) ifparser_haskey (if_block* iface, const char *key)
{ {
if_data *curr = iface->info; return !!ifparser_findkey (iface, key);
while (curr != NULL) {
if (nm_streq (curr->key, key))
return TRUE;
curr = curr->next;
}
return FALSE;
} }
int guint
ifparser_get_num_info (if_block* iface) ifparser_get_num_info (if_block* iface)
{ {
int i = 0; return c_list_length (&iface->data_lst_head);
if_data *iter = iface->info;
while (iter) {
i++;
iter = iter->next;
}
return i;
} }

View File

@@ -23,20 +23,24 @@
#ifndef _INTERFACE_PARSER_H #ifndef _INTERFACE_PARSER_H
#define _INTERFACE_PARSER_H #define _INTERFACE_PARSER_H
typedef struct _if_data { #include "c-list/src/c-list.h"
typedef struct {
CList data_lst;
char *key; char *key;
char *data; char *data;
struct _if_data *next;
} if_data; } if_data;
typedef struct _if_block { typedef struct {
CList block_lst;
CList data_lst_head;
char *type; char *type;
char *name; char *name;
if_data *info;
struct _if_block *next;
} if_block; } if_block;
typedef struct _if_parser if_parser; typedef struct {
CList block_lst_head;
} if_parser;
if_parser *ifparser_parse (const char *eni_file, int quiet); if_parser *ifparser_parse (const char *eni_file, int quiet);
@@ -48,7 +52,8 @@ if_block *ifparser_getif (if_parser *parser, const char* iface);
if_block *ifparser_getfirst (if_parser *parser); if_block *ifparser_getfirst (if_parser *parser);
const char *ifparser_getkey (if_block* iface, const char *key); const char *ifparser_getkey (if_block* iface, const char *key);
gboolean ifparser_haskey (if_block* iface, const char *key); gboolean ifparser_haskey (if_block* iface, const char *key);
int ifparser_get_num_blocks (if_parser *parser);
int ifparser_get_num_info (if_block* iface); guint ifparser_get_num_blocks (if_parser *parser);
guint ifparser_get_num_info (if_block* iface);
#endif #endif

View File

@@ -49,23 +49,23 @@
static const char* static const char*
_ifupdownplugin_guess_connection_type (if_block *block) _ifupdownplugin_guess_connection_type (if_block *block)
{ {
if_data *curr = block->info;
const char *ret_type = NULL; const char *ret_type = NULL;
const char* value = ifparser_getkey (block, "inet");
if (nm_streq0 (value, "ppp")) if(nm_streq0 (ifparser_getkey (block, "inet"), "ppp"))
ret_type = NM_SETTING_PPP_SETTING_NAME; ret_type = NM_SETTING_PPP_SETTING_NAME;
else {
if_data *ifb;
while (!ret_type && curr) { c_list_for_each_entry (ifb, &block->data_lst_head, data_lst) {
if ( _str_has_prefix (curr->key, "wireless-", FALSE) if ( _str_has_prefix (ifb->key, "wireless-", FALSE)
|| _str_has_prefix (curr->key, "wpa-", FALSE)) { || _str_has_prefix (ifb->key, "wpa-", FALSE)) {
ret_type = NM_SETTING_WIRELESS_SETTING_NAME; ret_type = NM_SETTING_WIRELESS_SETTING_NAME;
break;
} }
curr = curr->next;
} }
if(!ret_type) if(!ret_type)
ret_type = NM_SETTING_WIRED_SETTING_NAME; ret_type = NM_SETTING_WIRED_SETTING_NAME;
}
nm_log_info (LOGD_SETTINGS, "guessed connection type (%s) = %s", block->name, ret_type); nm_log_info (LOGD_SETTINGS, "guessed connection type (%s) = %s", block->name, ret_type);
return ret_type; return ret_type;
@@ -93,7 +93,7 @@ static void
update_wireless_setting_from_if_block (NMConnection *connection, update_wireless_setting_from_if_block (NMConnection *connection,
if_block *block) if_block *block)
{ {
if_data *curr = block->info; if_data *curr;
const char *value = ifparser_getkey (block, "inet"); const char *value = ifparser_getkey (block, "inet");
struct _Mapping mapping[] = { struct _Mapping mapping[] = {
{"ssid", "ssid"}, {"ssid", "ssid"},
@@ -110,7 +110,7 @@ update_wireless_setting_from_if_block (NMConnection *connection,
nm_log_info (LOGD_SETTINGS, "update wireless settings (%s).", block->name); nm_log_info (LOGD_SETTINGS, "update wireless settings (%s).", block->name);
wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
while (curr) { c_list_for_each_entry (curr, &block->data_lst_head, data_lst) {
if (_str_has_prefix (curr->key, "wireless-", TRUE)) { if (_str_has_prefix (curr->key, "wireless-", TRUE)) {
const char* newkey = map_by_mapping (mapping, curr->key + NM_STRLEN ("wireless-")); const char* newkey = map_by_mapping (mapping, curr->key + NM_STRLEN ("wireless-"));
@@ -156,7 +156,6 @@ update_wireless_setting_from_if_block (NMConnection *connection,
nm_log_info (LOGD_SETTINGS, "setting wpa newkey(%s)=data(%s)", newkey, curr->data); nm_log_info (LOGD_SETTINGS, "setting wpa newkey(%s)=data(%s)", newkey, curr->data);
} }
} }
curr = curr->next;
} }
nm_connection_add_setting (connection, (NMSetting*) wireless_setting); nm_connection_add_setting (connection, (NMSetting*) wireless_setting);
} }
@@ -248,7 +247,7 @@ static void
update_wireless_security_setting_from_if_block (NMConnection *connection, update_wireless_security_setting_from_if_block (NMConnection *connection,
if_block *block) if_block *block)
{ {
if_data *curr = block->info; if_data *curr;
const char* value = ifparser_getkey (block, "inet"); const char* value = ifparser_getkey (block, "inet");
struct _Mapping mapping[] = { struct _Mapping mapping[] = {
{"psk", "psk"}, {"psk", "psk"},
@@ -314,7 +313,7 @@ update_wireless_security_setting_from_if_block (NMConnection *connection,
nm_log_info (LOGD_SETTINGS, "update wireless security settings (%s).", block->name); nm_log_info (LOGD_SETTINGS, "update wireless security settings (%s).", block->name);
wireless_security_setting = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); wireless_security_setting = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
while (curr) { c_list_for_each_entry (curr, &block->data_lst_head, data_lst) {
if (_str_has_prefix (curr->key, "wireless-", TRUE)) { if (_str_has_prefix (curr->key, "wireless-", TRUE)) {
const char *key = curr->key + NM_STRLEN ("wireless-"); const char *key = curr->key + NM_STRLEN ("wireless-");
char *property_value = NULL; char *property_value = NULL;
@@ -391,7 +390,7 @@ wireless_next:
(*free_func) (typed_property_value); (*free_func) (typed_property_value);
} }
next: next:
curr = curr->next; ;
} }
if (security) if (security)

View File

@@ -158,9 +158,9 @@ initialize (NMSettingsPlugin *plugin)
const char *block_name; const char *block_name;
NMIfupdownConnection *conn; NMIfupdownConnection *conn;
/* Read in all the interfaces */
parser = ifparser_parse (ENI_INTERFACES_FILE, 0); parser = ifparser_parse (ENI_INTERFACES_FILE, 0);
for (block = ifparser_getfirst (parser); block; block = block->next) {
c_list_for_each_entry (block, &parser->block_lst_head, block_lst) {
if (NM_IN_STRSET (block->type, "auto", "allow-hotplug")) { if (NM_IN_STRSET (block->type, "auto", "allow-hotplug")) {
if (!auto_ifaces) if (!auto_ifaces)

View File

@@ -137,9 +137,8 @@ compare_expected_to_ifparser (if_parser *parser, Expected *e)
g_assert_cmpint (g_slist_length (e->blocks), ==, ifparser_get_num_blocks (parser)); g_assert_cmpint (g_slist_length (e->blocks), ==, ifparser_get_num_blocks (parser));
for (n = ifparser_getfirst (parser), biter = e->blocks; biter = e->blocks;
n && biter; c_list_for_each_entry (n, &parser->block_lst_head, block_lst) {
n = n->next, biter = g_slist_next (biter)) {
if_data *m; if_data *m;
ExpectedBlock *b = biter->data; ExpectedBlock *b = biter->data;
@@ -150,17 +149,22 @@ compare_expected_to_ifparser (if_parser *parser, Expected *e)
g_assert_cmpint (g_slist_length (b->keys), ==, ifparser_get_num_info (n)); g_assert_cmpint (g_slist_length (b->keys), ==, ifparser_get_num_info (n));
for (m = n->info, kiter = b->keys; kiter = b->keys;
m && kiter; c_list_for_each_entry (m, &n->data_lst_head, data_lst) {
m = m->next, kiter = g_slist_next (kiter)) {
ExpectedKey *k = kiter->data; ExpectedKey *k = kiter->data;
g_assert (k->key && m->key); g_assert (k->key && m->key);
g_assert_cmpstr (k->key, ==, m->key); g_assert_cmpstr (k->key, ==, m->key);
g_assert (k->data && m->data); g_assert (k->data && m->data);
g_assert_cmpstr (k->data, ==, m->data); g_assert_cmpstr (k->data, ==, m->data);
kiter = g_slist_next (kiter);
} }
g_assert (!kiter);
biter = g_slist_next (biter);
} }
g_assert (!biter);
} }
static void static void
@@ -169,7 +173,7 @@ dump_blocks (if_parser *parser)
if_block *n; if_block *n;
g_message ("\n***************************************************"); g_message ("\n***************************************************");
for (n = ifparser_getfirst (parser); n != NULL; n = n->next) { c_list_for_each_entry (n, &parser->block_lst_head, block_lst) {
if_data *m; if_data *m;
// each block start with its type & name // each block start with its type & name
@@ -178,7 +182,7 @@ dump_blocks (if_parser *parser)
// each key-value pair within a block is indented & separated by a tab // each key-value pair within a block is indented & separated by a tab
// (single quotes used to show typ & name baoundaries) // (single quotes used to show typ & name baoundaries)
for (m = n->info; m != NULL; m = m->next) c_list_for_each_entry (m, &n->data_lst_head, data_lst)
g_print("\t'%s'\t'%s'\n", m->key, m->data); g_print("\t'%s'\t'%s'\n", m->key, m->data);
// blocks are separated by an empty line // blocks are separated by an empty line