207 lines
4.4 KiB
C++
207 lines
4.4 KiB
C++
/*
|
|||
|
|
* Copyright 2014 Haiku Inc. All rights reserved.
|
||
|
|
* Distributed under the terms of the MIT License.
|
||
|
|
*
|
||
|
|
* Authors:
|
||
|
|
* Adrien Destugues, [email protected]
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
#include "DNSSettingsView.h"
|
||
|
|
|
||
|
|
#include <Button.h>
|
||
#include <File.h>
|
|||
|
|
#include <FindDirectory.h>
|
||
#include <LayoutBuilder.h>
|
|||
|
|
#include <ListView.h>
|
||
#include <Path.h>
|
|||
#include <ScrollView.h>
|
|||
|
|
#include <TextControl.h>
|
||
|
|
|
||
|
|
#include <arpa/inet.h>
|
||
|
|
#include <netinet/in.h>
|
||
|
|
#include <resolv.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <sys/socket.h>
|
||
|
|
|
||
|
|
|
||
|
|
static const int32 kAddServer = 'adds';
|
||
|
|
static const int32 kDeleteServer = 'dels';
|
||
static const int32 kMoveUp = 'mvup';
|
|||
|
|
static const int32 kMoveDown = 'mvdn';
|
||
static const int32 kEditServer = 'edit';
|
|||
|
|
|
||
|
|
|
||
|
|
DNSSettingsView::DNSSettingsView()
|
||
: BGroupView(B_VERTICAL)
|
|||
{
|
|||
|
|
fServerListView = new BListView("nameservers");
|
||
|
|
fTextControl = new BTextControl("", "", NULL);
|
||
|
|
fTextControl->SetModificationMessage(new BMessage(kEditServer));
|
||
|
|
|
||
|
|
fAddButton = new BButton("Add", new BMessage(kAddServer));
|
||
fUpButton = new BButton("Move up", new BMessage(kMoveUp));
|
|||
|
|
fDownButton = new BButton("Move down", new BMessage(kMoveDown));
|
||
fRemoveButton = new BButton("Remove", new BMessage(kDeleteServer));
|
|||
|
|
|
||
|
|
BLayoutBuilder::Group<>(this)
|
||
|
|
.AddGrid(B_HORIZONTAL)
|
||
|
|
.Add(fTextControl, 0, 0)
|
||
|
|
.Add(fAddButton, 1, 0)
|
||
|
|
.Add(new BScrollView("scroll", fServerListView, 0, false, true),
|
||
|
|
0, 1, 1, 4)
|
||
|
|
.Add(fUpButton, 1, 1)
|
||
|
|
.Add(fDownButton, 1, 2)
|
||
|
|
.Add(fRemoveButton, 1, 3)
|
||
|
|
.End()
|
||
.Add(fDomain = new BTextControl("Domain", "", NULL))
|
|||
.End();
|
|||
|
|
|
||
_LoadDNSConfiguration();
|
|||
}
|
|||
|
|
|
||
|
|
|
||
|
|
void
|
||
|
|
DNSSettingsView::AttachedToWindow()
|
||
|
|
{
|
||
|
|
fAddButton->SetTarget(this);
|
||
|
|
fRemoveButton->SetTarget(this);
|
||
|
|
fUpButton->SetTarget(this);
|
||
|
|
fDownButton->SetTarget(this);
|
||
|
|
|
||
|
|
fTextControl->SetTarget(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void
|
||
|
|
DNSSettingsView::MessageReceived(BMessage* message)
|
||
|
|
{
|
||
|
|
switch(message->what) {
|
||
|
|
case kAddServer:
|
||
|
|
{
|
||
|
|
const char* address = fTextControl->Text();
|
||
|
|
fServerListView->AddItem(new BStringItem(address));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case kDeleteServer:
|
||
|
|
{
|
||
delete fServerListView->RemoveItem(
|
|||
|
|
fServerListView->CurrentSelection());
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case kMoveUp:
|
||
|
|
{
|
||
|
|
int index = fServerListView->CurrentSelection();
|
||
|
|
|
||
|
|
if (index > 0)
|
||
|
|
fServerListView->SwapItems(index, index - 1);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case kMoveDown:
|
||
|
|
{
|
||
|
|
int index = fServerListView->CurrentSelection();
|
||
|
|
|
||
|
|
if (index < fServerListView->CountItems() - 1)
|
||
|
|
fServerListView->SwapItems(index, index + 1);
|
||
|
|
break;
|
||
}
|
|||
|
|
case kEditServer:
|
||
|
|
{
|
||
|
|
struct in_addr dummy;
|
||
|
|
bool success = inet_aton(fTextControl->Text(), &dummy);
|
||
|
|
fTextControl->MarkAsInvalid(!success);
|
||
|
|
fAddButton->SetEnabled(success);
|
||
break;
|
|||
}
|
|||
|
|
default:
|
||
|
|
BGroupView::MessageReceived(message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
status_t
|
||
DNSSettingsView::Apply()
|
|||
|
|
{
|
||
|
|
return _SaveDNSConfiguration();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
status_t
|
||
|
|
DNSSettingsView::Revert()
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
for(i = 0; i < fRevertList.CountStrings(); i++) {
|
||
|
|
BStringItem* item = static_cast<BStringItem*>(fServerListView->ItemAt(i));
|
||
|
|
if (item == NULL) {
|
||
|
|
item = new BStringItem("");
|
||
|
|
fServerListView->AddItem(item);
|
||
|
|
}
|
||
|
|
|
||
|
|
item->SetText(fRevertList.StringAt(i));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Now remove any extra item
|
||
|
|
for(; i < fServerListView->CountItems(); i++)
|
||
|
|
delete fServerListView->RemoveItem(i);
|
||
|
|
|
||
|
|
return B_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
status_t
|
||
|
|
DNSSettingsView::_LoadDNSConfiguration()
|
||
{
|
|||
|
|
res_init();
|
||
|
|
res_state state = __res_state();
|
||
|
|
|
||
|
|
if (state != NULL) {
|
||
|
|
for (int i = 0; i < state->nscount; i++) {
|
||
char* address = inet_ntoa(state->nsaddr_list[i].sin_addr);
|
|||
|
|
fServerListView->AddItem(new BStringItem(address));
|
||
|
|
fRevertList.Add(address);
|
||
}
|
|||
|
|||
|
|
fDomain->SetText(state->dnsrch[0]);
|
||
return B_OK;
|
|||
|
|
}
|
||
|
|
|
||
|
|
return B_ERROR;
|
||
|
|
}
|
||
|
|||
|
|
|
||
|
|
status_t
|
||
|
|
DNSSettingsView::_SaveDNSConfiguration()
|
||
|
|
{
|
||
|
|
BPath path;
|
||
|
|
status_t status;
|
||
|
|
status = find_directory(B_SYSTEM_SETTINGS_DIRECTORY, &path);
|
||
|
|
if (status != B_OK)
|
||
|
|
return status;
|
||
|
|
|
||
|
|
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 %s for writing: %s\n", path.Path(),
|
||
|
|
strerror(file.InitCheck()));
|
||
|
|
return file.InitCheck();
|
||
|
|
}
|
||
|
|
|
||
|
|
BString content("# Generated by Network Preflet\n");
|
||
|
|
|
||
|
|
for (int j = 0; j < fServerListView->CountItems(); j++) {
|
||
|
|
BString item = ((BStringItem*)fServerListView->ItemAt(j))->Text();
|
||
|
|
if (item.Length() > 0) {
|
||
|
|
content << "nameserver\t" << item.String() << "\n";
|
||
|
|
}
|
||
|
|
}
|
||
|
|||
|
|
if (strlen(fDomain->Text()) > 0)
|
||
|
|
content << "domain\t" << fDomain->Text() << "\n";
|
||
|
|||
|
|
return file.Write(content.String(), content.Length());
|
||
|
|
}
|
||
|
|
|
||
|
|
|