bug-sysutils
[Top][All Lists]
Advanced

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

[Bug-sysutils] argp patch for lsgroup


From: Barry deFreese
Subject: [Bug-sysutils] argp patch for lsgroup
Date: Tue, 01 Jun 2004 19:14:17 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5

OK, here is lsgroup. It all seems to work OK. I'm not sure if you will like how I delt with the --attr options but let me know.

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/lsgroup.c
===================================================================
RCS file: /cvsroot/sysutils/sysutils/src/lsgroup.c,v
retrieving revision 1.3
diff -u -p -r1.3 lsgroup.c
--- src/lsgroup.c       27 May 2004 07:50:33 -0000      1.3
+++ src/lsgroup.c       2 Jun 2004 02:55:50 -0000
@@ -20,6 +20,7 @@
  *  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <argp.h>
 #include <grp.h>
 #include <errno.h>
 #include <stdio.h>
@@ -33,47 +34,106 @@
 
 #define PRG_NAME "lsgroup"
 
-extern int optind;
-extern char *optarg;
 extern const char *progname;
 
 static int gshadowread;
 
-/**
- * Show usage information
- */
-static void usage(void)
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
+static char doc[] =
+       N_("List attributes for the specified groups."
+          "\n"
+          "GROUPS should be a comma-separated list of groups, "
+          "or the word ALL to list all groups");
+
+static char args_doc[] = N_("[GROUP(S)]");
+
+static struct argp_option options[] = {
+       {"attr", 'a', N_("ATTRS"), 0,
+         N_("display only the attributes "
+            "specified by a comma-separated list; "
+            "valid attributes are: "
+            "adms, group_locked | locked, id | gid, and users"), 0 },
+       {"colon", 'c', 0, OPTION_ARG_OPTIONAL,
+         N_("display the attributes as colon-seperated records"), 0 },
+       {"stanza", 'f', 0, OPTION_ARG_OPTIONAL,
+         N_("display the attribues as stanzas"), 0 },
+       {"list", 'l', 0, OPTION_ARG_OPTIONAL,
+         N_("list the names of all groups, "
+            "separated by commas\n"), 0 },
+       {"verbose", 'v', 0, OPTION_ARG_OPTIONAL,
+         N_("warn if the specified groups do not exist"), 0 },
+       { 0, 0, 0, 0, 0, 0 }
+};
+
+/* Available arguments */
+struct arguments {
+       char *attrs;
+       long colon;
+       long stanza;
+       long normal;
+       long list;
+       long verbose;
+       char *groups;
+};
+
+/* Parse a single option */
+static error_t parse_opt(int key, char *arg, struct argp_state *state)
 {
-       fprintf(stdout,
-               _("Usage: %s [OPTION]... GROUPS\n"
-                 "List attributes for the specified groups.\n"
-                 "\n"
-                 "GROUPS should be a comma-separated list of groups,\n"
-                 "or the word ALL to list all groups\n"
-                 "\n"
-                 "  -a, --attr=[ATTRS]     display only the attributes "
-                 "specified\n"
-                 "                           by a comma-separated list; "
-                 "valid attributes are:\n"
-                 "                           %s%s%s%s%s%s%s | %s, and %s\n"
-                 "  -c, --colon            display the attributes as "
-                 "colon-separated records\n"
-                 "  -f, --stanza           display the attributes as "
-                 "stanzas\n"
-                 "  -l, --list             list the names of all groups, "
-                 "separated by commas\n"
-                 "      --verbose          warn if the specified groups "
-                 "does not exist\n"),
-               progname,
-               gshadowread ? AS_ADMS : "",
-               gshadowread ? ", " : "",
-               gshadowread ? AS_G_LOCKED : "",
-               gshadowread ? " | " : "",
-               gshadowread ? AS_LOCKED : "",
-               gshadowread ? ", " : "",
-               AS_ID, AS_GID, AS_USERS);
-       usage_help();
-}
+       struct arguments *args = state->input;
+
+       switch (key) {
+       case 'a':
+               args->attrs = arg;
+               break;
+
+       case 'c':
+               args->colon = 1;
+               args->normal = 0;
+               break;
+
+       case 'f':
+               args->stanza = 1;
+               args->normal = 0;
+               break;
+
+       case 'l':
+               args->list = 1;
+               break;
+
+       case 'v':
+               args->verbose = 1;
+               break;
+
+       case ARGP_KEY_INIT:
+               args->attrs = NULL;
+               args->colon = 0;
+               args->stanza = 0;
+               args->list = 0;
+               args->normal = 1;
+               args->verbose = 0;
+               args->groups = NULL;
+               break;
+
+       case ARGP_KEY_ARG:
+               if (args->groups)
+                       argp_usage(state);
+
+               args->groups = arg;
+
+               break;
+
+       case ARGP_KEY_NO_ARGS:
+               if (!args->list)
+                       argp_usage(state);
+       
+               break;
+
+       default:
+               return ARGP_ERR_UNKNOWN;
+       }
+       return 0;
+}      
 
 /**
  * The program's main-function
@@ -84,175 +144,95 @@ static void usage(void)
  */
 int main(int argc, char *argv[])
 {
-       int verbose = 0;
-
-       int optc;
-       int opt_index;
-
        int status = 0;
 
-       int mode = M_NORMAL;
-
        unsigned int attr = A_ALL;
 
        char **grparray = NULL;
 
        gid_t i; /* We're scanning <= LASTGID, hence gid_t */
 
-       struct option const options[] = {
-               { "attr", optional_argument, 0, 'a' },
-               { "colon", no_argument, 0, M_COLON },
-               { "stanza", no_argument, 0, M_STANZA },
-               { "list", no_argument, 0, M_LIST },
-               { "verbose", no_argument, 0, 'v' },
-               { "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;
 
-       /* Find out if we're allowed to read the gshadow file */
-       if (!(gshadowread = !access(GSHADOW_FILE, R_OK))) {
-               if (errno == EACCES || errno == ENOENT) {
-                       errno = 0;
-                       attr &= ~A_LOCKED;
-                       attr &= ~A_ADMS;
-               } else {
-                       fprintf(stderr,
-                               _("%s: `%s' failed; %s\n"),
-                               progname, "access()", strerror(errno));
-                       status = errno;
-                       goto EXIT;
-               }
-       }
+       set_author_information(_("Written by David Weinehall.\n"));
 
-       /* Parse the command-line options */
-       while ((optc = getopt_long(argc, argv, "a::cfl",
-                                  options, &opt_index)) != -1) {
+       /* Parse command line */
+       argp_parse(&argp, argc, argv, 0, 0, &args);
+
+       /* Parse the attributes if --attr is used */
+       if (args.attrs) {
                char **attrarray = NULL;
 
-               switch (optc) {
-               case 'a':
-                       attr = A_NAME;
+               attr = A_NAME;
 
-                       if (!optarg)
-                               break;
+               if (!(attrarray = strsplit(args.attrs, ",", 0))) {
+                       fprintf(stderr,
+                               _("%s: '%s' failed; %s\n"),
+                               progname, "strsplit", strerror(errno));
+                       status = errno;
+                       goto EXIT;
+               }
 
-                       if (!(attrarray = strsplit(optarg, ",", 0))) {
+               for (i = 0; attrarray[i]; i++) {
+                       if (!strcmp(attrarray[i], AS_ID)) {
+                               attr |= A_ID;
+                       } else if (!strcmp(attrarray[i], AS_GID)) {
+                               attr |= A_ID;
+                       } else if (!strcmp(attrarray[i], AS_USERS)) {
+                               attr |= A_USERS;
+                       } else if (gshadowread && 
+                                       !strcmp(attrarray[i], AS_LOCKED)) {
+                               attr |= A_LOCKED;
+                       } else if (gshadowread &&
+                                       !strcmp(attrarray[i], AS_G_LOCKED)) {
+                               attr |= A_LOCKED;
+                       } else if (gshadowread &&
+                                       !strcmp(attrarray[i], AS_ADMS)) {
+                               attr |= A_ADMS;
+                       } else {
                                fprintf(stderr,
-                                       _("%s: `%s' failed; %s\n"),
-                                       progname, "strsplit", strerror(errno));
-                               status = errno;
-                               goto EXIT;
-                       }
+                                       _("%s: invalid attributes "
+                                         "for '--attr'\n"
+                                         "Valid attributes are:\n"
+                                         "adms, group_locked | locked, id | 
gid, and users\n"),
+                                       progname);
 
-                       for (i = 0; attrarray[i]; i++) {
-                               if (!strcmp(attrarray[i], AS_ID)) {
-                                       attr |= A_ID;
-                               } else if (!strcmp(attrarray[i], AS_GID)) {
-                                       attr |= A_ID;
-                               } else if (!strcmp(attrarray[i], AS_USERS)) {
-                                       attr |= A_USERS;
-                               } else if (gshadowread &&
-                                          !strcmp(attrarray[i], AS_LOCKED)) {
-                                       attr |= A_LOCKED;
-                               } else if (gshadowread &&
-                                          !strcmp(attrarray[i], AS_G_LOCKED)) {
-                                       attr |= A_LOCKED;
-                               } else if (gshadowread &&
-                                          !strcmp(attrarray[i], AS_ADMS)) {
-                                       attr |= A_ADMS;
-                               } else {
-                                       fprintf(stderr,
-                                               _("%s: invalid attributes "
-                                                 "for `--attr'\n"
-                                                 "Valid attributes are:\n"
-                                                 "%s%s%s"
-                                                 "%s%s%s%s%s"
-                                                 "- `%s' | `%s'\n"
-                                                 "- `%s'\n"
-                                                 "Try `%s --help' for more "
-                                                 "information.\n"),
-                                               progname,
-                                               gshadowread ? "- `" : "",
-                                               gshadowread ? AS_ADMS : "",
-                                               gshadowread ? "'\n" : "",
-                                               gshadowread ? "- `" : "",
-                                               gshadowread ? AS_G_LOCKED : "",
-                                               gshadowread ? "' | `" : "",
-                                               gshadowread ? AS_LOCKED : "",
-                                               gshadowread ? "'\n" : "",
-                                               AS_ID, AS_GID,
-                                               AS_USERS,
-                                               progname);
-                                       status = EINVAL;
-                                       strfreev(attrarray);
-                                       goto EXIT;
-                               }
-                       }
-
-                       strfreev(attrarray);
-                       break;
-
-               case M_COLON:
-               case M_STANZA:
-               case M_LIST:
-                       if (mode != M_NORMAL && mode != (char)optc) {
-                               fprintf(stderr,
-                                       _("%s: `-c', `-f' and `-l' cannot be "
-                                         "combined\n"
-                                         "Try `%s --help' for more "
-                                         "information.\n"),
-                                       progname, progname);
                                status = EINVAL;
+                               strfreev(attrarray);
                                goto EXIT;
                        }
+               }
+       }
 
-                       mode = (char)optc;
-                       break;
-
-               case 'v':
-                       verbose = 1;
-                       break;
-
-               case 'h':
-                       usage();
-                       goto EXIT;
-
-               case 'V':
-                       version();
-                       goto EXIT;
 
-               default:
-                       usage();
-                       status = EINVAL;
+       /* Find out if we're allowed to read the gshadow file */
+       if (!(gshadowread = !access(GSHADOW_FILE, R_OK))) {
+               if (errno == EACCES || errno == ENOENT) {
+                       errno = 0;
+                       attr &= ~A_LOCKED;
+                       attr &= ~A_ADMS;
+               } else {
+                       fprintf(stderr,
+                               _("%s: `%s' failed; %s\n"),
+                               progname, "access()", strerror(errno));
+                       status = errno;
                        goto EXIT;
                }
        }
 
-       /* Make sure we get the correct number of arguments */
-       if (optind == argc && mode != M_LIST) {
-               fprintf(stderr,
-                       _("%s: too few arguments\n"
-                         "Try `%s --help' for more information.\n"),
-                       progname, progname);
-               status = EINVAL;
-               goto EXIT;
-       } else if ((optind < argc && mode == M_LIST) ||
-                  ((argc - optind) > 1)) {
-               fprintf(stderr,
-                       _("%s: too many arguments\n"
-                         "Try `%s --help' for more information.\n"),
-                       progname, progname);
-               status = EINVAL;
-               goto EXIT;
-       }
-
        /* There are two alternatives here, neither of which are really
         * pretty; either to read the entire group file once to get
         * all groupnames, then use them for the ALL list, or to
@@ -260,7 +240,7 @@ int main(int argc, char *argv[])
         * group-entries.  Since the latter is probably the most common,
         * the latter has been chosen.
         */
-       if (mode == M_LIST || !strcmp(argv[argc - 1], "ALL")) {
+       if (args.list || !strcmp(args.groups, "ALL")) {
                char *tmp = NULL;
 
                if (!(tmp = get_all_groups())) {
@@ -271,7 +251,7 @@ int main(int argc, char *argv[])
                                  "might be corrupt\n"),
                                progname, _("groups"), _("group database"));
                        status = ENOENT;
-               } else if (mode == M_LIST) {
+               } else if (args.list) {
                        fprintf(stdout, "%s\n", tmp);
                } else if (!(grparray = strsplit(tmp, ",", 0))) {
                        fprintf(stderr,
@@ -282,10 +262,10 @@ int main(int argc, char *argv[])
 
                free(tmp);
 
-               if (status || mode == M_LIST)
+               if (status || args.list)
                        goto EXIT;
        } else {
-               if (!(grparray = strsplit(argv[argc - 1], ",", 0))) {
+               if (!(grparray = strsplit(args.groups, ",", 0))) {
                        fprintf(stderr,
                                _("%s: `%s' failed; %s\n"),
                                progname, "strsplit", strerror(errno));
@@ -312,7 +292,7 @@ int main(int argc, char *argv[])
 
                /* Skip non-existing entries */
                if (!gr) {
-                       if (verbose)
+                       if (args.verbose)
                                fprintf(stderr,
                                        _("%s: warning: %s `%s' "
                                          "does not exist\n"),
@@ -348,7 +328,7 @@ int main(int argc, char *argv[])
                }
 
                /* Output all information */
-               if (mode == M_NORMAL) {
+               if (args.normal) {
                        fprintf(stdout, "%s", gr->gr_name);
 
                        if (attr & A_LOCKED)
@@ -371,7 +351,7 @@ int main(int argc, char *argv[])
                                fprintf(stdout,
                                        " %s=%s",
                                        _("adms"), admlist);
-               } else if (mode == M_COLON) {
+               } else if (args.colon) {
                        fprintf(stdout,
                                "#%s%s%s%s%s%s%s%s%s",
                                _("name"),
@@ -426,7 +406,7 @@ int main(int argc, char *argv[])
 
                fprintf(stdout, "\n");
 
-               if (mode == M_STANZA)
+               if (args.stanza)
                        fprintf(stdout, "\n");
 
                free(admlist);

reply via email to

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