Remove the now obsolete NetworkTime application.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41931 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ryan Leavengood 2011-06-05 02:38:05 +00:00
parent 323ba9b7fb
commit f4e32875a9
11 changed files with 0 additions and 1627 deletions

View File

@ -1,248 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#include "EditServerListWindow.h"
#include "NetworkTime.h"
#include <Application.h>
#include <TextView.h>
#include <ScrollView.h>
#include <Button.h>
#include <Screen.h>
#include <string.h>
#include <stdlib.h>
static const uint32 kMsgServersEdited = 'sedt';
static const char *kServerDelimiters = ", \n\t";
struct tokens {
char *buffer;
char *next;
const char *delimiters;
};
static void
put_tokens(tokens &tokens)
{
free(tokens.buffer);
tokens.buffer = NULL;
}
static status_t
prepare_tokens(tokens &tokens, const char *text, const char *delimiters)
{
tokens.buffer = strdup(text);
if (tokens.buffer == NULL)
return B_NO_MEMORY;
tokens.delimiters = delimiters;
tokens.next = tokens.buffer;
return B_OK;
}
static const char *
next_token(tokens &tokens)
{
char *token = strtok(tokens.next, tokens.delimiters);
if (tokens.next != NULL)
tokens.next = NULL;
if (token == NULL)
put_tokens(tokens);
return token;
}
// #pragma mark -
EditServerListWindow::EditServerListWindow(BRect position, const BMessage &settings)
: BWindow(position, "Edit Server List", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS),
fSettings(settings)
{
BRect rect = Bounds();
BView *view = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(view);
rect = view->Bounds().InsetByCopy(5, 5);
BButton *button = new BButton(rect, "defaults", "Reset To Defaults",
new BMessage(kMsgResetServerList), B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
float width, height;
button->GetPreferredSize(&width, &height);
button->ResizeTo(rect.Width(), height);
button->MoveBy(0, rect.Height() - height);
button->SetTarget(be_app);
view->AddChild(button);
rect.bottom -= 5 + height;
rect.InsetBy(2, 2);
rect.right -= B_V_SCROLL_BAR_WIDTH;
fServerView = new BTextView(rect, "list",
rect.OffsetToCopy(B_ORIGIN).InsetByCopy(3, 3), B_FOLLOW_ALL);
fServerView->SetStylable(true);
BScrollView *scrollView = new BScrollView("scroller", fServerView, B_FOLLOW_ALL, B_WILL_DRAW, false, true);
view->AddChild(scrollView);
UpdateServerView(settings);
SetSizeLimits(200, 16384, 200, 16384);
if (Frame().LeftTop() == B_ORIGIN) {
// center on screen
BScreen screen;
MoveTo((screen.Frame().Width() - Bounds().Width()) / 2,
(screen.Frame().Height() - Bounds().Height()) / 2);
}
}
EditServerListWindow::~EditServerListWindow()
{
}
void
EditServerListWindow::UpdateDefaultServerView(const BMessage &message)
{
int32 defaultServer;
if (message.FindInt32("default server", &defaultServer) != B_OK)
return;
BFont font(be_plain_font);
fServerView->SetFontAndColor(0, fServerView->TextLength(),
&font, B_FONT_FAMILY_AND_STYLE);
struct tokens tokens;
const char *server;
if (fSettings.FindString("server", defaultServer, &server) == B_OK
&& prepare_tokens(tokens, fServerView->Text(), kServerDelimiters) == B_OK) {
const char *token;
while ((token = next_token(tokens)) != NULL) {
if (strcasecmp(token, server))
continue;
int32 start = int32(token - tokens.buffer);
BFont font;
font.SetFace(B_BOLD_FACE);
fServerView->SetFontAndColor(start, start + strlen(server),
&font, B_FONT_FAMILY_AND_STYLE);
break;
}
put_tokens(tokens);
}
}
void
EditServerListWindow::UpdateServerView(const BMessage &message)
{
if (message.HasString("server") || message.HasBool("reset servers"))
fServerView->SetText("");
int32 defaultServer;
if (message.FindInt32("default server", &defaultServer) != B_OK)
defaultServer = 0;
const char *server;
int32 index = 0;
for (; message.FindString("server", index, &server) == B_OK; index++) {
int32 start, end;
fServerView->GetSelection(&start, &end);
fServerView->Insert(server);
fServerView->Insert("\n");
}
UpdateDefaultServerView(message);
}
void
EditServerListWindow::UpdateServerList()
{
// get old default server
int32 defaultServer;
if (fSettings.FindInt32("default server", &defaultServer) != B_OK)
defaultServer = 0;
const char *server;
if (fSettings.FindString("server", defaultServer, &server) != B_OK)
server = NULL;
// take over server list
struct tokens tokens;
if (prepare_tokens(tokens, fServerView->Text(), kServerDelimiters) == B_OK) {
BMessage servers(kMsgUpdateSettings);
int32 count = 0, newDefaultServer = -1;
const char *token;
while ((token = next_token(tokens)) != NULL) {
servers.AddString("server", token);
if (!strcasecmp(token, server))
newDefaultServer = count;
count++;
}
if (count != 0) {
if (newDefaultServer == -1)
newDefaultServer = 0;
servers.AddInt32("default server", newDefaultServer);
be_app->PostMessage(&servers);
} else
be_app->PostMessage(kMsgResetServerList);
}
}
bool
EditServerListWindow::QuitRequested()
{
be_app->PostMessage(kMsgEditServerListWindowClosed);
BMessage update(kMsgUpdateSettings);
update.AddRect("edit servers frame", Frame());
be_app->PostMessage(&update);
UpdateServerList();
return true;
}
void
EditServerListWindow::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgServersEdited:
UpdateServerList();
break;
case kMsgSettingsUpdated:
if (message->HasString("server"))
UpdateServerView(*message);
else
UpdateDefaultServerView(*message);
break;
}
}

