Report back SetNTP errors
All checks were successful
Build / build (push) Successful in 19s

This commit is contained in:
Eugen Wissner 2024-06-13 13:09:52 +02:00
parent 8d43caadcc
commit e72976840c
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
2 changed files with 86 additions and 93 deletions

View File

@ -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;
}
}

View File

@ -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);