Revert "su.c: replace getopt with ad-hoc flag processing"
This reverts commit dc732e7734
.
This commit is contained in:
109
src/su.c
109
src/su.c
@@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -94,7 +95,6 @@ static bool doshell = false;
|
|||||||
static bool fakelogin = false;
|
static bool fakelogin = false;
|
||||||
static /*@observer@*/const char *shellstr;
|
static /*@observer@*/const char *shellstr;
|
||||||
static /*@null@*/char *command = NULL;
|
static /*@null@*/char *command = NULL;
|
||||||
static int optidx;
|
|
||||||
|
|
||||||
|
|
||||||
/* not needed by sulog.c anymore */
|
/* not needed by sulog.c anymore */
|
||||||
@@ -760,48 +760,6 @@ static void save_caller_context (char **argv)
|
|||||||
pw_free (pw);
|
pw_free (pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* flags_match - test arg against flag candidates
|
|
||||||
*/
|
|
||||||
static bool flags_match(const char *arg, const char *a, const char *b, const char *c)
|
|
||||||
{
|
|
||||||
return (a != NULL && strcmp (arg, a) == 0) ||
|
|
||||||
(b != NULL && strcmp (arg, b) == 0) ||
|
|
||||||
(c != NULL && strcmp (arg, c) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* is_flag_like - test if arg resembles a flag
|
|
||||||
*
|
|
||||||
* lone "--" and bare leading-hyphen-less words are not flag-like,
|
|
||||||
* everything else is considered a probable flag.
|
|
||||||
*/
|
|
||||||
static bool is_flag_like(const char *arg)
|
|
||||||
{
|
|
||||||
if (arg[0] != '-')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (strcmp (arg, "--") == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void flag_arg_required(const char *arg)
|
|
||||||
{
|
|
||||||
fprintf (stderr,
|
|
||||||
_("%s: option \'%s\' requires an argument\n"),
|
|
||||||
Prog, arg);
|
|
||||||
usage (E_USAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void flag_unknown(const char *arg)
|
|
||||||
{
|
|
||||||
fprintf (stderr,
|
|
||||||
_("%s: unrecognized option \'%s\'\n"),
|
|
||||||
Prog, arg);
|
|
||||||
usage (E_BAD_ARG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* process_flags - Process the command line arguments
|
* process_flags - Process the command line arguments
|
||||||
*
|
*
|
||||||
@@ -811,41 +769,51 @@ static void flag_unknown(const char *arg)
|
|||||||
*/
|
*/
|
||||||
static void process_flags (int argc, char **argv)
|
static void process_flags (int argc, char **argv)
|
||||||
{
|
{
|
||||||
for (optidx = 1; optidx < argc; optidx++) {
|
int c;
|
||||||
const char *arg = argv[optidx];
|
static struct option long_options[] = {
|
||||||
|
{"command", required_argument, NULL, 'c'},
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{"login", no_argument, NULL, 'l'},
|
||||||
|
{"preserve-environment", no_argument, NULL, 'p'},
|
||||||
|
{"shell", required_argument, NULL, 's'},
|
||||||
|
{NULL, 0, NULL, '\0'}
|
||||||
|
};
|
||||||
|
|
||||||
if (flags_match (arg, "--command", "-c", NULL)) {
|
while ((c = getopt_long (argc, argv, "c:hlmps:",
|
||||||
if (optidx == argc - 1) {
|
long_options, NULL)) != -1) {
|
||||||
flag_arg_required (arg);
|
switch (c) {
|
||||||
}
|
case 'c':
|
||||||
|
command = optarg;
|
||||||
command = argv[++optidx];
|
break;
|
||||||
} else if (flags_match (arg, "--help", "-h", NULL)) {
|
case 'h':
|
||||||
usage (E_SUCCESS);
|
usage (E_SUCCESS);
|
||||||
} else if (flags_match (arg, "--login", "-l", "-")) {
|
break;
|
||||||
|
case 'l':
|
||||||
fakelogin = true;
|
fakelogin = true;
|
||||||
} else if (flags_match (arg, "--preserve-environment", "-p", "-m")) {
|
break;
|
||||||
|
case 'm':
|
||||||
|
case 'p':
|
||||||
/* This will only have an effect if the target
|
/* This will only have an effect if the target
|
||||||
* user do not have a restricted shell, or if
|
* user do not have a restricted shell, or if
|
||||||
* su is called by root.
|
* su is called by root.
|
||||||
*/
|
*/
|
||||||
change_environment = false;
|
change_environment = false;
|
||||||
} else if (flags_match (arg, "--shell", "-s", NULL)) {
|
|
||||||
if (optidx == argc - 1) {
|
|
||||||
flag_arg_required (arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
shellstr = argv[++optidx];
|
|
||||||
} else if (is_flag_like (arg)) {
|
|
||||||
flag_unknown (arg);
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
shellstr = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage (E_USAGE); /* NOT REACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if next arg is not "--", treat as USER */
|
if ((optind < argc) && (strcmp (argv[optind], "-") == 0)) {
|
||||||
if (optidx < argc && strcmp (argv[optidx], "--")) {
|
fakelogin = true;
|
||||||
STRFCPY (name, argv[optidx++]); /* use this login id */
|
optind++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind < argc) {
|
||||||
|
STRFCPY (name, argv[optind++]); /* use this login id */
|
||||||
}
|
}
|
||||||
if ('\0' == name[0]) { /* use default user */
|
if ('\0' == name[0]) { /* use default user */
|
||||||
struct passwd *root_pw = getpwnam ("root");
|
struct passwd *root_pw = getpwnam ("root");
|
||||||
@@ -861,12 +829,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if more and next arg is "--", skip it and leave rest as-is */
|
doshell = (argc == optind); /* any arguments remaining? */
|
||||||
if (optidx < argc && strcmp (argv[optidx], "--") == 0) {
|
|
||||||
optidx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
doshell = (argc == optidx); /* any arguments remaining? */
|
|
||||||
if (NULL != command) {
|
if (NULL != command) {
|
||||||
doshell = false;
|
doshell = false;
|
||||||
}
|
}
|
||||||
@@ -1215,7 +1178,7 @@ int main (int argc, char **argv)
|
|||||||
if (!doshell) {
|
if (!doshell) {
|
||||||
int err;
|
int err;
|
||||||
/* Position argv to the remaining arguments */
|
/* Position argv to the remaining arguments */
|
||||||
argv += optidx;
|
argv += optind;
|
||||||
if (NULL != command) {
|
if (NULL != command) {
|
||||||
argv -= 2;
|
argv -= 2;
|
||||||
argv[0] = "-c";
|
argv[0] = "-c";
|
||||||
|
Reference in New Issue
Block a user