* EthernetSettingsView now stores resolv.conf to the correct location.

* Settings::ReadConfiguration() now uses functions of resolv.h to retrieve the
  list of name servers instead of parsing resolv.conf itself.
* Thanks for the note, Siarzhuk - this closes ticket #2603.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33993 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-11-11 08:45:36 +00:00
parent f03b7f8915
commit 1e8709cb52
2 changed files with 42 additions and 65 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2008 Haiku Inc. All rights reserved. * Copyright 2004-2009 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -10,6 +10,7 @@
* Philippe Saint-Pierre * Philippe Saint-Pierre
*/ */
#include "EthernetSettingsView.h" #include "EthernetSettingsView.h"
#include "settings.h" #include "settings.h"
@@ -375,9 +376,14 @@ EthernetSettingsView::_SaveConfiguration()
void void
EthernetSettingsView::_SaveDNSConfiguration() EthernetSettingsView::_SaveDNSConfiguration()
{ {
BFile file("/etc/resolv.conf", BPath path;
B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); if (find_directory(B_COMMON_SETTINGS_DIRECTORY, &path) != B_OK)
if (file.InitCheck() < B_OK) { return;
path.Append("network/resolv.conf");
BFile file(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
if (file.InitCheck() != B_OK) {
fprintf(stderr, "failed to open /etc/resolv.conf for writing: %s\n", fprintf(stderr, "failed to open /etc/resolv.conf for writing: %s\n",
strerror(file.InitCheck())); strerror(file.InitCheck()));
return; return;
+32 -61
View File
@@ -1,54 +1,58 @@
/* /*
* Copyright 2004-2007 Haiku Inc. All rights reserved. * Copyright 2004-2009 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Author: * Authors:
* Andre Alves Garzia, [email protected] * Andre Alves Garzia, [email protected]
* Axel Dörfler, [email protected].
*/ */
#include "settings.h" #include "settings.h"
#include <String.h>
#include <File.h>
#include <Path.h>
#include <SupportDefs.h>
#include <AutoDeleter.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h>
#include <net/if.h> #include <net/if.h>
#include <net/if_dl.h> #include <net/if_dl.h>
#include <net/if_media.h> #include <net/if_media.h>
#include <net/if_types.h> #include <net/if_types.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/socket.h> #include <resolv.h>
#include <sys/sockio.h>
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <unistd.h> #include <unistd.h>
#include <File.h>
#include <Path.h>
#include <String.h>
#include <AutoDeleter.h>
Settings::Settings(const char *name) Settings::Settings(const char *name)
: :
fAuto(true) fAuto(true)
{ {
fSocket = socket(AF_INET, SOCK_DGRAM, 0); fSocket = socket(AF_INET, SOCK_DGRAM, 0);
fName = name; fName = name;
ReadConfiguration(); ReadConfiguration();
} }
Settings::~Settings() Settings::~Settings()
{ {
close(fSocket); close(fSocket);
} }
bool bool
Settings::_PrepareRequest(struct ifreq& request) Settings::_PrepareRequest(struct ifreq& request)
{ {
//This function is used for talking direct to the stack. // This function is used for talking direct to the stack.
//It´s used by _ShowConfiguration. // It´s used by _ShowConfiguration.
const char* name = fName.String(); const char* name = fName.String();
@@ -71,16 +75,16 @@ Settings::ReadConfiguration()
char address[32]; char address[32];
sockaddr_in* inetAddress = NULL; sockaddr_in* inetAddress = NULL;
// Obtain IP. // Obtain IP.
if (ioctl(fSocket, SIOCGIFADDR, &request, sizeof(request)) < 0) if (ioctl(fSocket, SIOCGIFADDR, &request, sizeof(request)) < 0)
return; return;
inetAddress = (sockaddr_in*)&request.ifr_addr; inetAddress = (sockaddr_in*)&request.ifr_addr;
if (inet_ntop(AF_INET, &inetAddress->sin_addr, address, if (inet_ntop(AF_INET, &inetAddress->sin_addr, address,
sizeof(address)) == NULL) { sizeof(address)) == NULL) {
return; return;
} }
fIP = address; fIP = address;
// Obtain netmask. // Obtain netmask.
@@ -121,7 +125,6 @@ Settings::ReadConfiguration()
ifreq *interface = (ifreq *)buffer; ifreq *interface = (ifreq *)buffer;
ifreq *end = (ifreq *)((uint8 *)buffer + size); ifreq *end = (ifreq *)((uint8 *)buffer + size);
while (interface < end) { while (interface < end) {
route_entry& route = interface->ifr_route; route_entry& route = interface->ifr_route;
@@ -138,7 +141,7 @@ Settings::ReadConfiguration()
if (route.gateway != NULL) if (route.gateway != NULL)
addressSize += route.gateway->sa_len; addressSize += route.gateway->sa_len;
interface = (ifreq *)((addr_t)interface + interface = (ifreq *)((addr_t)interface +
IF_NAMESIZE + sizeof(route_entry) + addressSize); IF_NAMESIZE + sizeof(route_entry) + addressSize);
} }
@@ -146,50 +149,18 @@ Settings::ReadConfiguration()
if (ioctl(fSocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0) if (ioctl(fSocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
flags = request.ifr_flags; flags = request.ifr_flags;
fAuto = flags & IFF_AUTO_CONFIGURED; fAuto = (flags & IFF_AUTO_CONFIGURED) != 0;
// read resolv.conf for the dns. // read resolv.conf for the dns.
fNameservers.MakeEmpty(); fNameservers.MakeEmpty();
#define MATCH(line, name) \ res_init();
(!strncmp(line, name, sizeof(name) - 1) && \ res_state state = __res_state();
(line[sizeof(name) - 1] == ' ' || \
line[sizeof(name) - 1] == '\t'))
if (state != NULL) {
register FILE *fp = fopen("/etc/resolv.conf", "r"); for (int i = 0; i < state->nscount; i++) {
if (fp == NULL) { fNameservers.AddItem(
fprintf(stderr, "failed to open '/etc/resolv.conf' to " new BString(inet_ntoa(state->nsaddr_list[i].sin_addr)));
"read nameservers: %s\n", strerror(errno));
return;
}
int nserv = 0;
char buf[1024];
register char *cp; //, **pp;
// register int n;
int MAXNS = 2;
// read the config file
while (fgets(buf, sizeof(buf), fp) != NULL) {
// skip comments
if (*buf == ';' || *buf == '#')
continue;
// read nameservers to query
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
// char sbuf[2];
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
cp[strcspn(cp, ";# \t\n")] = '\0';
if ((*cp != '\0') && (*cp != '\n')) {
fNameservers.AddItem(new BString(cp));
nserv++;
}
} }
continue;
} }
fclose(fp);
} }