bug-sysutils
[Top][All Lists]
Advanced

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

[Bug-sysutils] argp patch for chfn.c


From: Barry deFreese
Subject: [Bug-sysutils] argp patch for chfn.c
Date: Fri, 28 May 2004 20:30:53 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5

OK, here are the argp updates for chfn.

Thank you,

--
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/chfn.c
===================================================================
RCS file: /cvsroot/sysutils/sysutils/src/chfn.c,v
retrieving revision 1.3
diff -u -p -r1.3 chfn.c
--- src/chfn.c  27 May 2004 07:50:32 -0000      1.3
+++ src/chfn.c  29 May 2004 04:18:11 -0000
@@ -20,6 +20,7 @@
  *  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <argp.h>
 #include <pwd.h>
 #include <errno.h>
 #include <stdio.h>
@@ -34,40 +35,105 @@
 
 static unsigned int chperms = 0;
 
-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 full name and other information for a user."
+               "\n"
+               "If no username is specified, "
+               "the information for the current user is changed.");
+
+static char args_doc[] = N_("[USER]");
+
+static struct argp_option options[] = {
+       {"fname", 'f', N_("NAME"), 0,
+         N_("the user's full name"), 0 },
+       {"room", 'r', N_("ROOM"), 0,
+         N_("the user's room number"), 0 },
+       {"wphone", 'w', N_("PHONE#"), 0,
+         N_("the user's work phone"), 0 },
+       {"hphone", 'h', N_("PHONE#"), 0,
+         N_("the user's home phone"), 0 },
+       {"other", 'o', N_("OTHER"), 0,
+         N_("other information for the user"), 0},
+       { 0, 0, 0, 0, 0, 0 }
+};
+
+/* Available arguments */
+struct arguments {
+       char *user;
+       char *fname;
+       char *room;
+       char *wphone;
+       char *hphone;
+       char *other;
+};
+
+/* parse a single option */
+static error_t parse_opt(int key, char *arg, struct argp_state *state)
 {
-       fprintf(stdout,
-               _("Usage: %s [OPTION]... [USER]\n"
-                 "Change full name and other information for a user.\n"
-                 "\n"
-                 "If no username is specified, "
-                 "the information for the current user is changed.\n"
-                 "\n"
-                 "%s"
-                 "%s"
-                 "%s"
-                 "%s"
-                 "%s"),
-               progname,
-               (chperms & CH_FNAME) ?
-               _("  -f, --fname=STRING     the user's full name\n") : "",
-               (chperms & CH_HPHONE) ?
-               _("  -h, --hphone=STRING    the user's home phone\n") : "",
-               (chperms & CH_OTHER) ?
-               _("  -o, --other=STRING     other information for the "
-                 "user\n") : "",
-               (chperms & CH_ROOM) ?
-               _("  -r, --room=STRING      the user's room number\n") : "",
-               (chperms & CH_WPHONE) ?
-               _("  -w, --wphone=STRING    the user's work phone\n") : ""),
-       usage_help();
+       struct arguments *args = state->input;
+
+       switch(key) {
+       case 'f':
+               if (is_valid_gecos_field(arg)) {
+                       argp_error(state, "Invalid value supplied");
+               } else {
+                       args->fname = arg;
+                       break;
+               }
+               
+       case 'r':
+               if (is_valid_gecos_field(arg)) {
+                       argp_error(state, "Invalid value supplied.");
+               } else {
+                       args->room = arg;
+                       break;
+               }
+
+       case 'w':
+               if (is_valid_gecos_field(arg)) {
+                       argp_error(state, "Invalid value supplied.");
+               } else {
+                       args->wphone = arg;
+                       break;
+               }
+
+       case 'h':
+               if (is_valid_gecos_field(arg)) {
+                       argp_error(state, "Invalid value supplied.");
+               } else {
+                       args->hphone = arg;
+                       break;
+               }
+
+       case 'o':
+               if (is_valid_gecos_field(arg)) {
+                       argp_error(state, "Invalid value supplied.");
+               } else {
+                       args->other = arg;
+                       break;
+               }
+
+       case ARGP_KEY_INIT:
+               args->user = NULL;
+               args->fname = NULL;
+               args->room = NULL;
+               args->wphone = NULL;
+               args->hphone = NULL;
+               args->other = NULL;
+               break;
+
+       case ARGP_KEY_ARG:
+               args->user = arg;
+               break;
+
+       default:
+               return ARGP_ERR_UNKNOWN;
+       }
+       return 0;
 }
 
 /**
@@ -85,35 +151,24 @@ int main(int argc, char *argv[])
 
        int empty = 1;
 
-       int optc;
-       int opt_index;
-
        int status = 0;
        int isadmin = 0;
 
        char *pwwname = NULL;
        char *pwbname = NULL;
-       char *fname = NULL;
-       char *room = NULL;
-       char *wphone = NULL;
-       char *hphone = NULL;
-       char *other = NULL;
        char *newgecos = NULL;
-       char *username = NULL;
 
        char **gecosv = NULL;
 
-       struct option const options[] = {
-               { "fname", required_argument, 0, 'f' },
-               { "hphone", required_argument, 0, 'h' },
-               { "other", required_argument, 0, 'o' },
-               { "room", required_argument, 0, 'r' },
-               { "wphone", required_argument, 0, 'w' },
-               { "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;
+
        chperms = CH_ALL;
 
        errno = 0;
@@ -122,6 +177,11 @@ int main(int argc, char *argv[])
        if ((status = init_locales(PRG_NAME)))
                goto EXIT;
 
+       set_author_information(_("Written by David Weinehall.\n"));
+
+       /* Parse command line */
+       argp_parse(&argp, argc, argv, 0, 0, &args);
+
        /* Only user-admins are allowed to change the Other field */
        if ((status = is_useradmin())) {
                if (status == EPERM) {
@@ -137,149 +197,11 @@ int main(int argc, char *argv[])
                chperms |= CH_OTHER;
        }
 
-
-       /* Parse the command-line options */
-       while ((optc = getopt_long(argc, argv, "f:h:o:r:w:",
-                                  options, &opt_index)) != -1) {
-               switch (optc) {
-               case 'f':
-                       if ((status = is_valid_gecos_field(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: invalid value supplied to "
-                                         "`%s'\n"),
-                                       progname, "-f | --fname");
-                               goto EXIT;
-                       }
-
-                       if (!(fname = strdup(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: `%s' failed; %s\n"),
-                                       progname, "strdup()", strerror(errno));
-                               status = errno;
-                               goto EXIT;
-                       }
-
-                       break;
-
-               case 'r':
-                       if ((is_valid_gecos_field(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: invalid value supplied to "
-                                         "`%s'\n"),
-                                       progname, "-r | --room");
-                               goto EXIT;
-                       }
-
-                       if (!(room = strdup(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: `%s' failed; %s\n"),
-                                       progname, "strdup()", strerror(errno));
-                               status = errno;
-                               goto EXIT;
-                       }
-
-                       break;
-
-               case 'w':
-                       if ((status = is_valid_gecos_field(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: invalid value supplied to "
-                                         "`%s'\n"),
-                                       progname, "-w | --wphone");
-                               goto EXIT;
-                       }
-
-                       if (!(wphone = strdup(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: `%s' failed; %s\n"),
-                                       progname, "strdup()", strerror(errno));
-                               status = errno;
-                               goto EXIT;
-                       }
-
-                       break;
-
-               case 'h':
-                       if ((status = is_valid_gecos_field(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: invalid value supplied to "
-                                         "`%s'\n"),
-                                       progname, "-h | --hphone");
-                               goto EXIT;
-                       }
-
-                       if (!(hphone = strdup(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: `%s' failed; %s\n"),
-                                       progname, "strdup()", strerror(errno));
-                               status = errno;
-                               goto EXIT;
-                       }
-
-                       break;
-
-               case 'o':
-                       if ((status = is_valid_gecos_other(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: invalid value supplied to "
-                                         "`%s'\n"),
-                                       progname, "-o | --other");
-                               goto EXIT;
-                       }
-
-                       if (!(other = strdup(optarg))) {
-                               fprintf(stderr,
-                                       _("%s: `%s' failed; %s\n"),
-                                       progname, "strdup()", strerror(errno));
-                               status = errno;
-                               goto EXIT;
-                       }
-
-                       break;
-
-               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 an argument is supplied, it is the name
-        * of the user to change GECOS field comments for
-        */
-       if (optind != argc) {
-               if (!(username = strdup(argv[optind]))) {
-                       fprintf(stderr,
-                               _("%s: `%s' failed; %s\n"),
-                               progname, "strdup()", strerror(errno));
-                       status = errno;
-                       goto EXIT;
-               }
-       }
-
        /* Unless the user requests to change information about himself,
         * or calls the program as root, deny the request
         */
-       if (username && !isadmin) {
-               int retval = is_caller(username);
+       if (args.user && !isadmin) {
+               int retval = is_caller(args.user);
 
                if (retval == -1) {
                        fprintf(stderr,
@@ -302,8 +224,8 @@ int main(int argc, char *argv[])
        /* If no username was provided, retrieve the name
         * of the caller of the program
         */
-       if (!username) {
-               if (!(username = get_username(getuid()))) {
+       if (!args.user) {
+               if (!(args.user = get_username(getuid()))) {
                        status = errno;
                        goto EXIT;
                }
@@ -313,11 +235,11 @@ int main(int argc, char *argv[])
         * changes
         */
        if (!chperms ||
-           (!(chperms & CH_FNAME) && fname) ||
-           (!(chperms & CH_ROOM) && room) ||
-           (!(chperms & CH_WPHONE) && wphone) ||
-           (!(chperms & CH_HPHONE) && hphone) ||
-           (!(chperms & CH_OTHER) && other)) {
+           (!(chperms & CH_FNAME) && args.fname) ||
+           (!(chperms & CH_ROOM) && args.room) ||
+           (!(chperms & CH_WPHONE) && args.wphone) ||
+           (!(chperms & CH_HPHONE) && args.hphone) ||
+           (!(chperms & CH_OTHER) && args.other)) {
                fprintf(stderr,
                        _("%s: insufficient privileges to change "
                          "GECOS information\n"),
@@ -327,7 +249,7 @@ int main(int argc, char *argv[])
        }
 
        /* Verify that the user exists */
-       if (!(pw = getpwnam(username)) && errno) {
+       if (!(pw = getpwnam(args.user)) && errno) {
                fprintf(stderr,
                        _("%s: `%s' failed; %s\n"),
                        progname, "getpwnam()", strerror(errno));
@@ -356,12 +278,12 @@ int main(int argc, char *argv[])
        }
 
        /* If we have no options, enter interactive mode */
-       if (optind == 1) {
+       if (argc == 1) {
                fprintf(stdout,
                        _("Changing the user information for `%s'\n"
                          "Enter the new value, or press enter to keep "
                          "the old value\n"),
-                       username);
+                       args.user);
 
                /* Note: From now on we assume that the old information
                 * is untainted; if not some other program is to blame
@@ -372,7 +294,7 @@ int main(int argc, char *argv[])
                                gecosv[GE_FNAME]);
                        (void)fflush(stdout);
 
-                       if (!(fname = input_string(1))) {
+                       if (!(args.fname = input_string(1))) {
                                if (errno) {
                                        fprintf(stderr,
                                                _("%s: `%s' failed; %s\n"),
@@ -385,13 +307,12 @@ int main(int argc, char *argv[])
                                }
                        }
 
-                       if (!is_valid_gecos_field(fname))
+                       if (!is_valid_gecos_field(args.fname))
                                break;
 
                        fprintf(stderr, _("\nInvalid input\n\n"));
 
-                       free(fname);
-                       fname = NULL;
+                       args.fname = NULL;
                }
 
                while (chperms & CH_ROOM) {
@@ -400,7 +321,7 @@ int main(int argc, char *argv[])
                                gecosv[GE_ROOM]);
                        (void)fflush(stdout);
 
-                       if (!(room = input_string(1))) {
+                       if (!(args.room = input_string(1))) {
                                if (errno) {
                                        fprintf(stderr,
                                                _("%s: `%s' failed; %s\n"),
@@ -413,13 +334,12 @@ int main(int argc, char *argv[])
                                }
                        }
 
-                       if (!is_valid_gecos_field(room))
+                       if (!is_valid_gecos_field(args.room))
                                break;
 
                        fprintf(stderr, _("\nInvalid input\n\n"));
 
-                       free(room);
-                       room = NULL;
+                       args.room = NULL;
                }
 
                while (chperms & CH_WPHONE) {
@@ -428,7 +348,7 @@ int main(int argc, char *argv[])
                                gecosv[GE_WPHONE]);
                        (void)fflush(stdout);
 
-                       if (!(wphone = input_string(1))) {
+                       if (!(args.wphone = input_string(1))) {
                                if (errno) {
                                        fprintf(stderr,
                                                _("%s: `%s' failed; %s\n"),
@@ -441,13 +361,12 @@ int main(int argc, char *argv[])
                                }
                        }
 
-                       if (!is_valid_gecos_field(wphone))
+                       if (!is_valid_gecos_field(args.wphone))
                                break;
 
                        fprintf(stderr, _("\nInvalid input\n\n"));
 
-                       free(wphone);
-                       wphone = NULL;
+                       args.wphone = NULL;
                }
 
                while (chperms & CH_HPHONE) {
@@ -456,7 +375,7 @@ int main(int argc, char *argv[])
                                gecosv[GE_HPHONE]);
                        (void)fflush(stdout);
 
-                       if (!(hphone = input_string(1))) {
+                       if (!(args.hphone = input_string(1))) {
                                if (errno) {
                                        fprintf(stderr,
                                                _("%s: `%s' failed; %s\n"),
@@ -469,13 +388,12 @@ int main(int argc, char *argv[])
                                }
                        }
 
-                       if (!is_valid_gecos_field(hphone))
+                       if (!is_valid_gecos_field(args.hphone))
                                break;
 
                        fprintf(stderr, _("\nInvalid input\n\n"));
 
-                       free(hphone);
-                       hphone = NULL;
+                       args.hphone = NULL;
                }
 
                while (chperms & CH_OTHER) {
@@ -484,7 +402,7 @@ int main(int argc, char *argv[])
                                gecosv[GE_OTHER]);
                        (void)fflush(stdout);
 
-                       if (!(other = input_string(1))) {
+                       if (!(args.other = input_string(1))) {
                                if (errno) {
                                        fprintf(stderr,
                                                _("%s: `%s' failed; %s\n"),
@@ -497,29 +415,28 @@ int main(int argc, char *argv[])
                                }
                        }
 
-                       if (!is_valid_gecos_other(other))
+                       if (!is_valid_gecos_other(args.other))
                                break;
 
                        fprintf(stderr, _("\nInvalid input\n\n"));
 
-                       free(other);
-                       other = NULL;
+                       args.other = NULL;
                }
        }
 
        /* No new information specified, or the same as the old one;
         * exit without changes
         */
-       if ((!fname || !strcmp(fname, gecosv[GE_FNAME])) &&
-           (!room || !strcmp(room, gecosv[GE_ROOM])) &&
-           (!wphone || !strcmp(wphone, gecosv[GE_WPHONE])) &&
-           (!hphone || !strcmp(hphone, gecosv[GE_HPHONE])) &&
-           (!other || !strcmp(other, gecosv[GE_OTHER])))
+       if ((!args.fname || !strcmp(args.fname, gecosv[GE_FNAME])) &&
+           (!args.room || !strcmp(args.room, gecosv[GE_ROOM])) &&
+           (!args.wphone || !strcmp(args.wphone, gecosv[GE_WPHONE])) &&
+           (!args.hphone || !strcmp(args.hphone, gecosv[GE_HPHONE])) &&
+           (!args.other || !strcmp(args.other, gecosv[GE_OTHER])))
                goto EXIT;
 
        /* If fname is missing, copy the old string */
-       if (!fname) {
-               if (!(fname = strdup(gecosv[GE_FNAME]))) {
+       if (!args.fname) {
+               if (!(args.fname = strdup(gecosv[GE_FNAME]))) {
                        fprintf(stderr,
                                _("%s: `%s' failed; %s\n"),
                                progname, "strdup()", strerror(errno));
@@ -529,8 +446,8 @@ int main(int argc, char *argv[])
        }
 
        /* If room is missing, copy the old string */
-       if (!room) {
-               if (!(room = strdup(gecosv[GE_ROOM]))) {
+       if (!args.room) {
+               if (!(args.room = strdup(gecosv[GE_ROOM]))) {
                        fprintf(stderr,
                                _("%s: `%s' failed; %s\n"),
                                progname, "strdup()", strerror(errno));
@@ -540,8 +457,8 @@ int main(int argc, char *argv[])
        }
 
        /* If wphone is missing, copy the old string */
-       if (!wphone) {
-               if (!(wphone = strdup(gecosv[GE_WPHONE]))) {
+       if (!args.wphone) {
+               if (!(args.wphone = strdup(gecosv[GE_WPHONE]))) {
                        fprintf(stderr,
                                _("%s: `%s' failed; %s\n"),
                                progname, "strdup()", strerror(errno));
@@ -551,8 +468,8 @@ int main(int argc, char *argv[])
        }
 
        /* If hphone is missing, copy the old string */
-       if (!hphone) {
-               if (!(hphone = strdup(gecosv[GE_HPHONE]))) {
+       if (!args.hphone) {
+               if (!(args.hphone = strdup(gecosv[GE_HPHONE]))) {
                        fprintf(stderr,
                                _("%s: `%s' failed; %s\n"),
                                progname, "strdup()", strerror(errno));
@@ -562,8 +479,8 @@ int main(int argc, char *argv[])
        }
 
        /* If other is missing, copy the old string */
-       if (!other) {
-               if (!(other = strdup(gecosv[GE_OTHER]))) {
+       if (!args.other) {
+               if (!(args.other = strdup(gecosv[GE_OTHER]))) {
                        fprintf(stderr,
                                _("%s: `%s' failed; %s\n"),
                                progname, "strdup()", strerror(errno));
@@ -573,7 +490,7 @@ int main(int argc, char *argv[])
        }
 
        /* Join all gecos strings */
-       if (!(newgecos = join_gecos(fname, room, wphone, hphone, other))) {
+       if (!(newgecos = join_gecos(args.fname, args.room, args.wphone, 
args.hphone, args.other))) {
                status = errno;
                goto EXIT;
        }
@@ -627,7 +544,7 @@ int main(int argc, char *argv[])
                pw2.pw_gid = pw->pw_gid;
 
                /* If the entry is the user to edit, perform changes */
-               pw2.pw_gecos = strcmp(username, pw->pw_name) ? pw->pw_gecos :
+               pw2.pw_gecos = strcmp(args.user, pw->pw_name) ? pw->pw_gecos :
                                                               newgecos;
 
                pw2.pw_dir = pw->pw_dir;
@@ -678,13 +595,7 @@ EXIT:
        strfreev(gecosv);
        free(pwwname);
        free(pwbname);
-       free(fname);
-       free(room);
-       free(wphone);
-       free(hphone);
-       free(other);
        free(newgecos);
-       free(username);
 
        return status;
 }

reply via email to

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