changeset 1008:a55854bde872

su: cleanery * make help message more like others * s/TT\.(.)Argu/TT.\1/g * move environ to toys.h * simplify failure messages * clear password before quit * not check what execve returns * -lc
author Strake <strake888@gmail.com>
date Sat, 17 Aug 2013 02:54:58 -0500
parents c05343c592fa
children ad4d2e8dc7c3
files toys.h toys/pending/su.c
diffstat 2 files changed, 25 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/toys.h	Fri Aug 16 14:46:52 2013 -0500
+++ b/toys.h	Sat Aug 17 02:54:58 2013 -0500
@@ -117,6 +117,8 @@
 
 extern char toybuf[4096];
 
+extern char **environ;
+
 #define GLOBALS(...)
 
 #define ARRAY_LEN(array) (sizeof(array)/sizeof(*array))
--- a/toys/pending/su.c	Fri Aug 16 14:46:52 2013 -0500
+++ b/toys/pending/su.c	Sat Aug 17 02:54:58 2013 -0500
@@ -10,7 +10,7 @@
   bool "su"
   default n
   help
-    usage: su [-lmp] [-c cmd] [-s shell] [user [argu...]]
+    usage: su [-lmp] [-c CMD] [-s SHELL] [USER [ARGS...]]
 
     Switch to given user, or root if not given, and call a shell with the given arguments.
 
@@ -27,12 +27,10 @@
 #include "toys.h"
 
 GLOBALS(
-  char *sArgu;
-  char *cArgu;
+  char *s;
+  char *c;
 )
 
-extern char **environ;
-
 static void deny () {
   printf ("Denied\n");
   xexit ();
@@ -55,7 +53,7 @@
   }
   else name = "root";
   shp = getspnam (name);
-  if (!shp) perror_exit ("failed to find password");
+  if (!shp) perror_exit ("can't find password");
 
   switch (shp -> sp_pwdp[0]) {
   case '!': deny ();
@@ -63,36 +61,37 @@
   default : error_exit ("bad password format");
   }
 
-  if (read_password (toybuf, sizeof (toybuf), "Password: ") != 0) perror_exit ("failed to read password");
+  if (read_password (toybuf, sizeof (toybuf), "Password: ") != 0) perror_exit ("can't read password");
 
   passhash = crypt (toybuf, shp -> sp_pwdp);
-  if (!passhash) perror_exit ("failed to compute password hash");
   for (ii = 0; toybuf[ii]; ii++) toybuf[ii] = 0;
+  if (!passhash) perror_exit ("can't crypt");
 
   if (strcmp (passhash, shp -> sp_pwdp) != 0) deny ();
 
   up = getpwnam (name);
-  if (!up) perror_exit ("failed to getpwnam");
+  if (!up) perror_exit ("can't getpwnam");
 
-  if (setuid (up -> pw_uid) < 0) perror_exit ("failed to setuid");
-  if (chdir  (up -> pw_dir) < 0) perror_exit ("failed to chdir");
+  xsetuid (up -> pw_uid);
+  xchdir  (up -> pw_dir);
 
   argu = xmalloc (sizeof (char *)*(toys.optc + 4));
   argv = argu;
-  argv[0] = toys.optflags & FLAG_s ? TT.sArgu : up -> pw_shell;
+  argv[0] = toys.optflags & FLAG_s ? TT.s : up -> pw_shell;
+  if (toys.optflags & FLAG_l) (argv++)[1] = "-l";
   if (toys.optflags & FLAG_c) {
-    argv[1] = toys.optflags & FLAG_l ? "-lc" : "-c";
-    argv[2] = TT.cArgu;
+    argv[1] = "-c";
+    argv[2] = TT.c;
     argv += 2;
   }
-  else if (toys.optflags & FLAG_l) (argv++)[1] = "-l";
-  for (ii = 0; ii < toys.optc; ii++) argv[ii + 1] = toys.optargs[ii];
-  if (execve (argu[0], argu,
-              toys.optflags & FLAG_l ? (char *[]){
-                xmsprintf ( "HOME=%s", up -> pw_dir),
-                xmsprintf ("SHELL=%s", up -> pw_shell),
-                xmsprintf ( "USER=%s", up -> pw_name),
-                xmsprintf ( "TERM=%s", getenv ("TERM")),
-                0
-              } : environ) < 0) perror_exit ("failed to exec %s", argu[0]);
+  memcpy (argv + 1, toys.optargs, sizeof (char *)*toys.optc);
+  execve (argu[0], argu,
+          toys.optflags & FLAG_l ? (char *[]){
+            xmsprintf ( "HOME=%s", up -> pw_dir),
+            xmsprintf ("SHELL=%s", up -> pw_shell),
+            xmsprintf ( "USER=%s", up -> pw_name),
+            xmsprintf ( "TERM=%s", getenv ("TERM")),
+            0
+          } : environ);
+  perror_exit ("can't exec %s", argu[0]);
 }