summaryrefslogtreecommitdiff
path: root/src/config.c
blob: 73bebe2eafc7069057b1997ae68deb528edfc339 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <glib.h>
#include <string.h>

#include "pa-sink-ctl.h"
#include "config.h"

static int
parse_priorities(struct config *cfg)
{
	gchar **groups;
	struct priority p;
	int i;
	gsize length;
	GError *error = NULL;

	groups = g_key_file_get_groups(cfg->keyfile, &length);

	for (i = 0; i < length; ++i) {
		if (strncmp(groups[i], "priority", 8) != 0)
			continue;

		memset(&p, 0, sizeof p);

		p.match = g_key_file_get_value(cfg->keyfile, groups[i],
					       "match", &error);
		if (error)
			goto error;
		p.value = g_key_file_get_value(cfg->keyfile, groups[i],
					       "value", &error);
		if (error)
			goto error;
		p.priority = g_key_file_get_integer(cfg->keyfile, groups[i],
						    "priority", &error);
		if (error)
			goto error;

		list_append_struct(cfg->priorities, p);
	}

	return 0;

error:
	if (p.value)
		g_free(p.value);
	if (p.match)
		g_free(p.match);

	g_printerr("Failed to read property in prioritiy group '%s': %s\n",
		   groups[i], error->message);

	return -1;
}

static void
destroy_priority(gpointer data)
{
	struct priority *p = data;

	g_free(p->value);
	g_free(p->match);
	g_free(p);
}

int
config_init(struct config *cfg)
{
	/* FIXME: Not a nicer method available in glib? */
	const gchar *home_dirs[] = { g_get_user_config_dir(), NULL };
	const gchar * const * dirs_array[] = { home_dirs, g_get_system_config_dirs() };
	GError *error;
	int i;

	memset(cfg, 0, sizeof *cfg);
	cfg->keyfile = g_key_file_new();
	cfg->priorities = NULL;

	for (i = 0; i < G_N_ELEMENTS(dirs_array); ++i) {
		error = NULL;
		if (g_key_file_load_from_dirs(cfg->keyfile,
					      "pa-sink-ctl/config.ini",
					      (const gchar **) dirs_array[i],
					      NULL, G_KEY_FILE_NONE, &error)
		    && !error)
			break;
	}
	if (error) {
			g_printerr("Failed to open config file: %s\n",
				   error->message);
			return -1;
	}

	if (parse_priorities(cfg) < 0)
		return -1;

	return 0;
}

void
config_uninit(struct config *cfg)
{
	g_list_free_full(cfg->priorities, destroy_priority);

	g_key_file_free(cfg->keyfile);
}