[Xfce4-commits] <terminal:master> Improve handling shells and fix bug #6368.

Nick Schermer noreply at xfce.org
Thu May 20 21:56:02 CEST 2010


Updating branch refs/heads/master
         to a86b61bc54aaadeb36eb32fa7b288607511e6898 (commit)
       from 26cc2ed9d387932b3a4866d1406192a7ed879b58 (commit)

commit a86b61bc54aaadeb36eb32fa7b288607511e6898
Author: Nick Schermer <nick at xfce.org>
Date:   Thu May 20 21:43:42 2010 +0200

    Improve handling shells and fix bug #6368.
    
    Add more fallback shells and use $SHELL before the shell
    defined in the password database. Also add checks if the
    shell is executable before settings the command.

 terminal/terminal-screen.c |   74 +++++++++++++++++++++++++++++++------------
 1 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/terminal/terminal-screen.c b/terminal/terminal-screen.c
index 208781a..0333206 100644
--- a/terminal/terminal-screen.c
+++ b/terminal/terminal-screen.c
@@ -51,6 +51,7 @@
 #if defined(GDK_WINDOWING_X11)
 #include <gdk/gdkx.h>
 #endif
+#include <glib/gstdio.h>
 
 
 
@@ -464,9 +465,16 @@ terminal_screen_get_child_command (TerminalScreen   *screen,
                                    GError          **error)
 {
   struct passwd *pw;
-  const gchar   *shell_name = NULL;
-  const gchar   *shell_fullpath;
+  const gchar   *shell_name;
+  const gchar   *shell_fullpath = NULL;
   gboolean       command_login_shell;
+  guint          i;
+  const gchar   *shells[] = { "/bin/sh",
+                              "/bin/bash", "/usr/bin/bash",
+                              "/bin/dash", "/usr/bin/dash",
+                              "/bin/zsh",  "/usr/bin/zsh",
+                              "/bin/tcsh", "/usr/bin/tcsh",
+                              "/bin/ksh",  "/usr/bin/ksh" };
 
   if (screen->custom_command != NULL)
     {
@@ -475,31 +483,51 @@ terminal_screen_get_child_command (TerminalScreen   *screen,
     }
   else
     {
-      pw = getpwuid (getuid ());
-      if (G_UNLIKELY (pw == NULL))
+      /* use the SHELL environement variable if we're in
+       * non-setuid mode and the path is executable */
+      if (geteuid () == getuid ()
+          && getegid () == getgid ())
         {
-          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
-                       _("Unable to determine your login shell."));
-          return FALSE;
+          shell_fullpath = g_getenv ("SHELL");
+          if (shell_fullpath != NULL
+              && g_access (shell_fullpath, X_OK) != 0)
+            shell_fullpath = NULL;
         }
 
-      g_object_get (G_OBJECT (screen->preferences),
-                    "command-login-shell", &command_login_shell,
-                    NULL);
-
-
-      if (pw->pw_shell == NULL || *(pw->pw_shell) == 0)
+      if (shell_fullpath == NULL)
         {
-          shell_fullpath = g_getenv ("SHELL");
-          if (shell_fullpath == NULL)
-            /* the very last fallback */
-            shell_fullpath = "/bin/sh";
+          pw = getpwuid (getuid ());
+          if (pw != NULL
+              && pw->pw_shell != NULL
+              && g_access (pw->pw_shell, X_OK) == 0)
+            {
+              /* set the shell from the password database */
+              shell_fullpath = pw->pw_shell;
+            }
+          else
+            {
+              /* lookup a good fallback */
+              for (i = 0; i < G_N_ELEMENTS (shells); i++)
+                {
+                  if (access (shells [i], X_OK) == 0)
+                    {
+                      shell_fullpath = shells [i];
+                      break;
+                    }
+                }
+
+              if (G_UNLIKELY (shell_fullpath == NULL))
+                {
+                  /* the system is truly broken */
+                  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
+                               _("Unable to determine your login shell."));
+                  return FALSE;
+                }
+            }
         }
-      else
-        shell_fullpath = pw->pw_shell;
 
-      if (shell_fullpath != NULL)
-        shell_name = strrchr (shell_fullpath, '/');
+      terminal_assert (shell_fullpath != NULL);
+      shell_name = strrchr (shell_fullpath, '/');
 
       if (shell_name != NULL)
         ++shell_name;
@@ -507,6 +535,10 @@ terminal_screen_get_child_command (TerminalScreen   *screen,
         shell_name = shell_fullpath;
       *command = g_strdup (shell_fullpath);
 
+      g_object_get (G_OBJECT (screen->preferences),
+                    "command-login-shell", &command_login_shell,
+                    NULL);
+
       *argv = g_new (gchar *, 2);
       if (command_login_shell)
         (*argv)[0] = g_strconcat ("-", shell_name, NULL);



More information about the Xfce4-commits mailing list