// File: davmac314[P]dinit/src/includes/load-service.h
// Function: void dinit_load::service_settings_wrapper<prelim_dep>::finalise<false, load_service(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, service_record*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, service_record*>>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<dir_entry, std::allocator<dir_entry>> const&)::$_4, load_service(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, service_record*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, service_record*>>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<dir_entry, std::allocator<dir_entry>> const&)::$_4, load_service(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, service_record*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, service_record*>>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<dir_entry, std::allocator<dir_entry>> const&)::$_1, true>(load_service(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, service_record*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, service_record*>>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<dir_entry, std::allocator<dir_entry>> const&)::$_4&, char const*, load_service(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, service_record*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, service_record*>>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<dir_entry, std::allocator<dir_entry>> const&)::$_4 const&, load_service(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, service_record*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, service_record*>>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<dir_entry, std::allocator<dir_entry>> const&)::$_1 const&)
void finalise(T &report_error, const char *service_arg, const U &report_lint,
            const V &var_subst)
    {
        if (service_type == service_type_t::PROCESS || service_type == service_type_t::BGPROCESS
                || service_type == service_type_t::SCRIPTED) {
            if (command.empty()) {
                report_error("'command' setting not specified.");
            }
        }

        if (do_report_lint && (service_type == service_type_t::INTERNAL
                || service_type == service_type_t::TRIGGERED)) {
            if (!command.empty()) {
                report_lint("'command' specified, but ignored for the specified (or default) service type.");
            }
            if (!stop_command.empty()) {
                report_lint("'stop-command' specified, but ignored for the specified (or default) service type.");
            }
            if (!working_dir.empty()) {
                report_lint("'working-dir' specified, but ignored for the specified (or default) service type.");
            }
            #if SUPPORT_CGROUPS
            if (!run_in_cgroup.empty()) {
                report_lint("'run-in-cgroup' specified, but ignored for the specified (or default) service type.");
            }
            #endif
            #if SUPPORT_CAPABILITIES
            if (capabilities.get()) {
                report_lint("'capabilities' specified, but ignored for the specified (or default) service type.");
            }
            if (secbits.get()) {
                report_lint("'securebits' specified, but ignored for the specified (or default) service type.");
            }
            #endif
            if (run_as_uid != (uid_t)-1) {
                report_lint("'run-as' specified, but ignored for the specified (or default) service type.");
            }
            if (!socket_path.empty()) {
                report_lint("'socket-listen' specified, but ignored for the specified (or default) service type'.");
            }
            #if USE_UTMPX
            if (inittab_id[0] != 0 || inittab_line[0] != 0) {
                report_lint("'inittab_line' or 'inittab_id' specified, but ignored for the specified (or default) service type.");
            }
            #endif
            if (onstart_flags.signal_process_only || onstart_flags.start_interruptible) {
                report_lint("signal options were specified, but ignored for the specified (or default) service type.");
            }
            if (onstart_flags.pass_cs_fd) {
                report_lint("option 'pass_cs_fd' was specified, but ignored for the specified (or default) service type.");
            }
            if (onstart_flags.skippable) {
                report_lint("option 'skippable' was specified, but ignored for the specified (or default) service type.");
            }
            #if SUPPORT_CAPABILITIES
            if (onstart_flags.no_new_privs) {
                report_lint("option 'no_new_privs' was specified, but ignored for the specified (or default) service type.");
            }
            #endif
            if (log_type != log_type_id::NONE) {
                report_lint("option 'log_type' was specified, but ignored for the specified (or default) service type.");
            }
            if (nice_is_set) {
                report_lint("option 'nice' was specified, but ignored for the specified (or default) service type.");
            }
            #if SUPPORT_IOPRIO
            if (ioprio >= 0) {
                report_lint("option 'ioprio' was specified, but ignored for the specified (or default) service type.");
            }
            #endif
            #if SUPPORT_OOM_ADJ
            if (oom_adj_is_set) {
                report_lint("option 'oom-score-adj' was specified, but ignored for the specified (or default) service type.");
            }
            #endif
        }

        if (do_report_lint) {
            if (log_type != log_type_id::LOGFILE && !logfile.empty()) {
                report_lint("option 'logfile' was specified, but selected log type is not 'file'");
            }
            if (log_type == log_type_id::LOGFILE && logfile.empty()) {
                report_lint("option 'logfile' not set, but selected log type is 'file'");
            }
        }

        if (service_type == service_type_t::BGPROCESS) {
            if (pid_file.empty()) {
                report_error("process ID file ('pid-file') not specified for bgprocess service.");
            }

            if (readiness_fd != -1 || !readiness_var.empty()) {
                report_error("readiness notification ('ready-notification') is not supported "
                        "for bgprocess services.");
            }
        }

        if (onstart_flags.kill_all_on_stop && service_type != service_type_t::INTERNAL
                && service_type != service_type_t::SCRIPTED) {
            report_error("kill-all-on-stop can only be set on scripted or internal services.");
        }

        // Resolve paths via variable substitution
        {
            auto do_resolve = [&](const char *setting_name, string &setting_value) {
                try {
                    list<pair<unsigned,unsigned>> str_offsets;
                    str_offsets.emplace_back(0, setting_value.size());
                    value_var_subst(setting_name, setting_value, str_offsets, var_subst, service_arg);
                }
                catch (service_description_exc &exc) {
                    if (propagate_sde) throw;
                    report_error((string() + setting_name + ": " + exc.exc_description).c_str());
                }
            };

            do_resolve("socket-listen", socket_path);
            do_resolve("logfile", logfile);
            do_resolve("working-dir", working_dir);
            do_resolve("pid-file", pid_file);
        }

        // If socket_gid hasn't been explicitly set, but the socket_uid was specified as a name (and
        // we therefore recovered the primary group), use the primary group of the specified user.
        if (socket_gid == (gid_t)-1) socket_gid = socket_uid_gid;
        // Also for logfile_uid/gid, we reset logfile ownership to dinit process uid/gid if uid/gid
        // wasn't specified by service
        if (logfile_uid == (uid_t) -1) logfile_uid = getuid();
        if (logfile_gid == (gid_t)-1) logfile_gid = logfile_uid_gid;
        if (logfile_gid == (gid_t)-1) logfile_gid = getgid();
        // likewise for "run as" gid/uid, but only if we aren't supporting supplementary group initialisation
        // (if we do support supplementary groups, run_as_gid==-1 means "use the user groups including
        // supplementary groups" whereas run_as_gid==X means "use group X with no supplementary groups").
#if USE_INITGROUPS
        if (run_as_uid_gid == (gid_t)-1 && run_as_gid == (gid_t)-1) {
            // run-as-UID specified by number; set run_as_gid to inhibit initialisation of
            // supplementary groups
            run_as_gid = getgid();
        }
#else // !USE_INITGROUPS
        if (run_as_gid == (gid_t)-1) run_as_gid = run_as_uid_gid;
#endif

        if (log_type != log_type_id::LOGFILE) {
            logfile.clear();
        }

        if (!value(service_type).is_in(service_type_t::PROCESS, service_type_t::BGPROCESS)) {
            if (!consumer_of_name.empty()) {
                report_error("only a process or bgprocess service can be a log consumer ('consume-for') another service.");
            }
        }
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpl $0x1, 0xb4(%rax)
je 0xc197
movq -0x58(%rbp), %rax
cmpl $0x2, 0xb4(%rax)
je 0xc197
movq -0x58(%rbp), %rax
cmpl $0x3, 0xb4(%rax)
jne 0xc1b8
movq -0x58(%rbp), %rdi
callq 0x16b70
testb $0x1, %al
jne 0xc1a6
jmp 0xc1b6
movq -0x10(%rbp), %rdi
leaq 0x2e4f8(%rip), %rsi     # 0x3a6a9
callq 0x13310
jmp 0xc1b8
movq -0x58(%rbp), %rax
cmpl $0x4, 0xb4(%rax)
je 0xc1d6
movq -0x58(%rbp), %rax
cmpl $0x5, 0xb4(%rax)
jne 0xc3b7
movq -0x58(%rbp), %rdi
callq 0x16b70
testb $0x1, %al
jne 0xc1f3
movq -0x20(%rbp), %rdi
leaq 0x2e4dc(%rip), %rsi     # 0x3a6ca
callq 0x13310
movq -0x58(%rbp), %rdi
addq $0x28, %rdi
callq 0x16b70
testb $0x1, %al
jne 0xc214
movq -0x20(%rbp), %rdi
leaq 0x2e509(%rip), %rsi     # 0x3a718
callq 0x13310
movq -0x58(%rbp), %rdi
addq $0x50, %rdi
callq 0x5830
testb $0x1, %al
jne 0xc235
movq -0x20(%rbp), %rdi
leaq 0x2e53b(%rip), %rsi     # 0x3a76b
callq 0x13310
movq -0x58(%rbp), %rdi
addq $0x260, %rdi            # imm = 0x260
callq 0x5830
testb $0x1, %al
jne 0xc259
movq -0x20(%rbp), %rdi
leaq 0x2e569(%rip), %rsi     # 0x3a7bd
callq 0x13310
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x208(%rax)
je 0xc276
movq -0x20(%rbp), %rdi
leaq 0x2e5a0(%rip), %rsi     # 0x3a811
callq 0x13310
movq -0x58(%rbp), %rdi
addq $0x150, %rdi            # imm = 0x150
callq 0x5830
testb $0x1, %al
jne 0xc29a
movq -0x20(%rbp), %rdi
leaq 0x2e5c9(%rip), %rsi     # 0x3a85e
callq 0x13310
movq -0x58(%rbp), %rax
movsbl 0x284(%rax), %eax
cmpl $0x0, %eax
jne 0xc2ba
movq -0x58(%rbp), %rax
movsbl 0x288(%rax), %eax
cmpl $0x0, %eax
je 0xc2ca
movq -0x20(%rbp), %rdi
leaq 0x2e5ee(%rip), %rsi     # 0x3a8b3
callq 0x13310
movq -0x58(%rbp), %rax
movw 0x13c(%rax), %ax
shrw $0x9, %ax
andw $0x1, %ax
testw $0x1, %ax
jne 0xc2fc
movq -0x58(%rbp), %rax
movw 0x13c(%rax), %ax
shrw $0x7, %ax
andw $0x1, %ax
testw $0x1, %ax
je 0xc30c
movq -0x20(%rbp), %rdi
leaq 0x2e60f(%rip), %rsi     # 0x3a916
callq 0x13310
movq -0x58(%rbp), %rax
movw 0x13c(%rax), %ax
shrw $0x6, %ax
andw $0x1, %ax
testw $0x1, %ax
je 0xc335
movq -0x20(%rbp), %rdi
leaq 0x2e63e(%rip), %rsi     # 0x3a96e
callq 0x13310
movq -0x58(%rbp), %rax
movw 0x13c(%rax), %ax
shrw $0x8, %ax
andw $0x1, %ax
testw $0x1, %ax
je 0xc35e
movq -0x20(%rbp), %rdi
leaq 0x2e671(%rip), %rsi     # 0x3a9ca
callq 0x13310
movq -0x58(%rbp), %rax
cmpl $0x0, 0x100(%rax)
je 0xc37b
movq -0x20(%rbp), %rdi
leaq 0x2e6af(%rip), %rsi     # 0x3aa25
callq 0x13310
movq -0x58(%rbp), %rax
testb $0x1, 0x214(%rax)
je 0xc398
movq -0x20(%rbp), %rdi
leaq 0x2e6ec(%rip), %rsi     # 0x3aa7f
callq 0x13310
movq -0x58(%rbp), %rax
testb $0x1, 0x280(%rax)
je 0xc3b5
movq -0x20(%rbp), %rdi
leaq 0x2e725(%rip), %rsi     # 0x3aad5
callq 0x13310
jmp 0xc3b7
movq -0x58(%rbp), %rax
cmpl $0x1, 0x100(%rax)
je 0xc3e8
movq -0x58(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x5830
testb $0x1, %al
jne 0xc3e8
movq -0x20(%rbp), %rdi
leaq 0x2e751(%rip), %rsi     # 0x3ab34
callq 0x13310
movq -0x58(%rbp), %rax
cmpl $0x1, 0x100(%rax)
jne 0xc41b
movq -0x58(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x5830
testb $0x1, %al
jne 0xc40b
jmp 0xc41b
movq -0x20(%rbp), %rdi
leaq 0x2e762(%rip), %rsi     # 0x3ab78
callq 0x13310
movq -0x58(%rbp), %rax
cmpl $0x2, 0xb4(%rax)
jne 0xc47e
movq -0x58(%rbp), %rdi
addq $0x70, %rdi
callq 0x5830
testb $0x1, %al
jne 0xc43b
jmp 0xc44b
movq -0x10(%rbp), %rdi
leaq 0x2e76c(%rip), %rsi     # 0x3abb2
callq 0x13310
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x1e0(%rax)
jne 0xc46c
movq -0x58(%rbp), %rdi
addq $0x1e8, %rdi            # imm = 0x1E8
callq 0x5830
testb $0x1, %al
jne 0xc47c
movq -0x10(%rbp), %rdi
leaq 0x2e77d(%rip), %rsi     # 0x3abf4
callq 0x13310
jmp 0xc47e
movq -0x58(%rbp), %rax
movw 0x13c(%rax), %ax
shrw $0xb, %ax
andw $0x1, %ax
testw $0x1, %ax
je 0xc4c1
movq -0x58(%rbp), %rax
cmpl $0x4, 0xb4(%rax)
je 0xc4c1
movq -0x58(%rbp), %rax
cmpl $0x3, 0xb4(%rax)
je 0xc4c1
movq -0x10(%rbp), %rdi
leaq 0x2e78f(%rip), %rsi     # 0x3ac4b
callq 0x13310
movq -0x58(%rbp), %rdx
movq -0x28(%rbp), %rax
movq %rax, -0x40(%rbp)
leaq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x30(%rbp)
addq $0x150, %rdx            # imm = 0x150
leaq -0x40(%rbp), %rdi
leaq 0x2e79f(%rip), %rsi     # 0x3ac8e
callq 0x133b0
movq -0x58(%rbp), %rdx
addq $0x108, %rdx            # imm = 0x108
leaq -0x40(%rbp), %rdi
leaq 0x2e792(%rip), %rsi     # 0x3ac9c
callq 0x133b0
movq -0x58(%rbp), %rdx
addq $0x50, %rdx
leaq -0x40(%rbp), %rdi
leaq 0x2e782(%rip), %rsi     # 0x3aca4
callq 0x133b0
movq -0x58(%rbp), %rdx
addq $0x70, %rdx
leaq -0x40(%rbp), %rdi
leaq 0x2e776(%rip), %rsi     # 0x3acb0
callq 0x133b0
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x17c(%rax)
jne 0xc55c
movq -0x58(%rbp), %rax
movl 0x178(%rax), %ecx
movl %ecx, 0x17c(%rax)
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x12c(%rax)
jne 0xc57a
callq 0x5230
movl %eax, %ecx
movq -0x58(%rbp), %rax
movl %ecx, 0x12c(%rax)
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x134(%rax)
jne 0xc597
movq -0x58(%rbp), %rax
movl 0x130(%rax), %ecx
movl %ecx, 0x134(%rax)
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x134(%rax)
jne 0xc5b5
callq 0x5500
movl %eax, %ecx
movq -0x58(%rbp), %rax
movl %ecx, 0x134(%rax)
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x20c(%rax)
jne 0xc5e0
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x210(%rax)
jne 0xc5e0
callq 0x5500
movl %eax, %ecx
movq -0x58(%rbp), %rax
movl %ecx, 0x210(%rax)
movq -0x58(%rbp), %rax
cmpl $0x1, 0x100(%rax)
je 0xc5fd
movq -0x58(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x5680
movq -0x58(%rbp), %rdi
addq $0xb4, %rdi
callq 0x14a00
movq %rax, -0x48(%rbp)
movl $0x1, -0x4c(%rbp)
movl $0x2, -0x50(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x4c(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x34270
xorb $-0x1, %al
testb $0x1, %al
jne 0xc638
jmp 0xc65e
movq -0x58(%rbp), %rdi
addq $0x240, %rdi            # imm = 0x240
callq 0x5830
testb $0x1, %al
jne 0xc65c
movq -0x10(%rbp), %rdi
leaq 0x2e662(%rip), %rsi     # 0x3acb9
callq 0x13310
jmp 0xc65e
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)