1/*
2 * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
4 */
5
6#include <KPPPDefs.h>
7#include <driver_settings.h>
8
9#include "settings_tools.h"
10
11#include <cstring>
12#include <malloc.h>
13
14
15static const char *sSkipInterfaceParameters[] = {
16	PPP_ASK_BEFORE_CONNECTING_KEY,
17	PPP_DISONNECT_AFTER_IDLE_SINCE_KEY,
18	PPP_CONNECT_RETRIES_LIMIT_KEY,
19	PPP_CONNECT_RETRY_DELAY_KEY,
20	PPP_AUTO_RECONNECT_KEY,
21	PPP_RECONNECT_DELAY_KEY,
22	NULL
23};
24
25
26driver_settings*
27dup_driver_settings(const driver_settings *dup)
28{
29	if (!dup)
30		return NULL; // we got a NULL pointer, so return nothing
31
32	driver_settings *ret = new_driver_settings();
33
34	ret->parameter_count = dup->parameter_count;
35
36	if (ret->parameter_count > 0) {
37		ret->parameters = (driver_parameter*)
38			malloc(ret->parameter_count * sizeof(driver_parameter));
39		memset(ret->parameters, 0, ret->parameter_count * sizeof(driver_parameter));
40	} else
41		ret->parameters = NULL;
42
43	for (int32 index = 0; index < ret->parameter_count; index++)
44		copy_driver_parameter(&dup->parameters[index], &ret->parameters[index]);
45
46	return ret;
47}
48
49
50void
51free_driver_settings(driver_settings *settings)
52{
53	if (!settings)
54		return;
55
56	for (int32 index = 0; index < settings->parameter_count; index++)
57		free_driver_parameter_fields(&settings->parameters[index]);
58
59	free(settings->parameters);
60	free(settings);
61}
62
63
64void
65free_driver_parameter(driver_parameter *parameter)
66{
67	free_driver_parameter_fields(parameter);
68	free(parameter);
69}
70
71
72void
73free_driver_parameter_fields(driver_parameter *parameter)
74{
75	free(parameter->name);
76
77	for (int32 index = 0; index < parameter->value_count; index++)
78		free(parameter->values[index]);
79
80	free(parameter->values);
81
82	for (int32 index = 0; index < parameter->parameter_count; index++)
83		free_driver_parameter_fields(&parameter->parameters[index]);
84
85	free(parameter->parameters);
86}
87
88
89driver_settings*
90new_driver_settings()
91{
92	driver_settings *settings = (driver_settings*) malloc(sizeof(driver_settings));
93	memset(settings, 0, sizeof(driver_settings));
94
95	return settings;
96}
97
98
99driver_parameter*
100new_driver_parameter(const char *name)
101{
102	driver_parameter *parameter = (driver_parameter*) malloc(sizeof(driver_parameter));
103	memset(parameter, 0, sizeof(driver_parameter));
104
105	set_driver_parameter_name(name, parameter);
106
107	return parameter;
108}
109
110
111bool
112copy_driver_parameter(const driver_parameter *from, driver_parameter *to)
113{
114	if (!from || !to)
115		return false;
116
117	free_driver_parameter_fields(to);
118
119	if (from->name)
120		to->name = strdup(from->name);
121	else
122		to->name = NULL;
123
124	to->value_count = from->value_count;
125	if (from->value_count > 0)
126		to->values = (char**) malloc(from->value_count * sizeof(char*));
127	else
128		to->values = NULL;
129
130	for (int32 index = 0; index < to->value_count; index++)
131		to->values[index] = strdup(from->values[index]);
132
133	to->parameter_count = from->parameter_count;
134
135	if (to->parameter_count > 0) {
136		to->parameters =
137			(driver_parameter*) malloc(to->parameter_count * sizeof(driver_parameter));
138		memset(to->parameters, 0, to->parameter_count * sizeof(driver_parameter));
139	} else
140		to->parameters = NULL;
141
142	for (int32 index = 0; index < to->parameter_count; index++)
143		copy_driver_parameter(&from->parameters[index], &to->parameters[index]);
144
145	return true;
146}
147
148
149bool
150set_driver_parameter_name(const char *name, driver_parameter *parameter)
151{
152	if (!parameter)
153		return false;
154
155	free(parameter->name);
156
157	if (name)
158		parameter->name = strdup(name);
159	else
160		parameter->name = NULL;
161
162	return true;
163}
164
165
166bool
167add_driver_parameter_value(const char *value, driver_parameter *to)
168{
169	if (!value || !to)
170		return false;
171
172	int32 oldCount = to->value_count;
173	char **old = to->values;
174
175	to->values = (char**) malloc((oldCount + 1) * sizeof(char*));
176
177	if (!to->values) {
178		to->values = old;
179		return false;
180	}
181
182	to->value_count++;
183	memcpy(to->values, old, oldCount * sizeof(char*));
184	to->values[oldCount] = strdup(value);
185
186	return true;
187}
188
189
190bool
191add_driver_parameter(driver_parameter *add, driver_settings *to)
192{
193	if (!add || !to)
194		return false;
195
196	int32 oldCount = to->parameter_count;
197	driver_parameter *old = to->parameters;
198
199	to->parameters =
200		(driver_parameter*) malloc((oldCount + 1) * sizeof(driver_parameter));
201
202	if (!to->parameters) {
203		to->parameters = old;
204		return false;
205	}
206
207	to->parameter_count++;
208	memcpy(to->parameters, old, oldCount * sizeof(driver_parameter));
209	memcpy(to->parameters + oldCount, add, sizeof(driver_parameter));
210
211	return true;
212}
213
214
215bool
216equal_driver_settings(const driver_settings *lhs, const driver_settings *rhs)
217{
218	if (!lhs && !rhs)
219		return true;
220	else if (!lhs || !rhs)
221		return false;
222
223	if (lhs->parameter_count != rhs->parameter_count)
224		return false;
225
226	for (int32 index = 0; index < lhs->parameter_count; index++) {
227		if (!equal_driver_parameters(&lhs->parameters[index], &rhs->parameters[index]))
228			return false;
229	}
230
231	return true;
232}
233
234
235bool
236equal_driver_parameters(const driver_parameter *lhs, const driver_parameter *rhs)
237{
238	if (!lhs && !rhs)
239		return true;
240	else if (!lhs || !rhs)
241		return false;
242
243	if (lhs->name && rhs->name) {
244		if (strcmp(lhs->name, rhs->name))
245			return false;
246	} else if (lhs->name != rhs->name)
247		return false;
248
249	if (lhs->value_count != rhs->value_count
250			|| lhs->parameter_count != rhs->parameter_count)
251		return false;
252
253	for (int32 index = 0; index < lhs->value_count; index++) {
254		if (strcmp(lhs->values[index], rhs->values[index]))
255			return false;
256	}
257
258	for (int32 index = 0; index < lhs->parameter_count; index++) {
259		if (!equal_driver_parameters(&lhs->parameters[index], &rhs->parameters[index]))
260			return false;
261	}
262
263	return true;
264}
265
266
267bool
268skip_interface_parameter(const driver_parameter *parameter)
269{
270	if (!parameter || !parameter->name)
271		return false;
272
273	for (int32 index = 0; sSkipInterfaceParameters[index]; index++)
274		if (!strcasecmp(parameter->name, sSkipInterfaceParameters[index]))
275			return true;
276
277	return false;
278}
279
280
281bool
282equal_interface_settings(const driver_settings *lhs, const driver_settings *rhs)
283{
284	if (!lhs && !rhs)
285		return true;
286	else if (!lhs || !rhs)
287		return false;
288
289	int32 lhsIndex = 0, rhsIndex = 0;
290	for (; lhsIndex < lhs->parameter_count; lhsIndex++) {
291		if (skip_interface_parameter(&lhs->parameters[lhsIndex]))
292			continue;
293
294		for (; rhsIndex < rhs->parameter_count; rhsIndex++)
295			if (!skip_interface_parameter(&rhs->parameters[rhsIndex]))
296				break;
297
298		if (rhsIndex >= rhs->parameter_count)
299			return false;
300
301		if (!equal_driver_parameters(&lhs->parameters[lhsIndex],
302				&rhs->parameters[rhsIndex]))
303			return false;
304	}
305
306	for (; rhsIndex < rhs->parameter_count; rhsIndex++)
307		if (!skip_interface_parameter(&rhs->parameters[rhsIndex]))
308			return false;
309
310	return true;
311}
312
313
314ppp_side
315get_side_string_value(const char *sideString, ppp_side unknownValue)
316{
317	if (!sideString)
318		return unknownValue;
319
320	if (!strcasecmp(sideString, "local"))
321		return PPP_LOCAL_SIDE;
322	if (!strcasecmp(sideString, "peer"))
323		return PPP_PEER_SIDE;
324	if (!strcasecmp(sideString, "none")
325			|| !strcasecmp(sideString, "no"))
326		return PPP_NO_SIDE;
327	if (!strcasecmp(sideString, "both"))
328		return PPP_BOTH_SIDES;
329
330	// no correct value has been found => return default value
331	return unknownValue;
332}
333
334
335bool
336get_boolean_value(const char *string, bool unknownValue)
337{
338	if (!string)
339		return unknownValue;
340
341	if (!strcmp(string, "1")
342			|| !strcasecmp(string, "true")
343			|| !strcasecmp(string, "yes")
344			|| !strcasecmp(string, "on")
345			|| !strcasecmp(string, "enable")
346			|| !strcasecmp(string, "enabled"))
347		return true;
348
349	if (!strcmp(string, "0")
350			|| !strcasecmp(string, "false")
351			|| !strcasecmp(string, "no")
352			|| !strcasecmp(string, "off")
353			|| !strcasecmp(string, "disable")
354			|| !strcasecmp(string, "disabled"))
355		return false;
356
357	// no correct value has been found => return default value
358	return unknownValue;
359}
360
361
362const driver_parameter*
363get_parameter_with_name(const char *name, const driver_settings *settings)
364{
365	if (!name || !settings)
366		return NULL;
367
368	for (int32 index = 0; index < settings->parameter_count; index++)
369		if (!strcasecmp(settings->parameters[index].name, name))
370			return &settings->parameters[index];
371
372	return NULL;
373}
374
375
376const char*
377get_settings_value(const char *name, const driver_settings *settings)
378{
379	const driver_parameter *parameter = get_parameter_with_name(name, settings);
380
381	if (parameter && parameter->value_count > 0 && parameter->values)
382		return parameter->values[0];
383
384	return NULL;
385}
386