1a4a34e42SAxel Dörfler /* 29a7e231eSAxel Dörfler * Copyright 2014-2015 Haiku Inc. All rights reserved. 3a4a34e42SAxel Dörfler * Distributed under the terms of the MIT License. 4a4a34e42SAxel Dörfler * 5a4a34e42SAxel Dörfler * Authors: 6a4a34e42SAxel Dörfler * Adrien Destugues, pulkomandy@pulkomandy.tk 7a4a34e42SAxel Dörfler */ 8a4a34e42SAxel Dörfler 9a4a34e42SAxel Dörfler 10a4a34e42SAxel Dörfler #include "DNSSettingsView.h" 11a4a34e42SAxel Dörfler 129a7e231eSAxel Dörfler #include <arpa/inet.h> 139a7e231eSAxel Dörfler #include <netinet/in.h> 149a7e231eSAxel Dörfler #include <resolv.h> 159a7e231eSAxel Dörfler #include <stdio.h> 169a7e231eSAxel Dörfler #include <string.h> 179a7e231eSAxel Dörfler #include <sys/socket.h> 189a7e231eSAxel Dörfler 19b4ec589bSAxel Dörfler #include <Box.h> 20a4a34e42SAxel Dörfler #include <Button.h> 21b4ec589bSAxel Dörfler #include <Catalog.h> 22a4a34e42SAxel Dörfler #include <File.h> 23a4a34e42SAxel Dörfler #include <FindDirectory.h> 24a4a34e42SAxel Dörfler #include <LayoutBuilder.h> 25a4a34e42SAxel Dörfler #include <ListView.h> 26a4a34e42SAxel Dörfler #include <Path.h> 27a4a34e42SAxel Dörfler #include <ScrollView.h> 28b4ec589bSAxel Dörfler #include <StringView.h> 29d0b107f3SAxel Dörfler 30d0b107f3SAxel Dörfler #include "IPAddressControl.h" 31a4a34e42SAxel Dörfler 32a4a34e42SAxel Dörfler 33b4ec589bSAxel Dörfler static const int32 kMsgAddServer = 'adds'; 34b4ec589bSAxel Dörfler static const int32 kMsgDeleteServer = 'dels'; 35b4ec589bSAxel Dörfler static const int32 kMsgMoveUp = 'mvup'; 36b4ec589bSAxel Dörfler static const int32 kMsgMoveDown = 'mvdn'; 37b4ec589bSAxel Dörfler static const int32 kMsgApply = 'aply'; 38b4ec589bSAxel Dörfler 39b4ec589bSAxel Dörfler 40b4ec589bSAxel Dörfler #undef B_TRANSLATION_CONTEXT 41b4ec589bSAxel Dörfler #define B_TRANSLATION_CONTEXT "DNSSettingsView" 42a4a34e42SAxel Dörfler 43a4a34e42SAxel Dörfler 44*3d7aaa30SAxel Dörfler DNSSettingsView::DNSSettingsView(BNetworkSettingsItem* item) 459a7e231eSAxel Dörfler : 46*3d7aaa30SAxel Dörfler BView("dns", 0), 47*3d7aaa30SAxel Dörfler fItem(item) 48a4a34e42SAxel Dörfler { 49a4a34e42SAxel Dörfler fServerListView = new BListView("nameservers"); 50d0b107f3SAxel Dörfler fTextControl = new IPAddressControl(AF_UNSPEC, "server", ""); 51a4a34e42SAxel Dörfler fTextControl->SetExplicitMinSize(BSize(fTextControl->StringWidth("5") * 18, 52a4a34e42SAxel Dörfler B_SIZE_UNSET)); 53a4a34e42SAxel Dörfler 54b4ec589bSAxel Dörfler fAddButton = new BButton(B_TRANSLATE("Add"), new BMessage(kMsgAddServer)); 55b4ec589bSAxel Dörfler fAddButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); 56b4ec589bSAxel Dörfler fUpButton = new BButton(B_TRANSLATE("Move up"), new BMessage(kMsgMoveUp)); 57b4ec589bSAxel Dörfler fUpButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); 58b4ec589bSAxel Dörfler fDownButton = new BButton(B_TRANSLATE("Move down"), 59b4ec589bSAxel Dörfler new BMessage(kMsgMoveDown)); 60b4ec589bSAxel Dörfler fDownButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); 61b4ec589bSAxel Dörfler fRemoveButton = new BButton(B_TRANSLATE("Remove"), new BMessage(kMsgDeleteServer)); 62b4ec589bSAxel Dörfler fRemoveButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); 63a4a34e42SAxel Dörfler 64b4ec589bSAxel Dörfler fApplyButton = new BButton(B_TRANSLATE("Apply"), new BMessage(kMsgApply)); 65b4ec589bSAxel Dörfler 66b4ec589bSAxel Dörfler BBox* box = new BBox("dns"); 67b4ec589bSAxel Dörfler box->SetLabel(B_TRANSLATE("DNS servers")); 68b4ec589bSAxel Dörfler box->AddChild(BLayoutBuilder::Grid<>() 69b4ec589bSAxel Dörfler .SetInsets(B_USE_DEFAULT_SPACING) 70a4a34e42SAxel Dörfler .Add(fTextControl, 0, 0) 71a4a34e42SAxel Dörfler .Add(fAddButton, 1, 0) 72a4a34e42SAxel Dörfler .Add(new BScrollView("scroll", fServerListView, 0, false, true), 73b4ec589bSAxel Dörfler 0, 1, 1, 3) 74a4a34e42SAxel Dörfler .Add(fUpButton, 1, 1) 75a4a34e42SAxel Dörfler .Add(fDownButton, 1, 2) 76a4a34e42SAxel Dörfler .Add(fRemoveButton, 1, 3) 77b4ec589bSAxel Dörfler .View()); 78b4ec589bSAxel Dörfler 79b4ec589bSAxel Dörfler BLayoutBuilder::Group<>(this, B_VERTICAL) 80b4ec589bSAxel Dörfler .Add(box) 81b4ec589bSAxel Dörfler .Add(fDomain = new BTextControl(B_TRANSLATE("Domain"), "", NULL)) 82b4ec589bSAxel Dörfler .AddGroup(B_HORIZONTAL) 83b4ec589bSAxel Dörfler .AddGlue() 84b4ec589bSAxel Dörfler .Add(fApplyButton); 85a4a34e42SAxel Dörfler 86a4a34e42SAxel Dörfler _LoadDNSConfiguration(); 87a4a34e42SAxel Dörfler } 88a4a34e42SAxel Dörfler 89a4a34e42SAxel Dörfler 909a7e231eSAxel Dörfler DNSSettingsView::~DNSSettingsView() 919a7e231eSAxel Dörfler { 929a7e231eSAxel Dörfler } 939a7e231eSAxel Dörfler 949a7e231eSAxel Dörfler 95a4a34e42SAxel Dörfler status_t 96a4a34e42SAxel Dörfler DNSSettingsView::Revert() 97a4a34e42SAxel Dörfler { 98a4a34e42SAxel Dörfler int i; 99a4a34e42SAxel Dörfler for (i = 0; i < fRevertList.CountStrings(); i++) { 1009a7e231eSAxel Dörfler BStringItem* item = static_cast<BStringItem*>( 1019a7e231eSAxel Dörfler fServerListView->ItemAt(i)); 102a4a34e42SAxel Dörfler if (item == NULL) { 103a4a34e42SAxel Dörfler item = new BStringItem(""); 104a4a34e42SAxel Dörfler fServerListView->AddItem(item); 105a4a34e42SAxel Dörfler } 106a4a34e42SAxel Dörfler 107a4a34e42SAxel Dörfler item->SetText(fRevertList.StringAt(i)); 108a4a34e42SAxel Dörfler } 109a4a34e42SAxel Dörfler 110a4a34e42SAxel Dörfler // Now remove any extra item 111a4a34e42SAxel Dörfler for (; i < fServerListView->CountItems(); i++) 112a4a34e42SAxel Dörfler delete fServerListView->RemoveItem(i); 113a4a34e42SAxel Dörfler 114a4a34e42SAxel Dörfler return B_OK; 115a4a34e42SAxel Dörfler } 116a4a34e42SAxel Dörfler 117a4a34e42SAxel Dörfler 118b4ec589bSAxel Dörfler void 119b4ec589bSAxel Dörfler DNSSettingsView::AttachedToWindow() 120b4ec589bSAxel Dörfler { 121b4ec589bSAxel Dörfler fAddButton->SetTarget(this); 122b4ec589bSAxel Dörfler fRemoveButton->SetTarget(this); 123b4ec589bSAxel Dörfler fUpButton->SetTarget(this); 124b4ec589bSAxel Dörfler fDownButton->SetTarget(this); 125b4ec589bSAxel Dörfler 126b4ec589bSAxel Dörfler fTextControl->SetTarget(this); 127b4ec589bSAxel Dörfler 128b4ec589bSAxel Dörfler fApplyButton->SetTarget(this); 129b4ec589bSAxel Dörfler } 130b4ec589bSAxel Dörfler 131b4ec589bSAxel Dörfler 132b4ec589bSAxel Dörfler void 133b4ec589bSAxel Dörfler DNSSettingsView::MessageReceived(BMessage* message) 134b4ec589bSAxel Dörfler { 135b4ec589bSAxel Dörfler switch (message->what) { 136b4ec589bSAxel Dörfler case kMsgAddServer: 137b4ec589bSAxel Dörfler { 138b4ec589bSAxel Dörfler const char* address = fTextControl->Text(); 139b4ec589bSAxel Dörfler fServerListView->AddItem(new BStringItem(address)); 140b4ec589bSAxel Dörfler break; 141b4ec589bSAxel Dörfler } 142b4ec589bSAxel Dörfler case kMsgDeleteServer: 143b4ec589bSAxel Dörfler delete fServerListView->RemoveItem( 144b4ec589bSAxel Dörfler fServerListView->CurrentSelection()); 145b4ec589bSAxel Dörfler break; 146b4ec589bSAxel Dörfler 147b4ec589bSAxel Dörfler case kMsgMoveUp: 148b4ec589bSAxel Dörfler { 149b4ec589bSAxel Dörfler int index = fServerListView->CurrentSelection(); 150b4ec589bSAxel Dörfler if (index > 0) 151b4ec589bSAxel Dörfler fServerListView->SwapItems(index, index - 1); 152b4ec589bSAxel Dörfler break; 153b4ec589bSAxel Dörfler } 154b4ec589bSAxel Dörfler case kMsgMoveDown: 155b4ec589bSAxel Dörfler { 156b4ec589bSAxel Dörfler int index = fServerListView->CurrentSelection(); 157b4ec589bSAxel Dörfler if (index < fServerListView->CountItems() - 1) 158b4ec589bSAxel Dörfler fServerListView->SwapItems(index, index + 1); 159b4ec589bSAxel Dörfler break; 160b4ec589bSAxel Dörfler } 161b4ec589bSAxel Dörfler case kMsgApply: 162*3d7aaa30SAxel Dörfler if (_SaveDNSConfiguration() == B_OK) 163*3d7aaa30SAxel Dörfler fItem->NotifySettingsUpdated(); 164b4ec589bSAxel Dörfler break; 165b4ec589bSAxel Dörfler 166b4ec589bSAxel Dörfler default: 167b4ec589bSAxel Dörfler BView::MessageReceived(message); 168b4ec589bSAxel Dörfler break; 169b4ec589bSAxel Dörfler } 170b4ec589bSAxel Dörfler } 171b4ec589bSAxel Dörfler 172b4ec589bSAxel Dörfler 173a4a34e42SAxel Dörfler status_t 174a4a34e42SAxel Dörfler DNSSettingsView::_LoadDNSConfiguration() 175a4a34e42SAxel Dörfler { 176a4a34e42SAxel Dörfler res_init(); 177a4a34e42SAxel Dörfler res_state state = __res_state(); 178a4a34e42SAxel Dörfler 179a4a34e42SAxel Dörfler if (state != NULL) { 180a4a34e42SAxel Dörfler for (int i = 0; i < state->nscount; i++) { 181a4a34e42SAxel Dörfler char* address = inet_ntoa(state->nsaddr_list[i].sin_addr); 182a4a34e42SAxel Dörfler fServerListView->AddItem(new BStringItem(address)); 183a4a34e42SAxel Dörfler fRevertList.Add(address); 184a4a34e42SAxel Dörfler } 185a4a34e42SAxel Dörfler 186a4a34e42SAxel Dörfler fDomain->SetText(state->dnsrch[0]); 187a4a34e42SAxel Dörfler return B_OK; 188a4a34e42SAxel Dörfler } 189a4a34e42SAxel Dörfler 190a4a34e42SAxel Dörfler return B_ERROR; 191a4a34e42SAxel Dörfler } 192a4a34e42SAxel Dörfler 193a4a34e42SAxel Dörfler 194a4a34e42SAxel Dörfler status_t 195a4a34e42SAxel Dörfler DNSSettingsView::_SaveDNSConfiguration() 196a4a34e42SAxel Dörfler { 197a4a34e42SAxel Dörfler BPath path; 198a4a34e42SAxel Dörfler status_t status; 199a4a34e42SAxel Dörfler status = find_directory(B_SYSTEM_SETTINGS_DIRECTORY, &path); 200a4a34e42SAxel Dörfler if (status != B_OK) 201a4a34e42SAxel Dörfler return status; 202a4a34e42SAxel Dörfler 203a4a34e42SAxel Dörfler path.Append("network/resolv.conf"); 204a4a34e42SAxel Dörfler 205a4a34e42SAxel Dörfler BFile file(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); 206a4a34e42SAxel Dörfler if (file.InitCheck() != B_OK) { 207a4a34e42SAxel Dörfler fprintf(stderr, "failed to open %s for writing: %s\n", path.Path(), 208a4a34e42SAxel Dörfler strerror(file.InitCheck())); 209a4a34e42SAxel Dörfler return file.InitCheck(); 210a4a34e42SAxel Dörfler } 211a4a34e42SAxel Dörfler 212b4ec589bSAxel Dörfler BString content("# Generated by Network preferences\n"); 213a4a34e42SAxel Dörfler 2149a7e231eSAxel Dörfler for (int i = 0; i < fServerListView->CountItems(); i++) { 2159a7e231eSAxel Dörfler BString item = ((BStringItem*)fServerListView->ItemAt(i))->Text(); 2169a7e231eSAxel Dörfler if (item.Length() > 0) 217a4a34e42SAxel Dörfler content << "nameserver\t" << item.String() << "\n"; 218a4a34e42SAxel Dörfler } 219a4a34e42SAxel Dörfler 220a4a34e42SAxel Dörfler if (strlen(fDomain->Text()) > 0) 221a4a34e42SAxel Dörfler content << "domain\t" << fDomain->Text() << "\n"; 222a4a34e42SAxel Dörfler 223a4a34e42SAxel Dörfler return file.Write(content.String(), content.Length()); 224a4a34e42SAxel Dörfler } 225