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")
{
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;
}
}

View File

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