[Top][All Lists]
[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;
}
- [Bug-sysutils] argp patch for chfn.c,
Barry deFreese <=