Using UCI we can retrieve entire lists with the following command:
$ uci get system.ntp.server
This would read the kind of configuration below:
config system
option hostname 'OpenWrt'
option timezone 'UTC'
config timeserver 'ntp'
list server '0.openwrt.pool.ntp.org'
list server '1.openwrt.pool.ntp.org'
list server '2.openwrt.pool.ntp.org'
list server '3.openwrt.pool.ntp.org'
option enabled '1'
option enable_server '0'
That returns all the ntp servers in one long string fine.
0.openwrt.pool.ntp.org 1.openwrt.pool.ntp.org 2.openwrt.pool.ntp.org 3.openwrt.pool.ntp.org
I wish to achieve the same (or equivalent) using the C api.
I put together the following code:
#include <uci.h>
#include <string.h>
void main()
{
//char path[] = "system.ntp.enabled";
char path[] = "system.ntp.server";
char buffer[80];
get_config_entry(path, &buffer);
printf("%s\n", buffer);
}
int get_config_entry (char *path, char *buffer)
{
struct uci_context *c;
struct uci_ptr ptr;
c = uci_alloc_context ();
if (uci_lookup_ptr (c, &ptr, path, true) != UCI_OK)
{
uci_perror (c, "XXX");
return 1;
}
strcpy(buffer, ptr.o->v.string);
uci_free_context (c);
return 0;
}
Running this just returns garbage in the output string.
How should I deal with list content using UCI C API?
If a list element is requested it is stored in v.list not v.string.
I found the uci_show_value function in the uci cli code which helped a lot. I have managed to get the following code to work well with list options.
#include <uci.h>
#include <string.h>
static const char *delimiter = " ";
static void uci_show_value(struct uci_option *o)
{
struct uci_element *e;
bool sep = false;
switch(o->type) {
case UCI_TYPE_STRING:
printf("%s\n", o->v.string);
break;
case UCI_TYPE_LIST:
uci_foreach_element(&o->v.list, e) {
printf("%s%s", (sep ? delimiter : ""), e->name);
sep = true;
}
printf("\n");
break;
default:
printf("<unknown>\n");
break;
}
}
int show_config_entry (char *path)
{
struct uci_context *c;
struct uci_ptr ptr;
c = uci_alloc_context ();
if (uci_lookup_ptr (c, &ptr, path, true) != UCI_OK)
{
uci_perror (c, "get_config_entry Error");
return 1;
}
uci_show_value(ptr.o);
uci_free_context (c);
return 0;
}
void main()
{
char path[] = "system.ntp.server";
show_config_entry(path);
}