View File

@ -1,32 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef EDIT_SERVER_LIST_WINDOW_H
#define EDIT_SERVER_LIST_WINDOW_H
#include <Window.h>
class BTextView;
class EditServerListWindow : public BWindow {
public:
EditServerListWindow(BRect position, const BMessage &settings);
virtual ~EditServerListWindow();
virtual bool QuitRequested();
virtual void MessageReceived(BMessage *message);
private:
void UpdateDefaultServerView(const BMessage &message);
void UpdateServerView(const BMessage &message);
void UpdateServerList();
const BMessage &fSettings;
BTextView *fServerView;
};
#endif /* EDIT_SERVER_LIST_WINDOW_H */

View File

@ -1,21 +0,0 @@
SubDir HAIKU_TOP src apps networktime ;
Application NetworkTime :
EditServerListWindow.cpp
NetworkTime.cpp
ntp.cpp
UpdateWindow.cpp
$(DRIVER_SETTINGS)
: be $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS) $(HAIKU_NETWORK_LIBS)
: NetworkTime.rdef
;
DoCatalogs NetworkTime :
x-vnd.Haiku-NetworkTime
:
EditServerListWindow.cpp
NetworkTime.cpp
ntp.cpp
UpdateWindow.cpp
;

View File

@ -1,54 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef MONITOR_H
#define MONITOR_H
#include <SupportDefs.h>
#include <stdarg.h>
class Monitor {
public:
virtual ~Monitor() {}
virtual void Update(const char *text, ...);
virtual void Update(float progress, const char *text = NULL, ...);
virtual void Done(status_t status);
private:
virtual void update(float progress, const char *text, va_list args) = 0;
};
inline void
Monitor::Update(const char *text, ...)
{
va_list args;
va_start(args, text);
update(-1.f, text, args);
va_end(args);
}
inline void
Monitor::Update(float progress, const char *text, ...)
{
va_list args;
va_start(args, text);
update(progress, text, args);
va_end(args);
}
inline void
Monitor::Done(status_t /*status*/)
{
}
#endif /* MONITOR_H */

View File

