summaryrefslogtreecommitdiffstats
path: root/lib/shells.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/shells.c')
-rw-r--r--lib/shells.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/shells.c b/lib/shells.c
new file mode 100644
index 0000000..6693ab0
--- /dev/null
+++ b/lib/shells.c
@@ -0,0 +1,74 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include <sys/syslog.h>
+#if defined (HAVE_LIBECONF) && defined (USE_VENDORDIR)
+#include <libeconf.h>
+#endif
+
+#include "closestream.h"
+#include "shells.h"
+
+/*
+ * is_known_shell() -- if the given shell appears in /etc/shells
+ * or vendor defined files.
+ * Return 1 if found and return 0 if not found.
+ */
+extern int is_known_shell(const char *shell_name)
+{
+ int ret = 0;
+
+#if defined (HAVE_LIBECONF) && defined (USE_VENDORDIR)
+ size_t size = 0;
+ econf_err error;
+ char **keys;
+ econf_file *key_file;
+
+ error = econf_readDirs(&key_file,
+ _PATH_VENDORDIR,
+ "/etc",
+ "shells",
+ NULL,
+ "", /* key only */
+ "#" /* comment */);
+ if (error) {
+ syslog(LOG_ALERT,
+ _("Cannot parse shells files: %s"),
+ econf_errString(error));
+ exit(EXIT_FAILURE);
+ }
+
+ error = econf_getKeys(key_file, NULL, &size, &keys);
+ if (error) {
+ syslog(LOG_ALERT,
+ _("Cannot evaluate entries in shells files: %s"),
+ econf_errString(error));
+ econf_free (key_file);
+ exit(EXIT_FAILURE);
+ }
+
+ for (size_t i = 0; i < size; i++) {
+ if (strcmp (keys[i], shell_name) == 0) {
+ ret = 1;
+ break;
+ }
+ }
+ econf_free (key_file);
+#else
+ char *s;
+
+ if (!shell_name)
+ return 0;
+
+ setusershell();
+ while ((s = getusershell())) {
+ if (*s != '#' && strcmp(shell_name, s) == 0) {
+ ret = 1;
+ break;
+ }
+ }
+ endusershell();
+#endif
+ return ret;
+}
+