1 /*
2  * Copyright (c) 2002-2013 Balabit
3  * Copyright (c) 1998-2013 Balázs Scheidler
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * As an additional exemption you are allowed to compile & link against the
20  * OpenSSL libraries as published by the OpenSSL project. See the file
21  * COPYING for details.
22  *
23  */
24 #include "cfg-args.h"
25 #include "messages.h"
26 #include "str-utils.h"
27 #include "str-repr/encode.h"
28 
29 struct _CfgArgs
30 {
31   gint ref_cnt;
32   GHashTable *args;
33   gboolean accept_varargs;
34 };
35 
36 gboolean
cfg_args_is_accepting_varargs(CfgArgs * self)37 cfg_args_is_accepting_varargs(CfgArgs *self)
38 {
39   return self->accept_varargs;
40 }
41 
42 void
cfg_args_accept_varargs(CfgArgs * self)43 cfg_args_accept_varargs(CfgArgs *self)
44 {
45   self->accept_varargs = TRUE;
46 }
47 
48 void
cfg_args_foreach(CfgArgs * self,GHFunc func,gpointer user_data)49 cfg_args_foreach(CfgArgs *self, GHFunc func, gpointer user_data)
50 {
51   g_hash_table_foreach(self->args, func, user_data);
52 }
53 
54 static void
_resolve_unknown_blockargs_as_varargs(gpointer key,gpointer value,gpointer user_data)55 _resolve_unknown_blockargs_as_varargs(gpointer key, gpointer value, gpointer user_data)
56 {
57   CfgArgs *defaults = ((gpointer *) user_data)[0];
58   GString *varargs = ((gpointer *) user_data)[1];
59 
60   if (!defaults || !cfg_args_contains(defaults, key))
61     {
62       g_string_append_printf(varargs, "%s(%s) ", (gchar *)key, (gchar *)value);
63     }
64 }
65 
66 gchar *
cfg_args_format_varargs(CfgArgs * self,CfgArgs * defaults)67 cfg_args_format_varargs(CfgArgs *self, CfgArgs *defaults)
68 {
69   GString *varargs = g_string_new("");
70   gpointer user_data[] = { defaults, varargs };
71 
72   cfg_args_foreach(self, _resolve_unknown_blockargs_as_varargs, user_data);
73   return g_string_free(varargs, FALSE);
74 }
75 
76 void
cfg_args_set(CfgArgs * self,const gchar * name,const gchar * value)77 cfg_args_set(CfgArgs *self, const gchar *name, const gchar *value)
78 {
79   g_hash_table_insert(self->args, __normalize_key(name), g_strdup(value));
80 }
81 
82 const gchar *
cfg_args_get(CfgArgs * self,const gchar * name)83 cfg_args_get(CfgArgs *self, const gchar *name)
84 {
85   const gchar *value = g_hash_table_lookup(self->args, name);
86 
87   if (!value)
88     {
89       gchar *normalized_name = __normalize_key(name);
90       value = g_hash_table_lookup(self->args, normalized_name);
91       g_free(normalized_name);
92     }
93 
94   return value;
95 }
96 
97 gboolean
cfg_args_contains(CfgArgs * self,const gchar * name)98 cfg_args_contains(CfgArgs *self, const gchar *name)
99 {
100   gchar *normalized_name = __normalize_key(name);
101   gboolean contains = g_hash_table_lookup_extended(self->args, normalized_name, NULL, NULL);
102   g_free(normalized_name);
103   return contains;
104 }
105 
106 void
cfg_args_remove_normalized(CfgArgs * self,const gchar * normalized_name)107 cfg_args_remove_normalized(CfgArgs *self, const gchar *normalized_name)
108 {
109   gpointer orig_key;
110   if (g_hash_table_lookup_extended(self->args, normalized_name, &orig_key, NULL))
111     {
112       g_hash_table_remove(self->args, orig_key);
113     }
114 }
115 
116 void
cfg_args_remove(CfgArgs * self,const gchar * name)117 cfg_args_remove(CfgArgs *self, const gchar *name)
118 {
119   gchar *normalized_name = __normalize_key(name);
120   cfg_args_remove_normalized(self, normalized_name);
121   g_free(normalized_name);
122 }
123 
124 CfgArgs *
cfg_args_new(void)125 cfg_args_new(void)
126 {
127   CfgArgs *self = g_new0(CfgArgs, 1);
128 
129   self->args = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
130   self->ref_cnt = 1;
131   return self;
132 }
133 
134 CfgArgs *
cfg_args_ref(CfgArgs * self)135 cfg_args_ref(CfgArgs *self)
136 {
137   if (self)
138     self->ref_cnt++;
139   return self;
140 }
141 
142 void
cfg_args_unref(CfgArgs * self)143 cfg_args_unref(CfgArgs *self)
144 {
145   if (self && --self->ref_cnt == 0)
146     {
147       g_hash_table_destroy(self->args);
148       g_free(self);
149     }
150 }
151