@ -1,670 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#include "NetworkTime.h"
#include "UpdateWindow.h"
#include "EditServerListWindow.h"
#include "ntp.h"
#include <Application.h>
#include <Path.h>
#include <File.h>
#include <FindDirectory.h>
#include <Alert.h>
#include <TextView.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <ctype.h>
status_t update_time(const BMessage &settings, Monitor *monitor);
status_t update_time(const BMessage &server, Monitor *monitor, thread_id *_asyncThread);
static const uint32 kMsgNetworkTimeSettings = 'NtpS';
extern const char *__progname;
static const char *sProgramName = __progname;
class Settings {
public:
Settings();
~Settings();
void CopyMessage(BMessage &message) const;
const BMessage &Message() const;
void UpdateFrom(BMessage &message);
void ResetServersToDefaults();
void ResetToDefaults();
status_t Load();
status_t Save();
private:
status_t GetPath(BPath &path);
BMessage fMessage;
bool fWasUpdated;
};
class PrintMonitor : public Monitor {
private:
virtual void
update(float progress, const char *text, va_list args)
{
if (progress != -1.f)
printf("%3g%% ", progress);
else
printf(" ");
if (text != NULL)
vprintf(text, args);
putchar('\n');
}
};
class MessengerMonitor : public Monitor {
public:
MessengerMonitor(BMessenger messenger)
:
fMessenger(messenger)
{
}
virtual void
Done(status_t status)
{
BMessage message(kMsgStatusUpdate);
message.AddInt32("status", status);
fMessenger.SendMessage(&message);
fMessenger.SendMessage(kMsgStopTimeUpdate);
// This deadlocks Dano
//be_app_messenger.SendMessage(kMsgStopTimeUpdate);
}
private:
virtual void
update(float progress, const char *text, va_list args)
{
BMessage message(kMsgStatusUpdate);
if (progress != -1.f)
message.AddFloat("progress", progress);
if (text != NULL) {
char buffer[2048];
vsprintf(buffer, text, args);
message.AddString("message", buffer);
}
fMessenger.SendMessage(&message);
}
BMessenger fMessenger;
};
class NetworkTimeApplication : public BApplication {
public:
NetworkTimeApplication(Settings &settings);
virtual ~NetworkTimeApplication();
virtual void ReadyToRun();
virtual void MessageReceived(BMessage *message);
virtual void AboutRequested();
void BroadcastSettingsChanges(BMessage &message);
private:
Settings &fSettings;
thread_id fUpdateThread;
BWindow *fServerListWindow;
};
status_t
adopt_int32(const BMessage &from, BMessage &to, const char *name, bool &updated)
{
int32 value;
if (from.FindInt32(name, &value) != B_OK)
return B_ENTRY_NOT_FOUND;
int32 original;
if (to.FindInt32(name, &original) == B_OK) {
if (value == original)
return B_OK;
updated = true;
return to.ReplaceInt32(name, value);
}
updated = true;
return to.AddInt32(name, value);
}
status_t
adopt_bool(const BMessage &from, BMessage &to, const char *name, bool &updated)
{
bool value;
if (from.FindBool(name, &value) != B_OK)
return B_ENTRY_NOT_FOUND;
bool original;
if (to.FindBool(name, &original) == B_OK) {
if (value == original)
return B_OK;
updated = true;
return to.ReplaceBool(name, value);
}
updated = true;
return to.AddBool(name, value);
}
status_t
adopt_rect(const BMessage &from, BMessage &to, const char *name, bool &updated)
{
BRect rect;
if (from.FindRect(name, &rect) != B_OK)
return B_ENTRY_NOT_FOUND;
BRect original;
if (to.FindRect(name, &original) == B_OK) {
if (rect == original)
return B_OK;
updated = true;
return to.ReplaceRect(name, rect);
}
updated = true;
return to.AddRect(name, rect);
}
// #pragma mark -
class UpdateLooper : public BLooper {
public:
UpdateLooper(const BMessage &settings, Monitor *monitor);
void MessageReceived(BMessage *message);
private:
const BMessage &fSettings;
Monitor *fMonitor;
};
UpdateLooper::UpdateLooper(const BMessage &settings, Monitor *monitor)
: BLooper("update looper"),
fSettings(settings),
fMonitor(monitor)
{
PostMessage(kMsgUpdateTime);
}
void
UpdateLooper::MessageReceived(BMessage *message)
{
if (message->what != kMsgUpdateTime)
return;
update_time(fSettings, fMonitor);
}
// #pragma mark -
NetworkTimeApplication::NetworkTimeApplication(Settings &settings)
: BApplication("application/x-vnd.Haiku-NetworkTime"),
fSettings(settings),
fUpdateThread(-1),
fServerListWindow(NULL)
{
}
NetworkTimeApplication::~NetworkTimeApplication()
{
}
void
NetworkTimeApplication::ReadyToRun()
{
BRect rect;
if (fSettings.Message().FindRect("status frame", &rect) != B_OK)
rect.Set(0, 0, 300, 150);
UpdateWindow *window = new UpdateWindow(rect, fSettings.Message());
window->Show();
}
void
NetworkTimeApplication::BroadcastSettingsChanges(BMessage &message)
{
BWindow *window;
int32 index = 0;
while ((window = WindowAt(index++)) != NULL)
window->PostMessage(&message);
}
void
NetworkTimeApplication::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgUpdateSettings:
{
fSettings.UpdateFrom(*message);
message->what = kMsgSettingsUpdated;
BroadcastSettingsChanges(*message);
break;
}
case kMsgResetServerList:
{
fSettings.ResetServersToDefaults();
BMessage updated = fSettings.Message();
updated.what = kMsgSettingsUpdated;
BroadcastSettingsChanges(updated);
break;
}
case kMsgStopTimeUpdate:
if (fUpdateThread >= B_OK)
kill_thread(fUpdateThread);
fUpdateThread = -1;
break;
case kMsgUpdateTime:
{
if (fUpdateThread >= B_OK)
break;
MessengerMonitor *monitor = NULL;
BMessenger messenger;
if (message->FindMessenger("monitor", &messenger) == B_OK)
monitor = new MessengerMonitor(messenger);
update_time(fSettings.Message(), monitor, &fUpdateThread);
break;
}
case kMsgEditServerList:
if (fServerListWindow == NULL) {
BRect rect;
if (fSettings.Message().FindRect("edit servers frame", &rect) != B_OK)
rect.Set(0, 0, 250, 250);
fServerListWindow = new EditServerListWindow(rect, fSettings.Message());
}
fServerListWindow->Show();
break;
case kMsgEditServerListWindowClosed:
fServerListWindow = NULL;
break;
}
}
void
NetworkTimeApplication::AboutRequested()
{
BAlert *alert = new BAlert("about", "Network Time\n"
"\twritten by Axel Dörfler\n\n"
"\tCopyright " B_UTF8_COPYRIGHT "2004, pinc Software.\n"
"\tAll Rights Reserved.\n", "Ok");
BTextView *view = alert->TextView();
BFont font;
view->SetStylable(true);
view->GetFont(&font);
font.SetSize(18);
font.SetFace(B_BOLD_FACE);
view->SetFontAndColor(0, 12, &font);
alert->Go();
}
// #pragma mark -
Settings::Settings()
:
fMessage(kMsgNetworkTimeSettings),
fWasUpdated(false)
{
ResetToDefaults();
Load();
}
Settings::~Settings()
{
if (fWasUpdated)
Save();
}
void
Settings::CopyMessage(BMessage &message) const
{
message = fMessage;
}
const BMessage &
Settings::Message() const
{
return fMessage;
}
void
Settings::UpdateFrom(BMessage &message)
{
if (message.HasBool("reset servers")) {
fMessage.RemoveName("server");
fWasUpdated = true;
}
if (message.HasString("server")) {
// remove old servers
fMessage.RemoveName("server");
const char *server;
int32 index = 0;
while (message.FindString("server", index++, &server) == B_OK) {
fMessage.AddString("server", server);
}
fWasUpdated = true;
}
adopt_int32(message, fMessage, "default server", fWasUpdated);
adopt_bool(message, fMessage, "auto mode", fWasUpdated);
adopt_bool(message, fMessage, "knows auto mode", fWasUpdated);
adopt_bool(message, fMessage, "try all servers", fWasUpdated);
adopt_bool(message, fMessage, "choose default server", fWasUpdated);
adopt_rect(message, fMessage, "status frame", fWasUpdated);
adopt_rect(message, fMessage, "edit servers frame", fWasUpdated);
}
void
Settings::ResetServersToDefaults()
{
fMessage.RemoveName("server");
fMessage.AddString("server", "pool.ntp.org");
fMessage.AddString("server", "de.pool.ntp.org");
fMessage.AddString("server", "time.nist.gov");
if (fMessage.ReplaceInt32("default server", 0) != B_OK)
fMessage.AddInt32("default server", 0);
}
void
Settings::ResetToDefaults()
{
fMessage.MakeEmpty();
ResetServersToDefaults();
fMessage.AddBool("knows auto mode", false);
fMessage.AddBool("auto mode", false);
fMessage.AddBool("try all servers", true);
fMessage.AddBool("choose default server", true);
fMessage.AddRect("status frame", BRect(0, 0, 300, 150));
fMessage.AddRect("edit servers frame", BRect(0, 0, 250, 250));
}
status_t
Settings::Load()
{
status_t status;
BPath path;
if ((status = GetPath(path)) != B_OK)
return status;
BFile file(path.Path(), B_READ_ONLY);
if ((status = file.InitCheck()) != B_OK)
return status;
BMessage load;
if ((status = load.Unflatten(&file)) != B_OK)
return status;
if (load.what != kMsgNetworkTimeSettings)
return B_BAD_TYPE;
fMessage = load;
return B_OK;
}
status_t
Settings::Save()
{
status_t status;
BPath path;
if ((status = GetPath(path)) != B_OK)
return status;
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if ((status = file.InitCheck()) != B_OK)
return status;
file.SetSize(0);
return fMessage.Flatten(&file);
}
status_t
Settings::GetPath(BPath &path)
{
status_t status;
if ((status = find_directory(B_USER_SETTINGS_DIRECTORY, &path)) != B_OK)
return status;
path.Append("pinc.networktime settings");
return B_OK;
}
// #pragma mark -
status_t
update_time(const BMessage &settings, Monitor *monitor)
{
int32 defaultServer;
if (settings.FindInt32("default server", &defaultServer) != B_OK)
defaultServer = 0;
status_t status = B_ENTRY_NOT_FOUND;
const char *server;
if (settings.FindString("server", defaultServer, &server) == B_OK)
status = ntp_update_time(server, monitor);
// try other servers if we should
if (status != B_OK && settings.FindBool("try all servers")) {
for (int32 index = 0; ; index++) {
if (index == defaultServer)
index++;
if (settings.FindString("server", index, &server) != B_OK)
break;
status = ntp_update_time(server, monitor);
if (status == B_OK) {
if (be_app != NULL && settings.FindBool("choose default server")) {
BMessage update(kMsgUpdateSettings);
update.AddInt32("default server", index);
be_app->PostMessage(&update);
}
break;
}
}
}
if (monitor != NULL)
monitor->Done(status);
delete monitor;
return status;
}
status_t
update_time(const BMessage &settings, Monitor *monitor, thread_id *_asyncThread)
{
if (_asyncThread != NULL) {
BLooper *looper = new UpdateLooper(settings, monitor);
*_asyncThread = looper->Run();
return B_OK;
}
return update_time(settings, monitor);
}
bool
parse_time(char *arg, int32 *_seconds)
{
char *unit;
if (isdigit(arg[0]))
*_seconds = strtoul(arg, &unit, 10);
else
return false;
if (unit[0] == '\0' || !strcmp(unit, "m")) {
*_seconds *= 60;
return true;
}
if (!strcmp(unit, "h")) {
*_seconds *= 60 * 60;
return true;
}
if (!strcmp(unit, "s"))
return true;
return false;
}
void
usage(void)
{
fprintf(stderr, "usage: %s [-s|--server <host>] [-p|--periodic <interval>] [-n|--silent] [-g|--nogui]\n"
" -s, --server\t\tContact \"host\" instead of saved list\n"
" -p, --periodic\tPeriodically query for the time, interval specified in minutes\n"
" -n, --silent\t\tDo not print progress\n"
" -g, --nogui\t\tDo not show graphical user interface (implied by other options)\n",
sProgramName);
exit(0);
}
int
main(int argc, char **argv)
{
Settings settings;
if (argc > 1) {
// when there are any command line options, we will switch to command line mode
BMessage message;
settings.CopyMessage(message);
// we may want to override the global settings with command line options
static struct option const longopts[] = {
{"server", required_argument, NULL, 's'},
{"periodic", required_argument, NULL, 'p'},
{"silent", no_argument, NULL, 'n'},
{"nogui", no_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
int32 interval = 0;
bool silent = false;
char option;
while ((option = getopt_long(argc, argv, "s:p:h", longopts, NULL)) != -1) {
switch (option) {
case 's':
message.RemoveName("server");
message.AddString("server", optarg);
message.ReplaceInt32("default server", 0);
break;
case 'n':
silent = true;
break;
case 'g':
// default in command line mode
break;
case 'p':
if (parse_time(optarg, &interval))
break;
// supposed to fall through
case 'h':
default:
usage();
}
}
while (true) {
Monitor *monitor = NULL;
if (!silent)
monitor = new PrintMonitor();
update_time(message, monitor, NULL);
if (interval == 0)
break;
snooze(interval * 1000000LL);
}
} else {
NetworkTimeApplication app(settings);
app.Run();
}
return 0;
}

View File

@ -1,22 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef NETWORK_TIME_H
#define NETWORK_TIME_H
#include <SupportDefs.h>
static const uint32 kMsgUpdateTime = 'uptm';
static const uint32 kMsgStopTimeUpdate = 'stpt';
static const uint32 kMsgStatusUpdate = 'stup';
static const uint32 kMsgUpdateSettings = 'upse';
static const uint32 kMsgSettingsUpdated = 'seUp';
static const uint32 kMsgResetServerList = 'rtsl';
static const uint32 kMsgEditServerList = 'edsl';
static const uint32 kMsgEditServerListWindowClosed = 'eswc';
#endif /* NETWORK_TIME_H */

View File

@ -1,21 +0,0 @@
resource app_signature "application/x-vnd.Haiku-NetworkTime";
resource app_name_catalog_entry "x-vnd.Haiku-NetworkTime:System name:NetworkTime";
resource app_version {
major = 1,
middle = 0,
minor = 0,
/* 0 = development 1 = alpha 2 = beta
3 = gamma 4 = golden master 5 = final */
variety = 2,
internal = 0,
short_info = "NetworkTime",
long_info = "NetworkTime ©2004 pinc Software"
};
resource app_flags B_SINGLE_LAUNCH;

View File

@ -1,303 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#include "UpdateWindow.h"
#include "NetworkTime.h"
#include <Application.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <StatusBar.h>
#include <Button.h>
#include <Alert.h>
#include <Screen.h>
#include <stdio.h>
static const uint32 kMsgAutoMode = 'aumd';
static const uint32 kMsgTryAllServers = 'tasr';
static const uint32 kMsgChooseDefaultServer = 'cdsr';
static const uint32 kMsgDefaultServer = 'dsrv';
UpdateWindow::UpdateWindow(BRect position, const BMessage &settings)
: BWindow(position, "Network Time", B_TITLED_WINDOW,
B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS),
fSettings(settings)
{
bool autoMode;
if (settings.FindBool("auto mode", &autoMode) != B_OK)
autoMode = false;
// pressing the control key will avoid auto quit
fAutoQuit = modifiers() & B_CONTROL_KEY ? false : autoMode;
bool showMenu = !fAutoQuit;
BMenuBar *bar = new BMenuBar(Bounds(), "");
BMenu *menu;
BMenuItem *item;
menu = new BMenu("Project");
menu->AddItem(item = new BMenuItem("About" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED), '?'));
item->SetTarget(be_app);
menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'));
bar->AddItem(menu);
fServerMenu = new BMenu("Servers");
fServerMenu->SetRadioMode(true);
BuildServerMenu();
menu = new BMenu("Options");
menu->AddItem(fTryAllServersItem = new BMenuItem("Try All Servers",
new BMessage(kMsgTryAllServers)));
menu->AddItem(fChooseDefaultServerItem = new BMenuItem("Choose Default Server Automatically",
new BMessage(kMsgChooseDefaultServer)));
menu->AddItem(fAutoModeItem = new BMenuItem("Auto Mode", new BMessage(kMsgAutoMode)));
menu->AddSeparatorItem();
menu->AddItem(fServerMenu);
menu->AddItem(new BMenuItem("Edit Server List" B_UTF8_ELLIPSIS, new BMessage(kMsgEditServerList)));
bar->AddItem(menu);
if (showMenu)
AddChild(bar);
BRect rect = Bounds();
if (showMenu)
rect.top = bar->Bounds().Height();
BView *view = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(view);
rect = view->Bounds().InsetByCopy(5, 5);
fStatusBar = new BStatusBar(rect, "status", NULL, NULL);
float width, height;
fStatusBar->GetPreferredSize(&width, &height);
fStatusBar->ResizeTo(rect.Width(), height);
fStatusBar->SetResizingMode(B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT);
view->AddChild(fStatusBar);
BMessage *buttonMessage = new BMessage(fAutoQuit ? kMsgStopTimeUpdate : kMsgUpdateTime);
buttonMessage->AddMessenger("monitor", this);
if (showMenu) {
rect.top += height + 4;
fButton = new BButton(rect, NULL, "Update", buttonMessage,
B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT);
fButton->ResizeToPreferred();
if (autoMode)
fButton->SetLabel("Stop");
fButton->MoveBy((rect.Width() - fButton->Bounds().Width()) / 2, 0);
view->AddChild(fButton);
ResizeTo(Bounds().Width(),
bar->Bounds().Height() + fButton->Frame().bottom + 5);
} else {
fButton = NULL;
ResizeTo(Bounds().Width(), height + 9);
}
SetSizeLimits(200, 16384, Bounds().Height(), Bounds().Height());
if (Frame().LeftTop() == B_ORIGIN) {
// center on screen
BScreen screen;
MoveTo((screen.Frame().Width() - Bounds().Width()) / 2,
(screen.Frame().Height() - Bounds().Height()) / 2);
}
// Update views
BMessage update = fSettings;
update.what = kMsgSettingsUpdated;
PostMessage(&update);
// Automatically start update in "auto mode"
if (fAutoQuit) {
BMessage update(kMsgUpdateTime);
update.AddMessenger("monitor", this);
be_app->PostMessage(&update);
}
}
UpdateWindow::~UpdateWindow()
{
}
bool
UpdateWindow::QuitRequested()
{
BMessage update(kMsgUpdateSettings);
update.AddRect("status frame", Frame());
be_app_messenger.SendMessage(&update);
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
void
UpdateWindow::BuildServerMenu()
{
// remove old entries
BMenuItem *item;
while ((item = fServerMenu->RemoveItem(0L)) != NULL)
delete item;
int32 defaultServer;
if (fSettings.FindInt32("default server", &defaultServer) != B_OK)
defaultServer = 0;
const char *server;
for (int32 i = 0; fSettings.FindString("server", i, &server) == B_OK; i++) {
fServerMenu->AddItem(item = new BMenuItem(server, new BMessage(kMsgDefaultServer)));
if (i == defaultServer)
item->SetMarked(true);
}
}
void
UpdateWindow::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgSettingsUpdated:
{
if (message->HasString("server"))
BuildServerMenu();
else {
int32 index;
if (message->FindInt32("default server", &index) == B_OK) {
BMenuItem *item = fServerMenu->ItemAt(index);
if (item != NULL)
item->SetMarked(true);
}
}
bool boolean;
if (message->FindBool("auto mode", &boolean) == B_OK)
fAutoModeItem->SetMarked(boolean);
if (message->FindBool("try all servers", &boolean) == B_OK)
fTryAllServersItem->SetMarked(boolean);
if (message->FindBool("choose default server", &boolean) == B_OK)
fChooseDefaultServerItem->SetMarked(boolean);
break;
}
case kMsgAutoMode:
{
fAutoModeItem->SetMarked(!fAutoModeItem->IsMarked());
if (!fSettings.FindBool("knows auto mode")) {
// we should alert the user about the changed behaviour
(new BAlert("notice",
"Attention!\n\n"
"Activating this mode let's the user interface only show the "
"bare minimum, and you will not be able to reach the menu "
"anymore.\n"
"Also, the application will quit immediately after the time has "
"been updated successfully; it will only stay if updating fails, "
"so that you can catch the reason for the error.\n\n"
"If you want to get the full interface again, you have to "
"press the control key while starting this application.\n\n"
"This warning will appear only the first time you select this mode.",
"Ok"))->Go();
}
BMessage update(kMsgUpdateSettings);
update.AddBool("auto mode", fAutoModeItem->IsMarked());
update.AddBool("knows auto mode", true);
be_app->PostMessage(&update);
break;
}
case kMsgTryAllServers:
{
fTryAllServersItem->SetMarked(!fTryAllServersItem->IsMarked());
BMessage update(kMsgUpdateSettings);
update.AddBool("try all servers", fTryAllServersItem->IsMarked());
be_app->PostMessage(&update);
break;
}
case kMsgChooseDefaultServer:
{
fChooseDefaultServerItem->SetMarked(!fChooseDefaultServerItem->IsMarked());
BMessage update(kMsgUpdateSettings);
update.AddBool("choose default server", fChooseDefaultServerItem->IsMarked());
be_app->PostMessage(&update);
break;
}
case kMsgDefaultServer:
{
int32 index;
if (message->FindInt32("index", &index) != B_OK)
break;
BMessage update(kMsgUpdateSettings);
update.AddInt32("default server", index);
be_app->PostMessage(&update);
break;
}
case kMsgEditServerList:
be_app->PostMessage(kMsgEditServerList);
break;
case kMsgStopTimeUpdate:
if (fButton != NULL) {
fButton->SetLabel("Update");
fButton->Message()->what = kMsgUpdateTime;
}
BButton *source;
if (message->FindPointer("source", (void **)&source) == B_OK
&& fButton == source)
fStatusBar->SetText("Stopped.");
be_app->PostMessage(message);
break;
case kMsgUpdateTime:
if (fButton != NULL) {
fButton->SetLabel("Stop");
fButton->Message()->what = kMsgStopTimeUpdate;
}
be_app->PostMessage(message);
break;
case kMsgStatusUpdate:
float progress;
if (message->FindFloat("progress", &progress) == B_OK)
fStatusBar->Update(progress - fStatusBar->CurrentValue());
const char *text;
if (message->FindString("message", &text) == B_OK)
fStatusBar->SetText(text);
status_t status;
if (message->FindInt32("status", (int32 *)&status) == B_OK) {
if (status == B_OK && fAutoQuit)
QuitRequested();
else if (fButton != NULL) {
fButton->SetLabel("Update");
fButton->Message()->what = kMsgUpdateTime;
}
}
break;
default:
BWindow::MessageReceived(message);
}
}

