Diffstat (limited to 'noncore/net/networksetup/interfaces.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/net/networksetup/interfaces.cpp | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/noncore/net/networksetup/interfaces.cpp b/noncore/net/networksetup/interfaces.cpp new file mode 100644 index 0000000..b8a3e7f --- a/dev/null +++ b/noncore/net/networksetup/interfaces.cpp | |||
@@ -0,0 +1,513 @@ | |||
1 | #include "interfaces.h" | ||
2 | |||
3 | #include <qfile.h> | ||
4 | #include <qtextstream.h> | ||
5 | #include <qregexp.h> | ||
6 | |||
7 | #define AUTO "auto" | ||
8 | #define IFACE "iface" | ||
9 | #define MAPPING "mapping" | ||
10 | |||
11 | /** | ||
12 | * Constructor. Reads in the interfaces file and then split the file up by | ||
13 | * the \n for interfaces variable. | ||
14 | * @param useInterfacesFile if an interface file other then the default is | ||
15 | * desired to be used it should be passed in. | ||
16 | */ | ||
17 | Interfaces::Interfaces(QString useInterfacesFile){ | ||
18 | acceptedFamily.append(INTERFACES_FAMILY_INET); | ||
19 | acceptedFamily.append(INTERFACES_FAMILY_IPX); | ||
20 | acceptedFamily.append(INTERFACES_FAMILY_INET6); | ||
21 | |||
22 | interfacesFile = useInterfacesFile; | ||
23 | QFile file(interfacesFile); | ||
24 | if (!file.open(IO_ReadOnly)){ | ||
25 | qDebug(QString("Interfaces: Can't open file: %1 for reading.").arg(interfacesFile).latin1()); | ||
26 | currentIface = interfaces.end(); | ||
27 | currentMapping = interfaces.end(); | ||
28 | return; | ||
29 | } | ||
30 | QTextStream stream( &file ); | ||
31 | QString line; | ||
32 | while ( !stream.eof() ) { | ||
33 | line += stream.readLine(); | ||
34 | line += "\n"; | ||
35 | } | ||
36 | file.close(); | ||
37 | interfaces = QStringList::split("\n", line, true); | ||
38 | |||
39 | currentIface = interfaces.end(); | ||
40 | currentMapping = interfaces.end(); | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * Find out if interface is in an "auto" group or not. | ||
45 | * Report any duplicates such as eth0 being in two differnt auto's | ||
46 | * @param | ||
47 | * @return true is interface is in auto | ||
48 | */ | ||
49 | bool Interfaces::isAuto(QString interface){ | ||
50 | QStringList autoLines = interfaces.grep(QRegExp(AUTO)); | ||
51 | QStringList awi = autoLines.grep(QRegExp(interface)); | ||
52 | if(awi.count() > 1) | ||
53 | qDebug(QString("Interfaces: Found more then auto group with interface: %1.").arg(interface).latin1()); | ||
54 | if(awi.count() < 1) | ||
55 | return false; | ||
56 | return true; | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Attempt to set the auto option for interface to setAuto. | ||
61 | * @param interface the interface to set | ||
62 | * @param setAuto the value to set interface to. | ||
63 | * @return false if already set to setAuto. | ||
64 | * */ | ||
65 | bool Interfaces::setAuto(QString interface, bool setAuto){ | ||
66 | // Don't need to set it if it is already set. | ||
67 | if(isAuto(interface) == setAuto) | ||
68 | return false; | ||
69 | |||
70 | bool changed = false; | ||
71 | for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) { | ||
72 | if((*it).contains(AUTO)){ | ||
73 | //We know that they are not in any group so let add to this auto. | ||
74 | if(setAuto){ | ||
75 | (*it) = (*it) += " " + interface; | ||
76 | // Don't care to have such thins as: auto eth0 lo usb0 | ||
77 | (*it) = (*it).simplifyWhiteSpace(); | ||
78 | changed = true; | ||
79 | break; | ||
80 | } | ||
81 | else{ | ||
82 | if((*it).contains(interface)){ | ||
83 | (*it) = (*it).replace(QRegExp(interface), ""); | ||
84 | // clean up | ||
85 | QString line = (*it).simplifyWhiteSpace(); | ||
86 | line = line.replace(QRegExp(" "),""); | ||
87 | if(line == AUTO) | ||
88 | (*it) = ""; | ||
89 | changed = true; | ||
90 | // Don't break because we want to make sure we remove all cases. | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | if(changed == false){ | ||
96 | if(setAuto == true) | ||
97 | interfaces.append(QString(AUTO" %1").arg(interface)); | ||
98 | else{ | ||
99 | qDebug(QString("Interfaces: Can't set interface %1 auto to false sense it is already false.").arg(interface).latin1()); | ||
100 | } | ||
101 | } | ||
102 | return true; | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * Set the current interface to interface. This needs to be done before you | ||
107 | * can call getFamily(), getMethod, and get/setOption(). | ||
108 | * @param interface the name of the interface to set. All whitespace is | ||
109 | * removed from the interface name. | ||
110 | * @return bool true if it is successfull. | ||
111 | */ | ||
112 | bool Interfaces::setInterface(QString interface){ | ||
113 | interface = interface.simplifyWhiteSpace(); | ||
114 | interface = interface.replace(QRegExp(" "), ""); | ||
115 | return setStanza(IFACE, interface, currentIface); | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * A quick helper funtion to see if the current interface is set. | ||
120 | * @return bool true if set, false otherwise. | ||
121 | */ | ||
122 | bool Interfaces::isInterfaceSet(){ | ||
123 | return (currentIface != interfaces.end()); | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * Add a new interface of with the settings - family and method | ||
128 | * @param interface the name of the interface to set. All whitespace is | ||
129 | * removed from the interface name. | ||
130 | * @param family the family of this interface inet or inet, ipx or inet6 | ||
131 | * Must of one of the families defined in interfaces.h | ||
132 | * @param method for the family. see interfaces man page for family methods. | ||
133 | * @return true if successfull. | ||
134 | */ | ||
135 | bool Interfaces::addInterface(QString interface, QString family, QString method){ | ||
136 | if(acceptedFamily.contains(family)==0) | ||
137 | return false; | ||
138 | interface = interface.simplifyWhiteSpace(); | ||
139 | interface = interface.replace(QRegExp(" "), ""); | ||
140 | interfaces.append(""); | ||
141 | interfaces.append(QString(IFACE " %1 %2 %3").arg(interface).arg(family).arg(method)); | ||
142 | return true; | ||
143 | } | ||
144 | |||
145 | /** | ||
146 | * Remove the currently selected interface and all of its options. | ||
147 | * @return bool if successfull or not. | ||
148 | */ | ||
149 | bool Interfaces::removeInterface(){ | ||
150 | if(currentIface == interfaces.end()) | ||
151 | return false; | ||
152 | (*currentIface) = ""; | ||
153 | return removeAllInterfaceOptions(); | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * Gets the hardware name of the interface that is currently selected. | ||
158 | * @return QString name of the hardware interface (eth0, usb2, wlan1...). | ||
159 | * @param error set to true if any error occurs, false otherwise. | ||
160 | */ | ||
161 | QString Interfaces::getInterfaceName(bool &error){ | ||
162 | if(currentIface == interfaces.end()){ | ||
163 | error = true; | ||
164 | return QString(); | ||
165 | } | ||
166 | QString line = (*currentIface); | ||
167 | line = line.mid(QString(IFACE).length() +1, line.length()); | ||
168 | line = line.simplifyWhiteSpace(); | ||
169 | int findSpace = line.find(" "); | ||
170 | if( findSpace < 0){ | ||
171 | error = true; | ||
172 | return QString(); | ||
173 | } | ||
174 | error = false; | ||
175 | return line.mid(0, findSpace); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * Gets the family name of the interface that is currently selected. | ||
180 | * @return QString name of the family (inet, inet6, ipx). | ||
181 | * @param error set to true if any error occurs, false otherwise. | ||
182 | */ | ||
183 | QString Interfaces::getInterfaceFamily(bool &error){ | ||
184 | QString name = getInterfaceName(error); | ||
185 | if(error){ | ||
186 | error = true; | ||
187 | return QString(); | ||
188 | } | ||
189 | QString line = (*currentIface); | ||
190 | line = line.mid(QString(IFACE).length() +1, line.length()); | ||
191 | line = line.mid(name.length()+1, line.length()); | ||
192 | line = line.simplifyWhiteSpace(); | ||
193 | int findSpace = line.find(" "); | ||
194 | if( findSpace < 0){ | ||
195 | error = true; | ||
196 | return QString(); | ||
197 | } | ||
198 | error = false; | ||
199 | return line.mid(0, findSpace); | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * Gets the method of the interface that is currently selected. | ||
204 | * @return QString name of the method such as staic or dhcp. | ||
205 | * See the man page of interfaces for possible methods depending on the family. | ||
206 | * @param error set to true if any error occurs, false otherwise. | ||
207 | */ | ||
208 | QString Interfaces::getInterfaceMethod(bool &error){ | ||
209 | QString name = getInterfaceName(error); | ||
210 | if(error){ | ||
211 | error = true; | ||
212 | return QString(); | ||
213 | } | ||
214 | QString family = getInterfaceFamily(error); | ||
215 | if(error){ | ||
216 | error = true; | ||
217 | return QString(); | ||
218 | } | ||
219 | QString line = (*currentIface); | ||
220 | line = line.mid(QString(IFACE).length()+1, line.length()); | ||
221 | line = line.mid(name.length()+1, line.length()); | ||
222 | line = line.mid(family.length()+1, line.length()); | ||
223 | line = line.simplifyWhiteSpace(); | ||
224 | error = false; | ||
225 | return line; | ||
226 | } | ||
227 | |||
228 | /** | ||
229 | * Sets the interface name to newName. | ||
230 | * @param newName the new name of the interface. All whitespace is removed. | ||
231 | * @return bool true if successfull. | ||
232 | */ | ||
233 | bool Interfaces::setInterfaceName(QString newName){ | ||
234 | if(currentIface == interfaces.end()) | ||
235 | return false; | ||
236 | newName = newName.simplifyWhiteSpace(); | ||
237 | newName = newName.replace(QRegExp(" "), ""); | ||
238 | bool returnValue = false; | ||
239 | (*currentIface) = QString("iface %1 %2 %3").arg(newName).arg(getInterfaceFamily(returnValue)).arg(getInterfaceMethod(returnValue)); | ||
240 | return !returnValue; | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * Sets the interface family to newName. | ||
245 | * @param newName the new name of the interface. Must be one of the families | ||
246 | * defined in the interfaces.h file. | ||
247 | * @return bool true if successfull. | ||
248 | */ | ||
249 | bool Interfaces::setInterfaceFamily(QString newName){ | ||
250 | if(currentIface == interfaces.end()) | ||
251 | return false; | ||
252 | if(acceptedFamily.contains(newName)==0) | ||
253 | return false; | ||
254 | bool returnValue = false; | ||
255 | (*currentIface) = QString("iface %1 %2 %3").arg(getInterfaceName(returnValue)).arg(newName).arg(getInterfaceMethod(returnValue)); | ||
256 | return !returnValue; | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * Sets the interface method to newName | ||
261 | * @param newName the new name of the interface | ||
262 | * @return bool true if successfull. | ||
263 | */ | ||
264 | bool Interfaces::setInterfaceMethod(QString newName){ | ||
265 | if(currentIface == interfaces.end()) | ||
266 | return false; | ||
267 | bool returnValue = false; | ||
268 | (*currentIface) = QString("iface %1 %2 %3").arg(getInterfaceName(returnValue)).arg(getInterfaceFamily(returnValue)).arg(newName); | ||
269 | return !returnValue; | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Get a value for an option in the currently selected interface. For example | ||
274 | * calling getInterfaceOption("address") on the following stanza would | ||
275 | * return 192.168.1.1. | ||
276 | * iface eth0 static | ||
277 | * address 192.168.1.1 | ||
278 | * @param option the options to get the value. | ||
279 | * @param error set to true if any error occurs, false otherwise. | ||
280 | * @return QString the options value. QString::null if error == true | ||
281 | */ | ||
282 | QString Interfaces::getInterfaceOption(QString option, bool &error){ | ||
283 | return getOption(currentIface, option, error); | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * Set a value for an option in the currently selected interface. If option | ||
288 | * doesn't exist then it is added along with the value. If value is set to an | ||
289 | * empty string then option is removed. | ||
290 | * @param option the options to set the value. | ||
291 | * @param value the value that option should be set to. | ||
292 | * @param error set to true if any error occurs, false otherwise. | ||
293 | * @return QString the options value. QString::null if error == true | ||
294 | */ | ||
295 | bool Interfaces::setInterfaceOption(QString option, QString value){ | ||
296 | return setOption(currentIface, option, value); | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * Removes all of the options from the currently selected interface. | ||
301 | * @return bool error if if successfull | ||
302 | */ | ||
303 | bool Interfaces::removeAllInterfaceOptions(){ | ||
304 | return removeAllOptions(currentIface); | ||
305 | } | ||
306 | |||
307 | /** | ||
308 | * Set the current map to interface's map. This needs to be done before you | ||
309 | * can call addMapping(), set/getMap(), and get/setScript(). | ||
310 | * @param interface the name of the interface to set. All whitespace is | ||
311 | * removed from the interface name. | ||
312 | * @return bool true if it is successfull. | ||
313 | */ | ||
314 | bool Interfaces::setMapping(QString interface){ | ||
315 | interface = interface.simplifyWhiteSpace(); | ||
316 | interface = interface.replace(QRegExp(" "), ""); | ||
317 | return setStanza(MAPPING, interface, currentMapping); | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * Adds a new Mapping to the interfaces file with interfaces. | ||
322 | * @param interface the name(s) of the interfaces to set to this mapping | ||
323 | */ | ||
324 | void Interfaces::addMapping(QString interfaces){ | ||
325 | interfaces.append(""); | ||
326 | interfaces.append(QString(MAPPING " %1").arg(interfaces)); | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * Set a map option within a mapping. | ||
331 | * @param map map to use | ||
332 | * @param value value to go with map | ||
333 | * @return bool true if it is successfull. | ||
334 | */ | ||
335 | bool Interfaces::setMap(QString map, QString value){ | ||
336 | return setOption(currentMapping, map, value); | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * Get a map value within a mapping. | ||
341 | * @param map map to get value of | ||
342 | * @param bool true if it is successfull. | ||
343 | * @return value that goes to the map | ||
344 | */ | ||
345 | QString Interfaces::getMap(QString map, bool &error){ | ||
346 | return getOption(currentMapping, map, error); | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * Sets a script value of the current mapping to argument. | ||
351 | * @param argument the script name. | ||
352 | * @return true if successfull. | ||
353 | */ | ||
354 | bool Interfaces::setScript(QString argument){ | ||
355 | return setOption(currentMapping, "script", argument); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * @param error true if could not retrieve the current script argument. | ||
360 | * @return QString the argument of the script for the current mapping. | ||
361 | */ | ||
362 | QString Interfaces::getScript(bool &error){ | ||
363 | return getOption(currentMapping, "script", error); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Helper function used to parse through the QStringList and put pointers in | ||
368 | * the correct place. | ||
369 | * @param stanza The stanza (auto, iface, mapping) to look for. | ||
370 | * @param option string that must be in the stanza's main line. | ||
371 | * @param interator interator to place at location of stanza if successfull. | ||
372 | * @return bool true if the stanza is found. | ||
373 | */ | ||
374 | bool Interfaces::setStanza(QString stanza, QString option, QStringList::Iterator &iterator){ | ||
375 | bool found = false; | ||
376 | iterator = interfaces.end(); | ||
377 | for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) { | ||
378 | QString line = (*it).simplifyWhiteSpace(); | ||
379 | if(line.contains(stanza) && line.contains(option)){ | ||
380 | if(found == true){ | ||
381 | qDebug(QString("Interfaces: Found multiple stanza's for search: %1 %2").arg(stanza).arg(option).latin1()); | ||
382 | } | ||
383 | found = true; | ||
384 | iterator = it; | ||
385 | } | ||
386 | } | ||
387 | return !found; | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * Sets a value of an option in a stanza | ||
392 | * @param start the start of the stanza | ||
393 | * @param option the option to use when setting value. | ||
394 | * @return bool true if successfull, false otherwise. | ||
395 | */ | ||
396 | bool Interfaces::setOption(QStringList::Iterator start, QString option, QString value){ | ||
397 | if(start == interfaces.end()) | ||
398 | return false; | ||
399 | |||
400 | bool found = false; | ||
401 | for ( QStringList::Iterator it = start; it != interfaces.end(); ++it ) { | ||
402 | if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){ | ||
403 | if(!found && value != ""){ | ||
404 | // Got to the end of the stanza without finding it, so append it. | ||
405 | interfaces.insert(--it, QString("\t%1 %2").arg(option).arg(value)); | ||
406 | } | ||
407 | break; | ||
408 | } | ||
409 | if((*it).contains(option)){ | ||
410 | // Found it in stanza so replace it. | ||
411 | if(found) | ||
412 | qDebug(QString("Interfaces: Set Options found more then one value for option: %1 in stanza: %1").arg(option).arg((*start)).latin1()); | ||
413 | found = true; | ||
414 | if(value == "") | ||
415 | (*it) = ""; | ||
416 | else | ||
417 | (*it) = QString("\t%1 %2").arg(option).arg(value); | ||
418 | } | ||
419 | } | ||
420 | return true; | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * Removes all options in a stanza | ||
425 | * @param start the start of the stanza | ||
426 | * @return bool true if successfull, false otherwise. | ||
427 | */ | ||
428 | bool Interfaces::removeAllOptions(QStringList::Iterator start){ | ||
429 | if(start == interfaces.end()) | ||
430 | return false; | ||
431 | |||
432 | QStringList::Iterator it = start; | ||
433 | it = ++it; | ||
434 | for (it; it != interfaces.end(); ++it ) { | ||
435 | if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){ | ||
436 | break; | ||
437 | } | ||
438 | it = interfaces.remove(it); | ||
439 | it = --it; | ||
440 | } | ||
441 | // Leave a space between this interface and the next. | ||
442 | interfaces.insert(it, QString("")); | ||
443 | return true; | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * Gets a value of an option in a stanza | ||
448 | * @param start the start of the stanza | ||
449 | * @param option the option to use when getting the value. | ||
450 | * @param bool true if errors false otherwise. | ||
451 | * @return QString the value of option QString::null() if error == true. | ||
452 | */ | ||
453 | QString Interfaces::getOption(QStringList::Iterator start, QString option, bool &error){ | ||
454 | if(start == interfaces.end()){ | ||
455 | error = false; | ||
456 | return QString(); | ||
457 | } | ||
458 | |||
459 | QString value; | ||
460 | bool found = false; | ||
461 | for ( QStringList::Iterator it = start; it != interfaces.end(); ++it ) { | ||
462 | if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){ | ||
463 | break; | ||
464 | } | ||
465 | if((*it).contains(option)){ | ||
466 | if(found) | ||
467 | qDebug(QString("Interfaces: Get Options found more then one value: %1 for option: %2 in stanza %3").arg((*it)).arg(option).arg((*start)).latin1()); | ||
468 | found = true; | ||
469 | QString line = (*it).simplifyWhiteSpace(); | ||
470 | int space = line.find(" ", option.length()); | ||
471 | if(space != -1) | ||
472 | value = line.mid(space+1, line.length()); | ||
473 | else | ||
474 | qDebug(QString("Interfaces: Option %1 with no value").arg(option).latin1()); | ||
475 | } | ||
476 | } | ||
477 | error = !found; | ||
478 | return value; | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * Write out the interfaces file to the file passed into the constructor. | ||
483 | * Removes any excess blank lines over 1 line long. | ||
484 | * @return bool true if successfull, false if not. | ||
485 | */ | ||
486 | bool Interfaces::write(){ | ||
487 | QFile::remove(interfacesFile); | ||
488 | QFile file(interfacesFile); | ||
489 | |||
490 | if (!file.open(IO_ReadWrite)){ | ||
491 | qDebug(QString("Interfaces: Can't open file: %1 for writing.").arg(interfacesFile).latin1()); | ||
492 | return false; | ||
493 | } | ||
494 | QTextStream stream( &file ); | ||
495 | int whiteSpaceCount = 0; | ||
496 | for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) { | ||
497 | QString line = (*it).simplifyWhiteSpace(); | ||
498 | line = line.replace(QRegExp(" "),""); | ||
499 | if(line.length() == 0) | ||
500 | whiteSpaceCount++; | ||
501 | else | ||
502 | whiteSpaceCount = 0; | ||
503 | if(whiteSpaceCount < 2){ | ||
504 | qDebug((*it).latin1()); | ||
505 | stream << (*it) << '\n'; | ||
506 | } | ||
507 | } | ||
508 | file.close(); | ||
509 | return true; | ||
510 | } | ||
511 | |||
512 | // interfaces.cpp | ||
513 | |||