[Top][All Lists]
[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);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug-sysutils] argp patch for lsgroup,
Barry deFreese <=