(WRITTEN_BY): Rename from AUTHORS.
[platform/upstream/coreutils.git] / src / su.c
index ee31eaf..94594b2 100644 (file)
--- a/src/su.c
+++ b/src/su.c
@@ -1,5 +1,5 @@
 /* su for GNU.  Run a shell with substitute user and group IDs.
-   Copyright (C) 1992-2000 Free Software Foundation, Inc.
+   Copyright (C) 1992-2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -82,7 +82,7 @@
 #define getusershell _getusershell_sys_proto_
 
 #include "system.h"
-#include "closeout.h"
+#include "dirname.h"
 
 #undef getusershell
 
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "su"
 
-#define AUTHORS "David MacKenzie"
+#define WRITTEN_BY _("Written by David MacKenzie.")
 
 #if HAVE_PATHS_H
 # include <paths.h>
@@ -147,8 +147,6 @@ char *getusershell ();
 void endusershell ();
 void setusershell ();
 
-char *base_name ();
-
 extern char **environ;
 
 static void run_shell (const char *, const char *, char **)
@@ -181,7 +179,7 @@ static struct option const longopts[] =
 /* Add VAL to the environment, checking for out of memory errors.  */
 
 static void
-xputenv (const char *val)
+xputenv (char *val)
 {
   if (putenv (val))
     xalloc_die ();
@@ -194,7 +192,7 @@ static char *
 concat (const char *s1, const char *s2, const char *s3)
 {
   int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
-  char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
+  char *result = xmalloc (len1 + len2 + len3 + 1);
 
   strcpy (result, s1);
   strcpy (result + len1, s2);
@@ -311,7 +309,7 @@ modify_environment (const struct passwd *pw, const char *shell)
       /* Leave TERM unchanged.  Set HOME, SHELL, USER, LOGNAME, PATH.
          Unset all other environment variables.  */
       term = getenv ("TERM");
-      environ = (char **) xmalloc (2 * sizeof (char *));
+      environ = xmalloc (2 * sizeof (char *));
       environ[0] = 0;
       if (term)
        xputenv (concat ("TERM", "=", term));
@@ -348,13 +346,13 @@ change_identity (const struct passwd *pw)
 #ifdef HAVE_INITGROUPS
   errno = 0;
   if (initgroups (pw->pw_name, pw->pw_gid) == -1)
-    error (1, errno, _("cannot set groups"));
+    error (EXIT_FAILURE, errno, _("cannot set groups"));
   endgrent ();
 #endif
   if (setgid (pw->pw_gid))
-    error (1, errno, _("cannot set group id"));
+    error (EXIT_FAILURE, errno, _("cannot set group id"));
   if (setuid (pw->pw_uid))
-    error (1, errno, _("cannot set user id"));
+    error (EXIT_FAILURE, errno, _("cannot set user id"));
 }
 
 /* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
@@ -369,10 +367,10 @@ run_shell (const char *shell, const char *command, char **additional_args)
   int argno = 1;
 
   if (additional_args)
-    args = (const char **) xmalloc (sizeof (char *)
+    args = xmalloc (sizeof (char *)
                                    * (10 + elements (additional_args)));
   else
-    args = (const char **) xmalloc (sizeof (char *) * 10);
+    args = xmalloc (sizeof (char *) * 10);
   if (simulate_login)
     {
       char *arg0;
@@ -398,8 +396,12 @@ run_shell (const char *shell, const char *command, char **additional_args)
       args[argno++] = *additional_args;
   args[argno] = NULL;
   execv (shell, (char **) args);
-  error (0, errno, _("cannot run %s"), shell);
-  exit (1);
+
+  {
+    int exit_status = (errno == ENOENT ? 127 : 126);
+    error (0, errno, "%s", shell);
+    exit (exit_status);
+  }
 }
 
 /* Return 1 if SHELL is a restricted shell (one not returned by
@@ -432,7 +434,7 @@ usage (int status)
   else
     {
       printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
-      printf (_("\
+      fputs (_("\
 Change the effective user id and group id to that of USER.\n\
 \n\
   -, -l, --login               make the shell a login shell\n\
@@ -441,13 +443,14 @@ Change the effective user id and group id to that of USER.\n\
   -m, --preserve-environment   do not reset environment variables\n\
   -p                           same as -m\n\
   -s, --shell=SHELL            run SHELL if /etc/shells allows it\n\
-      --help                   display this help and exit\n\
-      --version                output version information and exit\n\
+"), stdout);
+      fputs (HELP_OPTION_DESCRIPTION, stdout);
+      fputs (VERSION_OPTION_DESCRIPTION, stdout);
+      fputs (_("\
 \n\
 A mere - implies -l.   If USER not given, assume root.\n\
-"));
-      puts (_("\nReport bugs to <bug-sh-utils@gnu.org>."));
-      close_stdout ();
+"), stdout);
+      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     }
   exit (status);
 }
@@ -463,11 +466,14 @@ main (int argc, char **argv)
   struct passwd *pw;
   struct passwd pw_copy;
 
+  initialize_main (&argc, &argv);
   program_name = argv[0];
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
+  atexit (close_stdout);
+
   fast_startup = 0;
   simulate_login = 0;
   change_environment = 1;
@@ -502,10 +508,10 @@ main (int argc, char **argv)
 
        case_GETOPT_HELP_CHAR;
 
-       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, WRITTEN_BY);
 
        default:
-         usage (1);
+         usage (EXIT_FAILURE);
        }
     }
 
@@ -521,7 +527,7 @@ main (int argc, char **argv)
 
   pw = getpwnam (new_user);
   if (pw == 0)
-    error (1, 0, _("user %s does not exist"), new_user);
+    error (EXIT_FAILURE, 0, _("user %s does not exist"), new_user);
   endpwent ();
 
   /* Make sure pw->pw_shell is non-NULL.  It may be NULL when NEW_USER
@@ -544,7 +550,7 @@ main (int argc, char **argv)
 #ifdef SYSLOG_FAILURE
       log_su (pw, 0);
 #endif
-      error (1, 0, _("incorrect password"));
+      error (EXIT_FAILURE, 0, _("incorrect password"));
     }
 #ifdef SYSLOG_SUCCESS
   else