bug-sysutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-sysutils] argp patch for passwd


From: Barry deFreese
Subject: [Bug-sysutils] argp patch for passwd
Date: Wed, 02 Jun 2004 20:08:05 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5

OK, here is the argp stuff for passwd. I also found a bug. When the user is asked to enter the two new passwords, it was checking if (same) so when the user was correctly entering the same password twice it was erroring. I changed this to if (!same).

Let me know how this looks.

PS: I got my assignment confirmation back from FSF.. w00t. :-)

Thanks as always,

--
Barry deFreese
Debian 3.0r1 "Woody"
GNU/Hurd
Registered Linux "Newbie" #302256 - Hurd H4XX0r wannabe

"Programming today is a race between software engineers striving
to build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots. So far, the Universe is
winning." Rich Cook.



Index: src/passwd.c
===================================================================
RCS file: /cvsroot/sysutils/sysutils/src/passwd.c,v
retrieving revision 1.3
diff -u -p -r1.3 passwd.c
--- src/passwd.c        27 May 2004 07:50:33 -0000      1.3
+++ src/passwd.c        3 Jun 2004 03:53:56 -0000
@@ -19,6 +19,7 @@
  *  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <argp.h>
 #include <pwd.h>
 #include <grp.h>
 #include <errno.h>
@@ -32,27 +33,70 @@
 
 #define PRG_NAME "passwd"
 
-extern int optind;
-extern char *optarg;
 extern const char *progname;
 
-/**
- * Show usage information
- */
-static void usage(void)
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
+static char doc[] =
+       N_("Change the password of the specified user or group. "
+          "\n"
+          "If no name is specified, "
+          "the password of the current user is changed. ");
+
+static char args_doc[] = N_("USER | GROUP");
+
+static struct argp_option options[] = {
+       {"remove-password", 'd', 0, OPTION_ARG_OPTIONAL,
+         N_("make the password empty"), 0 },
+       {"group", 'g', 0, OPTION_ARG_OPTIONAL,
+         N_("change group-password instead "
+            "of user-password"), 0, },
+       { 0, 0, 0, 0, 0, 0 }
+};
+
+
+/* Available arguments */
+struct arguments {
+       char *username;
+       long removepass;
+       long group;
+};
+
+/* Parse a single option */
+static error_t parse_opt(int key, char *arg, struct argp_state *state)
 {
-       fprintf(stdout,
-               _("Usage: %s [OPTION]... [NAME]\n"
-                 "Change the password of the specified user or group.\n"
-                 "\n"
-                 "If no name is specified, "
-                 "the password of the current user is changed.\n"
-                 "\n"
-                 "  -d, --remove-password  make the password empty\n"
-                 "  -g, --group            change group-password instead "
-                 "of user-password\n"),
-               progname);
-       usage_help();
+       struct arguments *args = state->input;
+
+       switch (key) {
+       case 'd':
+               args->removepass = 1;
+               break;
+
+       case 'g':
+               args->group = 1;
+               break;
+
+       case ARGP_KEY_INIT:
+               args->username = NULL;
+               args->removepass = 0;
+               args->group = 0;
+               break;
+
+       case ARGP_KEY_NO_ARGS:
+               argp_usage(state);
+               break;
+
+       case ARGP_KEY_ARG:
+               if (args->username)
+                       argp_usage(state);
+
+               args->username = arg;
+               break;
+
+       default:
+               return ARGP_ERR_UNKNOWN;
+       }
+       return 0;
 }
 
 /**
@@ -73,10 +117,6 @@ int main(int argc, char *argv[])
        int locked = 0;
 
        int group = 0;
-       int remove_password = 0;
-
-       int optc;
-       int opt_index;
 
        int status = 0;
 
@@ -89,65 +129,25 @@ int main(int argc, char *argv[])
        char *wname = NULL;
        char *bname = NULL;
 
-       struct option const options[] = {
-               { "group", no_argument, 0, 'g', },
-               { "remove-password", no_argument, 0, 'd' },
-               { "help", no_argument, 0, 'h' },
-               { "version", no_argument, 0, 'V' },
-               { 0, 0, 0, 0 }
+       /* argp parser */
+       struct argp argp = {
+               options, parse_opt, args_doc, doc, NULL, NULL, NULL
        };
 
+       struct arguments args;
+
+       argp_program_version_hook = version;
+
        errno = 0;
 
        /* Initialise support for locales, and set the program-name */
        if ((status = init_locales(PRG_NAME)))
                goto EXIT;
 
-       /* Parse the command-line options */
-       while ((optc = getopt_long(argc, argv, "dg",
-                                  options, &opt_index)) != -1) {
-               switch (optc) {
-               case 'd':
-                       remove_password = 1;
-                       break;
-
-               case 'g':
-                       group = 1;
-                       break;
+       set_author_information(_("Written by David Weinehall.\n"));
 
-               case 'h':
-                       usage();
-                       goto EXIT;
-
-               case 'V':
-                       version();
-                       goto EXIT;
-
-               default:
-                       usage();
-                       status = EINVAL;
-                       goto EXIT;
-               }
-       }
-
-       /* Make sure we get the correct number of arguments */
-       if ((argc - optind) > 1) {
-               fprintf(stderr,
-                       _("%s: too many arguments\n"
-                         "Try `%s --help' for more information.\n"),
-                       progname, progname);
-               status = EINVAL;
-               goto EXIT;
-       }
-
-       if (group && (argc - optind) < 1) {
-               fprintf(stderr,
-                       _("%s: too few arguments\n"
-                         "Try `%s --help' for more information.\n"),
-                       progname, progname);
-               status = EINVAL;
-               goto EXIT;
-       }
+       /* Parse command line */
+       argp_parse(&argp, argc, argv, 0, 0, &args);
 
        /* Check if the caller has root privileges */
        if ((status = is_useradmin())) {
@@ -166,8 +166,8 @@ int main(int argc, char *argv[])
        /* If an argument is supplied, it is the name
         * of the user or group to change the password of
         */
-       if (optind != argc) {
-               if (!(name = strdup(argv[optind]))) {
+       if (args.username) {
+               if (!(name = strdup(args.username))) {
                        fprintf(stderr,
                                _("%s: `%s' failed; %s\n"),
                                progname, "strdup()", strerror(errno));
@@ -203,7 +203,7 @@ int main(int argc, char *argv[])
                        status = EPERM;
                        goto EXIT;
                }
-       } else if (group) {
+       } else if (args.group) {
                int retval = is_groupadmin(name);
 
                if (retval == -1) {
@@ -219,11 +219,11 @@ int main(int argc, char *argv[])
                }
        }
 
-       if (!group) {
+       if (!args.group) {
                /* If no username was provided, retrieve the name
                 * of the caller of the program
                 */
-               if (!name) {
+               if (!args.username) {
                        if (!(name = get_username(getuid()))) {
                                status = errno;
                                goto EXIT;
@@ -283,7 +283,7 @@ int main(int argc, char *argv[])
        if ((locked = is_password_locked(spassword)))
                spassword++;
 
-       if (!remove_password) {
+       if (!args.removepass) {
                /* Note: from this point on we know that name is valid,
                 * since it existed in the user or group database, hence we
                 * can print it without fear if we want to
@@ -374,7 +374,7 @@ int main(int argc, char *argv[])
 
                                memset(spassword, 0, strlen(spassword));
                                goto EXIT;
-                       } else if (same) {
+                       } else if (!same) {
                                fprintf(stderr,
                                        _("Password unchanged\n"));
                                memset(newpassword, 0, strlen(newpassword));

reply via email to

[Prev in Thread] Current Thread [Next in Thread]