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")
|
||||
{
|
||||
Glib::Variant<Glib::ustring> timezone;
|
||||
std::error_code error_code;
|
||||
Glib::Variant<bool> user_interaction;
|
||||
|
||||
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());
|
||||
}
|
||||
else
|
||||
catch (const std::filesystem::filesystem_error& filesystem_error)
|
||||
{
|
||||
Gio::DBus::Error error{ Gio::DBus::Error::FAILED,
|
||||
error_code ? error_code.message().c_str() : "Zone info is not a regular file" };
|
||||
invocation->return_error(error);
|
||||
invocation->return_error(Gio::DBus::Error{ Gio::DBus::Error::FAILED, filesystem_error.what() });
|
||||
}
|
||||
}
|
||||
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")
|
||||
{
|
||||
Glib::Variant<bool> use_ntp;
|
||||
Glib::Variant<bool> user_interaction;
|
||||
|
||||
parameters.get_child(use_ntp, 0);
|
||||
parameters.get_child(user_interaction, 1);
|
||||
|
||||
// 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());
|
||||
}
|
||||
else
|
||||
catch (const std::filesystem::filesystem_error& filesystem_error)
|
||||
{
|
||||
Gio::DBus::Error error{ Gio::DBus::Error::FAILED, "Error enabling NTP" };
|
||||
invocation->return_error(error);
|
||||
invocation->return_error(Gio::DBus::Error{ Gio::DBus::Error::FAILED, filesystem_error.what() });
|
||||
}
|
||||
}
|
||||
else if (method_name == "ListTimezones")
|
||||
{
|
||||
try
|
||||
{
|
||||
auto return_tuple = Glib::Variant<std::vector<Glib::ustring>>::create_tuple({
|
||||
dlackware::timedate::list_timezones()
|
||||
auto return_tuple = Glib::VariantContainerBase::create_tuple({
|
||||
Glib::Variant<std::vector<Glib::ustring>>::create(dlackware::timedate::list_timezones())
|
||||
});
|
||||
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")
|
||||
{
|
||||
result = Glib::Variant<bool>::create(slack_get_is_localtime());
|
||||
result = Glib::Variant<bool>::create(dlackware::timedate::local_rtc());
|
||||
}
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
|
||||
list_timezones("", result);
|
||||
return Glib::Variant<std::vector<Glib::ustring>>::create(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Glib::ustring timezone()
|
||||
@ -225,21 +227,69 @@ namespace dlackware::timedate
|
||||
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();
|
||||
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::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;
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
// 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.
|
||||
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
|
||||
// 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
|
||||
{
|
||||
@ -91,12 +99,3 @@ namespace dlackware::timedate
|
||||
// Takes the amount of seconds since UNIX epoche and
|
||||
// Returns true on success, false otherwise
|
||||
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