xref: /haiku/src/preferences/network/NetworkWindow.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 #include "NetworkWindow.h"
2 #include "NetListView.h"
3 #include <ScrollView.h>
4 #include <StringView.h>
5 #include <Screen.h>
6 #include <malloc.h>
7 #include <stdlib.h>
8 #include <TextControl.h>
9 #include <Alert.h>
10 #include <Application.h>
11 #include <stdio.h>
12 #include <Directory.h>
13 #include <Entry.h>
14 #include <File.h>
15 #include <Region.h>
16 #include <Path.h>
17 
18 #include "InterfaceWin.h"
19 #include "BackupWindow.h"
20 #include "LoginInfo.h"
21 
22 //#define NETWORK_WINDOW_RIGHT 435
23 //#define NETWORK_WINDOW_BOTTOM 309
24 
25 class RestartWindow : public BWindow
26 {
27 public:
28 	RestartWindow();
29 
30 	BView		*fView;
31 	BStringView *fRestarting;
32 	BStringView *fWhatsHappening;
33 };
34 
35 
36 RestartWindow::RestartWindow()
37   : BWindow(BRect(400,300,650,350),"Restart Networking",B_MODAL_WINDOW,B_NOT_ANCHORED_ON_ACTIVATE | B_NOT_RESIZABLE,B_CURRENT_WORKSPACE)
38 {
39 	fView = new BView(Bounds(),"Restart_View",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
40 
41 	fView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
42 
43 	fRestarting = new BStringView(BRect(60,5,200,25),"Restarting_Text_1",
44 									"Restarting Networking");
45 	fWhatsHappening = new BStringView(BRect(60,30,200,50),"Restarting_Text_2",
46 									"Please Wait...");
47 
48 	BFont font(be_bold_font);
49 
50 	fRestarting->SetFont(&font);
51 	fWhatsHappening->SetFont(&font);
52 
53 	fView->AddChild(fRestarting);
54 	fView->AddChild(fWhatsHappening);
55 
56 	AddChild(fView);
57 }
58 
59 NetworkWindow::NetworkWindow()
60   : BWindow(BRect(0, 0, 435, 309),"Network",
61 			B_TITLED_WINDOW,B_NOT_ANCHORED_ON_ACTIVATE | B_NOT_ZOOMABLE | B_NOT_RESIZABLE,
62 			B_CURRENT_WORKSPACE)
63 {
64 	BScreen screen;
65 
66 	BRect screenframe = screen.Frame(), bounds = Bounds(), workrect(0,0,1,1);
67 	float width,height;
68 	float screenx, screeny;
69 
70 	screenx = ((screenframe.right + 1) / 2) - (bounds.right / 2) - 1;
71 	screeny = ((screenframe.bottom + 1) / 2) - (bounds.bottom / 2) - 1;
72 	MoveTo(screenx, screeny);
73 
74 	fView = new BView(bounds,"View",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
75 	fView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
76 	AddChild(fView);
77 
78 	fRestart = new BButton(workrect,"Restart_Networking",
79 							"Restart Networking",new BMessage(kRestart_Networking_M),
80 							B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
81 	fRestart->GetPreferredSize(&width,&height);
82 	fRestart->ResizeTo(width,height);
83 	fRestart->MoveTo(10,bounds.bottom - 10 - height);
84 
85 	// We fake the divider line by using a BBox. We have to call ConstrainClippingRegion
86 	// because otherwise we also see the corners drawn, which doesn't look nice
87 	BBox *vr = new BBox(BRect(width + 18, bounds.bottom - 11 - height, width + 19,
88 								bounds.bottom - 9),
89 						"vertical_rule", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
90 	fView->AddChild(vr);
91 
92 	BRegion clipreg(vr->Bounds().InsetByCopy(0,2));
93 	vr->ConstrainClippingRegion(&clipreg);
94 
95 	fRevert = new BButton(BRect(width + 25,bounds.bottom - 10 - height,width + 26,
96 								bounds.bottom - 10),
97 						"Revert","Revert", new BMessage(kRevert_M),
98 						B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
99 	fRevert->ResizeToPreferred();
100 	fRevert->SetEnabled(false);
101 
102 	fSave = new BButton(workrect,"Save","Save",new BMessage(kSave_M),
103 						B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
104 	fSave->GetPreferredSize(&width,&height);
105 	fSave->ResizeTo(width,height);
106 	fSave->MoveTo(bounds.right - 10 - width, bounds.bottom - 10 - height);
107 	fSave->MakeDefault(true);
108 	fSave->SetEnabled(false);
109 
110 	BBox *hr = new BBox(BRect(0,bounds.bottom - height - 20,bounds.right,
111 								bounds.bottom - height - 19),
112 						"horizontal_rule",B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
113 	fView->AddChild(hr);
114 
115 	workrect = Bounds();
116 	workrect.bottom = hr->Frame().top;
117 	workrect.top = 10;
118 
119 	fTabView = new BTabView(workrect,"tab_view",B_WIDTH_FROM_WIDEST, B_FOLLOW_ALL);
120 	fTabView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
121 	fView->AddChild(fTabView);
122 	bounds.bottom -= fTabView->TabHeight();
123 
124 	fView->AddChild(fRestart);
125 	fView->AddChild(fRevert);
126 	fView->AddChild(fSave);
127 
128 	bounds = fTabView->Bounds();
129 	bounds.bottom -= fTabView->TabHeight();
130 
131 	fIdentityView = new BView(bounds,"Identity",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
132 	fIdentityView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
133 
134 	fIdentity = new BTab();
135 	fTabView->AddTab(fIdentityView,fIdentity);
136 
137 	// We can just pick a view to call StringWidth because we're not using anything
138 	// except the unaltered be_plain_font. Note that for each BTextControl pair we
139 	// just use the longer word of the two in order to save us some speed and code size
140 	float labelwidth = fTabView->StringWidth("Domain name: ");
141 
142 	workrect.Set(10,20,11,21);
143 	fDomain = new BTextControl(workrect,"Domain_Name","Domain name:"," ",
144 							new BMessage(kSOMETHING_HAS_CHANGED_M));
145 
146 	// BTextControl::ResizeToPreferred() is a little strange for our purposes, so we
147 	// get the preferred size and ignore the width that we get.
148 	fDomain->GetPreferredSize(&width, &height);
149 	fDomain->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT);
150 	fDomain->SetDivider(labelwidth);
151 
152 	workrect.left = 10;
153 	workrect.right = 11;
154 	workrect.top = height + 30;
155 	workrect.bottom = workrect.top + height;
156 
157 	fHost = new BTextControl(workrect,"Host_Name","Host name:",NULL,
158 							new BMessage(kSOMETHING_HAS_CHANGED_M));
159 	fHost->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT);
160 	fHost->SetDivider(labelwidth);
161 
162 	labelwidth = fTabView->StringWidth("Secondary DNS: ");
163 
164 	workrect.OffsetTo((bounds.right / 2),20);
165 	workrect.right = bounds.right - 30;
166 	fPrimaryDNS = new BTextControl(workrect,"Primary_DNS","Primary DNS:",
167 								NULL,new BMessage(kSOMETHING_HAS_CHANGED_M),
168 								B_FOLLOW_TOP | B_FOLLOW_RIGHT);
169 	fPrimaryDNS->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT);
170 	fPrimaryDNS->SetDivider(labelwidth);
171 
172 	workrect.OffsetBy(0,height + 10);
173 	fSecondaryDNS = new BTextControl(workrect,"Secondary_DNS","Secondary DNS:",
174 								NULL,new BMessage(kSOMETHING_HAS_CHANGED_M),
175 								B_FOLLOW_TOP | B_FOLLOW_RIGHT);
176 	fSecondaryDNS->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT);
177 	fSecondaryDNS->SetDivider(labelwidth);
178 
179 	fNames = new BBox(BRect(10,10,bounds.right - 10, (height * 2) + 50),
180 					"Names",B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,B_WILL_DRAW |
181 					B_FRAME_EVENTS);
182 	fIdentityView->AddChild(fNames);
183 	fNames->SetLabel("Names");
184 
185 	fNames->AddChild(fDomain);
186 	fNames->AddChild(fHost);
187 	fNames->AddChild(fPrimaryDNS);
188 	fNames->AddChild(fSecondaryDNS);
189 
190 	// BTextControl resizing operations don't do anything under R5 unless they
191 	// have an owner. To make things worse, BTabView does some of its BView hierarchy
192 	// stuff in AttachedToWindow such that if you add a tab before it's attached to
193 	// a window, it won't be visible. :( As such, we make an extra call to
194 	// AttachedToWindow to be assured that everything works the way it is intended.
195 	fTabView->AttachedToWindow();
196 	fDomain->ResizeTo( (bounds.right / 2) - 25, height);
197 	fHost->ResizeTo( (bounds.right / 2) - 25, height);
198 
199 	workrect.left = 10;
200 	workrect.right = bounds.right - 10;
201 	workrect.top = fNames->Frame().bottom + 10;
202 	workrect.bottom = fIdentityView->Bounds().bottom - 15;
203 	fInterfaces = new BBox(workrect,"Network_Interfaces",B_FOLLOW_ALL,
204 						B_WILL_DRAW | B_FRAME_EVENTS);
205 	fInterfaces->SetLabel("Network Interfaces");
206 	fIdentityView->AddChild(fInterfaces);
207 
208 	workrect = fInterfaces->Bounds().InsetByCopy(5,5);
209 	fSettings = new BButton(BRect(0,0,1,1),"Settings","Settings...",
210 							new BMessage(kSettings_M),
211 							B_FOLLOW_TOP | B_FOLLOW_RIGHT);
212 	fSettings->ResizeToPreferred();
213 	fSettings->MoveTo(workrect.right - 5 - fSettings->Bounds().Width(), 15);
214 	fInterfaces->AddChild(fSettings);
215 
216 	workrect = fSettings->Frame();
217 	workrect.OffsetBy(0,workrect.Height()+5);
218 
219 	fClear = new BButton(workrect,"Clear","Clear",new BMessage(kClear_M),
220 						B_FOLLOW_TOP | B_FOLLOW_RIGHT);
221 	fInterfaces->AddChild(fClear);
222 
223 	workrect.OffsetBy(0,workrect.Height()+15);
224 	fCustom = new BButton(workrect,"Custom","Custom...",new BMessage(kCustom_M),
225 							B_FOLLOW_TOP | B_FOLLOW_RIGHT);
226 	fInterfaces->AddChild(fCustom);
227 
228 	if(workrect.bottom > fInterfaces->Bounds().bottom)
229 		ResizeBy(0,workrect.bottom - fInterfaces->Bounds().bottom + 10);
230 
231 	workrect.left = 10;
232 	workrect.top = 20;
233 	workrect.right = fCustom->Frame().left - 15 - B_V_SCROLL_BAR_WIDTH;
234 	workrect.bottom = fCustom->Frame().bottom - 5;
235 
236 	fInterfacesList = new NetListView(workrect,"Interfaces_List");
237 	BScrollView *interfaces_scroller = new BScrollView("Interfaces_Scroller",
238 														fInterfacesList, B_FOLLOW_ALL,
239 														0, 0, 1, B_FANCY_BORDER);
240 	fInterfaces->AddChild(interfaces_scroller);
241 
242 	fServicesView = new BView(bounds,"Services",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
243 	fServicesView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
244 	fServices = new BTab();
245 	fTabView->AddTab(fServicesView,fServices);
246 
247 	workrect.Set(10,10,11,11);
248 	fFTPServer = new BCheckBox(workrect,"FTP_Server","FTP Server",
249 								new BMessage(kSOMETHING_HAS_CHANGED_M));
250 	fFTPServer->GetPreferredSize(&width,&height);
251 	fFTPServer->ResizeTo(width,height);
252 	fServicesView->AddChild(fFTPServer);
253 
254 	fTelnetServer = new BCheckBox(workrect,"Telnet_Server","Telnet Server",
255 								new BMessage(kSOMETHING_HAS_CHANGED_M));
256 	fTelnetServer->ResizeToPreferred();
257 	fTelnetServer->MoveTo(10,height + 15);
258 	fServicesView->AddChild(fTelnetServer);
259 
260 	fLoginInfo = new BButton(workrect,"Login_Info","Login Info...",
261 								new BMessage(kLogin_Info_M));
262 	fLoginInfo->ResizeToPreferred();
263 	fLoginInfo->MoveTo(10,(height * 2) + 25);
264 	fServicesView->AddChild(fLoginInfo);
265 
266 	workrect = fLoginInfo->Frame();
267 	workrect.left -= 5;
268 	workrect.top = workrect.bottom + 10;
269 	workrect.bottom = workrect.top + 1;
270 	workrect.right += 70;
271 	BBox *hr2 = new BBox(workrect,"horizontal_rule2",B_FOLLOW_LEFT | B_FOLLOW_TOP);
272 	fServicesView->AddChild(hr2);
273 
274 
275 	fAppleTalk = new BCheckBox(workrect,"Apple_Talk","Apple Talk",
276 								new BMessage(kSOMETHING_HAS_CHANGED_M));
277 	fAppleTalk->ResizeToPreferred();
278 	fAppleTalk->MoveTo(10, workrect.bottom + 10);
279 	fServicesView->AddChild(fAppleTalk);
280 
281 	fIPForwarding = new BCheckBox(workrect,"IP_Forwarding","IP Forwarding",
282 								new BMessage(kSOMETHING_HAS_CHANGED_M));
283 	fIPForwarding->ResizeToPreferred();
284 	fIPForwarding->MoveTo(10, fAppleTalk->Frame().bottom + 5);
285 	fServicesView->AddChild(fIPForwarding);
286 
287 	workrect = bounds.InsetByCopy(10,10);
288 	workrect.bottom += 10;
289 	workrect.left = hr2->Frame().right + 10;
290 	fConfigurations = new BBox(workrect,"Configurations",B_FOLLOW_ALL,
291 								B_WILL_DRAW | B_FRAME_EVENTS);
292 	fConfigurations->SetLabel("Configurations");
293 	fServicesView->AddChild(fConfigurations);
294 
295 	workrect = fConfigurations->Bounds();
296 	fBackup = new BButton(BRect(0,0,1,1),"Backup","Backup", new BMessage(kBackup_M));
297 	fBackup->GetPreferredSize(&width,&height);
298 	fBackup->ResizeTo(width,height);
299 	fBackup->MoveTo(workrect.right - width - 10,15);
300 	fConfigurations->AddChild(fBackup);
301 
302 	fRestore = new BButton(BRect(0,0,width,height),"Restore","Restore",
303 							new BMessage(kRestore_M));
304 	fConfigurations->AddChild(fRestore);
305 	fRestore->MoveTo(workrect.right - width - 10, 20 + height);
306 	fRestore->SetEnabled(false);
307 
308 	fRemove = new BButton(BRect(0,0,width,height),"Delete","Delete",
309 							new BMessage(kDelete_M));
310 	fRemove->MoveTo(workrect.right - width - 10, 25 + (height * 2));
311 	fRemove->SetEnabled(false);
312 	fConfigurations->AddChild(fRemove);
313 
314 	workrect = fConfigurations->Bounds().InsetByCopy(15,15);
315 	workrect.top += 5;
316 	workrect.right = fBackup->Frame().left - 10 - B_V_SCROLL_BAR_WIDTH;
317 	fConfigurationsList = new NetListView(workrect,"Configurations_List");
318 	BScrollView *configurations_scroller = new BScrollView("Configurations_Scroller",
319 														fConfigurationsList,
320 														B_FOLLOW_ALL, 0, 0, 1,
321 														B_FANCY_BORDER);
322 	fConfigurations->AddChild(configurations_scroller);
323 
324 	LoadConfigEntries();
325 	LoadSettings();
326 
327 	fTabView->AttachedToWindow();
328 }
329 
330 void NetworkWindow::MessageReceived(BMessage *message)
331 {
332 	switch (message->what) {
333 		case kRestart_Networking_M: {
334 			RestartWindow *restartWindow = new RestartWindow();
335 			restartWindow->Show();
336 
337 			BMessenger messenger("application/x-vnd.Be-NETS");
338 			if (messenger.IsValid() == true)
339 				messenger.SendMessage(B_QUIT_REQUESTED);
340 
341 			const char **arg_v;
342 			int32 argc;
343 			thread_id thread;
344 			status_t return_value;
345 
346 			argc  = 1;
347 			arg_v = (const char **)malloc(sizeof(char *) * (argc + 1));
348 
349 			arg_v[0] = strdup("/boot/beos/system/servers/net_server");
350 			arg_v[1] = NULL;
351 
352 			thread = load_image(argc,arg_v,(const char **)environ);
353 
354 			while (--argc >= 0)
355 				free((void *)arg_v[argc]);
356 			free (arg_v);
357 
358 			return_value = resume_thread(thread);
359 
360 			restartWindow->Quit();
361 			break;
362 		}
363 		case kRevert_M: {
364 			LoadSettings();
365 			fRevert->SetEnabled(false);
366 			fSave->SetEnabled(false);
367 			break;
368 		}
369 		case kSave_M: {
370 			SaveBackup(NULL,fData);
371 			fRevert->SetEnabled(false);
372 			fSave->SetEnabled(false);
373 			break;
374 		}
375 		case kSettings_M: {
376 			BRect r(Frame());
377 			r.right = r.left + 325;
378 			r.bottom = r.top + 225;
379 
380 			NetListItem *selection = dynamic_cast <NetListItem *> (fInterfacesList->ItemAt(fInterfacesList->CurrentSelection()));
381 			if(!selection)
382 				break;
383 
384 			InterfaceWin *win = new InterfaceWin(r,selection->fData);
385 			r=win->Frame();
386 			win->MoveBy((Frame().Width()-r.Width())/2,
387 						(Frame().Height()-r.Height())/2);
388 
389 			win->fParentWindow = dynamic_cast <NetworkWindow *> (fView->Window());
390 
391 			if (selection->fData.fEnabled)
392 				win->fEnabled->SetValue(1);
393 
394 			if (selection->fData.fDHCP)
395 				win->fDHCP->SetValue(1);
396 			else
397 				win->fManual->SetValue(1);
398 
399 			win->fName->SetText(selection->fData.fPrettyName.String());
400 			win->fIPAddress->SetText(selection->fData.fIPAddress.String());
401 			win->fNetMask->SetText(selection->fData.fNetMask.String());
402 
403 			win->fChanged = false;
404 
405 			win->fIPAddress->SetTarget(win);
406 			win->fNetMask->SetTarget(win);
407 			win->fGateway->SetTarget(win);
408 
409 			win->Show();
410 			break;
411 		}
412 		case kClear_M: {
413 			break;
414 		}
415 		case kCustom_M: {
416 			break;
417 		}
418 		case kLogin_Info_M: {
419 			LoginInfo *login_info_pop = new LoginInfo();
420 			login_info_pop->fParentWindow = dynamic_cast <NetworkWindow *> (fView->Window());
421 			login_info_pop->fName->SetText(fusername.String());
422 			login_info_pop->fName->MakeFocus();
423 			login_info_pop->Show();
424 			break;
425 		}
426 		case kBackup_M: {
427 			BRect r(Frame());
428 			r.right = r.left + 260;
429 			r.bottom = r.top + 77;
430 			r.OffsetBy( (Frame().Width()-260)/2, (Frame().Height()-77)/2);
431 			BackupWin *backup_pop = new BackupWin(r);
432 			backup_pop->fParentWindow = dynamic_cast <NetworkWindow *> (fView->Window());
433 			backup_pop->Show();
434 			break;
435 		}
436 		case kRestore_M: {
437 			BStringItem *string_item = dynamic_cast <BStringItem *> (fConfigurationsList->ItemAt(fConfigurationsList->CurrentSelection()));
438 			LoadSettings(string_item->Text());
439 			PostMessage(kSOMETHING_HAS_CHANGED_M);
440 			break;
441 		}
442 		case kDelete_M: {
443 			DeleteConfigFile();
444 			LoadConfigEntries();
445 			fConfigurationsList->SelectionChanged();
446 			break;
447 		}
448 		case kSOMETHING_HAS_CHANGED_M: {
449 			fRevert->SetEnabled(true);
450 			fSave->SetEnabled(true);
451 			break;
452 		}
453 	}
454 }
455 
456 bool
457 NetworkWindow::QuitRequested(void)
458 {
459 	if (fSave->IsEnabled() == true) {
460 		BAlert *alert = new BAlert("Save Info Alert","Save changes before quitting?",
461 									"Don't Save","Cancel","Save");
462 		int32 result = alert->Go();
463 
464 		switch (result) {
465 			case 0: {
466 				// Don't Save
467 				break;
468 			}
469 			case 1:{
470 				// Cancel
471 				return false;
472 				break;
473 			}
474 			case 2:{
475 				// Save
476 				SaveBackup(NULL,fData);
477 				break;
478 			}
479 			default:
480 				break;
481 		}
482 	}
483 	be_app->PostMessage(B_QUIT_REQUESTED);
484 	return true;
485 }
486 
487 void NetworkWindow::DeleteConfigFile()
488 {
489 	BAlert *alert = new BAlert("Alert","Really delete networking configuration?",
490 								"Delete","Cancel");
491 	int32 result = alert->Go();
492 
493 	if (result == 0) {
494 		BStringItem *item = dynamic_cast <BStringItem *> (fConfigurationsList->ItemAt(fConfigurationsList->CurrentSelection()));
495 
496 		BString path;
497 		path = "/boot/home/config/settings/network.";
498 		path << item->Text();
499 
500 		BEntry entry(path.String());
501 		entry.Remove();
502 	}
503 }
504 
505 void
506 NetworkWindow::LoadConfigEntries()
507 {
508 	fConfigurationsList->MakeEmpty();
509 
510 	BDirectory settings("/boot/home/config/settings/");
511 	BEntry entry;
512 
513 	if (settings.InitCheck() == B_OK) {
514 		while (settings.GetNextEntry(&entry) == B_OK) {
515 			// All the config files start with "network." so we only compare the
516 			// first 8 characters
517 			char buffer[9];
518 			entry.GetName(buffer);
519 			buffer[8]='\0';
520 
521 			if (strcmp(buffer,"network.") == 0) {
522 				BString string;
523 				char name[B_FILE_NAME_LENGTH];
524 				entry.GetName(name);
525 				string << name;
526 				string = string.Remove(0,8);
527 
528 				BStringItem *item = new BStringItem(string.String());
529 				fConfigurationsList->AddItem(item);
530 			}
531 		}
532 	}
533 }
534 
535 void
536 NetworkWindow::LoadSettings(const char *filename)
537 {
538 	if(LoadBackup(filename,fData)!=B_OK)
539 		return;
540 
541 	Lock();
542 	for(int32 i=0; i<fData.fInterfaceList.CountItems(); i++) {
543 		InterfaceData *idata = (InterfaceData*)fData.fInterfaceList.ItemAt(i);
544 		fInterfacesList->AddItem(new NetListItem(*idata));
545 	}
546 	fInterfacesList->Select(0L);
547 
548 	fDomain->SetText(fData.fDomainName.String());
549 	fHost->SetText(fData.fHostname.String());
550 	fPrimaryDNS->SetText(fData.fPrimaryDNS.String());
551 	fSecondaryDNS->SetText(fData.fSecondaryDNS.String());
552 
553 	if(fData.fFTPServer)
554 		fFTPServer->SetValue(B_CONTROL_ON);
555 	if(fData.fIPForwarding)
556 		fIPForwarding->SetValue(B_CONTROL_ON);
557 	if(fData.fTelnetServer)
558 		fTelnetServer->SetValue(B_CONTROL_ON);
559 
560 	Unlock();
561 }
562