/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "bus-polkit.h"
#include "bus-util.h"
#include "dbus-util.h"
#include "escape.h"
#include "parse-util.h"
#include "path-util.h"
#include "unit-printf.h"
#include "user-util.h"
#include "unit.h"

int bus_property_get_triggered_unit(
                sd_bus *bus,
                const char *path,
                const char *interface,
                const char *property,
                sd_bus_message *reply,
                void *userdata,
                sd_bus_error *error) {

        Unit *u = userdata, *trigger;

        assert(bus);
        assert(reply);
        assert(u);

        trigger = UNIT_TRIGGER(u);

        return sd_bus_message_append(reply, "s", trigger ? trigger->id : NULL);
}

BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);

static inline bool valid_user_group_name_or_id_relaxed(const char *u) {
        return valid_user_group_name(u, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX);
}

BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_relaxed, valid_user_group_name_or_id_relaxed);
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute);

int bus_set_transient_string(
                Unit *u,
                const char *name,
                char **p,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        const char *v;
        int r;

        assert(p);

        r = sd_bus_message_read(message, "s", &v);
        if (r < 0)
                return r;

        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                r = free_and_strdup(p, empty_to_null(v));
                if (r < 0)
                        return r;

                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
                                    "%s=%s", name, strempty(v));
        }

        return 1;
}

int bus_set_transient_bool(
                Unit *u,
                const char *name,
                bool *p,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        int v, r;

        assert(p);

        r = sd_bus_message_read(message, "b", &v);
        if (r < 0)
                return r;

        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                *p = v;
                unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
        }

        return 1;
}

int bus_set_transient_usec_internal(
                Unit *u,
                const char *name,
                usec_t *p,
                bool fix_0,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        uint64_t v;
        int r;

        assert(p);

        r = sd_bus_message_read(message, "t", &v);
        if (r < 0)
                return r;

        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                char *n, ts[FORMAT_TIMESPAN_MAX];

                if (fix_0)
                        *p = v != 0 ? v: USEC_INFINITY;
                else
                        *p = v;

                n = strndupa(name, strlen(name) - 4);
                unit_write_settingf(u, flags, name, "%sSec=%s", n,
                                    format_timespan(ts, sizeof(ts), v, USEC_PER_MSEC));
        }

        return 1;
}

int bus_verify_manage_units_async_full(
                Unit *u,
                const char *verb,
                int capability,
                const char *polkit_message,
                bool interactive,
                sd_bus_message *call,
                sd_bus_error *error) {

        const char *details[9] = {
                "unit", u->id,
                "verb", verb,
        };

        if (polkit_message) {
                details[4] = "polkit.message";
                details[5] = polkit_message;
                details[6] = "polkit.gettext_domain";
                details[7] = GETTEXT_PACKAGE;
        }

        return bus_verify_polkit_async(
                        call,
                        capability,
                        "org.freedesktop.systemd1.manage-units",
                        details,
                        interactive,
                        UID_INVALID,
                        &u->manager->polkit_registry,
                        error);
}

/* ret_format_str is an accumulator, so if it has any pre-existing content, new options will be appended to it */
int bus_read_mount_options(
                sd_bus_message *message,
                sd_bus_error *error,
                MountOptions **ret_options,
                char **ret_format_str,
                const char *separator) {

        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
        _cleanup_free_ char *format_str = NULL;
        const char *mount_options, *partition;
        int r;

        assert(message);
        assert(ret_options);
        assert(separator);

        r = sd_bus_message_enter_container(message, 'a', "(ss)");
        if (r < 0)
                return r;

        while ((r = sd_bus_message_read(message, "(ss)", &partition, &mount_options)) > 0) {
                _cleanup_free_ char *escaped = NULL;
                _cleanup_free_ MountOptions *o = NULL;
                PartitionDesignator partition_designator;

                if (chars_intersect(mount_options, WHITESPACE))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
                                                "Invalid mount options string, contains whitespace character(s): %s", mount_options);

                partition_designator = partition_designator_from_string(partition);
                if (partition_designator < 0)
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid partition name %s", partition);

                /* Need to store the options with the escapes, so that they can be parsed again */
                escaped = shell_escape(mount_options, ":");
                if (!escaped)
                        return -ENOMEM;

                if (!strextend_with_separator(&format_str, separator, partition, ":", escaped))
                        return -ENOMEM;

                o = new(MountOptions, 1);
                if (!o)
                        return -ENOMEM;
                *o = (MountOptions) {
                        .partition_designator = partition_designator,
                        .options = strdup(mount_options),
                };
                if (!o->options)
                        return -ENOMEM;
                LIST_APPEND(mount_options, options, TAKE_PTR(o));
        }
        if (r < 0)
                return r;

        r = sd_bus_message_exit_container(message);
        if (r < 0)
                return r;

        if (!LIST_IS_EMPTY(options)) {
                if (ret_format_str) {
                        char *final = strjoin(*ret_format_str, !isempty(*ret_format_str) ? separator : "", format_str);
                        if (!final)
                                return -ENOMEM;
                        free_and_replace(*ret_format_str, final);
                }
                LIST_JOIN(mount_options, *ret_options, options);
        }

        return 0;
}
