xref: /haiku/src/add-ons/network_settings/dnsclient/DNSSettingsView.cpp (revision 3d7aaa308c3265fc8016767b9e5a5c9a196209be)
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