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