View File

@ -1,36 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef UPDATE_WINDOW_H
#define UPDATE_WINDOW_H
#include <Window.h>
class BStatusBar;
class BButton;
class BMenuItem;
class BMenu;
class UpdateWindow : public BWindow {
public:
UpdateWindow(BRect position, const BMessage &settings);
virtual ~UpdateWindow();
virtual bool QuitRequested();
virtual void MessageReceived(BMessage *message);
void BuildServerMenu();
private:
const BMessage &fSettings;
BStatusBar *fStatusBar;
BButton *fButton;
BMenuItem *fAutoModeItem, *fTryAllServersItem, *fChooseDefaultServerItem;
BMenu *fServerMenu;
bool fAutoQuit;
};
#endif /* UPDATE_WINDOW_H */

View File

@ -1,205 +0,0 @@
/*
* Copyright 2004-2009, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#include "ntp.h"
#include <OS.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
/* This structure and its data fields are described in RFC 1305
* "Network Time Protocol (Version 3)" in appendix A.
*/
struct fixed32 {
int16 integer;
uint16 fraction;
void
SetTo(int16 integer, uint16 fraction = 0)
{
this->integer = htons(integer);
this->fraction = htons(fraction);
}
int16 Integer() { return htons(integer); }
uint16 Fraction() { return htons(fraction); }
};
struct ufixed64 {
uint32 integer;
uint32 fraction;
void
SetTo(uint32 integer, uint32 fraction = 0)
{
this->integer = htonl(integer);
this->fraction = htonl(fraction);
}
uint32 Integer() { return htonl(integer); }
uint32 Fraction() { return htonl(fraction); }
};
struct ntp_data {
uint8 mode : 3;
uint8 version : 3;
uint8 leap_indicator : 2;
uint8 stratum;
int8 poll;
int8 precision; /* in seconds of the nearest power of two */
fixed32 root_delay;
fixed32 root_dispersion;
uint32 root_identifier;
ufixed64 reference_timestamp;
ufixed64 originate_timestamp;
ufixed64 receive_timestamp;
ufixed64 transmit_timestamp;
/* optional authenticator follows (96 bits) */
};
#define NTP_PORT 123
#define NTP_VERSION_3 3
enum ntp_leap_warnings {
LEAP_NO_WARNING = 0,
LEAP_LAST_MINUTE_61_SECONDS,
LEAP_LAST_MINUTE_59_SECONDS,
LEAP_CLOCK_NOT_IN_SYNC,
};
enum ntp_modes {
MODE_RESERVED = 0,
MODE_SYMMETRIC_ACTIVE,
MODE_SYMMETRIC_PASSIVE,
MODE_CLIENT,
MODE_SERVER,
MODE_BROADCAST,
MODE_NTP_CONTROL_MESSAGE,
};
const uint32 kSecondsBetween1900And1970 = 2208988800UL;
uint32
seconds_since_1900(void)
{
return kSecondsBetween1900And1970 + real_time_clock();
}
status_t
ntp_update_time(const char *hostname, Monitor *monitor)
{
if (monitor)
monitor->Update(0, "Contacting server \"%s\"...", hostname);
hostent *server = gethostbyname(hostname);
if (server == NULL) {
if (monitor)
monitor->Update("Could not contact server.");
return B_ENTRY_NOT_FOUND;
}
if (monitor)
monitor->Update(25, "Sending request...");
ntp_data message;
memset(&message, 0, sizeof(ntp_data));
message.leap_indicator = LEAP_CLOCK_NOT_IN_SYNC;
message.version = NTP_VERSION_3;
message.mode = MODE_CLIENT;
message.stratum = 1; // primary reference
message.precision = -5; // 2^-5 ~ 32-64 Hz precision
message.root_delay.SetTo(1); // 1 sec
message.root_dispersion.SetTo(1);
message.transmit_timestamp.SetTo(seconds_since_1900());
int connection = socket(AF_INET, SOCK_DGRAM, 0);
if (connection < 0) {
if (monitor)
monitor->Update("Could not create socket: %s", strerror(errno));
return errno;
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(NTP_PORT);
address.sin_addr.s_addr = *(uint32 *)server->h_addr_list[0];
if (sendto(connection, (char *)&message, sizeof(ntp_data),
0, (struct sockaddr *)&address, sizeof(address)) < 0) {
if (monitor)
monitor->Update("Sending request failed: %s", strerror(errno));
return errno;
}
// message is sent, now just wait for something to be returned...
if (monitor)
monitor->Update(50, "Waiting for answer...");
fd_set waitForReceived;
FD_ZERO(&waitForReceived);
FD_SET(connection, &waitForReceived);
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
// we'll wait 3 seconds for the answer
if (select(connection + 1, &waitForReceived, NULL, NULL, &timeout) <= 0) {
if (monitor)
monitor->Update("Waiting for answer failed: %s", strerror(errno));
return errno;
}
message.transmit_timestamp.SetTo(0);
socklen_t addressSize = sizeof(address);
if (recvfrom(connection, (char *)&message, sizeof(ntp_data), 0,
(sockaddr *)&address, &addressSize) < (ssize_t)sizeof(ntp_data)) {
if (monitor)
monitor->Update("Message receiving failed: %s", strerror(errno));
close(connection);
return errno;
}
close(connection);
if (message.transmit_timestamp.Integer() == 0) {
if (monitor)
monitor->Update("Received invalid time.");
return B_BAD_VALUE;
}
time_t now = message.transmit_timestamp.Integer() - kSecondsBetween1900And1970;
if (monitor) {
char buffer[64];
strftime(buffer, sizeof(buffer), "%a %b %T %Y", localtime(&now));
monitor->Update(100, "Message received: %s", buffer);
}
set_real_time_clock(now);
return B_OK;
}

View File

@ -1,15 +0,0 @@
/*
* Copyright 2004, pinc Software. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef NTP_H
#define NTP_H
#include "Monitor.h"
#include <SupportDefs.h>
extern status_t ntp_update_time(const char *host, Monitor *monitor = NULL);
#endif /* NTP_H */