/* * Copyright 2014 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Adrien Destugues, pulkomandy@pulkomandy.tk */ #include "DNSSettingsView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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(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()); }