This commit is contained in:
parent
8d43caadcc
commit
e72976840c
@ -35,18 +35,18 @@ static void slack_method_call(const Glib::RefPtr<Gio::DBus::Connection>& connect
|
|||||||
if (method_name == "SetTimezone")
|
if (method_name == "SetTimezone")
|
||||||
{
|
{
|
||||||
Glib::Variant<Glib::ustring> timezone;
|
Glib::Variant<Glib::ustring> timezone;
|
||||||
std::error_code error_code;
|
Glib::Variant<bool> user_interaction;
|
||||||
|
|
||||||
parameters.get_child(timezone, 0);
|
parameters.get_child(timezone, 0);
|
||||||
if (dlackware::timedate::set_timezone(timezone.get(), error_code))
|
parameters.get_child(user_interaction, 1);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
|
dlackware::timedate::set_timezone(timezone.get(), user_interaction.get());
|
||||||
invocation->return_value(Glib::VariantContainerBase());
|
invocation->return_value(Glib::VariantContainerBase());
|
||||||
}
|
}
|
||||||
else
|
catch (const std::filesystem::filesystem_error& filesystem_error)
|
||||||
{
|
{
|
||||||
Gio::DBus::Error error{ Gio::DBus::Error::FAILED,
|
invocation->return_error(Gio::DBus::Error{ Gio::DBus::Error::FAILED, filesystem_error.what() });
|
||||||
error_code ? error_code.message().c_str() : "Zone info is not a regular file" };
|
|
||||||
invocation->return_error(error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (method_name == "SetTime")
|
else if (method_name == "SetTime")
|
||||||
@ -70,26 +70,28 @@ static void slack_method_call(const Glib::RefPtr<Gio::DBus::Connection>& connect
|
|||||||
else if (method_name == "SetNTP")
|
else if (method_name == "SetNTP")
|
||||||
{
|
{
|
||||||
Glib::Variant<bool> use_ntp;
|
Glib::Variant<bool> use_ntp;
|
||||||
|
Glib::Variant<bool> user_interaction;
|
||||||
|
|
||||||
parameters.get_child(use_ntp, 0);
|
parameters.get_child(use_ntp, 0);
|
||||||
|
parameters.get_child(user_interaction, 1);
|
||||||
|
|
||||||
// Enable NTP
|
// Enable NTP
|
||||||
if (slack_set_ntp(use_ntp.get()))
|
try
|
||||||
{
|
{
|
||||||
|
dlackware::timedate::set_ntp(use_ntp.get(), user_interaction.get());
|
||||||
invocation->return_value(Glib::VariantContainerBase());
|
invocation->return_value(Glib::VariantContainerBase());
|
||||||
}
|
}
|
||||||
else
|
catch (const std::filesystem::filesystem_error& filesystem_error)
|
||||||
{
|
{
|
||||||
Gio::DBus::Error error{ Gio::DBus::Error::FAILED, "Error enabling NTP" };
|
invocation->return_error(Gio::DBus::Error{ Gio::DBus::Error::FAILED, filesystem_error.what() });
|
||||||
invocation->return_error(error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (method_name == "ListTimezones")
|
else if (method_name == "ListTimezones")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto return_tuple = Glib::Variant<std::vector<Glib::ustring>>::create_tuple({
|
auto return_tuple = Glib::VariantContainerBase::create_tuple({
|
||||||
dlackware::timedate::list_timezones()
|
Glib::Variant<std::vector<Glib::ustring>>::create(dlackware::timedate::list_timezones())
|
||||||
});
|
});
|
||||||
invocation->return_value(return_tuple);
|
invocation->return_value(return_tuple);
|
||||||
}
|
}
|
||||||
@ -111,11 +113,11 @@ static void slack_get_property(Glib::VariantBase& result, const Glib::RefPtr<Gio
|
|||||||
}
|
}
|
||||||
else if (prop_name == "LocalRTC")
|
else if (prop_name == "LocalRTC")
|
||||||
{
|
{
|
||||||
result = Glib::Variant<bool>::create(slack_get_is_localtime());
|
result = Glib::Variant<bool>::create(dlackware::timedate::local_rtc());
|
||||||
}
|
}
|
||||||
else if (prop_name == "NTP")
|
else if (prop_name == "NTP")
|
||||||
{
|
{
|
||||||
result = Glib::Variant<bool>::create(slack_get_ntp());
|
result = Glib::Variant<bool>::create(dlackware::timedate::ntp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +187,7 @@ namespace dlackware::timedate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_timezones(const std::string& prefix, std::vector<Glib::ustring>& accumulator)
|
static void list_timezones(const std::string& prefix, std::vector<Glib::ustring>& accumulator)
|
||||||
{
|
{
|
||||||
auto zoneinfo_path = std::filesystem::path(zoneinfo_database) / prefix;
|
auto zoneinfo_path = std::filesystem::path(zoneinfo_database) / prefix;
|
||||||
|
|
||||||
@ -205,12 +207,12 @@ namespace dlackware::timedate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::Variant<std::vector<Glib::ustring>> list_timezones()
|
std::vector<Glib::ustring> list_timezones()
|
||||||
{
|
{
|
||||||
std::vector<Glib::ustring> result;
|
std::vector<Glib::ustring> result;
|
||||||
|
|
||||||
list_timezones("", result);
|
list_timezones("", result);
|
||||||
return Glib::Variant<std::vector<Glib::ustring>>::create(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::ustring timezone()
|
Glib::ustring timezone()
|
||||||
@ -225,21 +227,69 @@ namespace dlackware::timedate
|
|||||||
return Glib::ustring{ zone_copied_from.get() + strlen(zoneinfo_database) + 1 };
|
return Glib::ustring{ zone_copied_from.get() + strlen(zoneinfo_database) + 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_timezone(const Glib::ustring& zone, std::error_code& ec)
|
void set_timezone(const Glib::ustring& zone, bool)
|
||||||
{
|
{
|
||||||
ec.clear();
|
|
||||||
auto zone_file = std::filesystem::path("/usr/share/zoneinfo") / zone.data();
|
auto zone_file = std::filesystem::path("/usr/share/zoneinfo") / zone.data();
|
||||||
|
std::error_code ec{};
|
||||||
|
|
||||||
if (!std::filesystem::is_regular_file(zone_file, ec) || ec)
|
if (!std::filesystem::is_regular_file(zone_file, ec))
|
||||||
{
|
{
|
||||||
return false;
|
throw std::filesystem::filesystem_error("Zone info is not a regular file", zone_file, ec);
|
||||||
}
|
}
|
||||||
std::filesystem::path etc_localtime = "/etc/localtime";
|
std::filesystem::path etc_localtime = "/etc/localtime";
|
||||||
|
|
||||||
std::filesystem::remove(etc_localtime);
|
std::filesystem::remove(etc_localtime);
|
||||||
std::filesystem::create_symlink(zone_file, etc_localtime, ec);
|
std::filesystem::create_symlink(zone_file, etc_localtime);
|
||||||
|
}
|
||||||
|
|
||||||
return !ec;
|
void set_ntp(bool use_ntp, bool)
|
||||||
|
{
|
||||||
|
std::filesystem::perms rc_mode = std::filesystem::perms::owner_read | std::filesystem::perms::owner_write
|
||||||
|
| std::filesystem::perms::group_read | std::filesystem::perms::others_read;
|
||||||
|
|
||||||
|
if (use_ntp)
|
||||||
|
{
|
||||||
|
rc_mode |= std::filesystem::perms::owner_exec
|
||||||
|
| std::filesystem::perms::group_exec | std::filesystem::perms::others_exec;
|
||||||
|
}
|
||||||
|
std::error_code ec;
|
||||||
|
const std::filesystem::path service_path{ "/etc/rc.d/rc.ntpd" };
|
||||||
|
|
||||||
|
if (std::filesystem::is_regular_file(service_path, ec))
|
||||||
|
{
|
||||||
|
std::filesystem::permissions("/etc/rc.d/rc.ntpd", rc_mode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::filesystem::filesystem_error("The NTP daemon isn't installed", service_path, ec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool local_rtc()
|
||||||
|
{
|
||||||
|
std::ifstream fh{ "/etc/hardwareclock", std::ios::in };
|
||||||
|
if (!fh.is_open())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::array<char, 10> time_str; // "localtime" is longer than "UTC" and has 9 letters + \0
|
||||||
|
|
||||||
|
while (fh.good())
|
||||||
|
{
|
||||||
|
fh.getline(time_str.data(), time_str.size());
|
||||||
|
fh.clear(fh.rdstate() & (~std::ios_base::failbit));
|
||||||
|
|
||||||
|
if (std::strncmp(time_str.data(), "localtime", time_str.size()) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ntp()
|
||||||
|
{
|
||||||
|
return Glib::file_test("/etc/rc.d/rc.ntpd", Glib::FileTest::FILE_TEST_IS_EXECUTABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,59 +319,3 @@ gboolean slack_set_time(gint64 seconds_since_epoch, gboolean relative)
|
|||||||
}
|
}
|
||||||
return clock_settime (CLOCK_REALTIME, &ts) == 0;
|
return clock_settime (CLOCK_REALTIME, &ts) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean slack_get_is_localtime()
|
|
||||||
{
|
|
||||||
std::ifstream fh{ "/etc/hardwareclock", std::ios::in };
|
|
||||||
if (!fh.is_open())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::array<char, 10> time_str; // "localtime" is longer than "UTC" and has 9 letters + \0
|
|
||||||
|
|
||||||
while (fh.good())
|
|
||||||
{
|
|
||||||
fh.getline(time_str.data(), time_str.size());
|
|
||||||
fh.clear(fh.rdstate() & (~std::ios_base::failbit));
|
|
||||||
|
|
||||||
if (std::strncmp(time_str.data(), "localtime", time_str.size()) == 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean slack_get_ntp()
|
|
||||||
{
|
|
||||||
return Glib::file_test("/etc/rc.d/rc.ntpd", Glib::FileTest::FILE_TEST_IS_EXECUTABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean slack_set_ntp(gboolean xntp)
|
|
||||||
{
|
|
||||||
std::filesystem::perms rc_mode = std::filesystem::perms::owner_read | std::filesystem::perms::owner_write
|
|
||||||
| std::filesystem::perms::group_read | std::filesystem::perms::others_read;
|
|
||||||
|
|
||||||
if (xntp)
|
|
||||||
{
|
|
||||||
rc_mode |= std::filesystem::perms::owner_exec
|
|
||||||
| std::filesystem::perms::group_exec | std::filesystem::perms::others_exec;
|
|
||||||
g_message("Please don't forget to configure the NTP daemon");
|
|
||||||
|
|
||||||
/* It doesn't matter if fails.
|
|
||||||
* The ntpdate command is considered obsolete, but "orthodox" ntpd -g
|
|
||||||
* will fail if your system clock is off for more than half an hour. */
|
|
||||||
g_spawn_command_line_async("/usr/sbin/ntpdate pool.ntp.org", NULL);
|
|
||||||
}
|
|
||||||
if (Glib::file_test("/etc/rc.d/rc.ntpd", Glib::FileTest::FILE_TEST_IS_REGULAR))
|
|
||||||
{
|
|
||||||
std::error_code ec;
|
|
||||||
std::filesystem::permissions("/etc/rc.d/rc.ntpd", rc_mode, ec);
|
|
||||||
return !ec;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_error("The NTP daemon isn't installed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -64,16 +64,24 @@ namespace dlackware::timedate
|
|||||||
{
|
{
|
||||||
constexpr const char *zoneinfo_database = "/usr/share/zoneinfo";
|
constexpr const char *zoneinfo_database = "/usr/share/zoneinfo";
|
||||||
|
|
||||||
// Returns the timezones available on the system.
|
|
||||||
Glib::Variant<std::vector<Glib::ustring>> list_timezones();
|
|
||||||
void list_timezones(const std::string& prefix, std::vector<Glib::ustring>& accumulator);
|
|
||||||
|
|
||||||
// Returns the system time zone.
|
// Returns the system time zone.
|
||||||
Glib::ustring timezone();
|
Glib::ustring timezone();
|
||||||
|
|
||||||
|
// Returns if the hardware clock is set to local time or not
|
||||||
|
bool local_rtc();
|
||||||
|
|
||||||
|
// Returns if NTP is enabled
|
||||||
|
bool ntp();
|
||||||
|
|
||||||
|
// Returns the timezones available on the system.
|
||||||
|
std::vector<Glib::ustring> list_timezones();
|
||||||
|
|
||||||
// Sets the system time zone to the one passed by the argument
|
// Sets the system time zone to the one passed by the argument
|
||||||
// Returns true on success, false otherwise
|
// Returns true on success, false otherwise
|
||||||
bool set_timezone(const Glib::ustring& zone, std::error_code& ec);
|
void set_timezone(const Glib::ustring& zone, bool user_interaction);
|
||||||
|
|
||||||
|
// Sets NTP
|
||||||
|
void set_ntp(bool use_ntp, bool user_interaction);
|
||||||
|
|
||||||
class timedate1
|
class timedate1
|
||||||
{
|
{
|
||||||
@ -91,12 +99,3 @@ namespace dlackware::timedate
|
|||||||
// Takes the amount of seconds since UNIX epoche and
|
// Takes the amount of seconds since UNIX epoche and
|
||||||
// Returns true on success, false otherwise
|
// Returns true on success, false otherwise
|
||||||
gboolean slack_set_time(gint64 seconds_since_epoch, gboolean relative);
|
gboolean slack_set_time(gint64 seconds_since_epoch, gboolean relative);
|
||||||
|
|
||||||
// Returns if the hardware clock is set to local time or not
|
|
||||||
gboolean slack_get_is_localtime ();
|
|
||||||
|
|
||||||
// Returns if NTP is enabled
|
|
||||||
gboolean slack_get_ntp ();
|
|
||||||
|
|
||||||
// Sets NTP
|
|
||||||
gboolean slack_set_ntp (gboolean);
|
|
||||||
|
Loading…
Reference in New Issue
Block a user