xref: /haiku/src/add-ons/kernel/network/ppp/shared/libppp/MessageDriverSettingsUtils.cpp (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
1 /*
2  * Copyright 2004-2007, Waldemar Kornewald <wkornew@gmx.net>
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "MessageDriverSettingsUtils.h"
7 
8 #include <PPPDefs.h>
9 #include <settings_tools.h>
10 #include <File.h>
11 #include <Message.h>
12 #include <String.h>
13 
14 #include <cstdio>
15 
16 
17 static bool AddParameters(const BMessage& message, driver_settings *to);
18 
19 
20 bool
21 FindMessageParameter(const char *name, const BMessage& message, BMessage *save,
22 	int32 *startIndex)
23 {
24 	// XXX: this should be removed when we can replace BMessage with something better
25 	BString string;
26 	int32 index = startIndex ? *startIndex : 0;
27 	for (; message.FindMessage(MDSU_PARAMETERS, index, save) == B_OK; index++) {
28 		if (save->FindString(MDSU_NAME, &string) == B_OK
29 				&& string.ICompare(name) == 0) {
30 			if (startIndex)
31 				*startIndex = index;
32 			return true;
33 		}
34 	}
35 
36 	return false;
37 }
38 
39 
40 static
41 bool
42 AddValues(const BMessage& message, driver_parameter *parameter)
43 {
44 	const char *value;
45 	for (int32 index = 0; message.FindString(MDSU_VALUES, index, &value) == B_OK;
46 			index++)
47 		if (!add_driver_parameter_value(value, parameter))
48 			return false;
49 
50 	return true;
51 }
52 
53 
54 inline
55 bool
56 AddParameters(const BMessage& message, driver_parameter *to)
57 {
58 	if (!to)
59 		return false;
60 
61 	return AddParameters(message,
62 		reinterpret_cast<driver_settings*>(&to->parameter_count));
63 }
64 
65 
66 static
67 bool
68 AddParameters(const BMessage& message, driver_settings *to)
69 {
70 	const char *name;
71 	BMessage current;
72 	driver_parameter *parameter;
73 	for (int32 index = 0; message.FindMessage(MDSU_PARAMETERS, index,
74 			&current) == B_OK; index++) {
75 		name = current.FindString(MDSU_NAME);
76 		parameter = new_driver_parameter(name);
77 		if (!AddValues(current, parameter))
78 			return false;
79 
80 		AddParameters(current, parameter);
81 		add_driver_parameter(parameter, to);
82 	}
83 
84 	return true;
85 }
86 
87 
88 driver_settings*
89 MessageToDriverSettings(const BMessage& message)
90 {
91 	driver_settings *settings = new_driver_settings();
92 
93 	if (!AddParameters(message, settings)) {
94 		free_driver_settings(settings);
95 		return NULL;
96 	}
97 
98 	return settings;
99 }
100 
101 
102 static
103 bool
104 AddParameter(const driver_parameter *parameter, BMessage *message)
105 {
106 	if (!parameter || !message)
107 		return false;
108 
109 	if (parameter->name)
110 		message->AddString(MDSU_NAME, parameter->name);
111 	else
112 		return false;
113 
114 	for (int32 index = 0; index < parameter->value_count; index++)
115 		if (parameter->values[index])
116 			message->AddString(MDSU_VALUES, parameter->values[index]);
117 
118 	for (int32 index = 0; index < parameter->parameter_count; index++) {
119 		BMessage parameterMessage;
120 		AddParameter(&parameter->parameters[index], &parameterMessage);
121 		message->AddMessage(MDSU_PARAMETERS, &parameterMessage);
122 	}
123 
124 	return true;
125 }
126 
127 
128 bool
129 ReadMessageDriverSettings(const char *name, BMessage *message)
130 {
131 	if (!name || !message)
132 		return false;
133 
134 	void *handle = load_driver_settings(name);
135 	if (!handle)
136 		return false;
137 	const driver_settings *settings = get_driver_settings(handle);
138 	if (!settings) {
139 		unload_driver_settings(handle);
140 		return false;
141 	}
142 
143 	for (int32 index = 0; index < settings->parameter_count; index++) {
144 		BMessage parameter;
145 		AddParameter(&settings->parameters[index], &parameter);
146 		message->AddMessage(MDSU_PARAMETERS, &parameter);
147 	}
148 
149 	unload_driver_settings(handle);
150 
151 	return true;
152 }
153 
154 
155 static
156 void
157 EscapeWord(BString& word)
158 {
159 	word.ReplaceAll("\\", "\\\\");
160 	word.ReplaceAll("#", "\\#");
161 	word.ReplaceAll("\"", "\\\"");
162 	word.ReplaceAll("\'", "\\\'");
163 }
164 
165 
166 static
167 bool
168 WriteParameter(BFile& file, const BMessage& parameter, int32 level)
169 {
170 	const char *name;
171 	if (parameter.FindString(MDSU_NAME, &name) != B_OK || !name)
172 		return false;
173 
174 	BString line, word(name);
175 	EscapeWord(word);
176 	bool needsEscaping = word.FindFirst(' ') >= 0;
177 	line.SetTo('\t', level);
178 	if (needsEscaping)
179 		line << '\"';
180 	line << word;
181 	if (needsEscaping)
182 		line << '\"';
183 
184 	for (int32 index = 0; parameter.FindString(MDSU_VALUES, index, &name) == B_OK;
185 			index++)
186 		if (name) {
187 			line << ' ';
188 			word = name;
189 			EscapeWord(word);
190 			needsEscaping = word.FindFirst(' ') >= 0;
191 			if (needsEscaping)
192 				line << '\"';
193 			line << word;
194 			if (needsEscaping)
195 				line << '\"';
196 		}
197 
198 	type_code type;
199 	int32 parameterCount;
200 	parameter.GetInfo(MDSU_PARAMETERS, &type, &parameterCount);
201 
202 	if (parameterCount > 0)
203 		line << " {";
204 
205 	line << '\n';
206 	file.Write(line.String(), line.Length());
207 
208 	if (parameterCount > 0) {
209 		BMessage subParameter;
210 		for (int32 index = 0; parameter.FindMessage(MDSU_PARAMETERS, index,
211 				&subParameter) == B_OK; index++)
212 			WriteParameter(file, subParameter, level + 1);
213 
214 		line.SetTo('\t', level);
215 		line << "}\n";
216 		file.Write(line.String(), line.Length());
217 	}
218 
219 	return true;
220 }
221 
222 
223 bool
224 WriteMessageDriverSettings(BFile& file, const BMessage& message)
225 {
226 	if (file.InitCheck() != B_OK || !file.IsWritable())
227 		return false;
228 
229 	file.SetSize(0);
230 	file.Seek(0, SEEK_SET);
231 
232 	BMessage parameter;
233 	for (int32 index = 0; message.FindMessage(MDSU_PARAMETERS, index, &parameter) == B_OK;
234 			index++) {
235 		if (index > 0)
236 			file.Write("\n", 1);
237 		WriteParameter(file, parameter, 0);
238 	}
239 
240 	return true;
241 }
242