File pam-use-plymouth.patch of Package pam

diff --git a/libpam_misc/meson.build b/libpam_misc/meson.build
index e0bb30f5..fcbcc552 100644
--- a/libpam_misc/meson.build
+++ b/libpam_misc/meson.build
@@ -14,16 +14,30 @@ libpam_misc_map_path = meson.current_source_dir() / libpam_misc_map
 libpam_misc_link_deps = [libpam_misc_map]
 libpam_misc_link_args = ['-Wl,--version-script=' + libpam_misc_map_path]
 
-libpam_misc = shared_library(
-  'pam_misc',
-  sources: libpam_misc_src,
-  include_directories: [libpam_misc_inc, libpamc_inc],
-  dependencies: [libpam_internal_dep, libpam_dep],
-  link_depends: libpam_misc_link_deps,
-  link_args: libpam_misc_link_args,
-  version: libpam_misc_version,
-  install: true,
-)
+if libply_boot_client.found()
+  libpam_misc = shared_library(
+    'pam_misc',
+    sources: libpam_misc_src,
+    include_directories: [libpam_ply_inc, libpam_misc_inc, libpamc_inc],
+    dependencies: [libpam_internal_dep, libpam_dep],
+    link_with: libpam_ply,
+    link_depends: libpam_misc_link_deps,
+    link_args: libpam_misc_link_args,
+    version: libpam_misc_version,
+    install: true,
+  )
+else
+  libpam_misc = shared_library(
+    'pam_misc',
+    sources: libpam_misc_src,
+    include_directories: [libpam_misc_inc, libpamc_inc],
+    dependencies: [libpam_internal_dep, libpam_dep],
+    link_depends: libpam_misc_link_deps,
+    link_args: libpam_misc_link_args,
+    version: libpam_misc_version,
+    install: true,
+  )
+endif
 
 libpam_misc_dep = declare_dependency(
   include_directories: [libpam_misc_inc],
diff --git a/libpam_misc/misc_conv.c b/libpam_misc/misc_conv.c
index fa3848e3..a6ca2dc5 100644
--- a/libpam_misc/misc_conv.c
+++ b/libpam_misc/misc_conv.c
@@ -1,11 +1,39 @@
 /*
- * A generic conversation function for text based applications
- *
- * Written by Andrew Morgan <morgan@linux.kernel.org>
- */
+    Generic conversation function
+    Copyright (C) XXXX-2026  Andrew Morgan <morgan@linux.kernel.org>
+    Copyright (C) 2022-2026  Mark A. Williams, Jr.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
 
 #include "config.h"
 
+#ifdef USE_PLYMOUTH
+# include <fcntl.h>
+# include <limits.h>
+# include <linux/futex.h>
+# include <linux/sched.h>
+# include <linux/vt.h>
+# include <paths.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+# include <sys/syscall.h>
+# include <sys/sysmacros.h>
+# include <sys/wait.h>
+#endif
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -17,6 +45,9 @@
 
 #include <security/pam_appl.h>
 #include <security/pam_misc.h>
+#ifdef USE_PLYMOUTH
+# include <security/pam_ply.h>
+#endif
 
 #include "pam_inline.h"
 #include "pam_i18n.h"
@@ -25,6 +56,12 @@
 #define CONV_ECHO_ON  1                            /* types of echo state */
 #define CONV_ECHO_OFF 0
 
+#ifdef USE_PLYMOUTH
+# ifndef _PATH_PLYHOME
+#  define _PATH_PLYHOME _PATH_VARRUN "plymouth"
+# endif
+#endif
+
 /*
  * external timeout definitions - these can be overridden by the
  * application.
@@ -277,8 +314,13 @@ static int read_string(int echo, const char *prompt, char **retstr)
  * confusing amount of pointer indirection).
  */
 
+#ifdef USE_PLYMOUTH
+static int tui_conv(int num_msg, const struct pam_message **msgm,
+                    struct pam_response **response, void *appdata_ptr)
+#else
 int misc_conv(int num_msg, const struct pam_message **msgm,
 	      struct pam_response **response, void *appdata_ptr)
+#endif
 {
     int count=0;
     struct pam_response *reply;
@@ -402,3 +444,158 @@ failed_conversation:
 
     return PAM_CONV_ERR;
 }
+
+#ifdef USE_PLYMOUTH
+/*
+ * This conversation function is supposed to be a graphical PAM one based on
+ * plymouth(8) via ply_conv(3). Like with tui_conv above, this too is _not_
+ * completely compatible with the Solaris PAM codebase.
+ */
+static int gui_conv(int num_msg, const struct pam_message **msgm,
+                    struct pam_response **response, void *appdata_ptr)
+{
+    int tries = 3;
+
+    do {
+        char cld_arg2[TTY_NAME_MAX + 6] = "--tty=";
+
+        if (!ttyname_r(STDIN_FILENO, cld_arg2 + 6, sizeof cld_arg2 - 6)) {
+            struct stat st;
+
+            if (fstat(STDIN_FILENO, &st) ||
+                ioctl(STDIN_FILENO, VT_WAITACTIVE, minor(st.st_rdev)))
+                continue;
+        }
+
+        struct pam_message msg_txt = {
+            .msg_style = PAM_TEXT_INFO,
+            .msg = cld_arg2 + (sizeof _PATH_TTY + 2),
+        };
+        struct pam_message msg_cmd = {
+            .msg_style = PAM_BINARY_PROMPT,
+            .msg = PLY_BOOT_PROTOCOL_REQUEST_TYPE_HAS_ACTIVE_VT,
+        };
+
+        const struct pam_message *msgs[] = { &msg_cmd, &msg_txt };
+        struct pam_response *resp = NULL;
+
+        switch (ply_conv(1, msgs, &resp, NULL)) {
+        case PAM_SUCCESS:
+            {
+                char *const s = resp->resp;
+
+                free(s);
+                free(resp);
+                resp = NULL;
+
+                if (s) {
+                    break;
+                }
+            }
+            msg_cmd.msg = PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT "\2\2\1";
+            ply_conv(1, msgs, &resp, NULL);
+            [[fallthrough]];
+        default:
+            if (resp) {
+                free(resp->resp);
+                free(resp);
+                resp = NULL;
+            }
+
+            siginfo_t si = { .si_status = EXIT_FAILURE };
+
+            const struct clone_args cl_args = {
+                .flags = CLONE_FS | CLONE_IO | CLONE_PTRACE | CLONE_SYSVSEM
+                                  | CLONE_CLEAR_SIGHAND
+                                  | CLONE_PARENT_SETTID | CLONE_VFORK,
+                .parent_tid = (uintptr_t)&si.si_pid,
+            };
+
+            switch (syscall(SYS_clone3, &cl_args, sizeof cl_args)) {
+            default:
+                while (waitid(P_PID, si.si_pid, &si, WEXITED) &&
+                       errno == EINTR) { }
+
+                if (si.si_code == CLD_EXITED && si.si_status == EXIT_SUCCESS) {
+                    break;
+                }
+            case -1:
+                continue;
+
+            case 0:
+                char cld_arg0[] = "plymouthd";
+                char cld_arg1[] = "--no-boot-log";
+                char *const cld_argv[] = { cld_arg0, cld_arg1, cld_arg2, NULL };
+
+                dup2(open(_PATH_DEVNULL, O_RDWR | O_CLOEXEC | O_NONBLOCK),
+                     STDERR_FILENO);
+
+                execv("/sbin/plymouthd", cld_argv);
+                syscall(SYS_exit, EXIT_FAILURE);
+            }
+        }
+
+        msg_cmd.msg = PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH;
+        ply_conv(2, msgs, &resp, NULL);
+        if (resp) {
+            free(resp->resp);
+            free(resp);
+        }
+
+        return ply_conv(num_msg, msgm, response, appdata_ptr);
+    } while (--tries);
+
+    return tui_conv(num_msg, msgm, response, appdata_ptr);
+}
+
+int misc_conv(int num_msg, const struct pam_message **msgm,
+              struct pam_response **response, void *appdata_ptr)
+{
+    static uint32_t mtx;
+    static int (*conv)(int, const struct pam_message **,
+                       struct pam_response **, void *) = tui_conv;
+
+    if (syscall(SYS_futex, &mtx, FUTEX_TRYLOCK_PI_PRIVATE)) {
+        syscall(SYS_futex, &mtx, FUTEX_WAIT_PRIVATE, 1, NULL);
+    } else {
+        if (getppid() == 1 && getenv("PWD")) {
+            struct pam_message msg_cmd = {
+                .msg_style = PAM_BINARY_PROMPT,
+                .msg = PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT "\2\2\1",
+            };
+
+            const struct pam_message *msgs[] = { &msg_cmd };
+            struct pam_response *resp = NULL;
+
+            char cl_stack[sysconf(_SC_PAGESIZE)];
+            struct clone_args cl_args = {
+                .flags = CLONE_FS | CLONE_IO | CLONE_PTRACE | CLONE_SYSVSEM
+                                  | CLONE_PARENT | CLONE_SIGHAND | CLONE_VM,
+                .stack = (uintptr_t)(cl_stack + sizeof cl_stack),
+                .stack_size = sizeof cl_stack,
+            };
+
+            switch (syscall(SYS_clone3, &cl_args, sizeof cl_args)) {
+            case 0:
+                const int fd = open(_PATH_WTMP, O_RDONLY | O_CLOEXEC);
+
+                syscall(SYS_exit, fcntl(fd, F_SETSIG, SIGCONT) ||
+                                  fcntl(fd, F_SETLEASE, F_RDLCK) ||
+                                  raise(SIGSTOP) ||
+                                  ply_conv(1, msgs, &resp, NULL) != PAM_SUCCESS
+                                  ? EXIT_FAILURE : EXIT_SUCCESS);
+                [[fallthrough]];
+            default:
+                conv = gui_conv;
+            case -1:
+                break;
+            }
+        }
+
+        mtx = 1;
+        syscall(SYS_futex, &mtx, FUTEX_WAKE, UINT32_MAX);
+    }
+
+    return conv(num_msg, msgm, response, appdata_ptr);
+}
+#endif /* USE_PLYMOUTH */
diff --git a/libpam_ply/help_socket.c b/libpam_ply/help_socket.c
new file mode 100644
index 00000000..8a2bba60
--- /dev/null
+++ b/libpam_ply/help_socket.c
@@ -0,0 +1,50 @@
+/*
+    Plymouth-based, PAM conversation function
+    Copyright (C) 2024-26  Mark A. Williams, Jr.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifdef PAM_DEBUG
+# include <err.h>
+#endif
+
+#include <security/pam_ply.h>
+
+static const char *const SOCKET_PATHV[] = {
+    PLY_BOOT_PROTOCOL_OLD_ABSTRACT_SOCKET_PATH,
+    PLY_BOOT_PROTOCOL_TRIMMED_ABSTRACT_SOCKET_PATH,
+};
+static const int SOCKET_TYPEV[] = {
+    PLY_UNIX_SOCKET_TYPE_ABSTRACT,
+    PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT,
+};
+
+inline int pam_ply_socket() {
+    int i = sizeof SOCKET_TYPEV / sizeof *SOCKET_TYPEV - 1;
+
+    do {
+        const int sockfd = ply_connect_to_unix_socket(SOCKET_PATHV[i],
+                                                      SOCKET_TYPEV[i]);
+
+	if (sockfd != -1)
+            return sockfd;
+    } while (i--);
+
+#ifdef PAM_DEBUG
+    warn("pam_ply_socket()");
+#endif
+    return -1;
+}
diff --git a/libpam_ply/include/security/meson.build b/libpam_ply/include/security/meson.build
new file mode 100644
index 00000000..49be3046
--- /dev/null
+++ b/libpam_ply/include/security/meson.build
@@ -0,0 +1 @@
+install_headers('pam_ply.h', install_dir: includedir)
diff --git a/libpam_ply/include/security/pam_ply.h b/libpam_ply/include/security/pam_ply.h
new file mode 100644
index 00000000..ff096943
--- /dev/null
+++ b/libpam_ply/include/security/pam_ply.h
@@ -0,0 +1,53 @@
+/*
+    Plymouth-based, PAM conversation function
+    Copyright (C) 2024-2  Mark A. Williams, Jr.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __PAMPLY_H
+#define __PAMPLY_H
+
+#include <plymouth-1/ply/ply-utils.h>
+#include <plymouth-1/ply-boot-client/ply-boot-protocol.h>
+
+#include <security/pam_appl.h>
+#include <security/pam_client.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* include some useful macros */
+
+#include <security/_pam_macros.h>
+
+/* functions defined in pam_ply.* libraries */
+
+extern int ply_conv(int num_msg, const struct pam_message **msgm,
+		    struct pam_response **response, void *appdata_ptr);
+
+/*
+ * Communication helper functions
+ */
+
+/* create an endpoint for communication (with plymouthd) */
+extern int pam_ply_socket();
+
+#ifdef __cplusplus
+}
+#endif /* def __cplusplus */
+
+#endif /* ndef __PAMPLY_H */
diff --git a/libpam_ply/libpam_ply.map b/libpam_ply/libpam_ply.map
new file mode 100644
index 00000000..262e16ef
--- /dev/null
+++ b/libpam_ply/libpam_ply.map
@@ -0,0 +1,8 @@
+LIBPAM_MISC_1.0 {
+  global:
+    ply_conv;
+    pam_ply_socket;
+
+  local:
+    *;
+};
diff --git a/libpam_ply/meson.build b/libpam_ply/meson.build
new file mode 100644
index 00000000..d7b8784c
--- /dev/null
+++ b/libpam_ply/meson.build
@@ -0,0 +1,40 @@
+subdir('include/security')
+
+libpam_ply_src = [
+  'help_socket.c',
+  'ply_conv.c',
+]
+
+libpam_ply_inc = include_directories('include')
+
+libpam_ply_version = '1.0.0'
+libpam_ply_map = 'libpam_ply.map'
+libpam_ply_map_path = meson.current_source_dir() / libpam_ply_map
+
+libpam_ply_link_deps = [libpam_ply_map]
+libpam_ply_link_args = ['-Wl,--version-script=' + libpam_ply_map_path]
+
+libpam_ply = shared_library(
+  'pam_ply',
+  sources: libpam_ply_src,
+  include_directories: [libpam_ply_inc, libpamc_inc],
+  dependencies: [libply_boot_client, libpam_internal_dep, libpam_dep],
+  link_depends: libpam_ply_link_deps,
+  link_args: libpam_ply_link_args,
+  version: libpam_ply_version,
+  install: true,
+)
+
+libpam_ply_dep = declare_dependency(
+  include_directories: [libpam_ply_inc],
+  link_with: [libpam_ply],
+)
+
+pkgconfig.generate(
+  libpam_ply,
+  description: 'PAM conversation function that uses Plymouth as its UX',
+  name: 'pam_ply',
+  filebase: 'pam_ply',
+  version: meson.project_version(),
+  url: 'http://www.linux-pam.org/'
+)
diff --git a/libpam_ply/ply_conv.c b/libpam_ply/ply_conv.c
new file mode 100644
index 00000000..54dff8a0
--- /dev/null
+++ b/libpam_ply/ply_conv.c
@@ -0,0 +1,229 @@
+/*
+    Plymouth-based, PAM conversation function
+    Copyright (C) 2024-26  Mark A. Williams, Jr.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifdef PAM_DEBUG
+# include <err.h>
+#endif
+#include <errno.h>
+#include <malloc.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+
+#include <security/pam_appl.h>
+#include <security/pam_ply.h>
+
+
+static ssize_t conv_send(const int sockfd,
+                          const struct pam_message *const msg) {
+    errno = EINVAL;
+
+    if (msg && msg->msg) do {
+        const char *s;
+
+        switch (msg->msg_style) {
+        case PAM_PROMPT_ECHO_OFF:
+            s = PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD;
+            break;
+
+        case PAM_PROMPT_ECHO_ON:
+            s = PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION;
+            break;
+
+        case PAM_ERROR_MSG:
+            s = PLY_BOOT_PROTOCOL_REQUEST_TYPE_ERROR;
+            break;
+
+        case PAM_TEXT_INFO:
+            s = PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_MESSAGE;
+            break;
+
+        case PAM_BINARY_PROMPT:
+            if (msg->msg[0]) {
+                ssize_t ret, len;
+
+                switch (msg->msg[1]) {
+                case '\0':
+                    ret = 0;
+                    len = 1;
+                    break;
+                case '\2':
+                    if ((ret = 2[(const unsigned char *)msg->msg])) {
+                        len = ret + 2;
+                        break;
+                    }
+                default:
+                    continue;
+                }
+
+                if (send(sockfd, msg->msg, len, MSG_MORE) == len &&
+                    send(sockfd, "", 1, 0) == 1) {
+                    return ret;
+                }
+            }
+        default:
+            continue;
+        }
+
+        if (send(sockfd, s, 1, MSG_MORE) == 1) {
+            const size_t len = strnlen(msg->msg, UINT8_MAX - 1);
+            const unsigned char dat[] = { '\2', len + 1 };
+
+            if (send(sockfd, dat, sizeof dat, MSG_MORE) == sizeof dat &&
+                send(sockfd, msg->msg, len, MSG_MORE) == (ssize_t)len &&
+                send(sockfd, "", 1, 0) == 1) {
+                    return dat[1];
+            }
+        }
+    } while(0);
+
+#ifdef PAM_DEBUG
+    warn("conv_send()");
+#endif
+    return -1;
+}
+
+static ssize_t conv_recv(const int sockfd, struct pam_response *const resp) {
+    union {
+        char ch;
+        void *p;
+    } res;
+
+    resp->resp_retcode = PAM_CONV_ERR;
+
+    if (recv(sockfd, &res.ch, 1, MSG_WAITALL) == 1) {
+        ssize_t ret = 0;
+
+        union {
+            int i;
+            uint32_t u32;
+            size_t n;
+        } len = { 0 };
+
+        while (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER
+               PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS
+               PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK
+               PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK
+               PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER[len.i] != res.ch) {
+            if (++len.i == 5) {
+                errno = EINVAL;
+                goto done;
+            }
+        }
+
+        switch (len.i) {
+        case 0:
+        case 1:
+            if (recv(sockfd, &len.u32, sizeof len.u32, MSG_WAITALL) == sizeof len.u32) {
+                if ((res.p = malloc((len.n = ret = len.u32) + 1))) {
+                    mlock(res.p, len.n);
+                    if (recv(sockfd, res.p, len.n, MSG_WAITALL) >= ret) {
+                        break;
+                    }
+                    munlock(res.p, len.n);
+                    free(res.p);
+                } else {
+                    resp->resp_retcode = PAM_BUF_ERR;
+                }
+            }
+            goto done;
+
+        case 2:
+            if ((res.p = aligned_alloc(sizeof(void *), 0))) {
+                break;
+            }
+            resp->resp_retcode = PAM_BUF_ERR;
+            goto done;
+
+        default:
+            res.p = NULL;
+            break;
+        }
+
+        resp->resp = res.p;
+        resp->resp_retcode = PAM_SUCCESS;
+        return ret;
+    }
+
+done:
+#ifdef PAM_DEBUG
+    warn("conv_recv()");
+#endif
+    return -1;
+}
+
+int ply_conv(const int num_msg, const struct pam_message **const msgv,
+             struct pam_response **const prespv, void *) {
+    int ret = PAM_SUCCESS;
+
+    mallopt(M_PERTURB, '\xFF');
+    do {
+        struct pam_response *const respv =
+            aligned_alloc(sizeof *respv, num_msg * sizeof *respv);
+
+        if (respv) {
+            const int sockfd = pam_ply_socket();
+
+            if (sockfd == -1) {
+                ret = PAM_CONV_ERR;
+            } else {
+                for (unsigned i = 0;;) {
+                    if ((unsigned)num_msg == i) {
+                        *prespv = respv;
+                        break;
+                    }
+
+                    struct pam_response *resp = respv + i;
+
+                    if (conv_send(sockfd, msgv[i++]) != -1 &&
+                        (conv_recv(sockfd, resp), resp->resp_retcode) != PAM_CONV_ERR) {
+                        if (resp->resp_retcode == PAM_BUF_ERR) {
+                            ret = PAM_BUF_ERR;
+                        }
+                        continue;
+                    }
+                    ret = PAM_CONV_ERR;
+
+                    do {
+                        free(resp->resp);
+                    } while (resp-- != respv);
+                    free(respv);
+
+                    break;
+                }
+
+                if (!close(sockfd)) {
+                    break;
+                }
+            }
+        } else {
+            ret = PAM_BUF_ERR;
+        }
+
+#ifdef PAM_DEBUG
+        warn("ply_conv()");
+#endif
+    } while (0);
+    mallopt(M_PERTURB, 0);
+
+    return ret;
+}
diff --git a/meson.build b/meson.build
index 123c88ed..e53da179 100644
--- a/meson.build
+++ b/meson.build
@@ -314,6 +314,11 @@ else
   stringparam_profileconditions += ';no_openssl_hmac'
 endif
 
+libply_boot_client = dependency('ply-boot-client', required: get_option('plymouth'))
+if libply_boot_client.found()
+  cdata.set('USE_PLYMOUTH', 1)
+endif
+
 use_logind = get_option('logind')
 use_elogind = get_option('elogind').require(not use_logind.enabled()).disable_auto_if(use_logind.enabled())
 use_logind = use_logind.disable_auto_if(use_elogind.enabled())
@@ -637,6 +642,9 @@ subdir('po')
 subdir('libpam_internal')
 subdir('libpam')
 subdir('libpamc')
+if libply_boot_client.found()
+  subdir('libpam_ply')
+endif
 subdir('libpam_misc')
 if enable_docs
   subdir('doc')
diff --git a/meson_options.txt b/meson_options.txt
index 35d979b5..9e36d43d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -20,6 +20,8 @@ option('selinux', type: 'feature', value: 'auto',
        description: 'SELinux support')
 option('nis', type: 'feature', value: 'auto',
        description: 'NIS/YP support in pam_unix')
+option('plymouth', type: 'feature', value: 'auto',
+       description: 'plymouth as GUI support in pam_misc via pam_ply')
 
 option('examples', type: 'boolean', value: true,
        description: 'Build examples')
openSUSE Build Service is sponsored by